policer.c (86761B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 */ 7 8 #include <shared/bsl.h> 9 10 #include <soc/debug.h> 11 #include <soc/drv.h> 12 #include <soc/scache.h> 13 #include <soc/mem.h> 14 #include <bcm/error.h> 15 #include <bcm/types.h> 16 #include <bcm/policer.h> 17 #include <bcm/field.h> 18 #if defined(BCM_GREYHOUND2_SUPPORT) 19 #include <bcm_int/esw/greyhound2.h> 20 #include <bcm_int/esw/policer.h> 21 #if defined(BCM_GLOBAL_METER_V2_SUPPORT) 22 23 #define GH2_GLOBAL_METER_TCAM_SIZE (SOC_INFO(unit).global_meter_tcam_size) 24 25 #define UNKNOWN_PKT (0x00) 26 #define CONTROL_PKT (0x01) 27 #define OAM_PKT (0x02) 28 #define BFD_PKT (0x03) 29 #define BPDU_PKT (0x04) 30 #define ICNM_PKT (0x05) 31 #define PKT_IS_1588 (0x06) 32 #define KNOWN_L2UC_PKT (0x07) 33 34 #define UNKNOWN_L2UC_PKT (0x08) 35 #define KNOWN_L2MC_PKT (0x09) 36 #define UNKNOWN_L2MC_PKT (0x0a) 37 #define L2BC_PKT (0x0b) 38 #define KNOWN_L3UC_PKT (0x0c) 39 #define UNKNOWN_L3UC_PKT (0x0d) 40 #define KNOWN_IPMC_PKT (0x0e) 41 #define UNKNOWN_IPMC_PKT (0x0f) 42 43 #define KNOWN_MPLS_L2_PKT (0x10) 44 #define UNKNOWN_MPLS_PKT (0x11) 45 #define KNOWN_MPLS_L3_PKT (0x12) 46 #define KNOWN_MPLS_PKT (0x13) 47 #define KNOWN_MPLS_MULTICAST_PKT (0x14) 48 #define KNOWN_MIM_PKT (0x15) 49 #define UNKNOWN_MIM_PKT (0x16) 50 #define KNOWN_TRILL_PKT (0x17) 51 52 #define UNKNOWN_TRILL_PKT (0x18) 53 #define KNOWN_NIV_PKT (0x19) 54 #define UNKNOWN_NIV_PKT (0x1a) 55 #define KNOWN_L2GRE_PKT (0x1b) 56 #define KNOWN_VDL2_PKT (0x1c) 57 #define KNOWN_FCOE_PKT (0x1d) 58 #define UNKNOWN_FCOE_PKT (0x1e) 59 #define SAT_DN_SAMP_RX (0x1f) 60 #define FP_RESOLUTION_MAX (0x20) /* Max value */ 61 62 /* For those unsupported packets will be mapped to 0 (GH2_UNKNOWN_PKT_VAL) */ 63 #define GH2_UNKNOWN_PKT_VAL (0) 64 65 #define GH2_CONTROL_PKT_VAL (1) 66 #define GH2_OAM_PKT_VAL (18) 67 #define GH2_BFD_PKT_VAL (GH2_UNKNOWN_PKT_VAL) 68 #define GH2_BPDU_PKT_VAL (2) 69 #define GH2_ICNM_PKT_VAL (GH2_UNKNOWN_PKT_VAL) 70 #define GH2_PKT_IS_1588_VAL (19) 71 #define GH2_KNOWN_L2UC_PKT_VAL (4) 72 73 #define GH2_UNKNOWN_L2UC_PKT_VAL (5) 74 #define GH2_KNOWN_L2MC_PKT_VAL (8) 75 #define GH2_UNKNOWN_L2MC_PKT_VAL (9) 76 #define GH2_L2BC_PKT_VAL (3) 77 #define GH2_KNOWN_L3UC_PKT_VAL (10) 78 #define GH2_UNKNOWN_L3UC_PKT_VAL (11) 79 #define GH2_KNOWN_IPMC_PKT_VAL (7) 80 #define GH2_UNKNOWN_IPMC_PKT_VAL (6) 81 82 #define GH2_KNOWN_MPLS_L2_PKT_VAL (14) 83 #define GH2_UNKNOWN_MPLS_PKT_VAL (15) 84 #define GH2_KNOWN_MPLS_L3_PKT_VAL (13) 85 #define GH2_KNOWN_MPLS_PKT_VAL (12) 86 #define GH2_KNOWN_MPLS_MULTICAST_PKT_VAL (GH2_UNKNOWN_PKT_VAL) 87 #define GH2_KNOWN_MIM_PKT_VAL (16) 88 #define GH2_UNKNOWN_MIM_PKT_VAL (17) 89 #define GH2_KNOWN_TRILL_PKT_VAL (GH2_UNKNOWN_PKT_VAL) 90 91 #define GH2_UNKNOWN_TRILL_PKT_VAL (GH2_UNKNOWN_PKT_VAL) 92 #define GH2_KNOWN_NIV_PKT_VAL (20) 93 #define GH2_UNKNOWN_NIV_PKT_VAL (21) 94 #define GH2_KNOWN_L2GRE_PKT_VAL (GH2_UNKNOWN_PKT_VAL) 95 #define GH2_KNOWN_VDL2_PKT_VAL (GH2_UNKNOWN_PKT_VAL) 96 #define GH2_KNOWN_FCOE_PKT_VAL (GH2_UNKNOWN_PKT_VAL) 97 #define GH2_UNKNOWN_FCOE_PKT_VAL (GH2_UNKNOWN_PKT_VAL) 98 #define GH2_SAT_DN_SAMP_RX_VAL (GH2_UNKNOWN_PKT_VAL) 99 100 /* 101 * Refer to FP_RESOLUTION in reg bcm53570_a0 102 */ 103 STATIC const uint8 bcmi_gh2_global_meter_pkt_res[FP_RESOLUTION_MAX] = 104 { 105 GH2_UNKNOWN_PKT_VAL, 106 GH2_CONTROL_PKT_VAL, 107 GH2_OAM_PKT_VAL, 108 GH2_BFD_PKT_VAL, 109 GH2_BPDU_PKT_VAL, 110 GH2_ICNM_PKT_VAL, 111 GH2_PKT_IS_1588_VAL, 112 GH2_KNOWN_L2UC_PKT_VAL, 113 114 GH2_UNKNOWN_L2UC_PKT_VAL, 115 GH2_KNOWN_L2MC_PKT_VAL, 116 GH2_UNKNOWN_L2MC_PKT_VAL, 117 GH2_L2BC_PKT_VAL, 118 GH2_KNOWN_L3UC_PKT_VAL, 119 GH2_UNKNOWN_L3UC_PKT_VAL, 120 GH2_KNOWN_IPMC_PKT_VAL, 121 GH2_UNKNOWN_IPMC_PKT_VAL, 122 123 GH2_KNOWN_MPLS_L2_PKT_VAL, 124 GH2_UNKNOWN_MPLS_PKT_VAL, 125 GH2_KNOWN_MPLS_L3_PKT_VAL, 126 GH2_KNOWN_MPLS_PKT_VAL, 127 GH2_KNOWN_MPLS_MULTICAST_PKT_VAL, 128 GH2_KNOWN_MIM_PKT_VAL, 129 GH2_UNKNOWN_MIM_PKT_VAL, 130 GH2_KNOWN_TRILL_PKT_VAL, 131 132 GH2_UNKNOWN_TRILL_PKT_VAL, 133 GH2_KNOWN_NIV_PKT_VAL, 134 GH2_UNKNOWN_NIV_PKT_VAL, 135 GH2_KNOWN_L2GRE_PKT_VAL, 136 GH2_KNOWN_VDL2_PKT_VAL, 137 GH2_KNOWN_FCOE_PKT_VAL, 138 GH2_UNKNOWN_FCOE_PKT_VAL, 139 GH2_SAT_DN_SAMP_RX_VAL 140 }; 141 142 /* Parameter NULL error handling */ 143 #define GH2_POL_CHECK_NULL_PARAMETER(_u_, _parameter_) \ 144 do { \ 145 if (NULL == (_parameter_)) { \ 146 LOG_ERROR(BSL_LS_BCM_POLICER, \ 147 (BSL_META_U((_u_), \ 148 "Error: NULL parameter\n"))); \ 149 return BCM_E_PARAM; \ 150 } \ 151 } while (0) 152 153 /* Function Enter/Leave Tracing */ 154 #define GH2_POL_FUNCTION_TRACE(_u_, _str_) \ 155 do { \ 156 LOG_VERBOSE(BSL_LS_BCM_POLICER, \ 157 (BSL_META_U((_u_), \ 158 "%s: " _str_ "\n"), __FUNCTION__)); \ 159 } while (0) 160 161 /* Function DEBUG Tracing */ 162 #define GH2_POL_FUNCTION_DEBUG(_u_, fmt, _args_) \ 163 do { \ 164 LOG_DEBUG(BSL_LS_BCM_POLICER, \ 165 (BSL_META_U((_u_), \ 166 "%s: " fmt "\n"), __FUNCTION__, _args_)); \ 167 } while (0) 168 169 /* Function ERROR Tracing */ 170 #define GH2_POL_FUNCTION_ERROR(_u_, fmt, _args_) \ 171 do { \ 172 LOG_ERROR(BSL_LS_BCM_POLICER, \ 173 (BSL_META_U((_u_), \ 174 fmt "\n"), _args_)); \ 175 } while (0) 176 177 /* Check if bcm_policer_action_t is supported or not */ 178 STATIC int 179 bcmi_gh2_action_supported( 180 int unit, 181 bcm_policer_action_t action) 182 { 183 bcm_error_t rv = BCM_E_UNAVAIL; 184 185 switch (action) { 186 case bcmPolicerActionGpDrop: 187 case bcmPolicerActionYpDrop: 188 case bcmPolicerActionRpDrop: 189 case bcmPolicerActionGpEcnNew: 190 case bcmPolicerActionYpEcnNew: 191 case bcmPolicerActionRpEcnNew: 192 case bcmPolicerActionGpDscpNew: 193 case bcmPolicerActionYpDscpNew: 194 case bcmPolicerActionRpDscpNew: 195 case bcmPolicerActionGpPrioIntNew: 196 case bcmPolicerActionYpPrioIntNew: 197 case bcmPolicerActionRpPrioIntNew: 198 case bcmPolicerActionGpCngNew: 199 case bcmPolicerActionYpCngNew: 200 case bcmPolicerActionRpCngNew: 201 case bcmPolicerActionGpVlanPrioNew: 202 case bcmPolicerActionYpVlanPrioNew: 203 case bcmPolicerActionRpVlanPrioNew: 204 case bcmPolicerActionGpIntCongestionNotificationNew: 205 case bcmPolicerActionYpIntCongestionNotificationNew: 206 case bcmPolicerActionRpIntCongestionNotificationNew: 207 { 208 /* Supported */ 209 rv = BCM_E_NONE; 210 break; 211 } 212 default: 213 { 214 /* Not Supported */ 215 rv = BCM_E_UNAVAIL; 216 break; 217 } 218 } 219 220 return rv; 221 } 222 223 /* Check if bcm_policer_group_mode_type_t is supported or not */ 224 STATIC int 225 bcmi_gh2_group_mode_type_supported( 226 int unit, 227 bcm_policer_group_mode_type_t group_mode_type) 228 { 229 /* GH2 doesn't support Cascade metering */ 230 if (group_mode_type != bcmPolicerGroupModeTypeNormal) { 231 GH2_POL_FUNCTION_ERROR(unit, 232 "Greyhound2 only support following bcm_policer_group_mode_type_t :" 233 "bcmPolicerGroupModeTypeNormal(%d)", 234 bcmPolicerGroupModeTypeNormal); 235 return BCM_E_UNAVAIL; 236 } 237 238 return BCM_E_NONE; 239 } 240 241 /* Check if bcm_policer_group_mode_t is supported or not */ 242 STATIC int 243 bcmi_gh2_group_mode_supported( 244 int unit, 245 bcm_policer_group_mode_t group_mode) 246 { 247 bcm_error_t rv = BCM_E_UNAVAIL; 248 249 switch (group_mode) { 250 case bcmPolicerGroupModeSingle: 251 case bcmPolicerGroupModeTrafficType: 252 case bcmPolicerGroupModeDlfAll: 253 case bcmPolicerGroupModeTyped: 254 case bcmPolicerGroupModeTypedAll: 255 case bcmPolicerGroupModeSingleWithControl: 256 case bcmPolicerGroupModeTrafficTypeWithControl: 257 case bcmPolicerGroupModeDlfAllWithControl: 258 case bcmPolicerGroupModeTypedWithControl: 259 case bcmPolicerGroupModeTypedAllWithControl: 260 case bcmPolicerGroupModeDot1P: 261 case bcmPolicerGroupModeInnerDot1P: 262 case bcmPolicerGroupModeIntPri: 263 case bcmPolicerGroupModeShortIntPri: 264 case bcmPolicerGroupModeDlfIntPri: 265 case bcmPolicerGroupModeTypedIntPri: 266 case bcmPolicerGroupModeDlfIntPriWithControl: 267 case bcmPolicerGroupModeTypedIntPriWithControl: 268 case bcmPolicerGroupModePreemptable: 269 { 270 /* Supported */ 271 rv = BCM_E_NONE; 272 break; 273 } 274 default: 275 { 276 /* Not Supported */ 277 rv = BCM_E_UNAVAIL; 278 break; 279 } 280 } 281 282 return rv; 283 } 284 285 /* Check if bcm_policer_group_mode_attr_t is supported or not */ 286 STATIC int 287 bcmi_gh2_group_mode_attr_supported( 288 int unit, 289 bcm_policer_group_mode_attr_t group_mode_attr) 290 { 291 bcm_error_t rv = BCM_E_UNAVAIL; 292 293 switch (group_mode_attr) { 294 case bcmPolicerGroupModeAttrFieldIngressColor: 295 case bcmPolicerGroupModeAttrIntPri: 296 case bcmPolicerGroupModeAttrVlan: 297 case bcmPolicerGroupModeAttrOuterPri: 298 case bcmPolicerGroupModeAttrInnerPri: 299 case bcmPolicerGroupModeAttrPort: 300 case bcmPolicerGroupModeAttrTosDscp: 301 case bcmPolicerGroupModeAttrPktType: 302 case bcmPolicerGroupModeAttrPreemptable: 303 case bcmPolicerGroupModeAttrEtherType: 304 case bcmPolicerGroupModeAttrOuterVlanCfi: 305 case bcmPolicerGroupModeAttrInnerVlanCfi: 306 { 307 /* Supported */ 308 rv = BCM_E_NONE; 309 break; 310 } 311 default: 312 { 313 /* Not Supported */ 314 rv = BCM_E_UNAVAIL; 315 break; 316 } 317 } 318 return rv; 319 } 320 321 /* Clear all meter tables */ 322 STATIC int 323 bcmi_gh2_global_meter_mem_clear(int unit) 324 { 325 bcm_error_t rv = BCM_E_NONE; 326 int i; 327 static const soc_mem_t clear_mem_list[] = { 328 SVM_METER_TABLEm, 329 SVM_POLICY_TABLEm, 330 SVC_METER_OFFSET_TCAMm, 331 SVC_METER_OFFSET_POLICY_TABLEm 332 }; 333 334 GH2_POL_FUNCTION_TRACE(unit, "IN"); 335 336 for (i = 0; 337 i < sizeof(clear_mem_list) / sizeof(soc_mem_t); 338 i++) { 339 soc_mem_lock(unit, clear_mem_list[i]); 340 rv = soc_mem_clear(unit, clear_mem_list[i], MEM_BLOCK_ALL, TRUE); 341 soc_mem_unlock(unit, clear_mem_list[i]); 342 BCM_IF_ERROR_RETURN(rv); 343 } 344 345 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 346 return rv; 347 } 348 349 /* Clear a range (base_index ~ base_index + numbers) of meter table */ 350 STATIC int 351 bcmi_gh2_global_meter_mem_range_clear( 352 int unit, 353 int base_index, 354 uint32 numbers) 355 { 356 bcm_error_t rv = BCM_E_NONE; 357 soc_mem_t policy_mem = SVM_POLICY_TABLEm; 358 soc_mem_t meter_mem = SVM_METER_TABLEm; 359 svm_policy_table_entry_t *policy_entry_buf; 360 svm_meter_table_entry_t *svm_meter_buf; 361 int entry_mem_size; /* Size of table entry. */ 362 int entry_index_max = 0; 363 int meter_base_index; 364 uint32 meter_numbers; 365 366 367 GH2_POL_FUNCTION_TRACE(unit, "IN"); 368 369 /* Clear base_index ~ base_index + numbers of SVM_POLICY_TABLEm */ 370 entry_mem_size = sizeof(svm_policy_table_entry_t); 371 entry_index_max = base_index + numbers - 1; 372 policy_entry_buf = 373 soc_cm_salloc(unit, entry_mem_size * numbers, 374 "svm policy table entry"); 375 if (policy_entry_buf == NULL) { 376 return BCM_E_MEMORY; 377 } 378 sal_memset(policy_entry_buf, 0, entry_mem_size * numbers); 379 380 soc_mem_lock(unit, policy_mem); 381 rv = soc_mem_write_range( 382 unit, policy_mem, MEM_BLOCK_ALL, base_index, 383 entry_index_max, policy_entry_buf); 384 soc_mem_unlock(unit, policy_mem); 385 386 if (policy_entry_buf != NULL) { 387 soc_cm_sfree(unit, policy_entry_buf); 388 } 389 BCM_IF_ERROR_RETURN(rv); 390 391 /* Clear base_index*2 ~ base_index*2 + numbers*2 of SVM_METER_TABLEm */ 392 meter_base_index = base_index * 2; 393 meter_numbers = numbers * 2; 394 395 entry_mem_size = sizeof(svm_meter_table_entry_t); 396 entry_index_max = meter_base_index + meter_numbers - 1; 397 svm_meter_buf = 398 soc_cm_salloc(unit, entry_mem_size * meter_numbers, 399 "svm meter table entry"); 400 if (svm_meter_buf == NULL) { 401 return BCM_E_MEMORY; 402 } 403 sal_memset(svm_meter_buf, 0, entry_mem_size * meter_numbers); 404 405 soc_mem_lock(unit, meter_mem); 406 rv = soc_mem_write_range( 407 unit, meter_mem, MEM_BLOCK_ALL, meter_base_index, 408 entry_index_max, svm_meter_buf); 409 soc_mem_unlock(unit, meter_mem); 410 411 if (svm_meter_buf != NULL) { 412 soc_cm_sfree(unit, svm_meter_buf); 413 } 414 415 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 416 return rv; 417 } 418 419 /* 420 * Function: 421 * bcmi_gh2_global_meter_ifg_set 422 * Purpose: 423 * Enable/Disable Inter Frame Gap(IFG) 424 * Parameters: 425 * unit - (IN) unit number 426 * ifg_enable - (IN) Enable/disable 427 * Returns: 428 * BCM_E_XXX 429 */ 430 STATIC int 431 bcmi_gh2_global_meter_ifg_set( 432 int unit, 433 uint8 ifg_enable) 434 { 435 uint32 rval = 0, val; 436 437 GH2_POL_FUNCTION_TRACE(unit, "IN"); 438 GH2_POL_FUNCTION_DEBUG(unit, "ifg_set %d", ifg_enable); 439 440 if (ifg_enable) { 441 val = 1; 442 } else { 443 val = 0; 444 } 445 446 BCM_IF_ERROR_RETURN(READ_SVM_TSN_CONTROLr(unit, &rval)); 447 soc_reg_field_set(unit, 448 SVM_TSN_CONTROLr, 449 &rval, 450 SVM_PACKET_IFG_ENf, 451 val); 452 BCM_IF_ERROR_RETURN(WRITE_SVM_TSN_CONTROLr(unit, rval)); 453 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 454 return BCM_E_NONE; 455 } 456 457 /* 458 * Function: 459 * bcmi_gh2_global_meter_ifg_get 460 * Purpose: 461 * Get Enable/Disable Inter Frame Gap(IFG) 462 * Parameters: 463 * unit - (IN) unit number 464 * ifg_enable - (OUT) Enable/disable 465 * Returns: 466 * BCM_E_XXX 467 */ 468 STATIC int 469 bcmi_gh2_global_meter_ifg_get( 470 int unit, 471 uint8 *ifg_enable) 472 { 473 uint32 rval = 0; 474 475 GH2_POL_FUNCTION_TRACE(unit, "IN"); 476 477 /* Parameter NULL error handling */ 478 GH2_POL_CHECK_NULL_PARAMETER(unit, ifg_enable); 479 480 BCM_IF_ERROR_RETURN(READ_SVM_TSN_CONTROLr(unit, &rval)); 481 *ifg_enable = (uint8)soc_reg_field_get(unit, 482 SVM_TSN_CONTROLr, 483 rval, 484 SVM_PACKET_IFG_ENf); 485 486 GH2_POL_FUNCTION_DEBUG(unit, "ifg_set %d", *ifg_enable); 487 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 488 return BCM_E_NONE; 489 } 490 491 /* 492 * Function: 493 * bcmi_gh2_global_meter_enable 494 * Purpose: 495 * Enable/Disable SVM Control block 496 * Parameters: 497 * unit - (IN) unit number 498 * enabled - (IN) Enable/disable 499 * Returns: 500 * BCM_E_XXX 501 */ 502 STATIC int 503 bcmi_gh2_global_meter_enable( 504 int unit, 505 uint8 enable) 506 { 507 uint32 rval = 0, val; 508 509 GH2_POL_FUNCTION_TRACE(unit, "IN"); 510 GH2_POL_FUNCTION_DEBUG(unit, "enable %d", enable); 511 512 if (enable) { 513 val = 0; 514 } else { 515 val = 1; 516 } 517 BCM_IF_ERROR_RETURN(READ_SVM_TSN_CONTROLr(unit, &rval)); 518 soc_reg_field_set(unit, SVM_TSN_CONTROLr, &rval, SVM_BLOCK_DISABLEf, val); 519 BCM_IF_ERROR_RETURN(WRITE_SVM_TSN_CONTROLr(unit, rval)); 520 521 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 522 return BCM_E_NONE; 523 } 524 525 /* 526 * Function: 527 * bcmi_gh2_global_meter_enable_get 528 * Purpose: 529 * Get Enable/Disable of SVM Control block 530 * Parameters: 531 * unit - (IN) unit number 532 * enabled - (OUT) Enable/disable 533 * Returns: 534 * BCM_E_XXX 535 */ 536 STATIC int 537 bcmi_gh2_global_meter_enable_get( 538 int unit, 539 uint8 *enabled) 540 { 541 uint32 rval = 0, val; 542 543 GH2_POL_FUNCTION_TRACE(unit, "IN"); 544 545 /* Parameter NULL error handling */ 546 GH2_POL_CHECK_NULL_PARAMETER(unit, enabled); 547 548 BCM_IF_ERROR_RETURN(READ_SVM_TSN_CONTROLr(unit, &rval)); 549 val = soc_reg_field_get(unit, SVM_TSN_CONTROLr, rval, SVM_BLOCK_DISABLEf); 550 551 if (val == 1) { 552 *enabled = FALSE; 553 } else { 554 *enabled = TRUE; 555 } 556 557 GH2_POL_FUNCTION_DEBUG(unit, "enabled %d", *enabled); 558 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 559 return BCM_E_NONE; 560 } 561 562 /* 563 * Function: 564 * bcmi_gh2_global_meter_seop_enable 565 * Purpose: 566 * Enable/Disable SOP/EOP Metering 567 * Note: SEOP Metering 568 * In GH2, the SOP cell size is at maximum. 144 bytes. Which means if packet 569 * arrives with size lesser than or equal to 144 bytes, both SOP & EOP happen 570 * on same instance in IPIPE, and an SEOP signal is generated. For these packet 571 * sizes, length of packet (L) is known at SOP itself, which is also EOP. 572 * Parameters: 573 * unit - (IN) unit number 574 * enabled - (IN) Enable/disable 575 * Returns: 576 * BCM_E_XXX 577 */ 578 STATIC int 579 bcmi_gh2_global_meter_seop_enable( 580 int unit, 581 uint8 enable) 582 { 583 uint32 rval = 0; 584 585 GH2_POL_FUNCTION_TRACE(unit, "IN"); 586 GH2_POL_FUNCTION_DEBUG(unit, "enable %d", enable); 587 588 BCM_IF_ERROR_RETURN(READ_SVM_TSN_CONTROLr(unit, &rval)); 589 soc_reg_field_set(unit, 590 SVM_TSN_CONTROLr, 591 &rval, 592 SVM_SEOP_METERING_ENf, 593 enable); 594 BCM_IF_ERROR_RETURN(WRITE_SVM_TSN_CONTROLr(unit, rval)); 595 596 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 597 return BCM_E_NONE; 598 } 599 600 /* 601 * Function: 602 * bcmi_gh2_global_meter_seop_enable_get 603 * Purpose: 604 * Get Enable/Disable of SOP/EOP Metering 605 * Note: SEOP Metering 606 * In GH2, the SOP cell size is at maximum. 144 bytes. Which means if packet 607 * arrives with size lesser than or equal to 144 bytes, both SOP & EOP happen 608 * on same instance in IPIPE, and an SEOP signal is generated. For these packet 609 * sizes, length of packet (L) is known at SOP itself, which is also EOP. 610 * Parameters: 611 * unit - (IN) unit number 612 * enabled - (OUT) Enable/disable 613 * Returns: 614 * BCM_E_XXX 615 */ 616 STATIC int 617 bcmi_gh2_global_meter_seop_enable_get( 618 int unit, 619 uint8 *enabled) 620 { 621 uint32 rval = 0; 622 623 GH2_POL_FUNCTION_TRACE(unit, "IN"); 624 625 /* Parameter NULL error handling */ 626 GH2_POL_CHECK_NULL_PARAMETER(unit, enabled); 627 628 BCM_IF_ERROR_RETURN(READ_SVM_TSN_CONTROLr(unit, &rval)); 629 *enabled = (uint8)soc_reg_field_get(unit, 630 SVM_TSN_CONTROLr, 631 rval, 632 SVM_SEOP_METERING_ENf); 633 634 GH2_POL_FUNCTION_DEBUG(unit, "enabled %d", *enabled); 635 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 636 return BCM_E_NONE; 637 } 638 639 /* 640 * Function: 641 * bcmi_gh2_global_meter_source_order_set 642 * Purpose: 643 * Configure the priority of VFP/L2/VXLT/VLAN/Port in the case of 644 * conflict source happened. 645 * Parameters: 646 * unit - (IN) unit number 647 * source_order - (IN) Service Metering Source Table Priority Config 648 * (The lower index of meter source in config array has higher priority) 649 * source_order_count - (IN) Valid index count in source_order 650 * Returns: 651 * BCM_E_XXX 652 */ 653 STATIC int 654 bcmi_gh2_global_meter_source_order_set( 655 int unit, 656 bcm_policer_global_meter_source_t *source_order, 657 uint32 source_order_count) 658 { 659 int priority, index; 660 bcm_policer_global_meter_source_t source; 661 soc_field_t source_field = INVALIDf; 662 663 GH2_POL_FUNCTION_TRACE(unit, "IN"); 664 665 /* Parameter NULL error handling */ 666 GH2_POL_CHECK_NULL_PARAMETER(unit, source_order); 667 668 if (source_order_count > 7) { 669 return BCM_E_PARAM; 670 } 671 672 for (index = 0; index < source_order_count; index++) { 673 source = source_order[index]; 674 if (source > 7) { 675 LOG_ERROR(BSL_LS_BCM_POLICER, 676 (BSL_META_U(unit, 677 "Invalid source(%d).\n"), 678 source)); 679 return BCM_E_PARAM; 680 } 681 /* highest value will have the highest priority */ 682 priority = source_order_count - index - 1; 683 if (source == bcmPolicerGlobalMeterSourceFieldStageLookup) { 684 source_field = VFP_TABLEf; 685 } else if (source == bcmPolicerGlobalMeterSourceDstMac) { 686 source_field = L2_TABLE_DA_LOOKUPf; 687 } else if (source == bcmPolicerGlobalMeterSourceSrcMac) { 688 source_field = L2_TABLE_SA_LOOKUPf; 689 } else if (source == bcmPolicerGlobalMeterSourceVlanTranslateFirst) { 690 source_field = VXLT_TABLE_KEY1f; 691 } else if (source == bcmPolicerGlobalMeterSourceVlanTranslateSecond) { 692 source_field = VXLT_TABLE_KEY2f; 693 } else if (source == bcmPolicerGlobalMeterSourceVlan) { 694 source_field = VLAN_TABLEf; 695 } else if (source == bcmPolicerGlobalMeterSourcePort) { 696 source_field = PORT_TABLEf; 697 /* need to write LPORT_TABLEf and PORT_TABLEf */ 698 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, 699 METER_SOURCE_PRIORITYr, 700 REG_PORT_ANY, 701 LPORT_TABLEf, 702 priority)); 703 } 704 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, 705 METER_SOURCE_PRIORITYr, 706 REG_PORT_ANY, 707 source_field, 708 priority)); 709 } 710 711 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 712 return BCM_E_NONE; 713 } 714 715 /* 716 * Function: 717 * bcmi_gh2_global_meter_source_order_get 718 * Purpose: 719 * Get the priority of VFP/L2/VXLT/VLAN/Port in the case of 720 * conflict source happened. 721 * Parameters: 722 * unit - (IN) unit number 723 * source_order_count - (IN) Valid index count in source_order 724 * source_order - (OUT) Service Metering Source Table Priority Config 725 * Returns: 726 * BCM_E_XXX 727 */ 728 STATIC int 729 bcmi_gh2_global_meter_source_order_get( 730 int unit, 731 uint32 source_order_count, 732 bcm_policer_global_meter_source_t *source_order) 733 { 734 uint32 rval = 0; 735 soc_field_t source_field = INVALIDf; 736 int priority, index; 737 bcm_policer_global_meter_source_t source; 738 739 GH2_POL_FUNCTION_TRACE(unit, "IN"); 740 741 /* Parameter NULL error handling */ 742 GH2_POL_CHECK_NULL_PARAMETER(unit, source_order); 743 744 if (source_order_count > 7) { 745 return BCM_E_PARAM; 746 } 747 748 for (source = 0; source < source_order_count; source++) { 749 if (source == bcmPolicerGlobalMeterSourceFieldStageLookup) { 750 source_field = VFP_TABLEf; 751 } else if (source == bcmPolicerGlobalMeterSourceDstMac) { 752 source_field = L2_TABLE_DA_LOOKUPf; 753 } else if (source == bcmPolicerGlobalMeterSourceSrcMac) { 754 source_field = L2_TABLE_SA_LOOKUPf; 755 } else if (source == bcmPolicerGlobalMeterSourceVlanTranslateFirst) { 756 source_field = VXLT_TABLE_KEY1f; 757 } else if (source == bcmPolicerGlobalMeterSourceVlanTranslateSecond) { 758 source_field = VXLT_TABLE_KEY2f; 759 } else if (source == bcmPolicerGlobalMeterSourceVlan) { 760 source_field = VLAN_TABLEf; 761 } else if (source == bcmPolicerGlobalMeterSourcePort) { 762 source_field = PORT_TABLEf; 763 } 764 765 BCM_IF_ERROR_RETURN(READ_METER_SOURCE_PRIORITYr(unit, &rval)); 766 priority = soc_reg_field_get(unit, 767 METER_SOURCE_PRIORITYr, 768 rval, 769 source_field); 770 /* highest value will have the highest priority */ 771 index = source_order_count - priority - 1; 772 source_order[index] = source; 773 } 774 775 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 776 return BCM_E_NONE; 777 } 778 779 /* TCAM (SVC_METER_OFFSET_TCAM) fields mapping of bcm_policer_group_mode_t */ 780 const soc_field_t gh2_policer_group_mode_field_list[] = 781 { 782 INVALIDf, 783 INVALIDf, 784 /* bcmPolicerGroupModeAttrUdf = 1 not used */ 785 INVALIDf, 786 INVALIDf, 787 /* bcmPolicerGroupModeAttrFieldIngressColor */ 788 CNGf, 789 CNG_MASKf, 790 /* bcmPolicerGroupModeAttrIntPri */ 791 INT_PRIf, 792 INT_PRI_MASKf, 793 /* bcmPolicerGroupModeAttrVlan */ 794 VLAN_FORMATf, 795 VLAN_FORMAT_MASKf, 796 /* bcmPolicerGroupModeAttrOuterPri */ 797 OUTER_DOT1Pf, 798 OUTER_DOT1P_MASKf, 799 /* bcmPolicerGroupModeAttrInnerPri */ 800 INNER_DOT1Pf, 801 INNER_DOT1P_MASKf, 802 /* bcmPolicerGroupModeAttrPort */ 803 INGRESS_PORTf, 804 INGRESS_PORT_MASKf, 805 /* bcmPolicerGroupModeAttrTosDscp */ 806 TOSf, 807 TOS_MASKf, 808 /* bcmPolicerGroupModeAttrTosEcn */ 809 INVALIDf, 810 INVALIDf, 811 /* bcmPolicerGroupModeAttrPktType */ 812 PACKET_RESOLUTIONf, 813 PACKET_RESOLUTION_MASKf, 814 /* bcmPolicerGroupModeAttrIngNetworkGroup */ 815 INVALIDf, 816 INVALIDf, 817 /* bcmPolicerGroupModeAttrDrop */ 818 INVALIDf, 819 INVALIDf, 820 /* bcmPolicerGroupModeAttrPacketTypeIp */ 821 INVALIDf, 822 INVALIDf, 823 /* bcmPolicerGroupModeAttrPreemptable */ 824 PREEMPTABLE_CELLf, 825 PREEMPTABLE_CELL_MASKf, 826 /* bcmPolicerGroupModeAttrEtherType */ 827 ETHER_TYPEf, 828 ETHER_TYPE_MASKf, 829 /* bcmPolicerGroupModeAttrOuterVlanCfi */ 830 OUTER_DOT1Pf, 831 OUTER_DOT1P_MASKf, 832 /* bcmPolicerGroupModeAttrInnerVlanCfi */ 833 INNER_DOT1Pf, 834 INNER_DOT1P_MASKf 835 }; 836 837 /* validate bcm_policer_group_mode_attr_t & value */ 838 STATIC void 839 bcmi_gh2_group_mode_attr_value_remapping( 840 bcm_policer_group_mode_attr_t group_mode_attr, 841 uint32 value, 842 uint32 value_mask, 843 uint32 *hw_value, 844 uint32 *hw_value_mask) 845 { 846 uint32 val, val_mask; 847 848 /* Parameter NULL error handling */ 849 if (hw_value == NULL || hw_value_mask == NULL) { 850 return; 851 } 852 val = value; 853 val_mask = value_mask; 854 switch (group_mode_attr) { 855 case bcmPolicerGroupModeAttrFieldIngressColor: 856 /* Re-mapping packet color to CNG value */ 857 if (val == bcmColorYellow) { 858 val = 0x3; 859 } else if (val == bcmColorRed) { 860 val = 0x1; 861 } 862 break; 863 case bcmPolicerGroupModeAttrVlan: 864 if (val == bcmPolicerGroupModeAttrVlanUnTagged) { 865 val = 0x0; 866 } else if (val == bcmPolicerGroupModeAttrVlanInnerTag) { 867 val = 0x1; 868 } else if (val == bcmPolicerGroupModeAttrVlanOuterTag) { 869 val = 0x2; 870 } else if (val == bcmPolicerGroupModeAttrVlanStackedTag) { 871 val = 0x3; 872 } 873 break; 874 case bcmPolicerGroupModeAttrOuterPri: 875 case bcmPolicerGroupModeAttrInnerPri: 876 /* 3bit PRI + 1 bit CFI */ 877 val = (val << 1); 878 /* Skip CFI bit */ 879 val_mask = val_mask & (~0x1); 880 break; 881 case bcmPolicerGroupModeAttrOuterVlanCfi: 882 case bcmPolicerGroupModeAttrInnerVlanCfi: 883 /* 3bit PRI + 1 bit CFI */ 884 val = val & 0x1; 885 /* Skip PRI bit */ 886 val_mask = val_mask & 0x1; 887 break; 888 case bcmPolicerGroupModeAttrPktType: 889 switch(val) { 890 case bcmPolicerGroupModeAttrPktTypeUnknown: 891 val = 892 bcmi_gh2_global_meter_pkt_res[UNKNOWN_PKT]; 893 break; 894 case bcmPolicerGroupModeAttrPktTypeControl: 895 val = 896 bcmi_gh2_global_meter_pkt_res[CONTROL_PKT]; 897 break; 898 case bcmPolicerGroupModeAttrPktTypeOAM: 899 val = 900 bcmi_gh2_global_meter_pkt_res[OAM_PKT]; 901 break; 902 case bcmPolicerGroupModeAttrPktTypeBFD: 903 val = 904 bcmi_gh2_global_meter_pkt_res[BFD_PKT]; 905 break; 906 case bcmPolicerGroupModeAttrPktTypeBPDU: 907 val = 908 bcmi_gh2_global_meter_pkt_res[BPDU_PKT]; 909 break; 910 case bcmPolicerGroupModeAttrPktTypeICNM: 911 val = 912 bcmi_gh2_global_meter_pkt_res[ICNM_PKT]; 913 break; 914 case bcmPolicerGroupModeAttrPktType1588: 915 val = 916 bcmi_gh2_global_meter_pkt_res[PKT_IS_1588]; 917 break; 918 case bcmPolicerGroupModeAttrPktTypeKnownL2UC: 919 val = 920 bcmi_gh2_global_meter_pkt_res[KNOWN_L2UC_PKT]; 921 break; 922 case bcmPolicerGroupModeAttrPktTypeUnknownL2UC: 923 val = 924 bcmi_gh2_global_meter_pkt_res[UNKNOWN_L2UC_PKT]; 925 break; 926 case bcmPolicerGroupModeAttrPktTypeL2BC: 927 val = 928 bcmi_gh2_global_meter_pkt_res[L2BC_PKT]; 929 break; 930 case bcmPolicerGroupModeAttrPktTypeKnownL2MC: 931 val = 932 bcmi_gh2_global_meter_pkt_res[KNOWN_L2MC_PKT]; 933 break; 934 case bcmPolicerGroupModeAttrPktTypeUnknownL2MC: 935 val = 936 bcmi_gh2_global_meter_pkt_res[UNKNOWN_L2MC_PKT]; 937 break; 938 case bcmPolicerGroupModeAttrPktTypeKnownL3UC: 939 val = 940 bcmi_gh2_global_meter_pkt_res[KNOWN_L3UC_PKT]; 941 break; 942 case bcmPolicerGroupModeAttrPktTypeUnknownL3UC: 943 val = 944 bcmi_gh2_global_meter_pkt_res[UNKNOWN_L3UC_PKT]; 945 break; 946 case bcmPolicerGroupModeAttrPktTypeKnownIPMC: 947 val = 948 bcmi_gh2_global_meter_pkt_res[KNOWN_IPMC_PKT]; 949 break; 950 case bcmPolicerGroupModeAttrPktTypeUnknownIPMC: 951 val = 952 bcmi_gh2_global_meter_pkt_res[UNKNOWN_IPMC_PKT]; 953 break; 954 case bcmPolicerGroupModeAttrPktTypeKnownMplsL2: 955 val = 956 bcmi_gh2_global_meter_pkt_res[KNOWN_MPLS_L2_PKT]; 957 break; 958 case bcmPolicerGroupModeAttrPktTypeKnownMplsL3: 959 val = 960 bcmi_gh2_global_meter_pkt_res[KNOWN_MPLS_L3_PKT]; 961 break; 962 case bcmPolicerGroupModeAttrPktTypeKnownMpls: 963 val = 964 bcmi_gh2_global_meter_pkt_res[KNOWN_MPLS_PKT]; 965 break; 966 case bcmPolicerGroupModeAttrPktTypeUnknownMpls: 967 val = 968 bcmi_gh2_global_meter_pkt_res[UNKNOWN_MPLS_PKT]; 969 break; 970 case bcmPolicerGroupModeAttrPktTypeKnownMplsMulticast: 971 val = 972 bcmi_gh2_global_meter_pkt_res[KNOWN_MPLS_MULTICAST_PKT]; 973 break; 974 case bcmPolicerGroupModeAttrPktTypeKnownMim: 975 val = 976 bcmi_gh2_global_meter_pkt_res[KNOWN_MIM_PKT]; 977 break; 978 case bcmPolicerGroupModeAttrPktTypeUnknownMim: 979 val = 980 bcmi_gh2_global_meter_pkt_res[UNKNOWN_MIM_PKT]; 981 break; 982 case bcmPolicerGroupModeAttrPktTypeKnownTrill: 983 val = 984 bcmi_gh2_global_meter_pkt_res[KNOWN_TRILL_PKT]; 985 break; 986 case bcmPolicerGroupModeAttrPktTypeUnknownTrill: 987 val = 988 bcmi_gh2_global_meter_pkt_res[UNKNOWN_TRILL_PKT]; 989 break; 990 case bcmPolicerGroupModeAttrPktTypeKnownNiv: 991 val = 992 bcmi_gh2_global_meter_pkt_res[KNOWN_NIV_PKT]; 993 break; 994 case bcmPolicerGroupModeAttrPktTypeUnknownNiv: 995 val = 996 bcmi_gh2_global_meter_pkt_res[UNKNOWN_NIV_PKT]; 997 break; 998 default: 999 break; 1000 } 1001 val_mask = 0x3F; 1002 break; 1003 default: 1004 break; 1005 } 1006 *hw_value = val; 1007 *hw_value_mask = val_mask; 1008 } 1009 1010 /* validate bcm_policer_group_mode_attr_t & value */ 1011 STATIC int 1012 bcmi_gh2_group_mode_attr_validate( 1013 int unit, 1014 bcm_policer_group_mode_attr_t group_mode_attr, 1015 uint32 value) 1016 { 1017 soc_mem_t meter_mem = SVC_METER_OFFSET_TCAMm; 1018 soc_field_t field = INVALIDf; 1019 uint32 hw_value = 0, hw_value_mask = 0; 1020 uint32 value_mask = 0; 1021 1022 /* Check if group_mode_attr supported */ 1023 BCM_IF_ERROR_RETURN( 1024 bcmi_gh2_group_mode_attr_supported( 1025 unit, group_mode_attr)); 1026 1027 /* Skip all cases checking */ 1028 if (value == BCM_POLICER_GROUP_MODE_ATTR_ALL_VALUES) { 1029 return BCM_E_UNAVAIL; 1030 } else if (group_mode_attr == bcmPolicerGroupModeAttrVlan && 1031 value == bcmPolicerGroupModeAttrVlanAll) { 1032 return BCM_E_UNAVAIL; 1033 } else if (group_mode_attr == bcmPolicerGroupModeAttrPktType && 1034 value == bcmPolicerGroupModeAttrPktTypeAll) { 1035 return BCM_E_UNAVAIL; 1036 } 1037 1038 /* group_mode_attr field for checking value */ 1039 field = gh2_policer_group_mode_field_list[group_mode_attr * 2]; 1040 1041 if (field == INVALIDf) { 1042 LOG_ERROR(BSL_LS_BCM_POLICER, 1043 (BSL_META_U(unit, 1044 "Invalid field.\n" 1045 "GH2 doesn't support group_mode_attr(%d)\n"), 1046 group_mode_attr)); 1047 return BCM_E_PARAM; 1048 } 1049 1050 /* Check if the value fit to HW field */ 1051 bcmi_gh2_group_mode_attr_value_remapping( 1052 group_mode_attr, value, value_mask, &hw_value, &hw_value_mask); 1053 1054 if (group_mode_attr == bcmPolicerGroupModeAttrPktType && 1055 value != bcmPolicerGroupModeAttrPktTypeUnknown && 1056 hw_value == GH2_UNKNOWN_PKT_VAL) { 1057 /* 1058 * GH2 doesn't support this pkt resolution, 1059 * Refer to FP_RESOLUTION in reg bcm53570_a0 1060 */ 1061 return BCM_E_UNAVAIL; 1062 } 1063 1064 BCM_IF_ERROR_RETURN( 1065 soc_mem_field32_fit( 1066 unit, meter_mem, field, hw_value)); 1067 return BCM_E_NONE; 1068 } 1069 1070 /* 1071 * Function: 1072 * bcmi_gh2_global_meter_tcam_keys_set 1073 * Purpose: 1074 * Set the Packet Attribute to TCAM hardware 1075 * Parameters: 1076 * unit - (IN) Unit number 1077 * pkt_attr_bits_v - (IN) Packet TCAM attributes 1078 * Returns: 1079 * BCM_E_xxx 1080 */ 1081 STATIC bcm_error_t 1082 bcmi_gh2_global_meter_tcam_keys_set( 1083 int unit, 1084 pkt_tcam_attr_bits_t *pkt_attr_bits_v) 1085 { 1086 uint32 hw_idx; 1087 int attr; 1088 uint32 value, value_mask; 1089 uint32 hw_value = 0, hw_value_mask = 0; 1090 uint32 fldbuf[SOC_MAX_MEM_WORDS] = { 0 }; 1091 uint8 pkt_attr_selector_enable = 0; 1092 soc_mem_t meter_mem = SVC_METER_OFFSET_TCAMm; 1093 soc_mem_t policy_mem = SVC_METER_OFFSET_POLICY_TABLEm; 1094 soc_field_t field = INVALIDf, mask_field = INVALIDf; 1095 svc_meter_offset_tcam_entry_t tcam; 1096 svc_meter_offset_policy_table_entry_t policy; 1097 1098 GH2_POL_FUNCTION_TRACE(unit, "IN"); 1099 1100 /* Parameter NULL error handling */ 1101 GH2_POL_CHECK_NULL_PARAMETER(unit, pkt_attr_bits_v); 1102 1103 hw_idx = pkt_attr_bits_v->tcam_idx; 1104 1105 /* Validate hw_idx */ 1106 if (hw_idx >= GH2_GLOBAL_METER_TCAM_SIZE) { 1107 LOG_ERROR(BSL_LS_BCM_POLICER, 1108 (BSL_META_U(unit, 1109 "Invalid hw_idx(%d).\n"), 1110 hw_idx)); 1111 return BCM_E_PARAM; 1112 } 1113 1114 sal_memset(&tcam, 0, 1115 sizeof(svc_meter_offset_tcam_entry_t)); 1116 sal_memset(&policy, 0, 1117 sizeof(svc_meter_offset_policy_table_entry_t)); 1118 1119 /* Write SVC_METER_OFFSET_TCAM start */ 1120 BCM_IF_ERROR_RETURN( 1121 soc_mem_read(unit, meter_mem, MEM_BLOCK_ANY, hw_idx, &tcam)); 1122 1123 pkt_attr_selector_enable = 1124 pkt_attr_bits_v->attr_bits_selector == 0 ? 0 : 1 ; 1125 1126 /* 1127 * Write SVC_METER_INDEXf and SVC_METER_OFFSET_MODEf 1128 * looping all elements in gh2_policer_group_mode_field_list 1129 */ 1130 for (attr = bcmPolicerGroupModeAttrFieldIngressColor; 1131 attr <= bcmPolicerGroupModeAttrInnerVlanCfi; 1132 attr++) { 1133 1134 /* TCAM value field */ 1135 field = gh2_policer_group_mode_field_list[attr * 2]; 1136 if (field == INVALIDf) { 1137 continue; 1138 } 1139 /* TCAM value mask field */ 1140 mask_field = gh2_policer_group_mode_field_list[attr * 2 + 1]; 1141 1142 if (pkt_attr_selector_enable && 1143 pkt_attr_bits_v->value_mask[attr] != 0) { 1144 value = pkt_attr_bits_v->value[attr]; 1145 value_mask = pkt_attr_bits_v->value_mask[attr]; 1146 GH2_POL_FUNCTION_DEBUG(unit, "TCAM attr %d", attr); 1147 GH2_POL_FUNCTION_DEBUG(unit, "TCAM value 0x%x", value); 1148 GH2_POL_FUNCTION_DEBUG(unit, "TCAM value_mask 0x%x", value_mask); 1149 bcmi_gh2_group_mode_attr_value_remapping( 1150 attr, value, value_mask, &hw_value, &hw_value_mask); 1151 GH2_POL_FUNCTION_DEBUG(unit, "TCAM hw_value 0x%x", hw_value); 1152 GH2_POL_FUNCTION_DEBUG(unit, "TCAM hw_value_mask 0x%x", hw_value_mask); 1153 } else { 1154 hw_value = 0; 1155 hw_value_mask = 0; 1156 } 1157 1158 /* 1159 * PRI & CFI Share the same field, we need to avoid overwrite issue 1160 * OUTER_DOT1Pf & OUTER_DOT1P_MASKf 1161 * INNER_DOT1Pf & INNER_DOT1P_MASKf 1162 */ 1163 if (attr == bcmPolicerGroupModeAttrOuterPri || 1164 attr == bcmPolicerGroupModeAttrInnerPri) { 1165 uint32 fldval = 0; 1166 soc_mem_field_get( 1167 unit, meter_mem, (uint32 *)&tcam, field, &fldval); 1168 /* OR original 1-bit CFI value & mask */ 1169 hw_value |= (fldval & 0x1); 1170 soc_mem_field_get( 1171 unit, meter_mem, (uint32 *)&tcam, mask_field, &fldval); 1172 hw_value_mask |= (fldval & 0x1); 1173 } 1174 1175 if (attr == bcmPolicerGroupModeAttrOuterVlanCfi || 1176 attr == bcmPolicerGroupModeAttrInnerVlanCfi) { 1177 uint32 fldval = 0; 1178 soc_mem_field_get( 1179 unit, meter_mem, (uint32 *)&tcam, field, &fldval); 1180 /* OR original 3-bit PRI value & mask */ 1181 hw_value |= (fldval & (0x7 << 1)); 1182 soc_mem_field_get( 1183 unit, meter_mem, (uint32 *)&tcam, mask_field, &fldval); 1184 hw_value_mask |= (fldval & (0x7 << 1)); 1185 } 1186 1187 /* Write value */ 1188 if (SOC_MEM_FIELD_VALID(unit, meter_mem, field)) { 1189 BCM_IF_ERROR_RETURN( 1190 soc_mem_field32_fit( 1191 unit, meter_mem, field, hw_value)); 1192 soc_mem_field_set( 1193 unit, meter_mem, (uint32 *)&tcam, field, &hw_value); 1194 } 1195 /* Write value_mask */ 1196 if (SOC_MEM_FIELD_VALID(unit, meter_mem, mask_field)) { 1197 sal_memset(fldbuf, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 1198 sal_memcpy(fldbuf, &hw_value_mask, sizeof(uint32)); 1199 soc_mem_field_width_fit_set( 1200 unit, meter_mem, (uint32 *)&tcam, mask_field, fldbuf); 1201 } 1202 } 1203 1204 /* UDF0 */ 1205 if (pkt_attr_bits_v->udf.udf0 != 0) { 1206 if (pkt_attr_selector_enable && 1207 pkt_attr_bits_v->udf_mask.udf0 != 0) { 1208 hw_value = (uint32)pkt_attr_bits_v->udf.udf0; 1209 hw_value_mask = (uint32)pkt_attr_bits_v->udf_mask.udf0; 1210 } else { 1211 hw_value = 0; 1212 hw_value_mask = 0; 1213 } 1214 GH2_POL_FUNCTION_DEBUG(unit, "UDF0 hw_value 0x%x", hw_value); 1215 GH2_POL_FUNCTION_DEBUG(unit, "UDF0 hw_value_mask 0x%x", hw_value_mask); 1216 BCM_IF_ERROR_RETURN( 1217 soc_mem_field32_fit( 1218 unit, meter_mem, UDF0f, hw_value)); 1219 BCM_IF_ERROR_RETURN( 1220 soc_mem_field32_fit( 1221 unit, meter_mem, UDF0_MASKf, hw_value_mask)); 1222 1223 soc_mem_field32_set( 1224 unit, meter_mem, &tcam, UDF0f, hw_value); 1225 soc_mem_field32_set( 1226 unit, meter_mem, &tcam, UDF0_MASKf, hw_value_mask); 1227 soc_mem_field32_set( 1228 unit, meter_mem, &tcam, UDF_VALID0f, 1); 1229 soc_mem_field32_set( 1230 unit, meter_mem, &tcam, UDF_VALID0_MASKf, 1); 1231 } 1232 1233 /* UDF1 */ 1234 if (pkt_attr_bits_v->udf.udf1 != 0) { 1235 if (pkt_attr_selector_enable && 1236 pkt_attr_bits_v->udf_mask.udf1 != 0) { 1237 hw_value = (uint32)pkt_attr_bits_v->udf.udf1; 1238 hw_value_mask = (uint32)pkt_attr_bits_v->udf_mask.udf1; 1239 } else { 1240 hw_value = 0; 1241 hw_value_mask = 0; 1242 } 1243 GH2_POL_FUNCTION_DEBUG(unit, "UDF1 hw_value 0x%x", hw_value); 1244 GH2_POL_FUNCTION_DEBUG(unit, "UDF1 hw_value_mask 0x%x", hw_value_mask); 1245 BCM_IF_ERROR_RETURN( 1246 soc_mem_field32_fit( 1247 unit, meter_mem, UDF1f, hw_value)); 1248 BCM_IF_ERROR_RETURN( 1249 soc_mem_field32_fit( 1250 unit, meter_mem, UDF1_MASKf, hw_value_mask)); 1251 1252 soc_mem_field32_set( 1253 unit, meter_mem, &tcam, UDF1f, hw_value); 1254 soc_mem_field32_set( 1255 unit, meter_mem, &tcam, UDF1_MASKf, hw_value_mask); 1256 soc_mem_field32_set( 1257 unit, meter_mem, &tcam, UDF_VALID1f, 1); 1258 soc_mem_field32_set( 1259 unit, meter_mem, &tcam, UDF_VALID1_MASKf, 1); 1260 } 1261 1262 /* OFFSET_MODE */ 1263 if (pkt_attr_selector_enable) { 1264 hw_value = (uint32)pkt_attr_bits_v->offset_mode; 1265 hw_value_mask = 0x3; 1266 } else { 1267 hw_value = 0; 1268 hw_value_mask = 0; 1269 } 1270 GH2_POL_FUNCTION_DEBUG( 1271 unit, "OFFSET_MODE hw_value 0x%x", hw_value); 1272 GH2_POL_FUNCTION_DEBUG( 1273 unit, "OFFSET_MODE hw_value_mask 0x%x", hw_value_mask); 1274 BCM_IF_ERROR_RETURN( 1275 soc_mem_field32_fit( 1276 unit, meter_mem, OFFSET_MODEf, hw_value)); 1277 1278 soc_SVC_METER_OFFSET_TCAMm_field32_set(unit, 1279 &tcam, OFFSET_MODEf, hw_value); 1280 soc_SVC_METER_OFFSET_TCAMm_field32_set(unit, 1281 &tcam, OFFSET_MODE_MASKf, hw_value_mask); 1282 1283 /* ENABLE / DISABLE pkt_attr_selector */ 1284 soc_SVC_METER_OFFSET_TCAMm_field32_set(unit, 1285 &tcam, VALIDf, (uint32)pkt_attr_selector_enable); 1286 1287 BCM_IF_ERROR_RETURN( 1288 soc_mem_write(unit, meter_mem, MEM_BLOCK_ALL, hw_idx, &tcam)); 1289 /* Write SVC_METER_OFFSET_TCAM end */ 1290 1291 /* Write SVC_METER_OFFSET_POLICY_TABLE start */ 1292 BCM_IF_ERROR_RETURN( 1293 soc_mem_read(unit, policy_mem, MEM_BLOCK_ANY, hw_idx, &policy)); 1294 1295 soc_mem_field32_set( 1296 unit, policy_mem, &policy, FINAL_OFFSET_ENABLEf, 1297 pkt_attr_selector_enable); 1298 1299 soc_mem_field32_set( 1300 unit, policy_mem, &policy, FINAL_OFFSETf, 1301 pkt_attr_bits_v->final_offset); 1302 1303 BCM_IF_ERROR_RETURN( 1304 soc_mem_write(unit, policy_mem, MEM_BLOCK_ALL, hw_idx, &policy)); 1305 /* Write SVC_METER_OFFSET_POLICY_TABLE end */ 1306 1307 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 1308 return BCM_E_NONE; 1309 } 1310 1311 /* 1312 * Function: 1313 * bcmi_gh2_global_meter_tcam_keys_get 1314 * Purpose: 1315 * Get the Packet Attribute from TCAM hardware 1316 * Parameters: 1317 * unit - (IN) Unit number 1318 * pkt_tcam_attr_bits_t - (OUT) Packet TCAM attributes 1319 * Returns: 1320 * BCM_E_xxx 1321 */ 1322 STATIC bcm_error_t 1323 bcmi_gh2_global_meter_tcam_keys_get( 1324 int unit, 1325 pkt_tcam_attr_bits_t *pkt_attr_bits_v) 1326 { 1327 bcm_error_t rv = BCM_E_UNAVAIL; 1328 GH2_POL_FUNCTION_TRACE(unit, "IN"); 1329 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 1330 return rv; 1331 } 1332 1333 /* 1334 * Function: 1335 * bcmi_gh2_global_meter_tcam_keys_delete 1336 * Purpose: 1337 * Delete the Packet Attribute on TCAM hardware 1338 * Parameters: 1339 * unit - (IN) Unit number 1340 * sw_idx - (IN) SW memory index. 1341 * Returns: 1342 * BCM_E_xxx 1343 */ 1344 STATIC bcm_error_t 1345 bcmi_gh2_global_meter_tcam_keys_delete( 1346 int unit, 1347 uint32 sw_idx) 1348 { 1349 bcm_error_t rv = BCM_E_NONE; 1350 uint32 hw_idx; 1351 pkt_tcam_attr_bits_t pkt_attr_bits_v; 1352 1353 GH2_POL_FUNCTION_TRACE(unit, "IN"); 1354 1355 hw_idx = sw_idx; 1356 1357 /* Validate hw_idx */ 1358 if (hw_idx >= GH2_GLOBAL_METER_TCAM_SIZE) { 1359 LOG_ERROR(BSL_LS_BCM_POLICER, 1360 (BSL_META_U(unit, 1361 "Invalid hw_idx(%d).\n"), 1362 hw_idx)); 1363 return BCM_E_PARAM; 1364 } 1365 1366 /* attr_bits_selector set to 0 will reset all value to 0 */ 1367 (void)pkt_tcam_attr_bits_t_init(&pkt_attr_bits_v); 1368 pkt_attr_bits_v.tcam_idx = hw_idx; 1369 1370 rv = bcmi_gh2_global_meter_tcam_keys_set(unit, &pkt_attr_bits_v); 1371 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 1372 return rv; 1373 } 1374 1375 /* Write meter_index & meter_offset_mode to source table */ 1376 STATIC bcm_error_t 1377 bcmi_gh2_global_meter_policer_to_table_set( 1378 int unit, 1379 soc_mem_t mem, 1380 uint32 mem_index, 1381 void *mem_data, 1382 int meter_index, 1383 int meter_offset_mode, 1384 int skip_read) 1385 { 1386 uint32 hw_idx = mem_index; 1387 1388 GH2_POL_FUNCTION_TRACE(unit, "IN"); 1389 1390 /* Parameter NULL error handling */ 1391 GH2_POL_CHECK_NULL_PARAMETER(unit, mem_data); 1392 1393 if (!SOC_MEM_IS_VALID(unit, mem) || 1394 !SOC_MEM_FIELD_VALID(unit, mem, SVC_METER_INDEXf) || 1395 !SOC_MEM_FIELD_VALID(unit, mem, SVC_METER_OFFSET_MODEf)) { 1396 return BCM_E_INTERNAL; 1397 } 1398 1399 /* Validate hw_idx */ 1400 if (hw_idx > (soc_mem_index_max(unit, mem))) 1401 { 1402 GH2_POL_FUNCTION_ERROR(unit, "Invalid hw_idx (%d) \n", hw_idx); 1403 return BCM_E_PARAM; 1404 } 1405 1406 if (FALSE == skip_read) { 1407 BCM_IF_ERROR_RETURN( 1408 soc_mem_read(unit, mem, MEM_BLOCK_ANY, hw_idx, mem_data)); 1409 } 1410 1411 /* Write SVC_METER_INDEXf and SVC_METER_OFFSET_MODEf */ 1412 soc_mem_field32_set(unit, mem, mem_data, 1413 SVC_METER_INDEXf, meter_index); 1414 1415 soc_mem_field32_set(unit, mem, mem_data, 1416 SVC_METER_OFFSET_MODEf, meter_offset_mode); 1417 1418 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 1419 return BCM_E_NONE; 1420 } 1421 1422 /* Read meter_index & meter_offset_mode from source table */ 1423 STATIC bcm_error_t 1424 bcmi_gh2_global_meter_policer_to_table_get( 1425 int unit, 1426 soc_mem_t mem, 1427 uint32 mem_index, 1428 void *mem_data, 1429 int *meter_index, 1430 int *meter_offset_mode, 1431 int skip_read) 1432 { 1433 uint32 hw_idx = mem_index; 1434 1435 GH2_POL_FUNCTION_TRACE(unit, "IN"); 1436 1437 /* Parameter NULL error handling */ 1438 GH2_POL_CHECK_NULL_PARAMETER(unit, mem_data); 1439 GH2_POL_CHECK_NULL_PARAMETER(unit, meter_index); 1440 GH2_POL_CHECK_NULL_PARAMETER(unit, meter_offset_mode); 1441 1442 if (!SOC_MEM_IS_VALID(unit, mem) || 1443 !SOC_MEM_FIELD_VALID(unit, mem, SVC_METER_INDEXf) || 1444 !SOC_MEM_FIELD_VALID(unit, mem, SVC_METER_OFFSET_MODEf)) { 1445 return BCM_E_INTERNAL; 1446 } 1447 1448 /* Validate hw_idx */ 1449 if (hw_idx > (soc_mem_index_max(unit, mem))) 1450 { 1451 GH2_POL_FUNCTION_ERROR(unit, "Invalid hw_idx (%d) \n", hw_idx); 1452 return BCM_E_PARAM; 1453 } 1454 1455 if (FALSE == skip_read) { 1456 BCM_IF_ERROR_RETURN( 1457 soc_mem_read(unit, mem, MEM_BLOCK_ANY, hw_idx, mem_data)); 1458 } 1459 1460 /* Write SVC_METER_INDEXf and SVC_METER_OFFSET_MODEf */ 1461 *meter_index = 1462 soc_mem_field32_get(unit, mem, mem_data, 1463 SVC_METER_INDEXf); 1464 *meter_offset_mode = 1465 soc_mem_field32_get(unit, mem, mem_data, 1466 SVC_METER_OFFSET_MODEf); 1467 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 1468 return BCM_E_NONE; 1469 } 1470 1471 /* 1472 * Function: 1473 * bcmi_gh2_global_meter_meter_table_set 1474 * Purpose: 1475 * Update (Install) the policer parameters 1476 * Parameters: 1477 * unit - (IN) BCM device number. 1478 * sw_idx - (IN) SW memory index. 1479 * meter_mode - (IN) policer meter mode. 1480 * meter_flags - (IN) policer meter flag. 1481 * bucket_size - (IN) Encoded bucket size. 1482 * bucket_count - (IN) Encoded bucket count. 1483 * refresh_rate - (IN) Tokens refresh rate. 1484 * granularity - (IN) Tokens granularity. 1485 * Returns: 1486 * BCM_E_XXX 1487 */ 1488 STATIC bcm_error_t 1489 bcmi_gh2_global_meter_meter_table_set( 1490 int unit, 1491 uint32 sw_idx, 1492 bcm_policer_mode_t meter_mode, 1493 uint32 meter_flags, 1494 uint32 average_pkt_size, 1495 uint32 meter_gran_mode, 1496 uint32 bucket_size, 1497 uint32 bucket_count, 1498 uint32 refresh_rate, 1499 uint32 granularity) 1500 { 1501 int rv = BCM_E_NONE; 1502 uint32 hw_idx = sw_idx; 1503 svm_meter_table_entry_t entry; 1504 uint32 refresh_mode = 0, tsn_modified = 0, pkt_bytes = 0; 1505 soc_mem_t mem = SVM_METER_TABLEm; 1506 1507 GH2_POL_FUNCTION_TRACE(unit, "IN"); 1508 1509 /* Validate hw_idx */ 1510 if (hw_idx > (soc_mem_index_max(unit, mem))) 1511 { 1512 GH2_POL_FUNCTION_ERROR(unit, "Invalid hw_idx (%d) \n", hw_idx); 1513 return BCM_E_PARAM; 1514 } 1515 1516 /* Refresh mode is only set to 1 for Single Rate. Other modes get 0 */ 1517 if (meter_mode == bcmPolicerModeSrTcmTsn) { 1518 refresh_mode = 1; 1519 tsn_modified = 1; 1520 } else if ((meter_mode == bcmPolicerModeSrTcm) || 1521 (meter_mode == bcmPolicerModeSrTcmModified)) { 1522 refresh_mode = 1; 1523 tsn_modified = 0; 1524 } else { 1525 refresh_mode = 0; 1526 tsn_modified = 0; 1527 } 1528 1529 /* PKT/BYTE - by default BYTE counter */ 1530 if (meter_flags & BCM_POLICER_MODE_PACKETS) { 1531 pkt_bytes = 1; 1532 } 1533 soc_mem_lock(unit, mem); 1534 1535 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, hw_idx, &entry); 1536 if (BCM_FAILURE(rv)) { 1537 soc_mem_unlock(unit, mem); 1538 return rv; 1539 } 1540 1541 soc_SVM_METER_TABLEm_field_set(unit, &entry, 1542 BUCKETCOUNTf, 1543 &bucket_count); 1544 soc_SVM_METER_TABLEm_field_set(unit, &entry, 1545 REFRESHCOUNTf, 1546 &refresh_rate); 1547 soc_SVM_METER_TABLEm_field_set(unit, &entry, 1548 BUCKETSIZEf, 1549 &bucket_size); 1550 soc_SVM_METER_TABLEm_field_set(unit, &entry, 1551 REFRESH_MODEf, 1552 &refresh_mode); 1553 soc_SVM_METER_TABLEm_field_set(unit, &entry, 1554 METER_MODE_TSN_MODIFIERf, 1555 &tsn_modified); 1556 soc_SVM_METER_TABLEm_field_set(unit, &entry, 1557 PKTS_BYTESf, 1558 &pkt_bytes); 1559 soc_SVM_METER_TABLEm_field_set(unit, &entry, 1560 METER_GRANf, 1561 &granularity); 1562 soc_SVM_METER_TABLEm_field_set(unit, &entry, 1563 THRESHOLD_CHECKf, 1564 &average_pkt_size); 1565 soc_SVM_METER_TABLEm_field_set(unit, &entry, 1566 METER_GRAN_MODEf, 1567 &meter_gran_mode); 1568 1569 /* write to hw */ 1570 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, hw_idx, &entry); 1571 soc_mem_unlock(unit, mem); 1572 1573 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 1574 return rv; 1575 } 1576 1577 /* 1578 * Function: 1579 * bcmi_gh2_global_meter_meter_table_get 1580 * Purpose: 1581 * Get the policer parameters 1582 * Parameters: 1583 * unit - (IN) BCM device number. 1584 * sw_idx - (IN) SW memory index. 1585 * bucket_size - (OUT) policer meter flag. 1586 * bucket_count - (OUT) Encoded bucket count. 1587 * refresh_rate - (OUT) Tokens refresh rate. 1588 * granularity - (OUT) Tokens granularity. 1589 * pkt_bytes - (OUT) packet mode or byte mode. 1590 * tsn_modified - (OUT) TSN mode or not. 1591 * Returns: 1592 * BCM_E_XXX 1593 */ 1594 STATIC bcm_error_t 1595 bcmi_gh2_global_meter_meter_table_get( 1596 int unit, 1597 uint32 sw_idx, 1598 uint32 *bucket_size, 1599 uint32 *bucket_count, 1600 uint32 *refresh_rate, 1601 uint32 *granularity, 1602 uint32 *pkt_bytes, 1603 uint32 *tsn_modified, 1604 uint32 *meter_gran_mode, 1605 uint32 *average_pkt_size) 1606 { 1607 int rv = BCM_E_NONE; 1608 uint32 hw_idx = sw_idx; 1609 svm_meter_table_entry_t entry; 1610 soc_mem_t meter_mem = SVM_METER_TABLEm; 1611 1612 GH2_POL_FUNCTION_TRACE(unit, "IN"); 1613 1614 /* Parameter NULL error handling */ 1615 GH2_POL_CHECK_NULL_PARAMETER(unit, bucket_size); 1616 GH2_POL_CHECK_NULL_PARAMETER(unit, bucket_count); 1617 GH2_POL_CHECK_NULL_PARAMETER(unit, refresh_rate); 1618 GH2_POL_CHECK_NULL_PARAMETER(unit, granularity); 1619 GH2_POL_CHECK_NULL_PARAMETER(unit, pkt_bytes); 1620 GH2_POL_CHECK_NULL_PARAMETER(unit, tsn_modified); 1621 GH2_POL_CHECK_NULL_PARAMETER(unit, meter_gran_mode); 1622 GH2_POL_CHECK_NULL_PARAMETER(unit, average_pkt_size); 1623 1624 /* Validate hw_idx */ 1625 if (hw_idx > (soc_mem_index_max(unit, meter_mem))) 1626 { 1627 GH2_POL_FUNCTION_ERROR(unit, "Invalid hw_idx (%d) \n", hw_idx); 1628 return BCM_E_PARAM; 1629 } 1630 1631 BCM_IF_ERROR_RETURN( 1632 soc_mem_read(unit, meter_mem, MEM_BLOCK_ANY, hw_idx, &entry)); 1633 1634 soc_SVM_METER_TABLEm_field_get(unit, &entry, 1635 BUCKETCOUNTf, 1636 bucket_count); 1637 soc_SVM_METER_TABLEm_field_get(unit, &entry, 1638 REFRESHCOUNTf, 1639 refresh_rate); 1640 soc_SVM_METER_TABLEm_field_get(unit, &entry, 1641 BUCKETSIZEf, 1642 bucket_size); 1643 soc_SVM_METER_TABLEm_field_get(unit, &entry, 1644 METER_MODE_TSN_MODIFIERf, 1645 tsn_modified); 1646 soc_SVM_METER_TABLEm_field_get(unit, &entry, 1647 METER_GRANf, 1648 granularity); 1649 soc_SVM_METER_TABLEm_field_get(unit, &entry, 1650 PKTS_BYTESf, 1651 pkt_bytes); 1652 soc_SVM_METER_TABLEm_field_get(unit, &entry, 1653 THRESHOLD_CHECKf, 1654 average_pkt_size); 1655 soc_SVM_METER_TABLEm_field_get(unit, &entry, 1656 METER_GRAN_MODEf, 1657 meter_gran_mode); 1658 1659 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 1660 return rv; 1661 } 1662 1663 /* 1664 * Function: 1665 * bcmi_gh2_global_meter_meter_table_bitsize_get 1666 * Purpose: 1667 * Get the policer parameters 1668 * Parameters: 1669 * unit - (IN) BCM device number. 1670 * sw_idx - (IN) SW memory index. 1671 * refresh_bitsize - (OUT) length of REFRESHCOUNTf 1672 * bucket_max_bitsize - (OUT) length of BUCKETSIZEf 1673 * bucket_cnt_bitsize - (OUT) length of BUCKETCOUNTf 1674 * Returns: 1675 * BCM_E_XXX 1676 */ 1677 STATIC int 1678 bcmi_gh2_global_meter_meter_table_bitsize_get( 1679 int unit, 1680 uint32 sw_idx, 1681 uint32 *refresh_bitsize, 1682 uint32 *bucket_max_bitsize, 1683 uint32 *bucket_cnt_bitsize) 1684 { 1685 int rv = BCM_E_NONE; 1686 uint32 hw_idx = sw_idx; 1687 svm_meter_table_entry_t entry; 1688 soc_mem_t meter_mem = SVM_METER_TABLEm; 1689 1690 GH2_POL_FUNCTION_TRACE(unit, "IN"); 1691 1692 /* Parameter NULL error handling */ 1693 GH2_POL_CHECK_NULL_PARAMETER(unit, refresh_bitsize); 1694 GH2_POL_CHECK_NULL_PARAMETER(unit, bucket_max_bitsize); 1695 GH2_POL_CHECK_NULL_PARAMETER(unit, bucket_cnt_bitsize); 1696 1697 /* Validate hw_idx */ 1698 if (hw_idx > (soc_mem_index_max(unit, meter_mem))) 1699 { 1700 GH2_POL_FUNCTION_ERROR(unit, "Invalid hw_idx(%d)\n", hw_idx); 1701 return BCM_E_PARAM; 1702 } 1703 1704 BCM_IF_ERROR_RETURN( 1705 soc_mem_read(unit, meter_mem, MEM_BLOCK_ANY, hw_idx, &entry)); 1706 1707 *refresh_bitsize = 1708 soc_mem_field_length(unit, meter_mem, REFRESHCOUNTf); 1709 *bucket_max_bitsize = 1710 soc_mem_field_length(unit, meter_mem, BUCKETSIZEf); 1711 *bucket_cnt_bitsize = 1712 soc_mem_field_length(unit, meter_mem, BUCKETCOUNTf); 1713 1714 GH2_POL_FUNCTION_DEBUG(unit, "sw_idx %d", sw_idx); 1715 GH2_POL_FUNCTION_DEBUG(unit, "refresh_bitsize %d", *refresh_bitsize); 1716 GH2_POL_FUNCTION_DEBUG(unit, "bucket_max_bitsize %d", *bucket_max_bitsize); 1717 GH2_POL_FUNCTION_DEBUG(unit, "bucket_cnt_bitsize %d", *bucket_cnt_bitsize); 1718 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 1719 return rv; 1720 } 1721 1722 /* Set the policy meter mode and flags to global meter */ 1723 STATIC int 1724 bcmi_gh2_global_meter_policy_mode_set( 1725 int unit, 1726 uint32 sw_idx, 1727 bcm_policer_mode_t meter_mode, 1728 uint32 meter_flags) 1729 { 1730 int rv = BCM_E_NONE; 1731 uint32 hw_idx = sw_idx; 1732 svm_policy_table_entry_t policy_entry; 1733 soc_mem_t policy_mem = SVM_POLICY_TABLEm; 1734 uint32 modifier_mode = 0, pair_mode = 0; 1735 1736 GH2_POL_FUNCTION_TRACE(unit, "IN"); 1737 GH2_POL_FUNCTION_DEBUG(unit, "meter_mode %d", meter_mode); 1738 GH2_POL_FUNCTION_DEBUG(unit, "meter_flags 0x%x", meter_flags); 1739 1740 /* Validate hw_idx */ 1741 if (hw_idx > soc_mem_index_max(unit, policy_mem)) { 1742 GH2_POL_FUNCTION_ERROR(unit, "Invalid hw_idx (%d) \n", hw_idx); 1743 return BCM_E_PARAM; 1744 } 1745 1746 sal_memset(&policy_entry, 0, 1747 sizeof(svm_policy_table_entry_t)); 1748 1749 /* Refresh mode is only set to 1 for Single Rate. Other modes get 0 */ 1750 switch (meter_mode) { 1751 case bcmPolicerModeGreen: 1752 pair_mode = BCM_FIELD_METER_MODE_DEFAULT; /* 0 */ 1753 break; 1754 case bcmPolicerModeCommitted: 1755 pair_mode = BCM_FIELD_METER_MODE_FLOW; /* 1 */ 1756 break; 1757 case bcmPolicerModeTrTcm: 1758 pair_mode = 1759 (meter_flags & BCM_POLICER_COLOR_BLIND) ? 1760 BCM_FIELD_METER_MODE_trTCM_COLOR_BLIND: /* 2 */ 1761 BCM_FIELD_METER_MODE_trTCM_COLOR_AWARE; /* 3 */ 1762 break; 1763 case bcmPolicerModeTrTcmDs: 1764 pair_mode = 1765 (meter_flags & BCM_POLICER_COLOR_BLIND) ? 4 : 5; 1766 break; 1767 case bcmPolicerModeSrTcmModified: 1768 modifier_mode = 1; 1769 /* fall through */ 1770 case bcmPolicerModeSrTcm: 1771 pair_mode = 1772 (meter_flags & BCM_POLICER_COLOR_BLIND) ? 1773 BCM_FIELD_METER_MODE_srTCM_COLOR_BLIND: /* 6 */ 1774 BCM_FIELD_METER_MODE_srTCM_COLOR_AWARE; /* 7 */ 1775 break; 1776 case bcmPolicerModeSrTcmTsn: 1777 pair_mode = 1778 (meter_flags & BCM_POLICER_COLOR_BLIND) ? 1779 BCM_FIELD_METER_MODE_srTCM_COLOR_BLIND: /* 6 */ 1780 BCM_FIELD_METER_MODE_srTCM_COLOR_AWARE; /* 7 */ 1781 modifier_mode = 0; 1782 break; 1783 default: 1784 pair_mode = 0; 1785 break; 1786 } 1787 1788 /* SVM_POLICY_TABLEm */ 1789 BCM_IF_ERROR_RETURN( 1790 soc_mem_read(unit, policy_mem, MEM_BLOCK_ANY, hw_idx, &policy_entry)); 1791 GH2_POL_FUNCTION_DEBUG(unit, "pair_mode %d", pair_mode); 1792 GH2_POL_FUNCTION_DEBUG(unit, "modifier_mode %d", modifier_mode); 1793 1794 soc_SVM_POLICY_TABLEm_field_set(unit, &policy_entry, 1795 METER_PAIR_MODEf, 1796 &pair_mode); 1797 soc_SVM_POLICY_TABLEm_field_set(unit, &policy_entry, 1798 METER_PAIR_MODE_MODIFIERf, 1799 &modifier_mode); 1800 /* write to hw */ 1801 BCM_IF_ERROR_RETURN( 1802 soc_mem_write(unit, policy_mem, MEM_BLOCK_ALL, hw_idx, &policy_entry)); 1803 1804 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 1805 return rv; 1806 } 1807 1808 /* Get the policy meter mode and flags from global meter */ 1809 STATIC int 1810 bcmi_gh2_global_meter_policy_mode_get( 1811 int unit, 1812 uint32 sw_idx, 1813 bcm_policer_mode_t *meter_mode, 1814 uint32 *meter_flags) 1815 { 1816 int rv = BCM_E_NONE; 1817 uint32 meter_hw_idx = sw_idx * 2; 1818 uint32 policy_hw_idx = sw_idx; 1819 svm_meter_table_entry_t meter_entry; 1820 svm_policy_table_entry_t policy_entry; 1821 soc_mem_t meter_mem = SVM_METER_TABLEm; 1822 soc_mem_t policy_mem = SVM_POLICY_TABLEm; 1823 uint32 modifier_mode, pair_mode, tsn_modifier; 1824 1825 GH2_POL_FUNCTION_TRACE(unit, "IN"); 1826 1827 /* Parameter NULL error handling */ 1828 GH2_POL_CHECK_NULL_PARAMETER(unit, meter_mode); 1829 GH2_POL_CHECK_NULL_PARAMETER(unit, meter_flags); 1830 1831 /* Validate meter_mem hw_idx */ 1832 if (meter_hw_idx > soc_mem_index_max(unit, meter_mem)) { 1833 GH2_POL_FUNCTION_ERROR( 1834 unit, "Invalid meter_hw_idx (%d) \n", meter_hw_idx); 1835 return BCM_E_PARAM; 1836 } 1837 1838 /* Validate policy_mem hw_idx */ 1839 if (policy_hw_idx > soc_mem_index_max(unit, policy_mem)) { 1840 GH2_POL_FUNCTION_ERROR( 1841 unit, "Invalid policy_hw_idx (%d) \n", policy_hw_idx); 1842 return BCM_E_PARAM; 1843 } 1844 1845 sal_memset(&meter_entry, 0, 1846 sizeof(svm_meter_table_entry_t)); 1847 sal_memset(&policy_entry, 0, 1848 sizeof(svm_policy_table_entry_t)); 1849 1850 BCM_IF_ERROR_RETURN( 1851 soc_mem_read( 1852 unit, meter_mem, MEM_BLOCK_ANY, meter_hw_idx, &meter_entry)); 1853 1854 BCM_IF_ERROR_RETURN( 1855 soc_mem_read( 1856 unit, policy_mem, MEM_BLOCK_ANY, policy_hw_idx, &policy_entry)); 1857 1858 pair_mode = 1859 soc_mem_field32_get(unit, policy_mem, 1860 &policy_entry, METER_PAIR_MODEf); 1861 modifier_mode = 1862 soc_mem_field32_get(unit, policy_mem, 1863 &policy_entry, METER_PAIR_MODE_MODIFIERf); 1864 1865 GH2_POL_FUNCTION_DEBUG(unit, "pair_mode %d", pair_mode); 1866 GH2_POL_FUNCTION_DEBUG(unit, "modifier_mode %d", modifier_mode); 1867 1868 switch (pair_mode) { 1869 case BCM_FIELD_METER_MODE_DEFAULT: /* 0 */ 1870 *meter_mode = bcmPolicerModeGreen; 1871 break; 1872 case BCM_FIELD_METER_MODE_FLOW: /* 1 */ 1873 *meter_mode = bcmPolicerModeCommitted; 1874 break; 1875 case BCM_FIELD_METER_MODE_trTCM_COLOR_BLIND: /* 2 */ 1876 *meter_flags |= BCM_POLICER_COLOR_BLIND; 1877 /* Fall thru */ 1878 case BCM_FIELD_METER_MODE_trTCM_COLOR_AWARE: /* 3 */ 1879 *meter_mode = bcmPolicerModeTrTcm; 1880 break; 1881 case BCM_FIELD_METER_MODE_srTCM_COLOR_BLIND: /* 6 */ 1882 *meter_flags |= BCM_POLICER_COLOR_BLIND; 1883 /* Fall thru */ 1884 case BCM_FIELD_METER_MODE_srTCM_COLOR_AWARE: /* 7 */ 1885 *meter_mode = modifier_mode 1886 ? bcmPolicerModeSrTcmModified 1887 : bcmPolicerModeSrTcm; 1888 tsn_modifier = 1889 soc_mem_field32_get(unit, meter_mem, &meter_entry, 1890 METER_MODE_TSN_MODIFIERf); 1891 if (tsn_modifier == 1) { 1892 *meter_mode = bcmPolicerModeSrTcmTsn; 1893 } 1894 break; 1895 case 4: 1896 *meter_flags |= BCM_POLICER_COLOR_BLIND; 1897 /* Fall thru */ 1898 case 5: 1899 *meter_mode = bcmPolicerModeTrTcmDs; 1900 break; 1901 default: 1902 ; 1903 } 1904 GH2_POL_FUNCTION_DEBUG(unit, "meter_mode %d", *meter_mode); 1905 GH2_POL_FUNCTION_DEBUG(unit, "meter_flags 0x%x", *meter_flags); 1906 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 1907 return rv; 1908 } 1909 1910 /* refer to # FORMAT SVM_ACTIONS */ 1911 1912 /* NEW_PKT_PRI (other chip called NEW_DOT1P) */ 1913 #define GH2_POLICER_ACTION_PKT_PRI_POS (0) 1914 /* NEW_INT_CN */ 1915 #define GH2_POLICER_ACTION_INT_CN_BIT_POS (3) 1916 /* NEW_DSCP_TOS */ 1917 #define GH2_POLICER_ACTION_DSCP_BIT_POS (5) 1918 /* DROP_PRECEDENCE (other chip called CHANGE_CNG) */ 1919 #define GH2_POLICER_ACTION_DROP_PRECEDENCE_BIT_POS (11) 1920 /* DROP */ 1921 #define GH2_POLICER_ACTION_DROP_BIT_POS (13) 1922 /* COS_INT_PRI */ 1923 #define GH2_POLICER_ACTION_INT_PRI_BIT_POS (15) 1924 /* CHANGE_PKT_PRI (other chip called CHANGE_DOT1P) */ 1925 #define GH2_POLICER_ACTION_CHANGE_PKT_PRI_BIT_POS (23) 1926 /* CHANGE_INT_CN */ 1927 #define GH2_POLICER_ACTION_CHANGE_INT_CN_BIT_POS (26) 1928 /* CHANGE_ECN */ 1929 #define GH2_POLICER_ACTION_CHANGE_ECN_BIT_POS (27) 1930 /* CHANGE_DSCP_TOS */ 1931 #define GH2_POLICER_ACTION_CHANGE_DSCP_BIT_POS (29) 1932 /* CHANGE_COS_OR_INT_PRI, 2*32 bit value, thus need to minus by 32 */ 1933 #define GH2_POLICER_ACTION_CHANGE_COS_OR_INT_PRI_BIT_POS (32 - 32) 1934 1935 /* 1936 * Function: 1937 * bcmi_gh2_global_meter_policy_action_param_configure 1938 * Purpose: 1939 * Update (Install) the policer action parameters 1940 * Parameters: 1941 * unit - (IN) BCM device number. 1942 * g_action - (IN) Green action 1943 * y_action - (IN) Yellow action 1944 * r_action - (IN) Red action 1945 * Returns: 1946 * BCM_E_XXX 1947 */ 1948 STATIC int 1949 bcmi_gh2_global_meter_policy_action_param_configure( 1950 int unit, 1951 bcm_policer_action_t action, 1952 uint32 param0, 1953 uint64 *g_action, 1954 uint64 *y_action, 1955 uint64 *r_action) 1956 { 1957 uint32 green_action[2] = {0}, yellow_action[2] = {0}, red_action[2] = {0}; 1958 1959 GH2_POL_CHECK_NULL_PARAMETER(unit, green_action); 1960 GH2_POL_CHECK_NULL_PARAMETER(unit, yellow_action); 1961 GH2_POL_CHECK_NULL_PARAMETER(unit, red_action); 1962 1963 COMPILER_64_TO_32_LO(green_action[0], *g_action); 1964 COMPILER_64_TO_32_HI(green_action[1], *g_action); 1965 COMPILER_64_TO_32_LO(yellow_action[0], *y_action); 1966 COMPILER_64_TO_32_HI(yellow_action[1], *y_action); 1967 COMPILER_64_TO_32_LO(red_action[0], *r_action); 1968 COMPILER_64_TO_32_HI(red_action[1], *r_action); 1969 1970 switch (action) { 1971 case bcmPolicerActionGpDrop: 1972 if (param0 != 0) { 1973 LOG_ERROR(BSL_LS_BCM_POLICER, 1974 (BSL_META_U(unit, 1975 "Invalid value for Drop\n"))); 1976 return BCM_E_PARAM; 1977 } 1978 SHR_BITSET(green_action, 1979 GH2_POLICER_ACTION_DROP_BIT_POS); 1980 break; 1981 case bcmPolicerActionYpDrop: 1982 if (param0 != 0) { 1983 LOG_ERROR(BSL_LS_BCM_POLICER, 1984 (BSL_META_U(unit, 1985 "Invalid value for Drop\n"))); 1986 return BCM_E_PARAM; 1987 } 1988 SHR_BITSET(yellow_action, 1989 GH2_POLICER_ACTION_DROP_BIT_POS); 1990 break; 1991 case bcmPolicerActionRpDrop: 1992 if (param0 != 0) { 1993 LOG_ERROR(BSL_LS_BCM_POLICER, 1994 (BSL_META_U(unit, 1995 "Invalid value for Drop\n"))); 1996 return BCM_E_PARAM; 1997 } 1998 SHR_BITSET(red_action, 1999 GH2_POLICER_ACTION_DROP_BIT_POS); 2000 break; 2001 case bcmPolicerActionGpEcnNew: 2002 if (param0 > 0x3) { 2003 LOG_ERROR(BSL_LS_BCM_POLICER, 2004 (BSL_META_U(unit, 2005 "Invalid value for ECN\n"))); 2006 return BCM_E_PARAM; 2007 } 2008 /* GH2 merge CHANGE_ECN and NEW_ECN into CHANGE_ECN */ 2009 SHR_BITCLR_RANGE(green_action, 2010 GH2_POLICER_ACTION_CHANGE_ECN_BIT_POS, 2); 2011 green_action[0] = green_action[0] | 2012 (param0 << GH2_POLICER_ACTION_CHANGE_ECN_BIT_POS); 2013 break; 2014 case bcmPolicerActionYpEcnNew: 2015 if (param0 > 0x3) { 2016 LOG_ERROR(BSL_LS_BCM_POLICER, 2017 (BSL_META_U(unit, 2018 "Invalid value for ECN\n"))); 2019 return BCM_E_PARAM; 2020 } 2021 /* GH2 merge CHANGE_ECN and NEW_ECN into CHANGE_ECN */ 2022 SHR_BITCLR_RANGE(yellow_action, 2023 GH2_POLICER_ACTION_CHANGE_ECN_BIT_POS, 2); 2024 yellow_action[0] = yellow_action[0] | 2025 (param0 << GH2_POLICER_ACTION_CHANGE_ECN_BIT_POS); 2026 break; 2027 case bcmPolicerActionRpEcnNew: 2028 if (param0 > 0x3) { 2029 LOG_ERROR(BSL_LS_BCM_POLICER, 2030 (BSL_META_U(unit, 2031 "Invalid value for ECN\n"))); 2032 return BCM_E_PARAM; 2033 } 2034 /* GH2 merge CHANGE_ECN and NEW_ECN into CHANGE_ECN */ 2035 SHR_BITCLR_RANGE(red_action, 2036 GH2_POLICER_ACTION_CHANGE_ECN_BIT_POS, 2); 2037 red_action[0] = red_action[0] | 2038 (param0 << GH2_POLICER_ACTION_CHANGE_ECN_BIT_POS); 2039 break; 2040 case bcmPolicerActionGpDscpNew: 2041 if (param0 > 0x3f) { 2042 LOG_ERROR(BSL_LS_BCM_POLICER, 2043 (BSL_META_U(unit, 2044 "Invalid value for DSCP\n"))); 2045 return BCM_E_PARAM; 2046 } 2047 SHR_BITCLR_RANGE(green_action, 2048 GH2_POLICER_ACTION_DSCP_BIT_POS, 6); 2049 green_action[0] = green_action[0] | 2050 (param0 << GH2_POLICER_ACTION_DSCP_BIT_POS); 2051 2052 /* CHANGE_DSCP_TOS = 3 for CHANGE_DSCP */ 2053 SHR_BITCLR_RANGE(green_action, 2054 GH2_POLICER_ACTION_CHANGE_DSCP_BIT_POS, 3); 2055 green_action[0] = green_action[0] | 2056 (0x3 << GH2_POLICER_ACTION_CHANGE_DSCP_BIT_POS); 2057 2058 break; 2059 case bcmPolicerActionYpDscpNew: 2060 if (param0 > 0x3f) { 2061 LOG_ERROR(BSL_LS_BCM_POLICER, 2062 (BSL_META_U(unit, 2063 "Invalid value for DSCP\n"))); 2064 return BCM_E_PARAM; 2065 } 2066 SHR_BITCLR_RANGE(yellow_action, 2067 GH2_POLICER_ACTION_DSCP_BIT_POS, 6); 2068 yellow_action[0] = yellow_action[0] | 2069 (param0 << GH2_POLICER_ACTION_DSCP_BIT_POS); 2070 2071 /* CHANGE_DSCP_TOS = 3 for CHANGE_DSCP */ 2072 SHR_BITCLR_RANGE(yellow_action, 2073 GH2_POLICER_ACTION_CHANGE_DSCP_BIT_POS, 3); 2074 yellow_action[0] = yellow_action[0] | 2075 (0x3 << GH2_POLICER_ACTION_CHANGE_DSCP_BIT_POS); 2076 break; 2077 case bcmPolicerActionRpDscpNew: 2078 if (param0 > 0x3f) { 2079 LOG_ERROR(BSL_LS_BCM_POLICER, 2080 (BSL_META_U(unit, 2081 "Invalid value for DSCP\n"))); 2082 return BCM_E_PARAM; 2083 } 2084 SHR_BITCLR_RANGE(red_action, 2085 GH2_POLICER_ACTION_DSCP_BIT_POS, 6); 2086 red_action[0] = red_action[0] | 2087 (param0 << GH2_POLICER_ACTION_DSCP_BIT_POS); 2088 2089 /* CHANGE_DSCP_TOS = 3 for CHANGE_DSCP */ 2090 SHR_BITCLR_RANGE(red_action, 2091 GH2_POLICER_ACTION_CHANGE_DSCP_BIT_POS, 3); 2092 red_action[0] = red_action[0] | 2093 (0x3 << GH2_POLICER_ACTION_CHANGE_DSCP_BIT_POS); 2094 break; 2095 case bcmPolicerActionGpPrioIntNew: 2096 if (param0 > 0xf) { 2097 LOG_ERROR(BSL_LS_BCM_POLICER, 2098 (BSL_META_U(unit, 2099 "Invalid value for int pri\n"))); 2100 return BCM_E_PARAM; 2101 } 2102 /* COS_INT_PRI */ 2103 SHR_BITCLR_RANGE(green_action, 2104 GH2_POLICER_ACTION_INT_PRI_BIT_POS, 4); 2105 green_action[0] = green_action[0] | 2106 (param0 << 2107 GH2_POLICER_ACTION_INT_PRI_BIT_POS); 2108 /* CHANGE_COS_OR_INT_PRI = 5 for CHANGE_INT_PRIORITY_NEW */ 2109 green_action[1] = green_action[1] | 2110 (0x5 << GH2_POLICER_ACTION_CHANGE_COS_OR_INT_PRI_BIT_POS); 2111 break; 2112 case bcmPolicerActionYpPrioIntNew: 2113 if (param0 > 0xf) { 2114 LOG_ERROR(BSL_LS_BCM_POLICER, 2115 (BSL_META_U(unit, 2116 "Invalid value for int pri\n"))); 2117 return BCM_E_PARAM; 2118 } 2119 /* COS_INT_PRI */ 2120 SHR_BITCLR_RANGE(yellow_action, 2121 GH2_POLICER_ACTION_INT_PRI_BIT_POS, 4); 2122 yellow_action[0] = yellow_action[0] | 2123 (param0 << 2124 GH2_POLICER_ACTION_INT_PRI_BIT_POS); 2125 /* CHANGE_COS_OR_INT_PRI = 5 for CHANGE_INT_PRIORITY_NEW */ 2126 yellow_action[1] = yellow_action[1] | 2127 (0x5 << GH2_POLICER_ACTION_CHANGE_COS_OR_INT_PRI_BIT_POS); 2128 break; 2129 case bcmPolicerActionRpPrioIntNew: 2130 if (param0 > 0xf) { 2131 LOG_ERROR(BSL_LS_BCM_POLICER, 2132 (BSL_META_U(unit, 2133 "Invalid value for int pri\n"))); 2134 return BCM_E_PARAM; 2135 } 2136 /* COS_INT_PRI */ 2137 SHR_BITCLR_RANGE(red_action, 2138 GH2_POLICER_ACTION_INT_PRI_BIT_POS, 4); 2139 red_action[0] = red_action[0] | 2140 (param0 << 2141 GH2_POLICER_ACTION_INT_PRI_BIT_POS); 2142 /* CHANGE_COS_OR_INT_PRI = 5 for CHANGE_INT_PRIORITY_NEW */ 2143 red_action[1] = red_action[1] | 2144 (0x5 << GH2_POLICER_ACTION_CHANGE_COS_OR_INT_PRI_BIT_POS); 2145 break; 2146 case bcmPolicerActionGpCngNew: 2147 if (param0 > 0x3) { 2148 LOG_ERROR(BSL_LS_BCM_POLICER, 2149 (BSL_META_U(unit, 2150 "Invalid value for CNG\n"))); 2151 return BCM_E_PARAM; 2152 } 2153 /* DROP_PRECEDENCE (other chip called CHANGE_CNG) */ 2154 SHR_BITCLR_RANGE(green_action, 2155 GH2_POLICER_ACTION_DROP_PRECEDENCE_BIT_POS, 2); 2156 green_action[0] = green_action[0] | 2157 (param0 << 2158 GH2_POLICER_ACTION_DROP_PRECEDENCE_BIT_POS); 2159 break; 2160 case bcmPolicerActionYpCngNew: 2161 if (param0 > 0x3) { 2162 LOG_ERROR(BSL_LS_BCM_POLICER, 2163 (BSL_META_U(unit, 2164 "Invalid value for CNG\n"))); 2165 return BCM_E_PARAM; 2166 } 2167 /* DROP_PRECEDENCE (other chip called CHANGE_CNG) */ 2168 SHR_BITCLR_RANGE(yellow_action, 2169 GH2_POLICER_ACTION_DROP_PRECEDENCE_BIT_POS, 2); 2170 yellow_action[0] = yellow_action[0] | 2171 (param0 << 2172 GH2_POLICER_ACTION_DROP_PRECEDENCE_BIT_POS); 2173 break; 2174 case bcmPolicerActionRpCngNew: 2175 if (param0 > 0x3) { 2176 LOG_ERROR(BSL_LS_BCM_POLICER, 2177 (BSL_META_U(unit, 2178 "Invalid value for CNG\n"))); 2179 return BCM_E_PARAM; 2180 } 2181 /* DROP_PRECEDENCE (other chip called CHANGE_CNG) */ 2182 SHR_BITCLR_RANGE(red_action, 2183 GH2_POLICER_ACTION_DROP_PRECEDENCE_BIT_POS, 2); 2184 red_action[0] = red_action[0] | 2185 (param0 << 2186 GH2_POLICER_ACTION_DROP_PRECEDENCE_BIT_POS); 2187 break; 2188 case bcmPolicerActionGpVlanPrioNew: 2189 if (param0 > 0x7) { 2190 LOG_ERROR(BSL_LS_BCM_POLICER, 2191 (BSL_META_U(unit, 2192 "Invalid value for vlan pri\n"))); 2193 return BCM_E_PARAM; 2194 } 2195 /* NEW_PKT_PRI */ 2196 SHR_BITCLR_RANGE(green_action, 2197 GH2_POLICER_ACTION_PKT_PRI_POS, 3); 2198 green_action[0] = green_action[0] | 2199 (param0 << 2200 GH2_POLICER_ACTION_PKT_PRI_POS); 2201 2202 /* CHANGE_PKT_PRI = 5 for NEW_PKT_PRI */ 2203 SHR_BITCLR_RANGE(green_action, 2204 GH2_POLICER_ACTION_CHANGE_PKT_PRI_BIT_POS, 3); 2205 green_action[0] = green_action[0] | 2206 (0x5 << GH2_POLICER_ACTION_CHANGE_PKT_PRI_BIT_POS); 2207 break; 2208 case bcmPolicerActionYpVlanPrioNew: 2209 if (param0 > 0x7) { 2210 LOG_ERROR(BSL_LS_BCM_POLICER, 2211 (BSL_META_U(unit, 2212 "Invalid value for vlan pri\n"))); 2213 return BCM_E_PARAM; 2214 } 2215 /* NEW_PKT_PRI */ 2216 SHR_BITCLR_RANGE(yellow_action, 2217 GH2_POLICER_ACTION_PKT_PRI_POS, 3); 2218 yellow_action[0] = yellow_action[0] | 2219 (param0 << 2220 GH2_POLICER_ACTION_PKT_PRI_POS); 2221 2222 /* CHANGE_PKT_PRI = 5 for NEW_PKT_PRI */ 2223 SHR_BITCLR_RANGE(yellow_action, 2224 GH2_POLICER_ACTION_CHANGE_PKT_PRI_BIT_POS, 3); 2225 yellow_action[0] = yellow_action[0] | 2226 (0x5 << GH2_POLICER_ACTION_CHANGE_PKT_PRI_BIT_POS); 2227 break; 2228 case bcmPolicerActionRpVlanPrioNew: 2229 if (param0 > 0x7) { 2230 LOG_ERROR(BSL_LS_BCM_POLICER, 2231 (BSL_META_U(unit, 2232 "Invalid value for vlan pri\n"))); 2233 return BCM_E_PARAM; 2234 } 2235 /* NEW_PKT_PRI */ 2236 SHR_BITCLR_RANGE(red_action, 2237 GH2_POLICER_ACTION_PKT_PRI_POS, 3); 2238 red_action[0] = red_action[0] | 2239 (param0 << 2240 GH2_POLICER_ACTION_PKT_PRI_POS); 2241 2242 /* CHANGE_PKT_PRI = 5 for NEW_PKT_PRI */ 2243 SHR_BITCLR_RANGE(red_action, 2244 GH2_POLICER_ACTION_CHANGE_PKT_PRI_BIT_POS, 3); 2245 red_action[0] = red_action[0] | 2246 (0x5 << GH2_POLICER_ACTION_CHANGE_PKT_PRI_BIT_POS); 2247 break; 2248 case bcmPolicerActionGpIntCongestionNotificationNew: 2249 if (param0 > 0x3) { 2250 LOG_ERROR(BSL_LS_BCM_POLICER, 2251 (BSL_META_U(unit, 2252 "Invalid value for " 2253 "Congestion Notification\n"))); 2254 return BCM_E_PARAM; 2255 } 2256 SHR_BITCLR_RANGE(green_action, 2257 GH2_POLICER_ACTION_INT_CN_BIT_POS, 2); 2258 green_action[0] = green_action[0] | 2259 (param0 << GH2_POLICER_ACTION_INT_CN_BIT_POS); 2260 2261 /* CHANGE_INT_CN = 1 for NEW_INT_CN */ 2262 green_action[0] = green_action[0] | 2263 (0x1 << GH2_POLICER_ACTION_CHANGE_INT_CN_BIT_POS); 2264 break; 2265 case bcmPolicerActionYpIntCongestionNotificationNew: 2266 if (param0 > 0x3) { 2267 LOG_ERROR(BSL_LS_BCM_POLICER, 2268 (BSL_META_U(unit, 2269 "Invalid value for " 2270 "Congestion Notification\n"))); 2271 return BCM_E_PARAM; 2272 } 2273 SHR_BITCLR_RANGE(yellow_action, 2274 GH2_POLICER_ACTION_INT_CN_BIT_POS, 2); 2275 yellow_action[0] = yellow_action[0] | 2276 (param0 << GH2_POLICER_ACTION_INT_CN_BIT_POS); 2277 2278 /* CHANGE_INT_CN = 1 for NEW_INT_CN */ 2279 yellow_action[0] = yellow_action[0] | 2280 (0x1 << GH2_POLICER_ACTION_CHANGE_INT_CN_BIT_POS); 2281 break; 2282 case bcmPolicerActionRpIntCongestionNotificationNew: 2283 if (param0 > 0x3) { 2284 LOG_ERROR(BSL_LS_BCM_POLICER, 2285 (BSL_META_U(unit, 2286 "Invalid value for " 2287 "Congestion Notification\n"))); 2288 return BCM_E_PARAM; 2289 } 2290 SHR_BITCLR_RANGE(red_action, 2291 GH2_POLICER_ACTION_INT_CN_BIT_POS, 2); 2292 red_action[0] = red_action[0] | 2293 (param0 << GH2_POLICER_ACTION_INT_CN_BIT_POS); 2294 2295 /* CHANGE_INT_CN = 1 for NEW_INT_CN */ 2296 red_action[0] = red_action[0] | 2297 (0x1 << GH2_POLICER_ACTION_CHANGE_INT_CN_BIT_POS); 2298 break; 2299 default: 2300 LOG_ERROR(BSL_LS_BCM_POLICER, 2301 (BSL_META_U(unit, 2302 "Unsupported Action specified\n"))); 2303 return BCM_E_PARAM; 2304 } 2305 2306 COMPILER_64_SET(*g_action, green_action[1], green_action[0]); 2307 COMPILER_64_SET(*y_action, yellow_action[1], yellow_action[0]); 2308 COMPILER_64_SET(*r_action, red_action[1], red_action[0]); 2309 return BCM_E_NONE; 2310 } 2311 2312 /* 2313 * Function: 2314 * bcmi_gh2_global_meter_policy_action_set 2315 * Purpose: 2316 * Update (Install) the policer action parameters 2317 * Parameters: 2318 * unit - (IN) BCM device number. 2319 * g_action - (IN) Green action 2320 * y_action - (IN) Yellow action 2321 * r_action - (IN) Red action 2322 * Returns: 2323 * BCM_E_XXX 2324 */ 2325 STATIC int 2326 bcmi_gh2_global_meter_policy_action_set( 2327 int unit, 2328 uint32 sw_idx, 2329 uint64 g_action, 2330 uint64 y_action, 2331 uint64 r_action) 2332 { 2333 int rv = BCM_E_NONE; 2334 uint32 hw_idx = sw_idx; 2335 soc_mem_t policy_mem = SVM_POLICY_TABLEm; 2336 svm_policy_table_entry_t policy_entry; 2337 2338 GH2_POL_FUNCTION_TRACE(unit, "IN"); 2339 GH2_POL_FUNCTION_DEBUG(unit, "sw_idx %d", sw_idx); 2340 GH2_POL_FUNCTION_DEBUG(unit, "Green H 0x%x", COMPILER_64_HI(g_action)); 2341 GH2_POL_FUNCTION_DEBUG(unit, "Green L 0x%x", COMPILER_64_LO(g_action)); 2342 GH2_POL_FUNCTION_DEBUG(unit, "Yellow H 0x%x", COMPILER_64_HI(y_action)); 2343 GH2_POL_FUNCTION_DEBUG(unit, "Yellow L 0x%x", COMPILER_64_LO(y_action)); 2344 GH2_POL_FUNCTION_DEBUG(unit, "Red H 0x%x", COMPILER_64_HI(r_action)); 2345 GH2_POL_FUNCTION_DEBUG(unit, "Red L 0x%x", COMPILER_64_LO(r_action)); 2346 2347 /* Validate hw_idx */ 2348 if (hw_idx > soc_mem_index_max(unit, policy_mem)) { 2349 LOG_ERROR(BSL_LS_BCM_POLICER, 2350 (BSL_META_U(unit, 2351 "Invalid hw_idx \n"))); 2352 return BCM_E_PARAM; 2353 } 2354 2355 sal_memset(&policy_entry, 0, 2356 sizeof(svm_policy_table_entry_t)); 2357 2358 BCM_IF_ERROR_RETURN( 2359 READ_SVM_POLICY_TABLEm(unit, MEM_BLOCK_ANY, hw_idx, &policy_entry)); 2360 2361 soc_mem_field64_set(unit, policy_mem, &policy_entry, G_ACTIONSf, g_action); 2362 soc_mem_field64_set(unit, policy_mem, &policy_entry, Y_ACTIONSf, y_action); 2363 soc_mem_field64_set(unit, policy_mem, &policy_entry, R_ACTIONSf, r_action); 2364 2365 BCM_IF_ERROR_RETURN( 2366 WRITE_SVM_POLICY_TABLEm(unit, MEM_BLOCK_ALL, hw_idx, &policy_entry)); 2367 2368 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 2369 return rv; 2370 } 2371 2372 /* 2373 * Function: 2374 * bcmi_gh2_global_meter_policy_action_get 2375 * Purpose: 2376 * Get the policer action parameters 2377 * Parameters: 2378 * unit - (IN) BCM device number. 2379 * g_action - (OUT) Green action 2380 * y_action - (OUT) Yellow action 2381 * r_action - (OUT) Red action 2382 * Returns: 2383 * BCM_E_XXX 2384 */ 2385 STATIC int 2386 bcmi_gh2_global_meter_policy_action_get( 2387 int unit, 2388 uint32 sw_idx, 2389 uint64 *g_action, 2390 uint64 *y_action, 2391 uint64 *r_action) 2392 { 2393 int rv = BCM_E_NONE; 2394 uint32 hw_idx = sw_idx; 2395 soc_mem_t policy_mem = SVM_POLICY_TABLEm; 2396 svm_policy_table_entry_t policy_entry; 2397 2398 GH2_POL_FUNCTION_TRACE(unit, "IN"); 2399 2400 /* Parameter NULL error handling */ 2401 GH2_POL_CHECK_NULL_PARAMETER(unit, g_action); 2402 GH2_POL_CHECK_NULL_PARAMETER(unit, y_action); 2403 GH2_POL_CHECK_NULL_PARAMETER(unit, r_action); 2404 2405 /* Validate hw_idx */ 2406 if (hw_idx > soc_mem_index_max(unit, policy_mem)) { 2407 GH2_POL_FUNCTION_ERROR(unit, "Invalid hw_idx (%d) \n", hw_idx); 2408 return BCM_E_PARAM; 2409 } 2410 2411 sal_memset(&policy_entry, 0, 2412 sizeof(svm_policy_table_entry_t)); 2413 2414 BCM_IF_ERROR_RETURN( 2415 READ_SVM_POLICY_TABLEm(unit, MEM_BLOCK_ANY, hw_idx, &policy_entry)); 2416 soc_mem_field64_get( 2417 unit, policy_mem, &policy_entry, G_ACTIONSf, g_action); 2418 soc_mem_field64_get( 2419 unit, policy_mem, &policy_entry, Y_ACTIONSf, y_action); 2420 soc_mem_field64_get( 2421 unit, policy_mem, &policy_entry, R_ACTIONSf, r_action); 2422 2423 GH2_POL_FUNCTION_DEBUG(unit, "sw_idx %d", sw_idx); 2424 GH2_POL_FUNCTION_DEBUG(unit, "Green H 0x%x", COMPILER_64_HI(*g_action)); 2425 GH2_POL_FUNCTION_DEBUG(unit, "Green L 0x%x", COMPILER_64_LO(*g_action)); 2426 GH2_POL_FUNCTION_DEBUG(unit, "Yellow H 0x%x", COMPILER_64_HI(*y_action)); 2427 GH2_POL_FUNCTION_DEBUG(unit, "Yellow L 0x%x", COMPILER_64_LO(*y_action)); 2428 GH2_POL_FUNCTION_DEBUG(unit, "Red H 0x%x", COMPILER_64_HI(*r_action)); 2429 GH2_POL_FUNCTION_DEBUG(unit, "Red L 0x%x", COMPILER_64_LO(*r_action)); 2430 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 2431 return rv; 2432 } 2433 2434 STATIC const bcmi_global_meter_dev_info_t bcmi_gh2_global_meter_dev_info = { 2435 "gh2_global_meter_dev_info", /* table_name */ 2436 bcmi_gh2_action_supported, /* action_supported */ 2437 bcmi_gh2_group_mode_supported, /* group_mode_supported */ 2438 bcmi_gh2_group_mode_type_supported, /* group_mode_type_supported */ 2439 bcmi_gh2_group_mode_attr_supported, /* group_mode_attr_supported */ 2440 bcmi_gh2_group_mode_attr_validate, /* group_mode_attr_validate */ 2441 bcmi_gh2_global_meter_mem_clear, /* mem_clear */ 2442 bcmi_gh2_global_meter_mem_range_clear, /* mem_range_clear */ 2443 bcmi_gh2_global_meter_ifg_set, /* ifg_set */ 2444 bcmi_gh2_global_meter_ifg_get, /* ifg_get */ 2445 bcmi_gh2_global_meter_source_order_set, /* source_order_set */ 2446 bcmi_gh2_global_meter_source_order_get, /* source_order_get */ 2447 bcmi_gh2_global_meter_enable, /* svm_enable */ 2448 bcmi_gh2_global_meter_enable_get, /* svm_enable_get */ 2449 bcmi_gh2_global_meter_seop_enable, /* seop_enable */ 2450 bcmi_gh2_global_meter_seop_enable_get, /* seop_enable_get */ 2451 bcmi_gh2_global_meter_tcam_keys_set, /* tcam_keys_set */ 2452 bcmi_gh2_global_meter_tcam_keys_get, /* tcam_keys_get */ 2453 bcmi_gh2_global_meter_tcam_keys_delete, /* tcam_keys_delete */ 2454 bcmi_gh2_global_meter_policer_to_table_set, /* policer_to_table_set */ 2455 bcmi_gh2_global_meter_policer_to_table_get, /* policer_to_table_get */ 2456 bcmi_gh2_global_meter_meter_table_bitsize_get,/* meter_table_bitsize_get */ 2457 bcmi_gh2_global_meter_meter_table_set, /* meter_table_set */ 2458 bcmi_gh2_global_meter_meter_table_get, /* meter_table_get */ 2459 bcmi_gh2_global_meter_policy_mode_set, /* policy_mode_set */ 2460 bcmi_gh2_global_meter_policy_mode_get, /* policy_mode_get */ 2461 bcmi_gh2_global_meter_policy_action_param_configure, 2462 /* policy_action_param_configure */ 2463 bcmi_gh2_global_meter_policy_action_set, /* policy_action_set */ 2464 bcmi_gh2_global_meter_policy_action_get /* policy_action_get */ 2465 }; 2466 2467 /* 2468 * Function: 2469 * bcmi_gh2_global_meter_dev_info_init 2470 * Description: 2471 * Set-up the chip specific info. 2472 * Parameters: 2473 * unit - (IN) Unit number. 2474 * dev_info - (OUT) device info structure. 2475 * Returns: 2476 * BCM_E_XXX 2477 */ 2478 int 2479 bcmi_gh2_global_meter_dev_info_init( 2480 int unit, 2481 const bcmi_global_meter_dev_info_t **dev_info) 2482 { 2483 GH2_POL_FUNCTION_TRACE(unit, "IN"); 2484 2485 /* Parameter NULL error handling */ 2486 GH2_POL_CHECK_NULL_PARAMETER(unit, dev_info); 2487 2488 /* Return the chip info structure */ 2489 *dev_info = &bcmi_gh2_global_meter_dev_info; 2490 2491 GH2_POL_FUNCTION_TRACE(unit, "OUT"); 2492 return BCM_E_NONE; 2493 } 2494 #endif /* BCM_GLOBAL_METER_V2_SUPPORT */ 2495 #endif /* BCM_GREYHOUND2_SUPPORT */ 2496 2497 2498