thresholds.c (124383B)
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 * Thresholds API implemenation for Tomahawk3 8 */ 9 #if defined(BCM_TOMAHAWK3_SUPPORT) 10 #include <bcm_int/esw/pfc.h> 11 #include <bcm_int/esw/port.h> 12 #include <bcm_int/esw/tomahawk3.h> 13 #include <soc/feature.h> 14 #include <soc/drv.h> 15 #include <soc/types.h> 16 #include <soc/scache.h> 17 #include <soc/profile_mem.h> 18 #include <soc/debug.h> 19 #include <soc/tomahawk3.h> 20 #include <soc/dma.h> 21 #include <soc/mmu_config.h> 22 23 24 /* 25 * Function: 26 _bcm_th3_cosq_port_inp_pri_to_pg_profile_set 27 * Purpose: 28 * Set the profile for Input priortty to PG mapping for a port 29 * Parameters: 30 * unit - (IN) device id. 31 * port - (IN) Port number. 32 * profile_id - (IN) Profile index 33 * Returns : 34 * BCM_E_XXX 35 */ 36 37 int 38 _bcm_th3_cosq_port_inp_pri_to_pg_profile_set( 39 int unit, 40 bcm_port_t port, 41 int profile_id) 42 { 43 uint32 rval; 44 45 if (!SOC_PORT_VALID(unit, port)) { 46 return BCM_E_PORT; 47 } 48 49 if ((profile_id < 0) || (profile_id >= _TH3_MMU_NUM_MAX_PROFILES)) { 50 return BCM_E_PARAM; 51 } 52 53 rval = 0; 54 BCM_IF_ERROR_RETURN( 55 soc_tomahawk3_itm_reg32_get(unit, MMU_THDI_ING_PORT_CONFIGr, 56 -1, port, 0, &rval)); 57 /* soc_reg_field_set(unit, MMU_THDI_ING_PORT_CONFIGr, &rval, 58 PG_PROFILE_SELf, buf_port->prigroup_profile_idx); */ 59 soc_reg_field_set(unit, MMU_THDI_ING_PORT_CONFIGr, &rval, 60 INPPRI_PROFILE_SELf, profile_id); 61 BCM_IF_ERROR_RETURN( 62 soc_tomahawk3_itm_reg32_set(unit, MMU_THDI_ING_PORT_CONFIGr, 63 -1, port, 0, rval)); 64 65 return BCM_E_NONE; 66 } 67 68 /* 69 * Function: 70 _bcm_th3_cosq_port_inp_pri_to_pg_profile_get 71 * Purpose: 72 * Get the profile for Input priortty to PG mapping for a port 73 * Parameters: 74 * unit - (IN) device id. 75 * port - (IN) Port number. 76 * profile_id - (IN) Profile index 77 * Returns : 78 * BCM_E_XXX 79 */ 80 81 int 82 _bcm_th3_cosq_port_inp_pri_to_pg_profile_get( 83 int unit, 84 bcm_port_t port, 85 int *profile_id) 86 { 87 uint32 rval; 88 89 if (!SOC_PORT_VALID(unit, port)) { 90 return BCM_E_PORT; 91 } 92 93 if (profile_id == NULL) { 94 return BCM_E_PARAM; 95 } 96 97 rval = 0; 98 BCM_IF_ERROR_RETURN( 99 soc_tomahawk3_itm_reg32_get(unit, MMU_THDI_ING_PORT_CONFIGr, 100 -1, port, 0, &rval)); 101 *profile_id = soc_reg_field_get(unit, MMU_THDI_ING_PORT_CONFIGr, rval, 102 INPPRI_PROFILE_SELf); 103 104 return BCM_E_NONE; 105 } 106 107 /* 108 * Function: 109 _bcm_th3_cosq_port_pg_profile_set 110 * Purpose: 111 * Set the profile for PG to SPID/HPID/PFCPRI mapping for a port 112 * Parameters: 113 * unit - (IN) device id. 114 * port - (IN) Port number. 115 * profile_id - (IN) Profile index 116 * Returns : 117 * BCM_E_XXX 118 */ 119 120 int 121 _bcm_th3_cosq_port_pg_profile_set( 122 int unit, 123 bcm_port_t port, 124 int profile_id) 125 { 126 uint32 rval; 127 128 if (!SOC_PORT_VALID(unit, port)) { 129 return BCM_E_PORT; 130 } 131 132 if ((profile_id < 0) || (profile_id >= _TH3_MMU_NUM_MAX_PROFILES)) { 133 return BCM_E_PARAM; 134 } 135 136 rval = 0; 137 BCM_IF_ERROR_RETURN( 138 soc_tomahawk3_itm_reg32_get(unit, MMU_THDI_ING_PORT_CONFIGr, 139 -1, port, 0, &rval)); 140 soc_reg_field_set(unit, MMU_THDI_ING_PORT_CONFIGr, &rval, 141 PG_PROFILE_SELf, profile_id); 142 BCM_IF_ERROR_RETURN( 143 soc_tomahawk3_itm_reg32_set(unit, MMU_THDI_ING_PORT_CONFIGr, 144 -1, port, 0, rval)); 145 146 return BCM_E_NONE; 147 } 148 149 /* 150 * Function: 151 _bcm_th3_cosq_port_pg_profile_get 152 * Purpose: 153 * Get the profile for PG to SPID/HPID/PFCPRI mapping for a port 154 * Parameters: 155 * unit - (IN) device id. 156 * port - (IN) Port number. 157 * profile_id - (OUT) Profile index 158 * Returns : 159 * BCM_E_XXX 160 */ 161 162 int 163 _bcm_th3_cosq_port_pg_profile_get( 164 int unit, 165 bcm_port_t port, 166 int *profile_id) 167 { 168 uint32 rval; 169 170 if (!SOC_PORT_VALID(unit, port)) { 171 return BCM_E_PORT; 172 } 173 174 if (profile_id == NULL) { 175 return BCM_E_PARAM; 176 } 177 178 rval = 0; 179 BCM_IF_ERROR_RETURN( 180 soc_tomahawk3_itm_reg32_get(unit, MMU_THDI_ING_PORT_CONFIGr, 181 -1, port, 0, &rval)); 182 *profile_id = soc_reg_field_get(unit, MMU_THDI_ING_PORT_CONFIGr, rval, 183 PG_PROFILE_SELf); 184 185 return BCM_E_NONE; 186 } 187 188 /* 189 * Function: 190 bcm_tomahawk3_cosq_priority_group_mapping_profile_set 191 * Purpose: 192 * Set a profile for the following mappings: Input Pri to priority group UC 193 * Input Pri to priority group MC 194 * Priority Group to Service Pool 195 * Priority Group to Headroom Pool 196 * Parameters: 197 * unit - (IN) device id. 198 * profile_index - (IN) Profile index. 199 * type - (IN) Mapping type 200 * array_count - (IN) actual size of array arg 201 * arg - (IN) Value of ouput to mapping type 202 * Returns: 203 * BCM_E_XXX 204 */ 205 int 206 bcm_tomahawk3_cosq_priority_group_mapping_profile_set( 207 int unit, 208 int profile_index, 209 bcm_cosq_priority_group_mapping_profile_type_t type, 210 int array_count, 211 int* arg) 212 { 213 int i; 214 uint64 rval; 215 soc_field_t field_pri[_TH3_MMU_NUM_INT_PRI] = { 216 INPPRI0_PGf, INPPRI1_PGf, INPPRI2_PGf, 217 INPPRI3_PGf, INPPRI4_PGf, INPPRI5_PGf, 218 INPPRI6_PGf, INPPRI7_PGf, INPPRI8_PGf, 219 INPPRI9_PGf, INPPRI10_PGf, INPPRI11_PGf, 220 INPPRI12_PGf, INPPRI13_PGf, INPPRI14_PGf, 221 INPPRI15_PGf}; 222 soc_field_t field_hpid[_TH3_MMU_NUM_PG] = { 223 PG0_HPIDf, PG1_HPIDf, PG2_HPIDf, 224 PG3_HPIDf, PG4_HPIDf, PG5_HPIDf, 225 PG6_HPIDf, PG7_HPIDf}; 226 soc_field_t field_spid[_TH3_MMU_NUM_PG] = { 227 PG0_SPIDf, PG1_SPIDf, PG2_SPIDf, 228 PG3_SPIDf, PG4_SPIDf, PG5_SPIDf, 229 PG6_SPIDf, PG7_SPIDf}; 230 231 if ((profile_index < 0) || (profile_index >= _TH3_MMU_NUM_MAX_PROFILES)) { 232 return BCM_E_PARAM; 233 } 234 235 if (arg == NULL) { 236 return SOC_E_PARAM; 237 } 238 239 switch (type) { 240 case bcmCosqInputPriPriorityGroupUcMapping: 241 COMPILER_64_ZERO(rval); 242 SOC_IF_ERROR_RETURN 243 (soc_reg64_get(unit, MMU_THDI_UC_INPPRI_PG_PROFILEr, 244 REG_PORT_ANY, profile_index, &rval)); 245 if ((array_count <= 0) || (array_count > _TH3_MMU_NUM_INT_PRI)) { 246 return BCM_E_PARAM; 247 } 248 for (i = 0; i < array_count; i++) { 249 if (arg[i] != -1) { 250 if ((arg[i] < 0) || (arg[i] >= _TH3_MMU_NUM_PG)) { 251 return BCM_E_PARAM; 252 } 253 } else { 254 continue; 255 } 256 soc_reg64_field32_set(unit, MMU_THDI_UC_INPPRI_PG_PROFILEr, &rval, 257 field_pri[i], arg[i]); 258 } 259 SOC_IF_ERROR_RETURN 260 (soc_reg64_set(unit, MMU_THDI_UC_INPPRI_PG_PROFILEr, 261 REG_PORT_ANY, profile_index, rval)); 262 break; 263 case bcmCosqInputPriPriorityGroupMcMapping: 264 COMPILER_64_ZERO(rval); 265 SOC_IF_ERROR_RETURN 266 (soc_reg64_get(unit, MMU_THDI_NONUC_INPPRI_PG_PROFILEr, 267 REG_PORT_ANY, profile_index, &rval)); 268 if ((array_count <= 0) || (array_count > _TH3_MMU_NUM_INT_PRI)) { 269 return BCM_E_PARAM; 270 } 271 for (i = 0; i < array_count; i++) { 272 if (arg[i] != -1) { 273 if ((arg[i] < 0) || (arg[i] >= _TH3_MMU_NUM_PG)) { 274 return BCM_E_PARAM; 275 } 276 } else { 277 continue; 278 } 279 soc_reg64_field32_set(unit, MMU_THDI_NONUC_INPPRI_PG_PROFILEr, &rval, 280 field_pri[i], arg[i]); 281 } 282 SOC_IF_ERROR_RETURN 283 (soc_reg64_set(unit, MMU_THDI_NONUC_INPPRI_PG_PROFILEr, 284 REG_PORT_ANY, profile_index, rval)); 285 break; 286 case bcmCosqPriorityGroupServicePoolMapping: 287 COMPILER_64_ZERO(rval); 288 SOC_IF_ERROR_RETURN 289 (soc_reg64_get(unit, MMU_THDI_PG_PROFILEr, REG_PORT_ANY, 290 profile_index, &rval)); 291 if ((array_count <= 0) || (array_count > _TH3_MMU_NUM_PG)) { 292 return BCM_E_PARAM; 293 } 294 for (i = 0; i < array_count; i++) { 295 if (arg[i] != -1) { 296 if ((arg[i] < 0) || (arg[i] >= _TH3_MMU_NUM_POOL)) { 297 return BCM_E_PARAM; 298 } 299 } else { 300 continue; 301 } 302 soc_reg64_field32_set(unit, MMU_THDI_PG_PROFILEr, &rval, 303 field_spid[i], arg[i]); 304 } 305 SOC_IF_ERROR_RETURN 306 (soc_reg64_set(unit, MMU_THDI_PG_PROFILEr, REG_PORT_ANY, 307 profile_index, rval)); 308 break; 309 case bcmCosqPriorityGroupHeadroomPoolMapping: 310 COMPILER_64_ZERO(rval); 311 SOC_IF_ERROR_RETURN 312 (soc_reg64_get(unit, MMU_THDI_PG_PROFILEr, REG_PORT_ANY, 313 profile_index, &rval)); 314 if ((array_count <= 0) || (array_count > _TH3_MMU_NUM_PG)) { 315 return BCM_E_PARAM; 316 } 317 for (i = 0; i < array_count; i++) { 318 if (arg[i] != -1) { 319 if ((arg[i] < 0) || (arg[i] >= _TH3_MMU_NUM_POOL)) { 320 return BCM_E_PARAM; 321 } 322 } else { 323 continue; 324 } 325 soc_reg64_field32_set(unit, MMU_THDI_PG_PROFILEr, &rval, 326 field_hpid[i], arg[i]); 327 } 328 SOC_IF_ERROR_RETURN 329 (soc_reg64_set(unit, MMU_THDI_PG_PROFILEr, REG_PORT_ANY, 330 profile_index, rval)); 331 break; 332 default: 333 return BCM_E_PARAM; 334 335 } 336 337 return BCM_E_NONE; 338 } 339 340 341 /* 342 * Function: 343 bcm_tomahawk3_cosq_priority_group_mapping_profile_get 344 * Purpose: 345 * Set a profile for the following mappings: Input Pri to priority group UC 346 * Input Pri to priority group MC 347 * Priority Group to Service Pool 348 * Priority Group to Headroom Pool 349 * Parameters: 350 * unit - (IN) device id. 351 * profile_index - (IN) Profile index. 352 * type - (IN) Mapping type 353 * array_max - (IN) Max size of array 354 * array_count - (OUT) actual size of array 355 * arg - (OUT) Value of ouput to mapping type 356 * Returns: 357 * BCM_E_XXX 358 */ 359 int 360 bcm_tomahawk3_cosq_priority_group_mapping_profile_get( 361 int unit, 362 int profile_index, 363 bcm_cosq_priority_group_mapping_profile_type_t type, 364 int array_max, 365 int* arg, 366 int* array_count) 367 { 368 int i; 369 uint64 rval; 370 soc_field_t field_pri[_TH3_MMU_NUM_INT_PRI] = { 371 INPPRI0_PGf, INPPRI1_PGf, INPPRI2_PGf, 372 INPPRI3_PGf, INPPRI4_PGf, INPPRI5_PGf, 373 INPPRI6_PGf, INPPRI7_PGf, INPPRI8_PGf, 374 INPPRI9_PGf, INPPRI10_PGf, INPPRI11_PGf, 375 INPPRI12_PGf, INPPRI13_PGf, INPPRI14_PGf, 376 INPPRI15_PGf}; 377 soc_field_t field_hpid[_TH3_MMU_NUM_PG] = { 378 PG0_HPIDf, PG1_HPIDf, PG2_HPIDf, 379 PG3_HPIDf, PG4_HPIDf, PG5_HPIDf, 380 PG6_HPIDf, PG7_HPIDf}; 381 soc_field_t field_spid[_TH3_MMU_NUM_PG] = { 382 PG0_SPIDf, PG1_SPIDf, PG2_SPIDf, 383 PG3_SPIDf, PG4_SPIDf, PG5_SPIDf, 384 PG6_SPIDf, PG7_SPIDf}; 385 386 if ((profile_index < 0) || (profile_index >= _TH3_MMU_NUM_MAX_PROFILES)) { 387 return BCM_E_PARAM; 388 } 389 390 if (((array_max == 0) && (arg != NULL)) || 391 ((array_max != 0) && (arg == NULL))) { 392 return SOC_E_PARAM; 393 } 394 395 *array_count = 0; 396 switch (type) { 397 case bcmCosqInputPriPriorityGroupUcMapping: 398 COMPILER_64_ZERO(rval); 399 SOC_IF_ERROR_RETURN 400 (soc_reg64_get(unit, MMU_THDI_UC_INPPRI_PG_PROFILEr, 401 REG_PORT_ANY, profile_index, &rval)); 402 for (i = 0; ((i < _TH3_MMU_NUM_INT_PRI) && (i < array_max)); i++) { 403 arg[i] = soc_reg64_field32_get(unit, MMU_THDI_UC_INPPRI_PG_PROFILEr, 404 rval, field_pri[i]); 405 406 } 407 *array_count = i; 408 break; 409 case bcmCosqInputPriPriorityGroupMcMapping: 410 COMPILER_64_ZERO(rval); 411 SOC_IF_ERROR_RETURN 412 (soc_reg64_get(unit, MMU_THDI_NONUC_INPPRI_PG_PROFILEr, 413 REG_PORT_ANY, profile_index, &rval)); 414 for (i = 0; ((i < _TH3_MMU_NUM_INT_PRI) && (i < array_max)); i++) { 415 arg[i] = soc_reg64_field32_get(unit, MMU_THDI_NONUC_INPPRI_PG_PROFILEr, 416 rval, field_pri[i]); 417 } 418 *array_count = i; 419 break; 420 case bcmCosqPriorityGroupServicePoolMapping: 421 COMPILER_64_ZERO(rval); 422 SOC_IF_ERROR_RETURN 423 (soc_reg64_get(unit, MMU_THDI_PG_PROFILEr, REG_PORT_ANY, 424 profile_index, &rval)); 425 for (i = 0; ((i < _TH3_MMU_NUM_PG) && (i < array_max)); i++) { 426 arg[i] = soc_reg64_field32_get(unit, MMU_THDI_PG_PROFILEr, 427 rval, field_spid[i]); 428 } 429 *array_count = i; 430 break; 431 case bcmCosqPriorityGroupHeadroomPoolMapping: 432 COMPILER_64_ZERO(rval); 433 SOC_IF_ERROR_RETURN 434 (soc_reg64_get(unit, MMU_THDI_PG_PROFILEr, REG_PORT_ANY, 435 profile_index, &rval)); 436 for (i = 0; ((i < _TH3_MMU_NUM_PG) && (i < array_max)); i++) { 437 arg[i] = soc_reg64_field32_get(unit, MMU_THDI_PG_PROFILEr, 438 rval, field_hpid[i]); 439 } 440 *array_count = i; 441 break; 442 default: 443 return BCM_E_PARAM; 444 445 } 446 447 return BCM_E_NONE; 448 } 449 450 /* 451 * Function: 452 bcm_tomahawk3_cosq_service_pool_override_set 453 * Purpose: 454 * Set service pool overrides for CPU, Multicast and Mirror 455 * Parameters: 456 * unit - (IN) device id. 457 * type - (IN) Service pool override type 458 * service_pool - (IN) Service pool id 459 * enable - (IN) Enable/Disable service pool override 460 * Returns: 461 * BCM_E_XXX 462 */ 463 int 464 bcm_tomahawk3_cosq_service_pool_override_set( 465 int unit, 466 bcm_cosq_service_pool_override_type_t type, 467 bcm_service_pool_id_t service_pool, 468 int enable) 469 { 470 uint64 rval; 471 472 if ((service_pool < 0) || (service_pool >= _TH3_MMU_NUM_POOL)) { 473 return BCM_E_PARAM; 474 } 475 476 if ((enable < 0) || (enable > 1)) { 477 return BCM_E_PARAM; 478 } 479 switch (type) { 480 case bcmCosqServicePoolOverrideCpu: 481 COMPILER_64_ZERO(rval); 482 SOC_IF_ERROR_RETURN 483 (soc_reg_get(unit, MMU_THDI_CPU_SPID_OVERRIDE_CTRLr, 484 REG_PORT_ANY, -1, &rval)); 485 soc_reg64_field32_set(unit, MMU_THDI_CPU_SPID_OVERRIDE_CTRLr, &rval, 486 SPIDf, service_pool); 487 soc_reg64_field32_set(unit, MMU_THDI_CPU_SPID_OVERRIDE_CTRLr, &rval, 488 ENABLEf, enable); 489 SOC_IF_ERROR_RETURN 490 (soc_reg_set(unit, MMU_THDI_CPU_SPID_OVERRIDE_CTRLr, 491 REG_PORT_ANY, -1, rval)); 492 break; 493 case bcmCosqServicePoolOverrideMcPkt: 494 COMPILER_64_ZERO(rval); 495 SOC_IF_ERROR_RETURN 496 (soc_reg_get(unit, MMU_THDI_MC_SPID_OVERRIDE_CTRLr, 497 REG_PORT_ANY, -1, &rval)); 498 soc_reg64_field32_set(unit, MMU_THDI_MC_SPID_OVERRIDE_CTRLr, &rval, 499 SPIDf, service_pool); 500 soc_reg64_field32_set(unit, MMU_THDI_MC_SPID_OVERRIDE_CTRLr, &rval, 501 ENABLEf, enable); 502 SOC_IF_ERROR_RETURN 503 (soc_reg_set(unit, MMU_THDI_MC_SPID_OVERRIDE_CTRLr, 504 REG_PORT_ANY, -1, rval)); 505 break; 506 case bcmCosqServicePoolOverrideMirror: 507 COMPILER_64_ZERO(rval); 508 SOC_IF_ERROR_RETURN 509 (soc_reg_get(unit, MMU_THDI_MIRROR_SPID_OVERRIDE_CTRLr, 510 REG_PORT_ANY, -1, &rval)); 511 soc_reg64_field32_set(unit, MMU_THDI_MIRROR_SPID_OVERRIDE_CTRLr, &rval, 512 SPIDf, service_pool); 513 soc_reg64_field32_set(unit, MMU_THDI_MIRROR_SPID_OVERRIDE_CTRLr, &rval, 514 ENABLEf, enable); 515 SOC_IF_ERROR_RETURN 516 (soc_reg_set(unit, MMU_THDI_MIRROR_SPID_OVERRIDE_CTRLr, 517 REG_PORT_ANY, -1, rval)); 518 break; 519 default: 520 return BCM_E_PARAM; 521 } 522 return BCM_E_NONE; 523 } 524 525 526 /* 527 * Function: 528 bcm_tomahawk3_cosq_service_pool_override_get 529 * Purpose: 530 * Set service pool overrides for CPU, Multicast and Mirror 531 * Parameters: 532 * unit - (IN) device id. 533 * type - (IN) Service pool override type 534 * service_pool - (OUT) Service pool id 535 * enable - (OUT) Enable/Disable service pool override 536 * Returns: 537 * BCM_E_XXX 538 */ 539 int 540 bcm_tomahawk3_cosq_service_pool_override_get( 541 int unit, 542 bcm_cosq_service_pool_override_type_t type, 543 bcm_service_pool_id_t* service_pool, 544 int* enable) 545 { 546 uint64 rval; 547 548 switch (type) { 549 case bcmCosqServicePoolOverrideCpu: 550 COMPILER_64_ZERO(rval); 551 SOC_IF_ERROR_RETURN 552 (soc_reg_get(unit, MMU_THDI_CPU_SPID_OVERRIDE_CTRLr, 553 REG_PORT_ANY, -1, &rval)); 554 *service_pool = soc_reg64_field32_get(unit, 555 MMU_THDI_CPU_SPID_OVERRIDE_CTRLr, rval, SPIDf); 556 *enable = soc_reg64_field32_get(unit, 557 MMU_THDI_CPU_SPID_OVERRIDE_CTRLr, rval, ENABLEf); 558 break; 559 case bcmCosqServicePoolOverrideMcPkt: 560 COMPILER_64_ZERO(rval); 561 SOC_IF_ERROR_RETURN 562 (soc_reg_get(unit, MMU_THDI_MC_SPID_OVERRIDE_CTRLr, 563 REG_PORT_ANY, -1, &rval)); 564 *service_pool = soc_reg64_field32_get(unit, 565 MMU_THDI_MC_SPID_OVERRIDE_CTRLr, rval, SPIDf); 566 *enable = soc_reg64_field32_get(unit, 567 MMU_THDI_MC_SPID_OVERRIDE_CTRLr, rval, ENABLEf); 568 break; 569 case bcmCosqServicePoolOverrideMirror: 570 COMPILER_64_ZERO(rval); 571 SOC_IF_ERROR_RETURN 572 (soc_reg_get(unit, MMU_THDI_MIRROR_SPID_OVERRIDE_CTRLr, 573 REG_PORT_ANY, -1, &rval)); 574 *service_pool = soc_reg64_field32_get(unit, 575 MMU_THDI_MIRROR_SPID_OVERRIDE_CTRLr, rval, SPIDf); 576 *enable = soc_reg64_field32_get(unit, 577 MMU_THDI_MIRROR_SPID_OVERRIDE_CTRLr, rval, ENABLEf); 578 break; 579 default: 580 return BCM_E_PARAM; 581 } 582 return BCM_E_NONE; 583 } 584 585 /* 586 * Function: 587 bcm_tomahawk3_cosq_port_priority_group_property_set 588 * Purpose: 589 * Get per port per priority group properties : Lossless, Pause 590 * Parameters: 591 * unit - (IN) device id. 592 * port - (IN) Port number. 593 * priority_group_id - (IN) Priority group 594 * type - (IN) Property type (Lossless or Pause enable) 595 * arg - (IN) Value based on property type 596 * Returns : 597 * BCM_E_XXX 598 */ 599 600 int 601 bcm_tomahawk3_cosq_port_priority_group_property_set( 602 int unit, 603 bcm_port_t port, 604 int priority_group_id, 605 bcm_cosq_port_prigroup_control_t type, 606 int arg) 607 { 608 uint64 rval; 609 int pg_lossless; 610 611 if (!SOC_PORT_VALID(unit, port)) { 612 return BCM_E_PORT; 613 } 614 615 switch (type) { 616 case bcmCosqPriorityGroupLossless: 617 if ((priority_group_id < 0) || 618 (priority_group_id >= _TH3_MMU_NUM_PG)) { 619 return BCM_E_PARAM; 620 } 621 COMPILER_64_ZERO(rval); 622 SOC_IF_ERROR_RETURN 623 (soc_reg_get(unit, MMU_THDI_ING_PORT_CONFIGr, port, -1, &rval)); 624 pg_lossless = soc_reg64_field32_get(unit, 625 MMU_THDI_ING_PORT_CONFIGr, rval, PG_IS_LOSSLESSf); 626 if (arg) { 627 pg_lossless = pg_lossless | (1 << priority_group_id); 628 } else { 629 pg_lossless &= (0xff ^ (1 << priority_group_id)); 630 } 631 soc_reg64_field32_set(unit, MMU_THDI_ING_PORT_CONFIGr, &rval, 632 PG_IS_LOSSLESSf, pg_lossless); 633 SOC_IF_ERROR_RETURN 634 (soc_reg_set(unit, MMU_THDI_ING_PORT_CONFIGr, port, -1, rval)); 635 break; 636 case bcmCosqPauseEnable: 637 COMPILER_64_ZERO(rval); 638 SOC_IF_ERROR_RETURN 639 (soc_reg_get(unit, MMU_THDI_ING_PORT_CONFIGr, port, -1, &rval)); 640 soc_reg64_field32_set(unit, MMU_THDI_ING_PORT_CONFIGr, &rval, 641 PAUSE_ENABLEf, arg); 642 /* Disable PFC if pause is enabled */ 643 if (arg == 1) { 644 soc_reg64_field32_set(unit, MMU_THDI_ING_PORT_CONFIGr, &rval, 645 PFC_PG_ENABLEf, 0); 646 } 647 SOC_IF_ERROR_RETURN 648 (soc_reg_set(unit, MMU_THDI_ING_PORT_CONFIGr, port, -1, rval)); 649 break; 650 } 651 652 return BCM_E_NONE; 653 } 654 /* 655 * Function: 656 bcm_tomahawk3_cosq_port_priority_group_property_get 657 * Purpose: 658 * Get per port per priority group properties : Lossless, Pause 659 * Parameters: 660 * unit - (IN) device id. 661 * port - (IN) Port number. 662 * priority_group_id - (IN) Priority group 663 * type - (IN) Property type (Lossless or Pause enable) 664 * arg - (OUT) Value based on property type 665 * Returns : 666 * BCM_E_XXX 667 */ 668 669 int 670 bcm_tomahawk3_cosq_port_priority_group_property_get( 671 int unit, 672 bcm_port_t port, 673 int priority_group_id, 674 bcm_cosq_port_prigroup_control_t type, 675 int *arg) 676 { 677 uint64 rval; 678 int pg_lossless; 679 680 if (!SOC_PORT_VALID(unit, port)) { 681 return BCM_E_PORT; 682 } 683 684 switch (type) { 685 case bcmCosqPriorityGroupLossless: 686 if ((priority_group_id < 0) || 687 (priority_group_id >= _TH3_MMU_NUM_PG)) { 688 return BCM_E_PARAM; 689 } 690 COMPILER_64_ZERO(rval); 691 SOC_IF_ERROR_RETURN 692 (soc_reg_get(unit, MMU_THDI_ING_PORT_CONFIGr, port, -1, &rval)); 693 pg_lossless = soc_reg64_field32_get(unit, MMU_THDI_ING_PORT_CONFIGr, 694 rval, PG_IS_LOSSLESSf); 695 *arg = (pg_lossless & (1 << priority_group_id)) >> priority_group_id; 696 break; 697 case bcmCosqPauseEnable: 698 COMPILER_64_ZERO(rval); 699 SOC_IF_ERROR_RETURN 700 (soc_reg_get(unit, MMU_THDI_ING_PORT_CONFIGr, port, -1, &rval)); 701 *arg = soc_reg64_field32_get(unit, MMU_THDI_ING_PORT_CONFIGr, 702 rval, PAUSE_ENABLEf); 703 break; 704 } 705 706 return BCM_E_NONE; 707 } 708 709 STATIC int 710 _bcm_th3_cosq_ing_pool_set(int unit, bcm_gport_t gport, 711 bcm_cos_t prigroup, 712 bcm_cosq_control_t type, int arg) 713 { 714 if ((arg < 0) || (arg >= _TH3_MMU_NUM_POOL)) { 715 return BCM_E_PARAM; 716 } 717 718 719 /* Expects priority group as input in Tomahawk3 720 * Future enhancement is to create gport type for priority group 721 */ 722 if ((prigroup < 0) || (prigroup >= _TH3_MMU_NUM_PG)) { 723 return BCM_E_PARAM; 724 } 725 726 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) || 727 BCM_GPORT_IS_SCHEDULER(gport) || 728 BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 729 return BCM_E_PARAM; 730 } 731 732 if (type == bcmCosqControlIngressPool) { 733 BCM_IF_ERROR_RETURN( 734 _bcm_th3_cosq_ingress_sp_set_by_pg(unit, gport, prigroup, arg)); 735 } else if (type == bcmCosqControlIngressHeadroomPool) { 736 BCM_IF_ERROR_RETURN( 737 _bcm_th3_cosq_ingress_hdrm_pool_set_by_pg(unit, gport, prigroup, arg)); 738 } else { 739 return BCM_E_PARAM; 740 } 741 742 return BCM_E_NONE; 743 } 744 745 746 STATIC int 747 _bcm_th3_cosq_ing_pool_get(int unit, bcm_gport_t gport, 748 bcm_cos_t prigroup, 749 bcm_cosq_control_t type, int *arg) 750 { 751 if (arg == NULL) { 752 return BCM_E_PARAM; 753 } 754 755 /* Expects priority group as input in Tomahawk3 756 * Future enhancement is to create gport type for priority group 757 */ 758 if ((prigroup < 0) || (prigroup >= _TH3_MMU_NUM_PG)) { 759 return BCM_E_PARAM; 760 } 761 762 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) || 763 BCM_GPORT_IS_SCHEDULER(gport) || 764 BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 765 return BCM_E_PARAM; 766 } 767 768 if (type == bcmCosqControlIngressPool) { 769 BCM_IF_ERROR_RETURN( 770 _bcm_th3_cosq_ingress_sp_get_by_pg(unit, gport, prigroup, arg)); 771 } else if (type == bcmCosqControlIngressHeadroomPool) { 772 BCM_IF_ERROR_RETURN( 773 _bcm_th3_cosq_ingress_hdrm_pool_get_by_pg(unit, gport, prigroup, arg)); 774 } else { 775 return BCM_E_PARAM; 776 } 777 return BCM_E_NONE; 778 } 779 780 781 STATIC int 782 _bcm_th3_cosq_dynamic_thresh_enable_get(int unit, 783 bcm_gport_t gport, bcm_cos_queue_t cosq, 784 bcm_cosq_control_t type, int* arg) 785 { 786 bcm_port_t local_port; 787 int startq; 788 int pipe; 789 int from_cos, to_cos, ci; 790 int midx; 791 uint32 entry[SOC_MAX_MEM_WORDS]; 792 soc_mem_t mem = INVALIDm; 793 int port_pg; 794 /* 795 soc_field_t field_pgshared_limit[_TH3_MMU_NUM_PG] = { 796 PG0_SHARED_LIMITf, PG1_SHARED_LIMITf, PG2_SHARED_LIMITf, 797 PG3_SHARED_LIMITf, PG4_SHARED_LIMITf, PG5_SHARED_LIMITf, 798 PG6_SHARED_LIMITf, PG7_SHARED_LIMITf}; 799 */ 800 soc_field_t field_pgshared_dynamic[_TH3_MMU_NUM_PG] = { 801 PG0_SHARED_DYNAMICf, PG1_SHARED_DYNAMICf, PG2_SHARED_DYNAMICf, 802 PG3_SHARED_DYNAMICf, PG4_SHARED_DYNAMICf, PG5_SHARED_DYNAMICf, 803 PG6_SHARED_DYNAMICf, PG7_SHARED_DYNAMICf}; 804 805 806 if (!arg) { 807 return BCM_E_PARAM; 808 } 809 810 if (type == bcmCosqControlIngressPortPGSharedDynamicEnable) { 811 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) || 812 BCM_GPORT_IS_SCHEDULER(gport) || 813 BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 814 return BCM_E_PARAM; 815 } 816 BCM_IF_ERROR_RETURN 817 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 818 819 if (local_port < 0) { 820 return BCM_E_PORT; 821 } 822 /* Expects that cosq is priority group in Tomahawk3 823 * Future enhancement is to create gport type of priority group 824 */ 825 if ((cosq < 0) || (cosq >= _TH3_MMU_NUM_PG)) { 826 return BCM_E_PARAM; 827 } 828 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 829 830 port_pg = cosq; 831 832 mem = SOC_MEM_UNIQUE_ACC(unit, MMU_THDI_PORT_PG_SHARED_CONFIGm)[pipe]; 833 if (mem != INVALIDm) { 834 sal_memset(&entry, 0, sizeof(entry)); 835 midx = SOC_TH3_MMU_PIPED_MEM_INDEX(unit, local_port, 836 MMU_THDI_PORT_PG_SHARED_CONFIGm,0); 837 BCM_IF_ERROR_RETURN 838 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry)); 839 *arg = soc_mem_field32_get(unit, mem, entry, field_pgshared_dynamic[port_pg]); 840 } 841 } else if (type == bcmCosqControlEgressUCSharedDynamicEnable) { 842 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 843 BCM_IF_ERROR_RETURN 844 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 845 _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 846 &local_port, &startq, NULL)); 847 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 848 return BCM_E_PARAM; 849 } else { 850 if (cosq == BCM_COS_INVALID) { 851 from_cos = to_cos = 0; 852 } else { 853 from_cos = to_cos = cosq; 854 } 855 856 BCM_IF_ERROR_RETURN 857 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 858 if (local_port < 0) { 859 return BCM_E_PORT; 860 } 861 for (ci = from_cos; ci <= to_cos; ci++) { 862 BCM_IF_ERROR_RETURN 863 (_bcm_th3_cosq_index_resolve(unit, local_port, ci, 864 _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 865 NULL, &startq, NULL)); 866 867 } 868 } 869 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 870 mem = MMU_THDO_QUEUE_CONFIGm; 871 872 BCM_IF_ERROR_RETURN 873 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 874 *arg = soc_mem_field32_get(unit, mem, entry, LIMIT_DYNAMICf); 875 } else if (type == bcmCosqControlEgressMCSharedDynamicEnable) { 876 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 877 return BCM_E_PARAM; 878 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 879 BCM_IF_ERROR_RETURN 880 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 881 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 882 &local_port, &startq, NULL)); 883 } 884 else { 885 if (cosq == BCM_COS_INVALID) { 886 from_cos = to_cos = 0; 887 } else { 888 from_cos = to_cos = cosq; 889 } 890 891 BCM_IF_ERROR_RETURN 892 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 893 if (local_port < 0) { 894 return BCM_E_PORT; 895 } 896 for (ci = from_cos; ci <= to_cos; ci++) { 897 BCM_IF_ERROR_RETURN 898 (_bcm_th3_cosq_index_resolve(unit, local_port, ci, 899 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 900 NULL, &startq, NULL)); 901 902 } 903 } 904 905 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 906 mem = MMU_THDO_QUEUE_CONFIGm; 907 908 BCM_IF_ERROR_RETURN 909 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 910 *arg = soc_mem_field32_get(unit, mem, entry, LIMIT_DYNAMICf); 911 } 912 else { 913 return BCM_E_PARAM; 914 } 915 916 return BCM_E_NONE; 917 } 918 919 920 STATIC int 921 _bcm_th3_cosq_dynamic_thresh_enable_set(int unit, 922 bcm_gport_t gport, bcm_cos_queue_t cosq, 923 bcm_cosq_control_t type, int arg) 924 { 925 bcm_port_t local_port; 926 int startq; 927 int pipe; 928 int from_cos, to_cos, ci; 929 int midx; 930 /* uint32 rval; */ 931 uint32 entry[SOC_MAX_MEM_WORDS]; 932 soc_mem_t mem = INVALIDm; 933 /* soc_reg_t reg = INVALIDr; */ 934 int port_pg; 935 soc_field_t field_pgshared_limit[_TH3_MMU_NUM_PG] = { 936 PG0_SHARED_LIMITf, PG1_SHARED_LIMITf, PG2_SHARED_LIMITf, 937 PG3_SHARED_LIMITf, PG4_SHARED_LIMITf, PG5_SHARED_LIMITf, 938 PG6_SHARED_LIMITf, PG7_SHARED_LIMITf}; 939 soc_field_t field_pgshared_dynamic[_TH3_MMU_NUM_PG] = { 940 PG0_SHARED_DYNAMICf, PG1_SHARED_DYNAMICf, PG2_SHARED_DYNAMICf, 941 PG3_SHARED_DYNAMICf, PG4_SHARED_DYNAMICf, PG5_SHARED_DYNAMICf, 942 PG6_SHARED_DYNAMICf, PG7_SHARED_DYNAMICf}; 943 944 945 if (type == bcmCosqControlIngressPortPGSharedDynamicEnable) { 946 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) || 947 BCM_GPORT_IS_SCHEDULER(gport) || 948 BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 949 return BCM_E_PARAM; 950 } 951 BCM_IF_ERROR_RETURN 952 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 953 954 if (local_port < 0) { 955 return BCM_E_PORT; 956 } 957 /* Expects that cosq is priority group in Tomahawk3 958 * Future enhancement is to create gport type of priority group 959 */ 960 if ((cosq < 0) || (cosq >= _TH3_MMU_NUM_PG)) { 961 return BCM_E_PARAM; 962 } 963 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 964 965 port_pg = cosq; 966 967 mem = SOC_MEM_UNIQUE_ACC(unit, MMU_THDI_PORT_PG_SHARED_CONFIGm)[pipe]; 968 if (mem != INVALIDm) { 969 sal_memset(&entry, 0, sizeof(entry)); 970 midx = SOC_TH3_MMU_PIPED_MEM_INDEX(unit, local_port, 971 MMU_THDI_PORT_PG_SHARED_CONFIGm,0); 972 BCM_IF_ERROR_RETURN 973 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry)); 974 soc_mem_field32_set(unit, mem, entry, 975 field_pgshared_dynamic[port_pg], arg ? 1 : 0); 976 if(arg) { 977 /* Set default alpha value*/ 978 soc_mem_field32_set(unit, mem, entry, field_pgshared_limit[port_pg], 979 SOC_TH3_COSQ_DROP_LIMIT_ALPHA_2); /* Value: 8 */ 980 } 981 SOC_IF_ERROR_RETURN 982 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, midx, entry)); 983 } 984 } else if (type == bcmCosqControlEgressUCSharedDynamicEnable) { 985 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 986 BCM_IF_ERROR_RETURN 987 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 988 _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 989 &local_port, &startq, NULL)); 990 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 991 return BCM_E_PARAM; 992 } else { 993 if (cosq == BCM_COS_INVALID) { 994 from_cos = to_cos = 0; 995 } else { 996 from_cos = to_cos = cosq; 997 } 998 999 BCM_IF_ERROR_RETURN 1000 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 1001 if (local_port < 0) { 1002 return BCM_E_PORT; 1003 } 1004 for (ci = from_cos; ci <= to_cos; ci++) { 1005 BCM_IF_ERROR_RETURN 1006 (_bcm_th3_cosq_index_resolve(unit, local_port, ci, 1007 _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 1008 NULL, &startq, NULL)); 1009 1010 } 1011 } 1012 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1013 mem = MMU_THDO_QUEUE_CONFIGm; 1014 1015 BCM_IF_ERROR_RETURN 1016 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1017 soc_mem_field32_set(unit, mem, entry, 1018 LIMIT_DYNAMICf, arg ? 1 : 0); 1019 if(arg) { 1020 soc_mem_field32_set(unit, mem, entry, SHARED_ALPHAf, 1021 SOC_TH3_COSQ_DROP_LIMIT_ALPHA_2); 1022 } 1023 SOC_IF_ERROR_RETURN 1024 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1025 } else if (type == bcmCosqControlEgressMCSharedDynamicEnable) { 1026 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 1027 return BCM_E_PARAM; 1028 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 1029 BCM_IF_ERROR_RETURN 1030 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 1031 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 1032 &local_port, &startq, NULL)); 1033 } 1034 else { 1035 if (cosq == BCM_COS_INVALID) { 1036 from_cos = to_cos = 0; 1037 } else { 1038 from_cos = to_cos = cosq; 1039 } 1040 1041 BCM_IF_ERROR_RETURN 1042 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 1043 if (local_port < 0) { 1044 return BCM_E_PORT; 1045 } 1046 for (ci = from_cos; ci <= to_cos; ci++) { 1047 BCM_IF_ERROR_RETURN 1048 (_bcm_th3_cosq_index_resolve(unit, local_port, ci, 1049 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 1050 NULL, &startq, NULL)); 1051 1052 } 1053 } 1054 1055 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1056 mem = MMU_THDO_QUEUE_CONFIGm; 1057 1058 BCM_IF_ERROR_RETURN 1059 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1060 soc_mem_field32_set(unit, mem, entry, LIMIT_DYNAMICf, arg ? 1 : 0); 1061 if(arg) { 1062 soc_mem_field32_set(unit, mem, entry, SHARED_ALPHAf, 1063 SOC_TH3_COSQ_DROP_LIMIT_ALPHA_2); 1064 } 1065 SOC_IF_ERROR_RETURN 1066 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1067 } 1068 else { 1069 return BCM_E_PARAM; 1070 } 1071 1072 return BCM_E_NONE; 1073 } 1074 1075 STATIC int 1076 _bcm_th3_cosq_alpha_set(int unit, 1077 bcm_gport_t gport, bcm_cos_queue_t cosq, 1078 bcm_cosq_control_drop_limit_alpha_value_t arg) 1079 { 1080 bcm_port_t local_port; 1081 int startq, midx, pipe; 1082 /* uint32 rval; */ 1083 uint32 entry[SOC_MAX_MEM_WORDS]; 1084 soc_mem_t mem = INVALIDm; 1085 int alpha, dynamic_thresh_mode, port_pg; 1086 /* int phy_port, mmu_port, local_mmu_port; */ 1087 soc_field_t field_pgshared_limit[_TH3_MMU_NUM_PG] = { 1088 PG0_SHARED_LIMITf, PG1_SHARED_LIMITf, PG2_SHARED_LIMITf, 1089 PG3_SHARED_LIMITf, PG4_SHARED_LIMITf, PG5_SHARED_LIMITf, 1090 PG6_SHARED_LIMITf, PG7_SHARED_LIMITf}; 1091 1092 1093 switch(arg) { 1094 case bcmCosqControlDropLimitAlpha_1_128: 1095 alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_128; 1096 break; 1097 case bcmCosqControlDropLimitAlpha_1_64: 1098 alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_64; 1099 break; 1100 case bcmCosqControlDropLimitAlpha_1_32: 1101 alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_32; 1102 break; 1103 case bcmCosqControlDropLimitAlpha_1_16: 1104 alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_16; 1105 break; 1106 case bcmCosqControlDropLimitAlpha_1_8: 1107 alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_8; 1108 break; 1109 case bcmCosqControlDropLimitAlpha_1_4: 1110 alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_4; 1111 break; 1112 case bcmCosqControlDropLimitAlpha_1_2: 1113 alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_2; 1114 break; 1115 case bcmCosqControlDropLimitAlpha_1: 1116 alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1; 1117 break; 1118 case bcmCosqControlDropLimitAlpha_2: 1119 alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_2; 1120 break; 1121 case bcmCosqControlDropLimitAlpha_4: 1122 alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_4; 1123 break; 1124 case bcmCosqControlDropLimitAlpha_8: 1125 alpha = SOC_TH3_COSQ_DROP_LIMIT_ALPHA_8; 1126 break; 1127 default: 1128 return BCM_E_PARAM; 1129 } 1130 1131 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 1132 BCM_IF_ERROR_RETURN 1133 (_bcm_th3_cosq_dynamic_thresh_enable_get(unit, gport, cosq, 1134 bcmCosqControlEgressUCSharedDynamicEnable, 1135 &dynamic_thresh_mode)); 1136 if (!dynamic_thresh_mode){ 1137 return BCM_E_CONFIG; 1138 } 1139 1140 BCM_IF_ERROR_RETURN 1141 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 1142 _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 1143 &local_port, &startq, NULL)); 1144 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1145 1146 mem = MMU_THDO_QUEUE_CONFIGm; 1147 1148 BCM_IF_ERROR_RETURN 1149 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1150 soc_mem_field32_set(unit, mem, entry, 1151 SHARED_ALPHAf, alpha); 1152 SOC_IF_ERROR_RETURN 1153 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1154 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 1155 BCM_IF_ERROR_RETURN 1156 (_bcm_th3_cosq_dynamic_thresh_enable_get(unit, gport, cosq, 1157 bcmCosqControlEgressMCSharedDynamicEnable, 1158 &dynamic_thresh_mode)); 1159 if (!dynamic_thresh_mode){ 1160 return BCM_E_CONFIG; 1161 } 1162 1163 BCM_IF_ERROR_RETURN 1164 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 1165 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 1166 &local_port, &startq, NULL)); 1167 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1168 1169 mem = MMU_THDO_QUEUE_CONFIGm; 1170 1171 BCM_IF_ERROR_RETURN 1172 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1173 soc_mem_field32_set(unit, mem, entry, SHARED_ALPHAf, alpha); 1174 SOC_IF_ERROR_RETURN 1175 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1176 1177 } else if (BCM_GPORT_IS_LOCAL(gport)) { 1178 /* Shared limits are not applicable for Qgroup in Tomahawk3 */ 1179 /* _bcm_th3_cosq_dynamic_thresh_enable_get will return error for 1180 bcmCosqControlEgressUCQueueGroupSharedDynamicEnable, type 1181 */ 1182 return BCM_E_PARAM; 1183 } else { 1184 BCM_IF_ERROR_RETURN 1185 (_bcm_th3_cosq_dynamic_thresh_enable_get(unit, gport, cosq, 1186 bcmCosqControlIngressPortPGSharedDynamicEnable, 1187 &dynamic_thresh_mode)); 1188 if (!dynamic_thresh_mode){ 1189 return BCM_E_CONFIG; 1190 } 1191 1192 BCM_IF_ERROR_RETURN 1193 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 1194 if (local_port < 0) { 1195 return BCM_E_PORT; 1196 } 1197 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1198 1199 /* Expects that cosq is priority group in Tomahawk3 1200 * Future enhancement is to create gport type of priority group 1201 */ 1202 if ((cosq < 0) || (cosq >= _TH3_MMU_NUM_PG)) { 1203 return BCM_E_PARAM; 1204 } 1205 port_pg = cosq; 1206 1207 mem = SOC_MEM_UNIQUE_ACC(unit, MMU_THDI_PORT_PG_SHARED_CONFIGm)[pipe]; 1208 sal_memset(&entry, 0, sizeof(entry)); 1209 midx = SOC_TH3_MMU_PIPED_MEM_INDEX(unit, local_port, 1210 MMU_THDI_PORT_PG_SHARED_CONFIGm,0); 1211 BCM_IF_ERROR_RETURN 1212 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry)); 1213 soc_mem_field32_set(unit, mem, entry, field_pgshared_limit[port_pg], alpha); 1214 SOC_IF_ERROR_RETURN 1215 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, midx, entry)); 1216 } 1217 1218 return BCM_E_NONE; 1219 } 1220 1221 1222 1223 STATIC int 1224 _bcm_th3_cosq_alpha_get(int unit, 1225 bcm_gport_t gport, bcm_cos_queue_t cosq, 1226 bcm_cosq_control_drop_limit_alpha_value_t *arg) 1227 { 1228 bcm_port_t local_port; 1229 int startq, midx, pipe; 1230 uint32 entry[SOC_MAX_MEM_WORDS]; 1231 soc_mem_t mem = INVALIDm; 1232 int alpha, dynamic_thresh_mode, port_pg; 1233 soc_field_t field_pgshared_limit[_TH3_MMU_NUM_PG] = { 1234 PG0_SHARED_LIMITf, PG1_SHARED_LIMITf, PG2_SHARED_LIMITf, 1235 PG3_SHARED_LIMITf, PG4_SHARED_LIMITf, PG5_SHARED_LIMITf, 1236 PG6_SHARED_LIMITf, PG7_SHARED_LIMITf}; 1237 1238 1239 if (!arg) { 1240 return BCM_E_PARAM; 1241 } 1242 1243 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 1244 BCM_IF_ERROR_RETURN 1245 (_bcm_th3_cosq_dynamic_thresh_enable_get(unit, gport, cosq, 1246 bcmCosqControlEgressUCSharedDynamicEnable, 1247 &dynamic_thresh_mode)); 1248 if (!dynamic_thresh_mode){ 1249 return BCM_E_CONFIG; 1250 } 1251 1252 BCM_IF_ERROR_RETURN 1253 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 1254 _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 1255 &local_port, &startq, NULL)); 1256 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1257 1258 mem = MMU_THDO_QUEUE_CONFIGm; 1259 1260 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, 1261 startq, entry)); 1262 alpha = soc_mem_field32_get(unit, mem, entry, SHARED_ALPHAf); 1263 1264 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 1265 BCM_IF_ERROR_RETURN 1266 (_bcm_th3_cosq_dynamic_thresh_enable_get(unit, gport, cosq, 1267 bcmCosqControlEgressMCSharedDynamicEnable, 1268 &dynamic_thresh_mode)); 1269 if (!dynamic_thresh_mode){ 1270 return BCM_E_CONFIG; 1271 } 1272 1273 BCM_IF_ERROR_RETURN 1274 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 1275 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 1276 &local_port, &startq, NULL)); 1277 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1278 1279 mem = MMU_THDO_QUEUE_CONFIGm; 1280 BCM_IF_ERROR_RETURN 1281 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1282 alpha = soc_mem_field32_get(unit, mem, entry, SHARED_ALPHAf); 1283 1284 } else { 1285 BCM_IF_ERROR_RETURN 1286 (_bcm_th3_cosq_dynamic_thresh_enable_get(unit, gport, cosq, 1287 bcmCosqControlIngressPortPGSharedDynamicEnable, 1288 &dynamic_thresh_mode)); 1289 if (!dynamic_thresh_mode){ 1290 return BCM_E_CONFIG; 1291 } 1292 1293 BCM_IF_ERROR_RETURN 1294 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 1295 if (local_port < 0) { 1296 return BCM_E_PORT; 1297 } 1298 1299 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1300 1301 /* Expects that cosq is priority group in Tomahawk3 1302 * Future enhancement is to create gport type of priority group 1303 */ 1304 if ((cosq < 0) || (cosq >= _TH3_MMU_NUM_PG)) { 1305 return BCM_E_PARAM; 1306 } 1307 port_pg = cosq; 1308 1309 mem = SOC_MEM_UNIQUE_ACC(unit, MMU_THDI_PORT_PG_SHARED_CONFIGm)[pipe]; 1310 sal_memset(&entry, 0, sizeof(entry)); 1311 midx = SOC_TH3_MMU_PIPED_MEM_INDEX(unit, local_port, 1312 MMU_THDI_PORT_PG_SHARED_CONFIGm,0); 1313 BCM_IF_ERROR_RETURN 1314 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry)); 1315 alpha = soc_mem_field32_get(unit, mem, entry, field_pgshared_limit[port_pg]); 1316 } 1317 1318 switch(alpha) { 1319 case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_128: 1320 *arg = bcmCosqControlDropLimitAlpha_1_128; 1321 break; 1322 case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_64: 1323 *arg = bcmCosqControlDropLimitAlpha_1_64; 1324 break; 1325 case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_32: 1326 *arg = bcmCosqControlDropLimitAlpha_1_32; 1327 break; 1328 case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_16: 1329 *arg = bcmCosqControlDropLimitAlpha_1_16; 1330 break; 1331 case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_8: 1332 *arg = bcmCosqControlDropLimitAlpha_1_8; 1333 break; 1334 case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_4: 1335 *arg = bcmCosqControlDropLimitAlpha_1_4; 1336 break; 1337 case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1_2: 1338 *arg = bcmCosqControlDropLimitAlpha_1_2; 1339 break; 1340 case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_1: 1341 *arg = bcmCosqControlDropLimitAlpha_1; 1342 break; 1343 case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_2: 1344 *arg = bcmCosqControlDropLimitAlpha_2; 1345 break; 1346 case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_4: 1347 *arg = bcmCosqControlDropLimitAlpha_4; 1348 break; 1349 case SOC_TH3_COSQ_DROP_LIMIT_ALPHA_8: 1350 *arg = bcmCosqControlDropLimitAlpha_8; 1351 break; 1352 default: 1353 return BCM_E_PARAM; 1354 } 1355 1356 return BCM_E_NONE; 1357 } 1358 1359 /* 1360 * Function: _bcm_th3_cosq_egr_queue_color_limit_set 1361 * Purpose: Set Red and Yellow color limit per queue 1362 * IF color mode dynamic: limit should be between 0-7 1363 * 0: 100% of green threshold 1364 * 1: 12.5% of green threshold 1365 * 2: 25% of green threshold 1366 * 3: 37.5% of green threshold 1367 * 4: 50% of green threshold 1368 * 5: 67.5% of green threshold 1369 * 6: 75% of green threshold 1370 * 7: 87.5% of green threshold 1371 * If color mode static: Limit is number of bytes 1372 */ 1373 1374 STATIC int 1375 _bcm_th3_cosq_egr_queue_color_limit_set(int unit, bcm_gport_t gport, 1376 bcm_cos_queue_t cosq, 1377 bcm_cosq_control_t type, 1378 int arg) 1379 { 1380 bcm_port_t local_port; 1381 int startq, pipe; 1382 uint32 entry[SOC_MAX_MEM_WORDS]; 1383 soc_mem_t mem = INVALIDm; 1384 soc_field_t fld_limit = INVALIDf; 1385 int color_mode, granularity, max_val; 1386 1387 if (arg < 0) { 1388 return BCM_E_PARAM; 1389 } 1390 granularity = 8; 1391 1392 if ((type == bcmCosqControlEgressUCQueueRedLimit) || 1393 (type == bcmCosqControlEgressUCQueueYellowLimit)) { 1394 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 1395 BCM_IF_ERROR_RETURN 1396 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 1397 _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 1398 &local_port, &startq, NULL)); 1399 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 1400 return BCM_E_PARAM; 1401 } else { 1402 if (cosq < 0) { 1403 return BCM_E_PARAM; 1404 } 1405 BCM_IF_ERROR_RETURN 1406 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 1407 if (local_port < 0) { 1408 return BCM_E_PORT; 1409 } 1410 BCM_IF_ERROR_RETURN 1411 (_bcm_th3_cosq_index_resolve 1412 (unit, local_port, cosq, _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 1413 NULL, &startq, NULL)); 1414 } 1415 1416 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1417 1418 if (type == bcmCosqControlEgressUCQueueRedLimit) { 1419 fld_limit = LIMIT_REDf; 1420 } else { 1421 fld_limit = LIMIT_YELLOWf; 1422 } 1423 1424 mem = MMU_THDO_QUEUE_CONFIGm; 1425 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1426 color_mode = soc_mem_field32_get(unit, mem, entry, COLOR_LIMIT_MODEf); 1427 1428 if (color_mode == 1) { /* Dynamic color limit */ 1429 if (arg > 7) { /* Legal values are 0 - 7 */ 1430 return BCM_E_PARAM; 1431 } else { 1432 soc_mem_field32_set(unit, mem, entry, fld_limit, arg); 1433 } 1434 } else { /* Static color limit */ 1435 arg = (arg + _TH3_MMU_BYTES_PER_CELL - 1) / _TH3_MMU_BYTES_PER_CELL; 1436 1437 /* Check for min/max values */ 1438 max_val = (1 << soc_mem_field_length(unit, mem, fld_limit)) - 1; 1439 if ((arg < 0) || ((arg/granularity) > max_val)) { 1440 return BCM_E_PARAM; 1441 } else { 1442 soc_mem_field32_set(unit, mem, entry, fld_limit, (arg/granularity)); 1443 } 1444 } 1445 BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1446 } else if ((type == bcmCosqControlEgressMCQueueRedLimit) || 1447 (type == bcmCosqControlEgressMCQueueYellowLimit)) { 1448 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 1449 return BCM_E_PARAM; 1450 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 1451 BCM_IF_ERROR_RETURN 1452 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 1453 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 1454 &local_port, &startq, NULL)); 1455 } else { 1456 if (cosq < 0) { 1457 return BCM_E_PARAM; 1458 } 1459 BCM_IF_ERROR_RETURN 1460 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 1461 if (local_port < 0) { 1462 return BCM_E_PORT; 1463 } 1464 BCM_IF_ERROR_RETURN 1465 (_bcm_th3_cosq_index_resolve(unit, local_port, cosq, 1466 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 1467 NULL, &startq, NULL)); 1468 } 1469 1470 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1471 1472 if (type == bcmCosqControlEgressMCQueueRedLimit) { 1473 fld_limit = LIMIT_REDf; 1474 } else { 1475 fld_limit = LIMIT_YELLOWf; 1476 } 1477 1478 mem = MMU_THDO_QUEUE_CONFIGm; 1479 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1480 color_mode = soc_mem_field32_get(unit, mem, entry, COLOR_LIMIT_MODEf); 1481 1482 if (color_mode == 1) { /* Dynamic color limit */ 1483 if (arg > 7) { /* Legal values are 0 - 7 */ 1484 return BCM_E_PARAM; 1485 } else { 1486 soc_mem_field32_set(unit, mem, entry, fld_limit, arg); 1487 } 1488 } else { /* Static color limit */ 1489 arg = (arg + _TH3_MMU_BYTES_PER_CELL - 1) / _TH3_MMU_BYTES_PER_CELL; 1490 1491 /* Check for min/max values */ 1492 max_val = (1 << soc_mem_field_length(unit, mem, fld_limit)) - 1; 1493 if ((arg < 0) || ((arg/granularity) > max_val)) { 1494 return BCM_E_PARAM; 1495 } else { 1496 soc_mem_field32_set(unit, mem, entry, fld_limit, (arg/granularity)); 1497 } 1498 } 1499 BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1500 1501 } else { 1502 return BCM_E_PARAM; 1503 } 1504 1505 return BCM_E_NONE; 1506 } 1507 1508 /* 1509 * Function: _bcm_th3_cosq_egr_queue_color_limit_get 1510 * Purpose: Get Red and Yellow color limit per queue 1511 * Return value: IF color mode dynamic: limit should be between 0-7 1512 * 0: 100% of green threshold 1513 * 1: 12.5% of green threshold 1514 * 2: 25% of green threshold 1515 * 3: 37.5% of green threshold 1516 * 4: 50% of green threshold 1517 * 5: 67.5% of green threshold 1518 * 6: 75% of green threshold 1519 * 7: 87.5% of green threshold 1520 * If color mode static: Limit is number of bytes 1521 */ 1522 1523 STATIC int 1524 _bcm_th3_cosq_egr_queue_color_limit_get(int unit, bcm_gport_t gport, 1525 bcm_cos_queue_t cosq, 1526 bcm_cosq_control_t type, 1527 int* arg) 1528 { 1529 bcm_port_t local_port; 1530 int startq, pipe; 1531 uint32 entry[SOC_MAX_MEM_WORDS]; 1532 soc_mem_t mem = INVALIDm; 1533 soc_field_t fld_limit = INVALIDf; 1534 int color_mode, granularity; 1535 1536 if (!arg) { 1537 return BCM_E_PARAM; 1538 } 1539 1540 granularity = 8; 1541 1542 if ((type == bcmCosqControlEgressUCQueueRedLimit) || 1543 (type == bcmCosqControlEgressUCQueueYellowLimit)) { 1544 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 1545 BCM_IF_ERROR_RETURN 1546 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 1547 _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 1548 &local_port, &startq, NULL)); 1549 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 1550 return BCM_E_PARAM; 1551 } else { 1552 if (cosq < 0) { 1553 return BCM_E_PARAM; 1554 } 1555 BCM_IF_ERROR_RETURN 1556 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 1557 if (local_port < 0) { 1558 return BCM_E_PORT; 1559 } 1560 BCM_IF_ERROR_RETURN 1561 (_bcm_th3_cosq_index_resolve 1562 (unit, local_port, cosq, _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 1563 NULL, &startq, NULL)); 1564 } 1565 1566 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1567 1568 if (type == bcmCosqControlEgressUCQueueRedLimit) { 1569 fld_limit = LIMIT_REDf; 1570 } else { 1571 fld_limit = LIMIT_YELLOWf; 1572 } 1573 1574 mem = MMU_THDO_QUEUE_CONFIGm; 1575 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1576 color_mode = soc_mem_field32_get(unit, mem, entry, COLOR_LIMIT_MODEf); 1577 1578 if (color_mode == 1) { /* Dynamic color limit */ 1579 *arg = soc_mem_field32_get(unit, mem, entry, fld_limit); 1580 } else { /* Static color limit */ 1581 *arg = soc_mem_field32_get(unit, mem, entry, fld_limit); 1582 *arg = (*arg) * granularity * _TH3_MMU_BYTES_PER_CELL; 1583 } 1584 } else if ((type == bcmCosqControlEgressMCQueueRedLimit) || 1585 (type == bcmCosqControlEgressMCQueueYellowLimit)) { 1586 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 1587 return BCM_E_PARAM; 1588 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 1589 BCM_IF_ERROR_RETURN 1590 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 1591 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 1592 &local_port, &startq, NULL)); 1593 } else { 1594 if (cosq < 0) { 1595 return BCM_E_PARAM; 1596 } 1597 BCM_IF_ERROR_RETURN 1598 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 1599 if (local_port < 0) { 1600 return BCM_E_PORT; 1601 } 1602 BCM_IF_ERROR_RETURN 1603 (_bcm_th3_cosq_index_resolve(unit, local_port, cosq, 1604 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 1605 NULL, &startq, NULL)); 1606 } 1607 1608 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1609 1610 if (type == bcmCosqControlEgressMCQueueRedLimit) { 1611 fld_limit = LIMIT_REDf; 1612 } else { 1613 fld_limit = LIMIT_YELLOWf; 1614 } 1615 1616 mem = MMU_THDO_QUEUE_CONFIGm; 1617 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1618 color_mode = soc_mem_field32_get(unit, mem, entry, COLOR_LIMIT_MODEf); 1619 1620 if (color_mode == 1) { /* Dynamic color limit */ 1621 *arg = soc_mem_field32_get(unit, mem, entry, fld_limit); 1622 } else { /* Static color limit */ 1623 *arg = soc_mem_field32_get(unit, mem, entry, fld_limit); 1624 *arg = (*arg) * granularity * _TH3_MMU_BYTES_PER_CELL; 1625 } 1626 1627 } else { 1628 return BCM_E_PARAM; 1629 } 1630 1631 return BCM_E_NONE; 1632 } 1633 1634 1635 /* 1636 * Function: _bcm_th3_cosq_egr_queue_color_limit_mode_set 1637 * Purpose: Set color limit mode per queue to static (0) or 1638 * dynamic (1) 1639 */ 1640 1641 STATIC int 1642 _bcm_th3_cosq_egr_queue_color_limit_mode_set(int unit, bcm_gport_t gport, 1643 bcm_cos_queue_t cosq, 1644 bcm_cosq_control_t type, 1645 int arg) 1646 { 1647 bcm_port_t local_port; 1648 int startq, pipe; 1649 uint32 entry[SOC_MAX_MEM_WORDS]; 1650 soc_mem_t mem = INVALIDm; 1651 int enable; 1652 1653 if (arg < 0) { 1654 return BCM_E_PARAM; 1655 } 1656 1657 arg = arg ? 1 : 0; 1658 1659 if (type == bcmCosqControlEgressUCQueueColorLimitDynamicEnable) { 1660 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 1661 BCM_IF_ERROR_RETURN 1662 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 1663 _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 1664 &local_port, &startq, NULL)); 1665 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 1666 return BCM_E_PARAM; 1667 } else { 1668 if (cosq < 0) { 1669 return BCM_E_PARAM; 1670 } 1671 BCM_IF_ERROR_RETURN 1672 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 1673 if (local_port < 0) { 1674 return BCM_E_PORT; 1675 } 1676 BCM_IF_ERROR_RETURN 1677 (_bcm_th3_cosq_index_resolve 1678 (unit, local_port, cosq, _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 1679 NULL, &startq, NULL)); 1680 } 1681 1682 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1683 1684 mem = MMU_THDO_QUEUE_CONFIGm; 1685 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1686 enable = soc_mem_field32_get(unit, mem, entry, COLOR_LIMIT_MODEf); 1687 if (enable != arg) { 1688 soc_mem_field32_set(unit, mem, entry, COLOR_LIMIT_MODEf, arg); 1689 /* Reset the Red and Yellow limits when color limit mode is changed */ 1690 soc_mem_field32_set(unit, mem, entry, LIMIT_REDf, 0); 1691 soc_mem_field32_set(unit, mem, entry, LIMIT_YELLOWf, 0); 1692 BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1693 } 1694 } else if (type == bcmCosqControlEgressMCQueueColorLimitDynamicEnable) { 1695 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 1696 return BCM_E_PARAM; 1697 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 1698 BCM_IF_ERROR_RETURN 1699 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 1700 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 1701 &local_port, &startq, NULL)); 1702 } else { 1703 if (cosq < 0) { 1704 return BCM_E_PARAM; 1705 } 1706 BCM_IF_ERROR_RETURN 1707 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 1708 if (local_port < 0) { 1709 return BCM_E_PORT; 1710 } 1711 BCM_IF_ERROR_RETURN 1712 (_bcm_th3_cosq_index_resolve(unit, local_port, cosq, 1713 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 1714 NULL, &startq, NULL)); 1715 } 1716 1717 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1718 1719 mem = MMU_THDO_QUEUE_CONFIGm; 1720 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1721 enable = soc_mem_field32_get(unit, mem, entry, COLOR_LIMIT_MODEf); 1722 if (enable != arg) { 1723 soc_mem_field32_set(unit, mem, entry, COLOR_LIMIT_MODEf, arg); 1724 /* Reset the Red and Yellow limits when color limit mode is changed */ 1725 soc_mem_field32_set(unit, mem, entry, LIMIT_REDf, 0); 1726 soc_mem_field32_set(unit, mem, entry, LIMIT_YELLOWf, 0); 1727 BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1728 } 1729 } else { 1730 return BCM_E_PARAM; 1731 } 1732 1733 return BCM_E_NONE; 1734 } 1735 1736 /* 1737 * Function: _bcm_th3_cosq_egr_queue_color_limit_mode_get 1738 * Purpose: Get color limit mode per queue. 1739 * Returns: 0 (static) or 1 (dynamic) 1740 */ 1741 STATIC int 1742 _bcm_th3_cosq_egr_queue_color_limit_mode_get(int unit, bcm_gport_t gport, 1743 bcm_cos_queue_t cosq, 1744 bcm_cosq_control_t type, 1745 int* arg) 1746 { 1747 bcm_port_t local_port; 1748 int startq, pipe; 1749 uint32 entry[SOC_MAX_MEM_WORDS]; 1750 soc_mem_t mem = INVALIDm; 1751 1752 if (arg == NULL) { 1753 return BCM_E_PARAM; 1754 } 1755 1756 if (type == bcmCosqControlEgressUCQueueColorLimitDynamicEnable) { 1757 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 1758 BCM_IF_ERROR_RETURN 1759 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 1760 _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 1761 &local_port, &startq, NULL)); 1762 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 1763 return BCM_E_PARAM; 1764 } else { 1765 if (cosq < 0) { 1766 return BCM_E_PARAM; 1767 } 1768 BCM_IF_ERROR_RETURN 1769 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 1770 if (local_port < 0) { 1771 return BCM_E_PORT; 1772 } 1773 BCM_IF_ERROR_RETURN 1774 (_bcm_th3_cosq_index_resolve 1775 (unit, local_port, cosq, _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 1776 NULL, &startq, NULL)); 1777 } 1778 1779 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1780 1781 mem = MMU_THDO_QUEUE_CONFIGm; 1782 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1783 *arg = soc_mem_field32_get(unit, mem, entry, COLOR_LIMIT_MODEf); 1784 } else if (type == bcmCosqControlEgressMCQueueColorLimitDynamicEnable) { 1785 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 1786 return BCM_E_PARAM; 1787 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 1788 BCM_IF_ERROR_RETURN 1789 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 1790 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 1791 &local_port, &startq, NULL)); 1792 } else { 1793 if (cosq < 0) { 1794 return BCM_E_PARAM; 1795 } 1796 BCM_IF_ERROR_RETURN 1797 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 1798 if (local_port < 0) { 1799 return BCM_E_PORT; 1800 } 1801 BCM_IF_ERROR_RETURN 1802 (_bcm_th3_cosq_index_resolve(unit, local_port, cosq, 1803 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 1804 NULL, &startq, NULL)); 1805 } 1806 1807 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1808 1809 mem = MMU_THDO_QUEUE_CONFIGm; 1810 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1811 *arg = soc_mem_field32_get(unit, mem, entry, COLOR_LIMIT_MODEf); 1812 } else { 1813 return BCM_E_PARAM; 1814 } 1815 1816 return BCM_E_NONE; 1817 } 1818 1819 1820 STATIC int 1821 _bcm_th3_cosq_egr_queue_limit_enable_set(int unit, bcm_gport_t gport, 1822 bcm_cos_queue_t cosq, 1823 bcm_cosq_control_t type, 1824 int arg) 1825 { 1826 bcm_port_t local_port; 1827 int startq, pipe; 1828 uint32 entry[SOC_MAX_MEM_WORDS]; 1829 soc_mem_t mem = INVALIDm; 1830 int enable; 1831 1832 if (arg < 0) { 1833 return BCM_E_PARAM; 1834 } 1835 1836 arg = arg ? 1 : 0; 1837 1838 if (type == bcmCosqControlEgressUCQueueLimitEnable) { 1839 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 1840 BCM_IF_ERROR_RETURN 1841 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 1842 _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 1843 &local_port, &startq, NULL)); 1844 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 1845 return BCM_E_PARAM; 1846 } else { 1847 if (cosq < 0) { 1848 return BCM_E_PARAM; 1849 } 1850 BCM_IF_ERROR_RETURN 1851 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 1852 if (local_port < 0) { 1853 return BCM_E_PORT; 1854 } 1855 BCM_IF_ERROR_RETURN 1856 (_bcm_th3_cosq_index_resolve 1857 (unit, local_port, cosq, _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 1858 NULL, &startq, NULL)); 1859 } 1860 1861 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1862 1863 mem = MMU_THDO_QUEUE_CONFIGm; 1864 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1865 enable = soc_mem_field32_get(unit, mem, entry, LIMIT_ENABLEf); 1866 if (enable != arg) { 1867 soc_mem_field32_set(unit, mem, entry, LIMIT_ENABLEf, arg); 1868 BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1869 } 1870 } else if (type == bcmCosqControlEgressMCQueueLimitEnable) { 1871 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 1872 return BCM_E_PARAM; 1873 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 1874 BCM_IF_ERROR_RETURN 1875 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 1876 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 1877 &local_port, &startq, NULL)); 1878 } else { 1879 if (cosq < 0) { 1880 return BCM_E_PARAM; 1881 } 1882 BCM_IF_ERROR_RETURN 1883 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 1884 if (local_port < 0) { 1885 return BCM_E_PORT; 1886 } 1887 BCM_IF_ERROR_RETURN 1888 (_bcm_th3_cosq_index_resolve(unit, local_port, cosq, 1889 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 1890 NULL, &startq, NULL)); 1891 } 1892 1893 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1894 1895 mem = MMU_THDO_QUEUE_CONFIGm; 1896 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1897 enable = soc_mem_field32_get(unit, mem, entry, LIMIT_ENABLEf); 1898 if (enable != arg) { 1899 soc_mem_field32_set(unit, mem, entry, LIMIT_ENABLEf, arg); 1900 BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1901 } 1902 } else { 1903 return BCM_E_PARAM; 1904 } 1905 1906 return BCM_E_NONE; 1907 } 1908 1909 STATIC int 1910 _bcm_th3_cosq_egr_queue_limit_enable_get(int unit, bcm_gport_t gport, 1911 bcm_cos_queue_t cosq, 1912 bcm_cosq_control_t type, 1913 int* arg) 1914 { 1915 bcm_port_t local_port; 1916 int startq, pipe; 1917 uint32 entry[SOC_MAX_MEM_WORDS]; 1918 soc_mem_t mem = INVALIDm; 1919 1920 if (arg == NULL) { 1921 return BCM_E_PARAM; 1922 } 1923 1924 if (type == bcmCosqControlEgressUCQueueLimitEnable) { 1925 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 1926 BCM_IF_ERROR_RETURN 1927 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 1928 _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 1929 &local_port, &startq, NULL)); 1930 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 1931 return BCM_E_PARAM; 1932 } else { 1933 if (cosq < 0) { 1934 return BCM_E_PARAM; 1935 } 1936 BCM_IF_ERROR_RETURN 1937 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 1938 if (local_port < 0) { 1939 return BCM_E_PORT; 1940 } 1941 BCM_IF_ERROR_RETURN 1942 (_bcm_th3_cosq_index_resolve 1943 (unit, local_port, cosq, _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 1944 NULL, &startq, NULL)); 1945 } 1946 1947 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1948 1949 mem = MMU_THDO_QUEUE_CONFIGm; 1950 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1951 *arg = soc_mem_field32_get(unit, mem, entry, LIMIT_ENABLEf); 1952 } else if (type == bcmCosqControlEgressMCQueueLimitEnable) { 1953 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 1954 return BCM_E_PARAM; 1955 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 1956 BCM_IF_ERROR_RETURN 1957 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 1958 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 1959 &local_port, &startq, NULL)); 1960 } else { 1961 if (cosq < 0) { 1962 return BCM_E_PARAM; 1963 } 1964 BCM_IF_ERROR_RETURN 1965 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 1966 if (local_port < 0) { 1967 return BCM_E_PORT; 1968 } 1969 BCM_IF_ERROR_RETURN 1970 (_bcm_th3_cosq_index_resolve(unit, local_port, cosq, 1971 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 1972 NULL, &startq, NULL)); 1973 } 1974 1975 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1976 1977 mem = MMU_THDO_QUEUE_CONFIGm; 1978 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 1979 *arg = soc_mem_field32_get(unit, mem, entry, LIMIT_ENABLEf); 1980 } else { 1981 return BCM_E_PARAM; 1982 } 1983 1984 return BCM_E_NONE; 1985 } 1986 1987 /* 1988 * Function: _bcm_th3_cosq_egr_queue_color_limit_enable_set 1989 * Purpose: Enable/Disable queue color discard thresholds for color congestion management 1990 * Set (1) to enable or (0) to disable 1991 */ 1992 1993 STATIC int 1994 _bcm_th3_cosq_egr_queue_color_limit_enable_set(int unit, bcm_gport_t gport, 1995 bcm_cos_queue_t cosq, 1996 bcm_cosq_control_t type, 1997 int arg) 1998 { 1999 bcm_port_t local_port; 2000 int startq, pipe; 2001 uint32 entry[SOC_MAX_MEM_WORDS]; 2002 soc_mem_t mem = INVALIDm; 2003 int enable; 2004 2005 if (arg < 0) { 2006 return BCM_E_PARAM; 2007 } 2008 2009 arg = arg ? 1 : 0; 2010 2011 if (type == bcmCosqControlEgressUCQueueColorLimitEnable) { 2012 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 2013 BCM_IF_ERROR_RETURN 2014 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 2015 _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 2016 &local_port, &startq, NULL)); 2017 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 2018 return BCM_E_PARAM; 2019 } else { 2020 if (cosq < 0) { 2021 return BCM_E_PARAM; 2022 } 2023 BCM_IF_ERROR_RETURN 2024 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 2025 if (local_port < 0) { 2026 return BCM_E_PORT; 2027 } 2028 BCM_IF_ERROR_RETURN 2029 (_bcm_th3_cosq_index_resolve 2030 (unit, local_port, cosq, _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 2031 NULL, &startq, NULL)); 2032 } 2033 2034 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 2035 2036 mem = MMU_THDO_QUEUE_CONFIGm; 2037 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 2038 enable = soc_mem_field32_get(unit, mem, entry, COLOR_ENABLEf); 2039 if (enable != arg) { 2040 soc_mem_field32_set(unit, mem, entry, COLOR_ENABLEf, arg); 2041 BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry)); 2042 } 2043 } else if (type == bcmCosqControlEgressMCQueueColorLimitEnable) { 2044 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 2045 return BCM_E_PARAM; 2046 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 2047 BCM_IF_ERROR_RETURN 2048 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 2049 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 2050 &local_port, &startq, NULL)); 2051 } else { 2052 if (cosq < 0) { 2053 return BCM_E_PARAM; 2054 } 2055 BCM_IF_ERROR_RETURN 2056 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 2057 if (local_port < 0) { 2058 return BCM_E_PORT; 2059 } 2060 BCM_IF_ERROR_RETURN 2061 (_bcm_th3_cosq_index_resolve(unit, local_port, cosq, 2062 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 2063 NULL, &startq, NULL)); 2064 } 2065 2066 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 2067 2068 mem = MMU_THDO_QUEUE_CONFIGm; 2069 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 2070 enable = soc_mem_field32_get(unit, mem, entry, COLOR_ENABLEf); 2071 if (enable != arg) { 2072 soc_mem_field32_set(unit, mem, entry, COLOR_ENABLEf, arg); 2073 BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, startq, entry)); 2074 } 2075 } else { 2076 return BCM_E_PARAM; 2077 } 2078 2079 return BCM_E_NONE; 2080 } 2081 2082 /* 2083 * Function: _bcm_th3_cosq_egr_queue_color_limit_enable_get 2084 * Purpose: Get color limit enable status per queue. 2085 * Returns: 0 (disabled) or 1 (enabled) 2086 */ 2087 STATIC int 2088 _bcm_th3_cosq_egr_queue_color_limit_enable_get(int unit, bcm_gport_t gport, 2089 bcm_cos_queue_t cosq, 2090 bcm_cosq_control_t type, 2091 int* arg) 2092 { 2093 bcm_port_t local_port; 2094 int startq, pipe; 2095 uint32 entry[SOC_MAX_MEM_WORDS]; 2096 soc_mem_t mem = INVALIDm; 2097 2098 if (arg == NULL) { 2099 return BCM_E_PARAM; 2100 } 2101 2102 if (type == bcmCosqControlEgressUCQueueColorLimitEnable) { 2103 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 2104 BCM_IF_ERROR_RETURN 2105 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 2106 _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 2107 &local_port, &startq, NULL)); 2108 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 2109 return BCM_E_PARAM; 2110 } else { 2111 if (cosq < 0) { 2112 return BCM_E_PARAM; 2113 } 2114 BCM_IF_ERROR_RETURN 2115 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 2116 if (local_port < 0) { 2117 return BCM_E_PORT; 2118 } 2119 BCM_IF_ERROR_RETURN 2120 (_bcm_th3_cosq_index_resolve 2121 (unit, local_port, cosq, _BCM_TH3_COSQ_INDEX_STYLE_UCAST_QUEUE, 2122 NULL, &startq, NULL)); 2123 } 2124 2125 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 2126 2127 mem = MMU_THDO_QUEUE_CONFIGm; 2128 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 2129 *arg = soc_mem_field32_get(unit, mem, entry, COLOR_ENABLEf); 2130 } else if (type == bcmCosqControlEgressMCQueueColorLimitEnable) { 2131 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 2132 return BCM_E_PARAM; 2133 } else if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 2134 BCM_IF_ERROR_RETURN 2135 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 2136 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 2137 &local_port, &startq, NULL)); 2138 } else { 2139 if (cosq < 0) { 2140 return BCM_E_PARAM; 2141 } 2142 BCM_IF_ERROR_RETURN 2143 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 2144 if (local_port < 0) { 2145 return BCM_E_PORT; 2146 } 2147 BCM_IF_ERROR_RETURN 2148 (_bcm_th3_cosq_index_resolve(unit, local_port, cosq, 2149 _BCM_TH3_COSQ_INDEX_STYLE_MCAST_QUEUE, 2150 NULL, &startq, NULL)); 2151 } 2152 2153 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 2154 2155 mem = MMU_THDO_QUEUE_CONFIGm; 2156 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, startq, entry)); 2157 *arg = soc_mem_field32_get(unit, mem, entry, COLOR_ENABLEf); 2158 } else { 2159 return BCM_E_PARAM; 2160 } 2161 2162 return BCM_E_NONE; 2163 } 2164 2165 /* 2166 * This function is used to get ingress pool 2167 * limit given Ingress [Port, Priority Group] 2168 */ 2169 STATIC int 2170 _bcm_th3_cosq_ing_res_limit_get(int unit, bcm_gport_t gport, bcm_cos_t cosq, 2171 bcm_cosq_buffer_id_t buffer, 2172 bcm_cosq_control_t type, int* arg) 2173 { 2174 uint32 rval = 0x0; 2175 int pool; 2176 int local_port, pipe, itm, idx; 2177 soc_reg_t reg = INVALIDr; 2178 soc_field_t fld_limit = INVALIDf; 2179 2180 if (!arg) { 2181 return BCM_E_PARAM; 2182 } 2183 2184 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) || 2185 BCM_GPORT_IS_SCHEDULER(gport) || 2186 BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 2187 return BCM_E_PARAM; 2188 } 2189 BCM_IF_ERROR_RETURN 2190 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 2191 2192 if (!SOC_PORT_VALID(unit, local_port)) { 2193 return BCM_E_PORT; 2194 } 2195 if (type == bcmCosqControlIngressPoolLimitBytes) { 2196 BCM_IF_ERROR_RETURN 2197 (_bcm_th3_cosq_ing_pool_get(unit, gport, cosq, 2198 bcmCosqControlIngressPool, 2199 &pool)); 2200 reg = MMU_THDI_BUFFER_CELL_LIMIT_SPr; 2201 fld_limit = LIMITf; 2202 } else if (type == bcmCosqControlIngressPoolResetOffsetLimitBytes) { 2203 BCM_IF_ERROR_RETURN 2204 (_bcm_th3_cosq_ing_pool_get(unit, gport, cosq, 2205 bcmCosqControlIngressPool, 2206 &pool)); 2207 reg = MMU_THDI_CELL_RESET_LIMIT_OFFSET_SPr; 2208 fld_limit = OFFSETf; 2209 } else if (type == bcmCosqControlIngressHeadroomPoolLimitBytes) { 2210 BCM_IF_ERROR_RETURN 2211 (_bcm_th3_cosq_ing_pool_get(unit, gport, cosq, 2212 bcmCosqControlIngressHeadroomPool, 2213 &pool)); 2214 reg = MMU_THDI_HDRM_BUFFER_CELL_LIMIT_HPr; 2215 fld_limit = LIMITf; 2216 } else { 2217 return BCM_E_PARAM; 2218 } 2219 SOC_IF_ERROR_RETURN( 2220 soc_port_pipe_get(unit, local_port, &pipe)); 2221 2222 itm = 0; 2223 for (idx = 0; idx < NUM_ITM(unit); idx++) { 2224 if (SOC_INFO(unit).ipipe_itm_map[pipe] & (1 << idx)) { 2225 itm = idx; 2226 } 2227 } 2228 2229 if (buffer != BCM_COSQ_BUFFER_ID_INVALID) { 2230 if (!(SOC_INFO(unit).ipipe_itm_map[pipe] & (1 << buffer))) { 2231 return BCM_E_PARAM; 2232 } 2233 } 2234 2235 SOC_IF_ERROR_RETURN( 2236 soc_tomahawk3_itm_reg32_get(unit, reg, 2237 itm, itm, pool, &rval)); 2238 *arg = soc_reg_field_get(unit, reg, rval, fld_limit); 2239 *arg = (*arg) * _TH3_MMU_BYTES_PER_CELL; 2240 2241 return BCM_E_NONE; 2242 } 2243 2244 /* 2245 * This function is used to set ingress pool 2246 * limit given Ingress [Port, Priority Group] 2247 */ 2248 STATIC int 2249 _bcm_th3_cosq_ing_res_limit_set(int unit, bcm_gport_t gport, bcm_cos_t cosq, 2250 bcm_cosq_buffer_id_t buffer, 2251 bcm_cosq_control_t type, int arg) 2252 { 2253 uint32 rval = 0x0; 2254 int pool; 2255 int local_port, pipe, itm, idx; 2256 soc_reg_t reg = INVALIDr; 2257 soc_field_t fld_limit = INVALIDf; 2258 int max_value; 2259 int pool_limit = 0; 2260 int headroom_limit = 0; 2261 int total_limit = 0; 2262 int mmu_total_cells = 0; 2263 2264 if (arg < 0) { 2265 return BCM_E_PARAM; 2266 } 2267 2268 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) || 2269 BCM_GPORT_IS_SCHEDULER(gport) || 2270 BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 2271 return BCM_E_PARAM; 2272 } 2273 BCM_IF_ERROR_RETURN 2274 (_bcm_th3_cosq_localport_resolve(unit, gport, &local_port)); 2275 2276 if (!SOC_PORT_VALID(unit, local_port)) { 2277 return BCM_E_PORT; 2278 } 2279 2280 BCM_IF_ERROR_RETURN(_bcm_th3_cosq_ing_res_limit_get( 2281 unit, gport, cosq, buffer, 2282 bcmCosqControlIngressPoolLimitBytes, &pool_limit)); 2283 BCM_IF_ERROR_RETURN(_bcm_th3_cosq_ing_res_limit_get( 2284 unit, gport, cosq, buffer, 2285 bcmCosqControlIngressHeadroomPoolLimitBytes, &headroom_limit)); 2286 2287 if (type == bcmCosqControlIngressPoolLimitBytes) { 2288 BCM_IF_ERROR_RETURN 2289 (_bcm_th3_cosq_ing_pool_get(unit, gport, cosq, 2290 bcmCosqControlIngressPool, 2291 &pool)); 2292 reg = MMU_THDI_BUFFER_CELL_LIMIT_SPr; 2293 fld_limit = LIMITf; 2294 max_value = _TH3_THDI_BUFFER_CELL_LIMIT_SP_MAX; 2295 total_limit = arg + headroom_limit; 2296 } else if (type == bcmCosqControlIngressPoolResetOffsetLimitBytes) { 2297 BCM_IF_ERROR_RETURN 2298 (_bcm_th3_cosq_ing_pool_get(unit, gport, cosq, 2299 bcmCosqControlIngressPool, 2300 &pool)); 2301 reg = MMU_THDI_CELL_RESET_LIMIT_OFFSET_SPr; 2302 fld_limit = OFFSETf; 2303 max_value = _TH3_THDI_BUFFER_CELL_LIMIT_SP_MAX; 2304 } else if (type == bcmCosqControlIngressHeadroomPoolLimitBytes) { 2305 BCM_IF_ERROR_RETURN 2306 (_bcm_th3_cosq_ing_pool_get(unit, gport, cosq, 2307 bcmCosqControlIngressHeadroomPool, 2308 &pool)); 2309 reg = MMU_THDI_HDRM_BUFFER_CELL_LIMIT_HPr; 2310 fld_limit = LIMITf; 2311 max_value = _TH3_THDI_HDRM_BUFFER_CELL_LIMIT_HP_MAX; 2312 total_limit = arg + pool_limit; 2313 } else { 2314 return BCM_E_PARAM; 2315 } 2316 arg = (arg + _TH3_MMU_BYTES_PER_CELL - 1) / _TH3_MMU_BYTES_PER_CELL; 2317 if (arg > max_value) { 2318 LOG_WARN(BSL_LS_BCM_COSQ, 2319 (BSL_META_U(unit, "Warning: Request of %d bytes exceeds maximum of %d bytes\n"), 2320 arg * _TH3_MMU_BYTES_PER_CELL, 2321 max_value * _TH3_MMU_BYTES_PER_CELL)); 2322 return BCM_E_PARAM; 2323 } 2324 2325 total_limit = (total_limit + _TH3_MMU_BYTES_PER_CELL - 1) / _TH3_MMU_BYTES_PER_CELL; 2326 mmu_total_cells = _TH3_MMU_TOTAL_CELLS_PER_ITM; 2327 if (total_limit > mmu_total_cells) { 2328 LOG_WARN(BSL_LS_BCM_COSQ, 2329 (BSL_META_U(unit, "Warning: Total allocation of %d bytes exceeds maximum of %d bytes\n"), 2330 total_limit * _TH3_MMU_BYTES_PER_CELL, 2331 mmu_total_cells * _TH3_MMU_BYTES_PER_CELL)); 2332 return BCM_E_PARAM; 2333 } 2334 2335 soc_reg_field_set(unit, reg, &rval, fld_limit, arg); 2336 SOC_IF_ERROR_RETURN( 2337 soc_port_pipe_get(unit, local_port, &pipe)); 2338 2339 itm = 0; 2340 for (idx = 0; idx < NUM_ITM(unit); idx++) { 2341 if (SOC_INFO(unit).ipipe_itm_map[pipe] & (1 << idx)) { 2342 itm = idx; 2343 } 2344 } 2345 2346 if (buffer != BCM_COSQ_BUFFER_ID_INVALID) { 2347 if (!(SOC_INFO(unit).ipipe_itm_map[pipe] & (1 << buffer))) { 2348 return BCM_E_PARAM; 2349 } 2350 } 2351 2352 SOC_IF_ERROR_RETURN( 2353 soc_tomahawk3_itm_reg32_set(unit, reg, 2354 itm, itm, pool, rval)); 2355 2356 if (type == bcmCosqControlIngressPoolLimitBytes) { 2357 BCM_IF_ERROR_RETURN( 2358 _bcm_th3_mmu_set_shared_size(unit, itm, arg)); 2359 2360 } 2361 2362 return BCM_E_NONE; 2363 } 2364 2365 2366 STATIC int 2367 _bcm_th3_cosq_egr_port_pool_get(int unit, bcm_gport_t gport, 2368 bcm_cos_queue_t cosq, 2369 bcm_cosq_control_t type, int* arg) 2370 { 2371 bcm_port_t local_port; 2372 uint32 entry[SOC_MAX_MEM_WORDS]; 2373 soc_mem_t mem = INVALIDm; 2374 soc_field_t fld_limit = INVALIDf; 2375 int granularity = 1; 2376 int pool, midx, pipe; 2377 int gport_type = 0; 2378 2379 if (!arg) { 2380 return BCM_E_PARAM; 2381 } 2382 2383 BCM_IF_ERROR_RETURN 2384 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 2385 _BCM_TH3_COSQ_INDEX_STYLE_EGR_POOL, 2386 &local_port, &pool, NULL)); 2387 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 2388 2389 gport_type = BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) || 2390 BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport); 2391 2392 if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) || 2393 (!gport_type && (cosq >= _bcm_th3_get_num_ucq(unit)))) { 2394 switch (type) { 2395 case bcmCosqControlEgressPortPoolYellowLimitBytes: 2396 fld_limit = SP_YELLOW_LIMITf; 2397 granularity = 8; 2398 mem = MMU_THDO_CONFIG_PORTSP_MCm; 2399 break; 2400 case bcmCosqControlEgressPortPoolRedLimitBytes: 2401 fld_limit = SP_RED_LIMITf; 2402 granularity = 8; 2403 mem = MMU_THDO_CONFIG_PORTSP_MCm; 2404 break; 2405 case bcmCosqControlEgressPortPoolSharedLimitBytes: 2406 fld_limit = SP_SHARED_LIMITf; 2407 mem = MMU_THDO_CONFIG_PORTSP_MCm; 2408 break; 2409 case bcmCosqControlEgressPortPoolSharedResumeBytes: 2410 granularity = 8; 2411 fld_limit = SHARED_RESUMEf; 2412 mem = MMU_THDO_RESUME_PORT_MC0m; 2413 break; 2414 case bcmCosqControlEgressPortPoolYellowResumeBytes: 2415 granularity = 8; 2416 fld_limit = YELLOW_RESUMEf; 2417 mem = MMU_THDO_RESUME_PORT_MC0m; 2418 break; 2419 case bcmCosqControlEgressPortPoolRedResumeBytes: 2420 granularity = 8; 2421 fld_limit = RED_RESUMEf; 2422 mem = MMU_THDO_RESUME_PORT_MC0m; 2423 break; 2424 default: 2425 return BCM_E_UNAVAIL; 2426 } 2427 midx = SOC_TH3_MMU_PIPED_MEM_INDEX(unit, local_port, mem, pool); 2428 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry)); 2429 2430 *arg = soc_mem_field32_get(unit, mem, entry, fld_limit); 2431 *arg = (*arg) * granularity * _TH3_MMU_BYTES_PER_CELL; 2432 } else { 2433 switch (type) { 2434 case bcmCosqControlEgressPortPoolYellowLimitBytes: 2435 mem = MMU_THDO_CONFIG_PORT_UC0m; 2436 switch (pool) { 2437 case 0: fld_limit = SP0_YELLOW_LIMITf; break; 2438 case 1: fld_limit = SP1_YELLOW_LIMITf; break; 2439 case 2: fld_limit = SP2_YELLOW_LIMITf; break; 2440 case 3: fld_limit = SP3_YELLOW_LIMITf; break; 2441 } 2442 granularity = 8; 2443 break; 2444 case bcmCosqControlEgressPortPoolRedLimitBytes: 2445 mem = MMU_THDO_CONFIG_PORT_UC0m; 2446 switch (pool) { 2447 case 0: fld_limit = SP0_RED_LIMITf; break; 2448 case 1: fld_limit = SP1_RED_LIMITf; break; 2449 case 2: fld_limit = SP2_RED_LIMITf; break; 2450 case 3: fld_limit = SP3_RED_LIMITf; break; 2451 } 2452 granularity = 8; 2453 break; 2454 case bcmCosqControlEgressPortPoolSharedLimitBytes: 2455 mem = MMU_THDO_CONFIG_PORT_UC0m; 2456 switch (pool) { 2457 case 0: fld_limit = SP0_SHARED_LIMITf; break; 2458 case 1: fld_limit = SP1_SHARED_LIMITf; break; 2459 case 2: fld_limit = SP2_SHARED_LIMITf; break; 2460 case 3: fld_limit = SP3_SHARED_LIMITf; break; 2461 } 2462 break; 2463 case bcmCosqControlEgressPortPoolSharedResumeBytes: 2464 mem = MMU_THDO_RESUME_PORT_UC0m; 2465 fld_limit = SHARED_RESUMEf; 2466 granularity = 8; 2467 break; 2468 case bcmCosqControlEgressPortPoolYellowResumeBytes: 2469 mem = MMU_THDO_RESUME_PORT_UC0m; 2470 fld_limit = YELLOW_RESUMEf; 2471 granularity = 8; 2472 break; 2473 case bcmCosqControlEgressPortPoolRedResumeBytes: 2474 mem = MMU_THDO_RESUME_PORT_UC0m; 2475 fld_limit = RED_RESUMEf; 2476 granularity = 8; 2477 break; 2478 default: 2479 return BCM_E_UNAVAIL; 2480 } 2481 midx = SOC_TH3_MMU_PIPED_MEM_INDEX(unit, local_port, mem, pool); 2482 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry)); 2483 2484 *arg = soc_mem_field32_get(unit, mem, entry, fld_limit); 2485 *arg = (*arg) * granularity * _TH3_MMU_BYTES_PER_CELL; 2486 } 2487 2488 return BCM_E_NONE; 2489 } 2490 2491 2492 STATIC int 2493 _bcm_th3_cosq_egr_port_pool_set(int unit, bcm_gport_t gport, 2494 bcm_cos_queue_t cosq, 2495 bcm_cosq_control_t type, int arg) 2496 { 2497 bcm_port_t local_port; 2498 uint32 max_val; 2499 uint32 entry[SOC_MAX_MEM_WORDS]; 2500 soc_mem_t mem = INVALIDm; 2501 soc_field_t fld_limit = INVALIDf; 2502 int granularity = 1; 2503 int final_value = 0; 2504 int pool, midx, pipe; 2505 int gport_type = 0; 2506 2507 if (arg < 0) { 2508 return BCM_E_PARAM; 2509 } 2510 2511 BCM_IF_ERROR_RETURN 2512 (_bcm_th3_cosq_index_resolve(unit, gport, cosq, 2513 _BCM_TH3_COSQ_INDEX_STYLE_EGR_POOL, 2514 &local_port, &pool, NULL)); 2515 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 2516 gport_type = BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) || 2517 BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport); 2518 2519 if (BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport) || 2520 (!gport_type && (cosq >= _bcm_th3_get_num_ucq(unit)))) { 2521 switch (type) { 2522 case bcmCosqControlEgressPortPoolYellowLimitBytes: 2523 fld_limit = SP_YELLOW_LIMITf; 2524 granularity = 8; 2525 mem = MMU_THDO_CONFIG_PORTSP_MCm; 2526 break; 2527 case bcmCosqControlEgressPortPoolRedLimitBytes: 2528 fld_limit = SP_RED_LIMITf; 2529 granularity = 8; 2530 mem = MMU_THDO_CONFIG_PORTSP_MCm; 2531 break; 2532 case bcmCosqControlEgressPortPoolSharedLimitBytes: 2533 fld_limit = SP_SHARED_LIMITf; 2534 mem = MMU_THDO_CONFIG_PORTSP_MCm; 2535 break; 2536 case bcmCosqControlEgressPortPoolSharedResumeBytes: 2537 fld_limit = SHARED_RESUMEf; 2538 granularity = 8; 2539 mem = MMU_THDO_RESUME_PORT_MC0m; 2540 break; 2541 case bcmCosqControlEgressPortPoolYellowResumeBytes: 2542 fld_limit = YELLOW_RESUMEf; 2543 granularity = 8; 2544 mem = MMU_THDO_RESUME_PORT_MC0m; 2545 break; 2546 case bcmCosqControlEgressPortPoolRedResumeBytes: 2547 fld_limit = RED_RESUMEf; 2548 granularity = 8; 2549 mem = MMU_THDO_RESUME_PORT_MC0m; 2550 break; 2551 default: 2552 return BCM_E_UNAVAIL; 2553 } 2554 2555 midx = SOC_TH3_MMU_PIPED_MEM_INDEX(unit, local_port, mem, pool); 2556 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry)); 2557 final_value = (arg + _TH3_MMU_BYTES_PER_CELL - 1) / _TH3_MMU_BYTES_PER_CELL; 2558 2559 /* Check for min/max values */ 2560 max_val = (1 << soc_mem_field_length(unit, mem, fld_limit)) - 1; 2561 if ((final_value < 0) || ((final_value/granularity) > max_val)) { 2562 return BCM_E_PARAM; 2563 } else { 2564 soc_mem_field32_set(unit, mem, entry, fld_limit, (final_value/granularity)); 2565 } 2566 BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, midx, entry)); 2567 } else { 2568 switch (type) { 2569 case bcmCosqControlEgressPortPoolYellowLimitBytes: 2570 mem = MMU_THDO_CONFIG_PORT_UC0m; 2571 switch (pool) { 2572 case 0: fld_limit = SP0_YELLOW_LIMITf; break; 2573 case 1: fld_limit = SP1_YELLOW_LIMITf; break; 2574 case 2: fld_limit = SP2_YELLOW_LIMITf; break; 2575 case 3: fld_limit = SP3_YELLOW_LIMITf; break; 2576 } 2577 granularity = 8; 2578 break; 2579 case bcmCosqControlEgressPortPoolRedLimitBytes: 2580 mem = MMU_THDO_CONFIG_PORT_UC0m; 2581 switch (pool) { 2582 case 0: fld_limit = SP0_RED_LIMITf; break; 2583 case 1: fld_limit = SP1_RED_LIMITf; break; 2584 case 2: fld_limit = SP2_RED_LIMITf; break; 2585 case 3: fld_limit = SP3_RED_LIMITf; break; 2586 } 2587 granularity = 8; 2588 break; 2589 case bcmCosqControlEgressPortPoolSharedLimitBytes: 2590 mem = MMU_THDO_CONFIG_PORT_UC0m; 2591 switch (pool) { 2592 case 0: fld_limit = SP0_SHARED_LIMITf; break; 2593 case 1: fld_limit = SP1_SHARED_LIMITf; break; 2594 case 2: fld_limit = SP2_SHARED_LIMITf; break; 2595 case 3: fld_limit = SP3_SHARED_LIMITf; break; 2596 } 2597 break; 2598 case bcmCosqControlEgressPortPoolSharedResumeBytes: 2599 mem = MMU_THDO_RESUME_PORT_UC0m; 2600 fld_limit = SHARED_RESUMEf; 2601 granularity = 8; 2602 break; 2603 case bcmCosqControlEgressPortPoolRedResumeBytes: 2604 mem = MMU_THDO_RESUME_PORT_UC0m; 2605 fld_limit = RED_RESUMEf; 2606 granularity = 8; 2607 break; 2608 case bcmCosqControlEgressPortPoolYellowResumeBytes: 2609 mem = MMU_THDO_RESUME_PORT_UC0m; 2610 fld_limit = YELLOW_RESUMEf; 2611 granularity = 8; 2612 break; 2613 default: 2614 return BCM_E_UNAVAIL; 2615 } 2616 2617 final_value = (arg + _TH3_MMU_BYTES_PER_CELL - 1) / _TH3_MMU_BYTES_PER_CELL; 2618 midx = SOC_TH3_MMU_PIPED_MEM_INDEX(unit, local_port, mem, pool); 2619 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, entry)); 2620 2621 /* Check for min/max values */ 2622 max_val = (1 << soc_mem_field_length(unit, mem, fld_limit)) - 1; 2623 if ((final_value < 0) || ((final_value/granularity) > max_val)) { 2624 return BCM_E_PARAM; 2625 } else { 2626 soc_mem_field32_set(unit, mem, entry, fld_limit, (final_value/granularity)); 2627 } 2628 BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, midx, entry)); 2629 } 2630 2631 return BCM_E_NONE; 2632 } 2633 2634 2635 /* 2636 * Function: 2637 * bcm_th3_cosq_control_set 2638 * Purpose: 2639 * Set specified feature configuration 2640 * 2641 * Parameters: 2642 * unit - (IN) Unit number. 2643 * port - (IN) GPORT ID. 2644 * cosq - (IN) COS queue. 2645 * buffer-(IN) XPE ID 2646 * type - (IN) feature 2647 * arg - (IN) feature value 2648 * Returns: 2649 * BCM_E_XXX 2650 * Notes: 2651 */ 2652 int 2653 bcm_th3_cosq_control_set(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq, 2654 bcm_cosq_buffer_id_t buffer, 2655 bcm_cosq_control_t type, int arg) 2656 { 2657 uint32 kbits_burst_min, kbits_burst_max; 2658 uint32 kbits_burst; 2659 2660 kbits_burst_min = 0; 2661 kbits_burst_max = 0; 2662 2663 COMPILER_REFERENCE(kbits_burst_min); 2664 COMPILER_REFERENCE(kbits_burst_max); 2665 2666 switch (type) { 2667 case bcmCosqControlBandwidthBurstMax: 2668 kbits_burst = arg & 0x7fffffff; 2669 BCM_IF_ERROR_RETURN 2670 (bcm_th3_cosq_gport_bandwidth_burst_get(unit, gport, cosq, 2671 &kbits_burst_min, 2672 &kbits_burst_max)); 2673 return bcm_th3_cosq_gport_bandwidth_burst_set(unit, gport, cosq, 2674 kbits_burst_min, 2675 kbits_burst); 2676 case bcmCosqControlBandwidthBurstMin: 2677 kbits_burst = arg & 0x7fffffff; 2678 BCM_IF_ERROR_RETURN 2679 (bcm_th3_cosq_gport_bandwidth_burst_get(unit, gport, cosq, 2680 &kbits_burst_min, 2681 &kbits_burst_max)); 2682 return bcm_th3_cosq_gport_bandwidth_burst_set(unit, gport, cosq, 2683 kbits_burst, 2684 kbits_burst_max); 2685 case bcmCosqControlEgressPool: 2686 case bcmCosqControlEgressPoolLimitBytes: 2687 case bcmCosqControlEgressPoolYellowLimitBytes: 2688 case bcmCosqControlEgressPoolRedLimitBytes: 2689 case bcmCosqControlEgressPoolLimitEnable: 2690 case bcmCosqControlUCEgressPool: 2691 case bcmCosqControlMCEgressPool: 2692 case bcmCosqControlEgressPoolSharedLimitBytes: 2693 case bcmCosqControlEgressPoolResumeLimitBytes: 2694 case bcmCosqControlEgressPoolYellowSharedLimitBytes: 2695 case bcmCosqControlEgressPoolYellowResumeLimitBytes: 2696 case bcmCosqControlEgressPoolRedSharedLimitBytes: 2697 case bcmCosqControlEgressPoolRedResumeLimitBytes: 2698 case bcmCosqControlEgressPoolHighCongestionLimitBytes: 2699 case bcmCosqControlEgressPoolLowCongestionLimitBytes: 2700 return _bcm_th3_cosq_egr_pool_set(unit, gport, cosq, buffer, type, arg); 2701 case bcmCosqControlEgressUCQueueSharedLimitBytes: 2702 case bcmCosqControlEgressMCQueueSharedLimitBytes: 2703 case bcmCosqControlEgressUCQueueMinLimitBytes: 2704 case bcmCosqControlEgressMCQueueMinLimitBytes: 2705 case bcmCosqControlEgressUCQueueResumeOffsetBytes: 2706 case bcmCosqControlEgressMCQueueResumeOffsetBytes: 2707 return _bcm_th3_cosq_egr_queue_set(unit, gport, cosq, type, arg); 2708 case bcmCosqControlIngressPortPGSharedLimitBytes: 2709 case bcmCosqControlIngressPortPGMinLimitBytes: 2710 case bcmCosqControlIngressPortPoolMinLimitBytes: 2711 case bcmCosqControlIngressPortPoolSharedLimitBytes: 2712 case bcmCosqControlIngressPortPGHeadroomLimitBytes: 2713 case bcmCosqControlIngressPortPGResetFloorBytes: 2714 case bcmCosqControlIngressPortPGResetOffsetBytes: 2715 case bcmCosqControlIngressPortPoolResumeLimitBytes: 2716 return _bcm_th3_cosq_ing_res_set(unit, gport, cosq, type, arg); 2717 case bcmCosqControlIngressPool: 2718 case bcmCosqControlIngressHeadroomPool: 2719 /* 2720 * This function is used to set headroom pool 2721 * or shared pool for given Ingress [Port, Priority] 2722 */ 2723 return _bcm_th3_cosq_ing_pool_set(unit, gport, cosq, type, arg); 2724 case bcmCosqControlDropLimitAlpha: 2725 return _bcm_th3_cosq_alpha_set(unit, gport, cosq, 2726 (bcm_cosq_control_drop_limit_alpha_value_t)arg); 2727 case bcmCosqControlIngressPortPGSharedDynamicEnable: 2728 case bcmCosqControlEgressUCSharedDynamicEnable: 2729 case bcmCosqControlEgressMCSharedDynamicEnable: 2730 return _bcm_th3_cosq_dynamic_thresh_enable_set(unit, gport, cosq, 2731 type, arg); 2732 case bcmCosqControlEgressPortPoolYellowLimitBytes: 2733 case bcmCosqControlEgressPortPoolRedLimitBytes: 2734 case bcmCosqControlEgressPortPoolSharedLimitBytes: 2735 case bcmCosqControlEgressPortPoolSharedResumeBytes: 2736 case bcmCosqControlEgressPortPoolYellowResumeBytes: 2737 case bcmCosqControlEgressPortPoolRedResumeBytes: 2738 return _bcm_th3_cosq_egr_port_pool_set(unit, gport, cosq, type, arg); 2739 case bcmCosqControlEgressUCQueueLimitEnable: 2740 case bcmCosqControlEgressMCQueueLimitEnable: 2741 return _bcm_th3_cosq_egr_queue_limit_enable_set(unit, gport, cosq, 2742 type, arg); 2743 case bcmCosqControlIngressPoolLimitBytes: 2744 case bcmCosqControlIngressPoolResetOffsetLimitBytes: 2745 case bcmCosqControlIngressHeadroomPoolLimitBytes: 2746 return _bcm_th3_cosq_ing_res_limit_set(unit, gport, cosq, buffer, type, arg); 2747 case bcmCosqControlEgressUCQueueGroupMinEnable: 2748 case bcmCosqControlEgressMCQueueGroupMinEnable: 2749 return _bcm_th3_cosq_qgroup_limit_enables_set(unit, gport, cosq, 2750 type, arg); 2751 case bcmCosqControlEgressUCQueueGroupMinLimitBytes: 2752 case bcmCosqControlEgressMCQueueGroupMinLimitBytes: 2753 return _bcm_th3_cosq_qgroup_limit_set(unit, gport, cosq, type, arg); 2754 case bcmCosqControlEgressUCQueueColorLimitDynamicEnable: 2755 case bcmCosqControlEgressMCQueueColorLimitDynamicEnable: 2756 return _bcm_th3_cosq_egr_queue_color_limit_mode_set(unit, gport, cosq, 2757 type, arg); 2758 case bcmCosqControlEgressUCQueueColorLimitEnable: 2759 case bcmCosqControlEgressMCQueueColorLimitEnable: 2760 return _bcm_th3_cosq_egr_queue_color_limit_enable_set(unit, gport, cosq, 2761 type, arg); 2762 case bcmCosqControlEgressUCQueueRedLimit: 2763 case bcmCosqControlEgressUCQueueYellowLimit: 2764 case bcmCosqControlEgressMCQueueRedLimit: 2765 case bcmCosqControlEgressMCQueueYellowLimit: 2766 return _bcm_th3_cosq_egr_queue_color_limit_set(unit, gport, cosq, type, arg); 2767 default: 2768 break; 2769 } 2770 return BCM_E_UNAVAIL; 2771 } 2772 2773 /* 2774 * Function: 2775 * bcm_th3_cosq_control_get 2776 * Purpose: 2777 * Get specified feature configuration 2778 * 2779 * Parameters: 2780 * unit - (IN) Unit number. 2781 * port - (IN) GPORT ID. 2782 * cosq - (IN) COS queue. 2783 * buffer-(IN) XPE ID 2784 * type - (IN) feature 2785 * arg - (OUT) feature value 2786 * Returns: 2787 * BCM_E_XXX 2788 * Notes: 2789 */ 2790 2791 int 2792 bcm_th3_cosq_control_get(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq, 2793 bcm_cosq_buffer_id_t buffer, 2794 bcm_cosq_control_t type, int *arg) 2795 { 2796 uint32 kburst_tmp, kbits_burst; 2797 2798 switch (type) { 2799 case bcmCosqControlBandwidthBurstMax: 2800 BCM_IF_ERROR_RETURN 2801 (bcm_th3_cosq_gport_bandwidth_burst_get(unit, gport, cosq, 2802 &kburst_tmp, 2803 &kbits_burst)); 2804 *arg = kbits_burst & 0x7fffffff; 2805 return BCM_E_NONE; 2806 case bcmCosqControlBandwidthBurstMin: 2807 return bcm_th3_cosq_gport_bandwidth_burst_get(unit, gport, cosq, 2808 (uint32*)arg, 2809 &kburst_tmp); 2810 case bcmCosqControlEgressPool: 2811 case bcmCosqControlEgressPoolLimitBytes: 2812 case bcmCosqControlEgressPoolYellowLimitBytes: 2813 case bcmCosqControlEgressPoolRedLimitBytes: 2814 case bcmCosqControlEgressPoolLimitEnable: 2815 case bcmCosqControlUCEgressPool: 2816 case bcmCosqControlMCEgressPool: 2817 case bcmCosqControlEgressPoolSharedLimitBytes: 2818 case bcmCosqControlEgressPoolResumeLimitBytes: 2819 case bcmCosqControlEgressPoolYellowSharedLimitBytes: 2820 case bcmCosqControlEgressPoolYellowResumeLimitBytes: 2821 case bcmCosqControlEgressPoolRedSharedLimitBytes: 2822 case bcmCosqControlEgressPoolRedResumeLimitBytes: 2823 case bcmCosqControlEgressPoolHighCongestionLimitBytes: 2824 case bcmCosqControlEgressPoolLowCongestionLimitBytes: 2825 return _bcm_th3_cosq_egr_pool_get(unit, gport, cosq, buffer, type, arg); 2826 case bcmCosqControlEgressUCQueueSharedLimitBytes: 2827 case bcmCosqControlEgressMCQueueSharedLimitBytes: 2828 case bcmCosqControlEgressUCQueueMinLimitBytes: 2829 case bcmCosqControlEgressMCQueueMinLimitBytes: 2830 case bcmCosqControlEgressUCQueueResumeOffsetBytes: 2831 case bcmCosqControlEgressMCQueueResumeOffsetBytes: 2832 return _bcm_th3_cosq_egr_queue_get(unit, gport, cosq, type, arg); 2833 case bcmCosqControlIngressPortPGSharedLimitBytes: 2834 case bcmCosqControlIngressPortPGMinLimitBytes: 2835 case bcmCosqControlIngressPortPoolMinLimitBytes: 2836 case bcmCosqControlIngressPortPoolSharedLimitBytes: 2837 case bcmCosqControlIngressPortPGHeadroomLimitBytes: 2838 case bcmCosqControlIngressPortPGResetFloorBytes: 2839 case bcmCosqControlIngressPortPGResetOffsetBytes: 2840 case bcmCosqControlIngressPortPoolResumeLimitBytes: 2841 return _bcm_th3_cosq_ing_res_get(unit, gport, cosq, type, arg); 2842 case bcmCosqControlIngressPool: 2843 case bcmCosqControlIngressHeadroomPool: 2844 /* 2845 * This function is used to set headroom pool 2846 * or shared pool for given Ingress [Port, Priority] 2847 */ 2848 return _bcm_th3_cosq_ing_pool_get(unit, gport, cosq, type, arg); 2849 case bcmCosqControlDropLimitAlpha: 2850 return _bcm_th3_cosq_alpha_get(unit, gport, cosq, 2851 (bcm_cosq_control_drop_limit_alpha_value_t *)arg); 2852 case bcmCosqControlIngressPortPGSharedDynamicEnable: 2853 case bcmCosqControlEgressUCSharedDynamicEnable: 2854 case bcmCosqControlEgressMCSharedDynamicEnable: 2855 return _bcm_th3_cosq_dynamic_thresh_enable_get(unit, gport, cosq, 2856 type, arg); 2857 case bcmCosqControlEgressPortPoolYellowLimitBytes: 2858 case bcmCosqControlEgressPortPoolRedLimitBytes: 2859 case bcmCosqControlEgressPortPoolSharedLimitBytes: 2860 case bcmCosqControlEgressPortPoolSharedResumeBytes: 2861 case bcmCosqControlEgressPortPoolYellowResumeBytes: 2862 case bcmCosqControlEgressPortPoolRedResumeBytes: 2863 return _bcm_th3_cosq_egr_port_pool_get(unit, gport, cosq, type, arg); 2864 case bcmCosqControlEgressUCQueueLimitEnable: 2865 case bcmCosqControlEgressMCQueueLimitEnable: 2866 return _bcm_th3_cosq_egr_queue_limit_enable_get(unit, gport, cosq, 2867 type, arg); 2868 case bcmCosqControlIngressPoolLimitBytes: 2869 case bcmCosqControlIngressPoolResetOffsetLimitBytes: 2870 case bcmCosqControlIngressHeadroomPoolLimitBytes: 2871 return _bcm_th3_cosq_ing_res_limit_get(unit, gport, cosq, buffer, type, arg); 2872 case bcmCosqControlEgressUCQueueGroupMinEnable: 2873 case bcmCosqControlEgressMCQueueGroupMinEnable: 2874 return _bcm_th3_cosq_qgroup_limit_enables_get(unit, gport, cosq, 2875 type, arg); 2876 case bcmCosqControlEgressUCQueueGroupMinLimitBytes: 2877 case bcmCosqControlEgressMCQueueGroupMinLimitBytes: 2878 return _bcm_th3_cosq_qgroup_limit_get(unit, gport, cosq, type, arg); 2879 case bcmCosqControlEgressUCQueueColorLimitDynamicEnable: 2880 case bcmCosqControlEgressMCQueueColorLimitDynamicEnable: 2881 return _bcm_th3_cosq_egr_queue_color_limit_mode_get(unit, gport, cosq, 2882 type, arg); 2883 case bcmCosqControlEgressUCQueueColorLimitEnable: 2884 case bcmCosqControlEgressMCQueueColorLimitEnable: 2885 return _bcm_th3_cosq_egr_queue_color_limit_enable_get(unit, gport, cosq, 2886 type, arg); 2887 case bcmCosqControlEgressUCQueueRedLimit: 2888 case bcmCosqControlEgressUCQueueYellowLimit: 2889 case bcmCosqControlEgressMCQueueRedLimit: 2890 case bcmCosqControlEgressMCQueueYellowLimit: 2891 return _bcm_th3_cosq_egr_queue_color_limit_get(unit, gport, cosq, type, arg); 2892 default: 2893 break; 2894 } 2895 return BCM_E_UNAVAIL; 2896 2897 } 2898 2899 int bcm_tomahawk3_cosq_control_dynamic_get(int unit, 2900 bcm_cosq_control_t type, bcm_cosq_dynamic_setting_type_t *dynamic) 2901 { 2902 switch (type) { 2903 case bcmCosqControlEgressPool: 2904 case bcmCosqControlUCEgressPool: 2905 case bcmCosqControlMCEgressPool: 2906 case bcmCosqControlEgressUCQueueGroupMinEnable: 2907 case bcmCosqControlEgressMCQueueGroupMinEnable: 2908 *dynamic = bcmCosqDynamicTypeConditional; 2909 break; 2910 case bcmCosqControlIngressPool: 2911 case bcmCosqControlIngressHeadroomPool: 2912 *dynamic = bcmCosqDynamicTypeFixed; 2913 break; 2914 case bcmCosqControlBandwidthBurstMax: 2915 case bcmCosqControlBandwidthBurstMin: 2916 case bcmCosqControlEgressPoolLimitBytes: 2917 case bcmCosqControlEgressPoolYellowLimitBytes: 2918 case bcmCosqControlEgressPoolRedLimitBytes: 2919 case bcmCosqControlEgressPoolLimitEnable: 2920 case bcmCosqControlEgressPoolSharedLimitBytes: 2921 case bcmCosqControlEgressPoolResumeLimitBytes: 2922 case bcmCosqControlEgressPoolYellowSharedLimitBytes: 2923 case bcmCosqControlEgressPoolYellowResumeLimitBytes: 2924 case bcmCosqControlEgressPoolRedSharedLimitBytes: 2925 case bcmCosqControlEgressPoolRedResumeLimitBytes: 2926 case bcmCosqControlEgressUCQueueSharedLimitBytes: 2927 case bcmCosqControlEgressMCQueueSharedLimitBytes: 2928 case bcmCosqControlEgressUCQueueMinLimitBytes: 2929 case bcmCosqControlEgressMCQueueMinLimitBytes: 2930 case bcmCosqControlEgressUCQueueResumeOffsetBytes: 2931 case bcmCosqControlEgressMCQueueResumeOffsetBytes: 2932 case bcmCosqControlEgressPoolHighCongestionLimitBytes: 2933 case bcmCosqControlEgressPoolLowCongestionLimitBytes: 2934 case bcmCosqControlIngressPortPGSharedLimitBytes: 2935 case bcmCosqControlIngressPortPGMinLimitBytes: 2936 case bcmCosqControlIngressPortPoolMinLimitBytes: 2937 case bcmCosqControlIngressPortPoolSharedLimitBytes: 2938 case bcmCosqControlIngressPortPGHeadroomLimitBytes: 2939 case bcmCosqControlIngressPortPGResetFloorBytes: 2940 case bcmCosqControlIngressPortPGResetOffsetBytes: 2941 case bcmCosqControlIngressPortPoolResumeLimitBytes: 2942 case bcmCosqControlDropLimitAlpha: 2943 case bcmCosqControlIngressPortPGSharedDynamicEnable: 2944 case bcmCosqControlEgressUCSharedDynamicEnable: 2945 case bcmCosqControlEgressMCSharedDynamicEnable: 2946 case bcmCosqControlEgressPortPoolYellowLimitBytes: 2947 case bcmCosqControlEgressPortPoolRedLimitBytes: 2948 case bcmCosqControlEgressPortPoolSharedLimitBytes: 2949 case bcmCosqControlEgressPortPoolSharedResumeBytes: 2950 case bcmCosqControlEgressPortPoolYellowResumeBytes: 2951 case bcmCosqControlEgressPortPoolRedResumeBytes: 2952 case bcmCosqControlEgressUCQueueLimitEnable: 2953 case bcmCosqControlEgressMCQueueLimitEnable: 2954 case bcmCosqControlIngressPoolLimitBytes: 2955 case bcmCosqControlIngressPoolResetOffsetLimitBytes: 2956 case bcmCosqControlIngressHeadroomPoolLimitBytes: 2957 case bcmCosqControlEgressUCQueueGroupMinLimitBytes: 2958 case bcmCosqControlEgressMCQueueGroupMinLimitBytes: 2959 case bcmCosqControlEgressUCQueueColorLimitDynamicEnable: 2960 case bcmCosqControlEgressMCQueueColorLimitDynamicEnable: 2961 case bcmCosqControlEgressUCQueueColorLimitEnable: 2962 case bcmCosqControlEgressMCQueueColorLimitEnable: 2963 case bcmCosqControlEgressUCQueueRedLimit: 2964 case bcmCosqControlEgressUCQueueYellowLimit: 2965 case bcmCosqControlEgressMCQueueRedLimit: 2966 case bcmCosqControlEgressMCQueueYellowLimit: 2967 *dynamic = bcmCosqDynamicTypeFlexible; 2968 break; 2969 default: 2970 break; 2971 } 2972 return BCM_E_UNAVAIL; 2973 } 2974 2975 int 2976 bcm_th3_cosq_service_pool_get( 2977 int unit, 2978 bcm_service_pool_id_t id, 2979 bcm_cosq_service_pool_t *cosq_service_pool) 2980 { 2981 uint32 rval; 2982 soc_field_t fld_enable = INVALIDf; 2983 int color_limit_enable = 0; 2984 2985 if (cosq_service_pool == NULL) { 2986 return BCM_E_PARAM; 2987 } 2988 2989 if (id < 0 || (id > _TH3_MMU_NUM_POOL - 1)) { 2990 return BCM_E_PARAM; 2991 } 2992 2993 rval = 0; 2994 SOC_IF_ERROR_RETURN( 2995 soc_tomahawk3_itm_reg32_get(unit, 2996 MMU_THDO_SHARED_DB_POOL_CONFIGr, -1, -1, -1, &rval)); 2997 2998 switch (cosq_service_pool->type) { 2999 case bcmCosqServicePoolColorAware: 3000 fld_enable = POOL_COLOR_LIMIT_ENABLEf; 3001 break; 3002 default: 3003 return BCM_E_PARAM; 3004 } 3005 3006 color_limit_enable = soc_reg_field_get(unit, MMU_THDO_SHARED_DB_POOL_CONFIGr, rval, 3007 fld_enable); 3008 color_limit_enable &= (1 << id); 3009 cosq_service_pool->enabled = (color_limit_enable != 0) ? 1 : 0; 3010 3011 return BCM_E_NONE; 3012 } 3013 3014 int 3015 bcm_th3_cosq_service_pool_set( 3016 int unit, 3017 bcm_service_pool_id_t id, 3018 bcm_cosq_service_pool_t cosq_service_pool) 3019 { 3020 uint32 rval; 3021 soc_field_t fld_enable = INVALIDf; 3022 int color_limit_enable = 0; 3023 3024 if (id < 0 || (id > _TH3_MMU_NUM_POOL - 1)) { 3025 return BCM_E_PARAM; 3026 } 3027 3028 rval = 0; 3029 SOC_IF_ERROR_RETURN( 3030 soc_tomahawk3_itm_reg32_get(unit, 3031 MMU_THDO_SHARED_DB_POOL_CONFIGr, -1, -1, -1, &rval)); 3032 switch (cosq_service_pool.type) { 3033 case bcmCosqServicePoolColorAware: 3034 fld_enable = POOL_COLOR_LIMIT_ENABLEf; 3035 break; 3036 default: 3037 return BCM_E_PARAM; 3038 } 3039 color_limit_enable = soc_reg_field_get(unit, MMU_THDO_SHARED_DB_POOL_CONFIGr, rval, 3040 fld_enable); 3041 if (cosq_service_pool.enabled) { 3042 color_limit_enable |= (1 << id); 3043 } else { 3044 color_limit_enable &= (~(1 << id)); 3045 color_limit_enable = color_limit_enable & 0xf; 3046 } 3047 soc_reg_field_set(unit, MMU_THDO_SHARED_DB_POOL_CONFIGr, &rval, 3048 fld_enable, color_limit_enable); 3049 SOC_IF_ERROR_RETURN(soc_tomahawk3_itm_reg32_set(unit, 3050 MMU_THDO_SHARED_DB_POOL_CONFIGr, -1, -1, 3051 -1, rval)); 3052 3053 return BCM_E_NONE; 3054 3055 } 3056 3057 static int 3058 _bcm_th3_adjust_delta_hdrm_service_pools(int unit, int itm, int hdrm_pool, int 3059 service_pool, uint32 new_hp_limit) { 3060 soc_reg_t reg; 3061 int cur_sp_limit[_TH3_ITMS_PER_DEV]; 3062 uint32 old_hp_limit[_TH3_ITMS_PER_DEV] = {0}, 3063 new_sp_limit[_TH3_ITMS_PER_DEV] = {0}; 3064 uint32 rval = 0; 3065 3066 /* Retrieve old value of headroom pool limit */ 3067 reg = MMU_THDI_HDRM_BUFFER_CELL_LIMIT_HPr; 3068 BCM_IF_ERROR_RETURN(soc_tomahawk3_itm_reg32_get(unit, reg, 3069 itm, itm, hdrm_pool, &old_hp_limit[itm])); 3070 if (old_hp_limit[itm] != new_hp_limit) { 3071 /* Delta of headroom pool limit */ 3072 BCM_IF_ERROR_RETURN(_bcm_th3_mmu_get_shared_size(unit, itm, 3073 &cur_sp_limit[itm])); 3074 if (old_hp_limit[itm] > new_hp_limit) { 3075 new_sp_limit[itm] = cur_sp_limit[itm] + (old_hp_limit[itm] - new_hp_limit); 3076 new_sp_limit[itm] = MIN(_TH3_THDI_BUFFER_CELL_LIMIT_SP_MAX, 3077 new_sp_limit[itm]); 3078 } else { 3079 if (cur_sp_limit[itm] > (new_hp_limit - old_hp_limit[itm])) { 3080 new_sp_limit[itm] = cur_sp_limit[itm] - (new_hp_limit - 3081 old_hp_limit[itm]); 3082 } else { 3083 LOG_WARN(BSL_LS_BCM_COSQ, 3084 (BSL_META_U(unit, "Warning: Given input params result" 3085 "in Headroom pool limit addition greater" 3086 "than available shared space: %d for itm:" 3087 "%d. Try reducing the number of lossless" 3088 "classes\n"), cur_sp_limit[itm], itm)); 3089 return BCM_E_RESOURCE; 3090 } 3091 } 3092 /* Update the saved shared limit */ 3093 reg = MMU_THDI_HDRM_BUFFER_CELL_LIMIT_HPr; 3094 BCM_IF_ERROR_RETURN(_bcm_th3_mmu_set_shared_size(unit, itm, 3095 new_sp_limit[itm])); 3096 BCM_IF_ERROR_RETURN(soc_tomahawk3_itm_reg32_set(unit, reg, 3097 itm, itm, hdrm_pool, new_hp_limit)); 3098 /* Update the Service pool shared limit for SP 0 */ 3099 reg = MMU_THDI_BUFFER_CELL_LIMIT_SPr; 3100 soc_reg_field_set(unit, reg, &rval, LIMITf, new_sp_limit[itm]); 3101 BCM_IF_ERROR_RETURN( 3102 soc_tomahawk3_itm_reg32_set(unit, reg, 3103 itm, itm, service_pool, rval)); 3104 } 3105 return BCM_E_NONE; 3106 } 3107 3108 /* Function to set Headroom Pool limit based on packet distribution and number 3109 * of lossless classes */ 3110 int 3111 bcm_tomahawk3_cosq_hdrm_pool_limit_set(int unit, int hdrm_pool, int num_lossless_class, 3112 int arr_size, bcm_cosq_pkt_size_dist_t *pkt_dist_array) 3113 { 3114 int rv, hdrm, i; 3115 _soc_pkt_size_dist_t *size_dist; 3116 uint32 fld_val; 3117 int itm; 3118 uint32 itm_map; 3119 int speed = 0, port; 3120 soc_info_t *si = &SOC_INFO(unit); 3121 #define _TH3_MMU_DEF_HDRM_CABLE_LEN 100 3122 3123 if ((arr_size > 3) || (pkt_dist_array == NULL) ) { 3124 return BCM_E_PARAM; 3125 } 3126 if (hdrm_pool > _TH3_MMU_NUM_POOL) { 3127 return BCM_E_PARAM; 3128 } 3129 3130 size_dist = sal_alloc(arr_size * sizeof(bcm_cosq_pkt_size_dist_t), 3131 "size dist"); 3132 if (size_dist == NULL) { 3133 return BCM_E_MEMORY; 3134 } 3135 3136 for (i = 0; i < arr_size; i++) { 3137 size_dist[i].pkt_size = pkt_dist_array[i].pkt_size; 3138 size_dist[i].dist_perc = pkt_dist_array[i].dist_perc; 3139 } 3140 PBMP_PORT_ITER(unit, port) { 3141 speed = MAX(speed, si->port_speed_max[port]); 3142 } 3143 3144 rv = soc_th3_get_port_pg_headroom(unit, speed, _TH3_MMU_DEF_HDRM_CABLE_LEN, 3145 arr_size, size_dist, &hdrm); 3146 sal_free(size_dist); 3147 if (rv) { 3148 return rv; 3149 } 3150 3151 fld_val = hdrm * num_lossless_class; 3152 itm_map = SOC_INFO(unit).itm_map; 3153 for (itm = 0; itm < NUM_ITM(unit); itm ++) { 3154 if (itm_map & (1 << itm)) { 3155 SOC_IF_ERROR_RETURN(_bcm_th3_adjust_delta_hdrm_service_pools(unit, itm, 3156 hdrm_pool, 0, fld_val)); 3157 } 3158 } 3159 #undef _TH3_MMU_DEF_HDRM_CABLE_LEN 3160 return rv; 3161 } 3162 3163 int 3164 bcm_tomahawk3_cosq_port_prigrp_hdrm_set(int unit, bcm_port_t port, uint32 pri_bmp, 3165 int cable_len, int arr_size, bcm_cosq_pkt_size_dist_t *pkt_dist_array) 3166 { 3167 _soc_pkt_size_dist_t *size_dist; 3168 int i, rv = 0, speed; 3169 int hdrm; 3170 int pri_pg_prof, pri_i, uc_pg, mc_pg, pg_i; 3171 soc_field_t pri_pg_flds[_TH3_MMU_NUM_INT_PRI] = { 3172 INPPRI0_PGf, INPPRI1_PGf, INPPRI2_PGf, 3173 INPPRI3_PGf, INPPRI4_PGf, INPPRI5_PGf, 3174 INPPRI6_PGf, INPPRI7_PGf, INPPRI8_PGf, 3175 INPPRI9_PGf, INPPRI10_PGf, INPPRI11_PGf, 3176 INPPRI12_PGf, INPPRI13_PGf, INPPRI14_PGf, 3177 INPPRI15_PGf}; 3178 soc_field_t field_pghdrm_limit[_TH3_MMU_NUM_PG] = { 3179 PG0_HDRM_LIMITf, PG1_HDRM_LIMITf, PG2_HDRM_LIMITf, 3180 PG3_HDRM_LIMITf, PG4_HDRM_LIMITf, PG5_HDRM_LIMITf, 3181 PG6_HDRM_LIMITf, PG7_HDRM_LIMITf}; 3182 uint32 pg_bmp = 0x0; 3183 uint64 rval64; 3184 soc_info_t *si = &SOC_INFO(unit); 3185 int pipe, midx; 3186 uint32 entry[SOC_MAX_MEM_WORDS]; 3187 soc_mem_t mem = INVALIDm; 3188 int delta = 0, old_limit; 3189 int itm; 3190 uint32 old_hp_limit = 0, itm_map = 0; 3191 3192 /* Parameter checks */ 3193 if (!SOC_PORT_VALID(unit, port)) { 3194 return BCM_E_PORT; 3195 } 3196 if ((arr_size > 3) || (pkt_dist_array == NULL) || (pri_bmp > 0xffff)) { 3197 return BCM_E_PARAM; 3198 } 3199 3200 3201 size_dist = sal_alloc(arr_size * sizeof(bcm_cosq_pkt_size_dist_t), 3202 "size dist"); 3203 if (size_dist == NULL) { 3204 return BCM_E_MEMORY; 3205 } 3206 3207 for (i = 0; i < arr_size; i++) { 3208 size_dist[i].pkt_size = pkt_dist_array[i].pkt_size; 3209 size_dist[i].dist_perc = pkt_dist_array[i].dist_perc; 3210 } 3211 3212 rv = bcm_esw_port_speed_get(unit, port, &speed); 3213 if (rv) { 3214 goto exit; 3215 } 3216 3217 rv = soc_th3_get_port_pg_headroom(unit, speed, cable_len, arr_size, 3218 size_dist, &hdrm); 3219 if (rv) { 3220 goto exit; 3221 } 3222 rv = _bcm_th3_cosq_port_inp_pri_to_pg_profile_get(unit, port, &pri_pg_prof); 3223 if (rv) { 3224 goto exit; 3225 } 3226 for (pri_i = 0; pri_i < _TH3_MMU_NUM_INT_PRI; pri_i++) { 3227 if (pri_bmp & (1U << pri_i)) { 3228 COMPILER_64_ZERO(rval64); 3229 rv = soc_reg64_get(unit, MMU_THDI_UC_INPPRI_PG_PROFILEr, 3230 REG_PORT_ANY, pri_pg_prof, &rval64); 3231 if (rv) { 3232 goto exit; 3233 } 3234 uc_pg = soc_reg64_field32_get(unit, MMU_THDI_UC_INPPRI_PG_PROFILEr, 3235 rval64, pri_pg_flds[pri_i]); 3236 pg_bmp |= (1U << uc_pg); 3237 COMPILER_64_ZERO(rval64); 3238 rv = soc_reg64_get(unit, MMU_THDI_NONUC_INPPRI_PG_PROFILEr, 3239 REG_PORT_ANY, pri_pg_prof, &rval64); 3240 if (rv) { 3241 goto exit; 3242 } 3243 mc_pg = soc_reg64_field32_get(unit, MMU_THDI_NONUC_INPPRI_PG_PROFILEr, 3244 rval64, pri_pg_flds[pri_i]); 3245 pg_bmp |= (1U << mc_pg); 3246 } 3247 } 3248 3249 pipe = si->port_pipe[port]; 3250 mem = SOC_MEM_UNIQUE_ACC(unit, MMU_THDI_PORT_PG_HDRM_CONFIGm)[pipe]; 3251 midx = SOC_TH3_MMU_LOCAL_PORT(unit, port); 3252 for (pg_i = 0; pg_i < _TH3_MMU_NUM_PG; pg_i++) { 3253 if (pg_bmp & (1U << pg_i)) { 3254 rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, 3255 entry); 3256 if (rv) { 3257 goto exit; 3258 } 3259 old_limit = soc_mem_field32_get(unit, mem, entry, 3260 field_pghdrm_limit[pg_i]); 3261 delta += (hdrm - old_limit); 3262 soc_mem_field32_set(unit, mem, entry, field_pghdrm_limit[pg_i], hdrm); 3263 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, midx, entry); 3264 if (rv) { 3265 goto exit; 3266 } 3267 } 3268 } 3269 itm_map = si->ipipe_itm_map[pipe]; 3270 for (itm = 0; itm < NUM_ITM(unit); itm++) { 3271 if (itm_map & (1 << itm)) { 3272 /* Retrieve old value of headroom pool limit */ 3273 rv = soc_tomahawk3_itm_reg32_get(unit, 3274 MMU_THDI_HDRM_BUFFER_CELL_LIMIT_HPr, itm, itm, 0, 3275 &old_hp_limit); 3276 if (rv) { 3277 goto exit; 3278 } 3279 rv = _bcm_th3_adjust_delta_hdrm_service_pools(unit, itm, 3280 0, 0, (old_hp_limit + delta)); 3281 if (rv) { 3282 goto exit; 3283 } 3284 } 3285 } 3286 3287 exit: 3288 sal_free(size_dist); 3289 return rv; 3290 } 3291 3292 #endif