cosq.c (21568B)
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 * COS Queue Management 8 * Purpose: API to set different cosq, priorities, and scheduler registers. 9 * 10 * Bradley supports two additional COS queues for high priority flow 11 * control (QM queue) and system control (SC queue.) Currently API 12 * access to these two queues is blocked since they do not participate 13 * in regular queue scheduling (they are both always using strict 14 * priority.) Likewise, internal priorities 14 and 15 are reserved 15 * for use with these two COS queues. This means that the COS mapping 16 * API will allow mapping of 14 internal priorities to the 8 normal 17 * COS queues. 18 */ 19 20 #include <sal/core/libc.h> 21 #include <shared/bsl.h> 22 #include <soc/defs.h> 23 #if defined(BCM_BRADLEY_SUPPORT) 24 #include <soc/drv.h> 25 #include <soc/scache.h> 26 #include <soc/debug.h> 27 28 #include <bcm/error.h> 29 #include <bcm/cosq.h> 30 31 #include <bcm_int/esw/cosq.h> 32 #include <bcm_int/esw/mbcm.h> 33 #include <bcm_int/esw/firebolt.h> 34 #include <bcm_int/esw/bradley.h> 35 36 #include <bcm_int/esw_dispatch.h> 37 38 #ifdef BCM_WARM_BOOT_SUPPORT 39 #include <bcm_int/esw/switch.h> 40 #endif /* BCM_WARM_BOOT_SUPPORT */ 41 42 #define HB_DRR_WEIGHT_MAX 0x7f 43 #define HB_WRR_WEIGHT_MAX 0x7f 44 45 #define HB_SC_COS 14 46 #define HB_QM_COS 15 47 48 static const soc_field_t cpu_prio_field[16] = { 49 PRI0f, PRI1f, PRI2f, PRI3f, PRI4f, PRI5f, PRI6f, PRI7f, 50 PRI8f, PRI9f, PRI10f, PRI11f, PRI12f, PRI13f, PRI14f, PRI15f 51 }; 52 53 #ifdef BCM_COSQ_HIGIG_MAP_DISABLE 54 55 static const soc_field_t cos_field[16] = { 56 COS0f, COS1f, COS2f, COS3f, COS4f, COS5f, COS6f, COS7f, 57 COS8f, COS9f, COS10f, COS11f, COS12f, COS13f, COS14f, COS15f 58 }; 59 60 static const soc_field_t hg_cos_val[16] = { 61 0, 1, 2, 3, 4, 5, 6, 7, 62 7, 7, 7, 7, 7, 7, 14, 15 63 }; 64 65 #endif 66 67 68 static int _num_cosq[SOC_MAX_NUM_DEVICES]; 69 static int _max_cosq = -1; 70 71 /* 72 * Convert the number of kbytes (1024 bytes) that can transmtted in one run 73 * to weight encoding as per table above 74 */ 75 static int 76 _bcm_hb_cos_drr_kbytes_to_weight(int kbytes) 77 { 78 int weight; 79 80 /* 1 weight-unit ~ 128 bytes */ 81 weight = 8 * kbytes; 82 83 if (weight > HB_DRR_WEIGHT_MAX) { 84 weight = HB_DRR_WEIGHT_MAX; 85 } 86 87 return weight; 88 } 89 90 /* 91 * Convert the encoded weights to number of kbytes that can transmtted 92 * in one run. 93 */ 94 static int 95 _bcm_hb_cos_drr_weight_to_kbytes(int weight) 96 { 97 assert(weight <= HB_DRR_WEIGHT_MAX); 98 99 /* 1 weight-unit ~ 128 bytes */ 100 return (weight / 8); 101 } 102 103 104 #ifdef BCM_WARM_BOOT_SUPPORT 105 106 #define BCM_WB_VERSION_1_0 SOC_SCACHE_VERSION(1,0) 107 #define BCM_WB_DEFAULT_VERSION BCM_WB_VERSION_1_0 108 109 /* 110 * Function: 111 * bcm_bradley_cosq_sync 112 * Purpose: 113 * Record COSQ module persistent info for Level 2 Warm Boot. 114 * Parameters: 115 * unit - Unit number. 116 * Returns: 117 * BCM_E_XXX 118 */ 119 int 120 bcm_bradley_cosq_sync(int unit) 121 { 122 soc_scache_handle_t scache_handle; 123 uint8 *cosq_scache_ptr; 124 uint32 num_cosq; 125 126 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_COSQ, 0); 127 BCM_IF_ERROR_RETURN 128 (_bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 129 0, &cosq_scache_ptr, 130 BCM_WB_DEFAULT_VERSION, NULL)); 131 132 /* Number COSQ */ 133 num_cosq = _num_cosq[unit]; 134 sal_memcpy(cosq_scache_ptr, &num_cosq, sizeof(num_cosq)); 135 136 return BCM_E_NONE; 137 } 138 139 /* 140 * Function: 141 * _bcm_bradley_cosq_reinit 142 * Purpose: 143 * Recover COSQ software state. 144 * Parameters: 145 * unit - Unit number. 146 * Returns: 147 * BCM_E_XXX 148 */ 149 STATIC int 150 _bcm_bradley_cosq_reinit(int unit) 151 { 152 int rv; 153 soc_scache_handle_t scache_handle; 154 uint8 *cosq_scache_ptr; 155 uint32 num_cosq; 156 157 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_COSQ, 0); 158 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 159 0, &cosq_scache_ptr, 160 BCM_WB_DEFAULT_VERSION, NULL); 161 162 if (rv == BCM_E_NOT_FOUND) { 163 cosq_scache_ptr = NULL; 164 } else if (BCM_FAILURE(rv)) { 165 return rv; 166 } 167 168 if (cosq_scache_ptr != NULL) { 169 /* Number COSQ */ 170 sal_memcpy(&num_cosq, cosq_scache_ptr, sizeof(num_cosq)); 171 _num_cosq[unit] = num_cosq; 172 } else { 173 _num_cosq[unit] = _bcm_esw_cosq_config_property_get(unit); 174 } 175 176 return BCM_E_NONE; 177 } 178 #endif /* BCM_WARM_BOOT_SUPPORT */ 179 180 /* 181 * Function: 182 * bcm_bradley_cosq_init 183 * Purpose: 184 * Initialize (clear) all COS schedule/mapping state. 185 * Parameters: 186 * unit - StrataSwitch unit number. 187 * Returns: 188 * BCM_E_XXX 189 */ 190 191 int 192 bcm_bradley_cosq_init(int unit) 193 { 194 int num_cos; 195 #ifdef BCM_WARM_BOOT_SUPPORT 196 int rv; 197 soc_scache_handle_t scache_handle; 198 uint32 cosq_scache_size; 199 uint8 *cosq_scache_ptr; 200 #endif /* BCM_WARM_BOOT_SUPPORT */ 201 202 if (_max_cosq < 0) { 203 _max_cosq = NUM_COS(unit); 204 NUM_COS(unit) = 8; 205 } 206 207 #ifdef BCM_WARM_BOOT_SUPPORT 208 /* Warm boot level 2 cache size */ 209 cosq_scache_size = sizeof(uint32); /* Number COSQ */ 210 211 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_COSQ, 0); 212 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, 213 (0 == SOC_WARM_BOOT(unit)), 214 cosq_scache_size, &cosq_scache_ptr, 215 BCM_WB_DEFAULT_VERSION, NULL); 216 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 217 return rv; 218 } 219 220 if (SOC_WARM_BOOT(unit)) { 221 return _bcm_bradley_cosq_reinit(unit); 222 } 223 #endif /* BCM_WARM_BOOT_SUPPORT */ 224 225 num_cos = _bcm_esw_cosq_config_property_get(unit); 226 227 return bcm_bradley_cosq_config_set(unit, num_cos); 228 } 229 230 /* 231 * Function: 232 * bcm_cosq_detach 233 * Purpose: 234 * Discard all COS schedule/mapping state. 235 * Parameters: 236 * unit - StrataSwitch unit number. 237 * Returns: 238 * BCM_E_XXX 239 */ 240 241 int 242 bcm_bradley_cosq_detach(int unit, int software_state_only) 243 { 244 return BCM_E_NONE; 245 } 246 247 /* 248 * Function: 249 * bcm_bradley_cosq_config_set 250 * Purpose: 251 * Set the number of COS queues 252 * Parameters: 253 * unit - Draco unit number. 254 * numq - number of COS queues (1-8). 255 * Returns: 256 * BCM_E_XXX 257 */ 258 259 int 260 bcm_bradley_cosq_config_set(int unit, int numq) 261 { 262 int cos, prio, ratio, remain; 263 uint32 val32; 264 #ifdef BCM_COSQ_HIGIG_MAP_DISABLE 265 soc_port_t port; 266 uint64 val64; 267 #endif 268 269 /* Validate cosq num */ 270 if (numq < 1) { 271 return BCM_E_PARAM; 272 } 273 274 if (SOC_WARM_BOOT(unit)) { 275 _num_cosq[unit] = numq; 276 return BCM_E_NONE; 277 } 278 279 /* Map the eight 802.1 priority levels to the active cosqs */ 280 if (numq > 8) { 281 numq = 8; 282 } 283 ratio = 8 / numq; 284 remain = 8 % numq; 285 cos = 0; 286 for (prio = 0; prio < 8; prio++) { 287 BCM_IF_ERROR_RETURN 288 (bcm_bradley_cosq_mapping_set(unit, -1, prio, cos)); 289 if ((prio + 1) == (((cos + 1) * ratio) + 290 ((remain < (numq - cos)) ? 0 : 291 (remain - (numq - cos) + 1)))) { 292 cos++; 293 } 294 } 295 296 /* Map remaining internal priority levels to highest priority cosq */ 297 cos = numq - 1; 298 for (prio = 8; prio < 14; prio++) { 299 BCM_IF_ERROR_RETURN 300 (bcm_bradley_cosq_mapping_set(unit, -1, prio, cos)); 301 } 302 303 /* Map SC COS queue */ 304 BCM_IF_ERROR_RETURN 305 (bcm_bradley_cosq_mapping_set(unit, -1, 14, HB_SC_COS)); 306 307 /* Map QM COS queue */ 308 BCM_IF_ERROR_RETURN 309 (bcm_bradley_cosq_mapping_set(unit, -1, 15, HB_QM_COS)); 310 311 #ifdef BCM_COSQ_HIGIG_MAP_DISABLE 312 /* identity mapping for higig ports */ 313 314 if (SOC_IS_HB_GW(unit)) { 315 /* map prio0->cos0, prio1->cos1, ... , prio7->cos7 */ 316 COMPILER_64_ZERO(val64); 317 for (prio = 0; prio < 8; prio++) { 318 soc_reg64_field32_set(unit, ICOS_SELr, &val64, 319 cos_field[prio], hg_cos_val[prio]); 320 } 321 PBMP_HG_ITER(unit, port) { 322 SOC_IF_ERROR_RETURN(WRITE_ICOS_SELr(unit, port, val64)); 323 } 324 SOC_IF_ERROR_RETURN(WRITE_ICOS_SELr(unit, (CMIC_PORT(unit)), val64)); 325 } 326 #endif 327 328 if (SOC_REG_IS_VALID(unit, CPU_PRIORITY_SELr)) { 329 /* use 1:1 CPU priority mapping */ 330 val32 = 0; 331 for (prio = 0; prio < 8; prio++) { 332 soc_reg_field_set(unit, CPU_PRIORITY_SELr, &val32, 333 cpu_prio_field[prio], prio); 334 } 335 SOC_IF_ERROR_RETURN(WRITE_CPU_PRIORITY_SELr(unit, val32)); 336 val32 = 0; 337 for (prio = 8; prio < 16; prio++) { 338 soc_reg_field_set(unit, CPU_PRIORITY_SEL_2r, &val32, 339 cpu_prio_field[prio], prio); 340 } 341 SOC_IF_ERROR_RETURN(WRITE_CPU_PRIORITY_SEL_2r(unit, val32)); 342 } 343 344 _num_cosq[unit] = numq; 345 346 return BCM_E_NONE; 347 } 348 349 /* 350 * Function: 351 * bcm_bradley_cosq_mapping_set 352 * Purpose: 353 * Set which cosq a given priority should fall into 354 * Parameters: 355 * unit - StrataSwitch unit number. 356 * priority - Priority value to map 357 * cosq - COS queue to map to 358 * Returns: 359 * BCM_E_XXX 360 * Notes: 361 * Priorities 14 and 15 are blocked unless used in 362 * conjunction with the SC and QM COS queues. 363 */ 364 365 int 366 bcm_bradley_cosq_mapping_set(int unit, bcm_port_t port, 367 bcm_cos_t priority, bcm_cos_queue_t cosq) 368 { 369 uint32 cval32, oval32; 370 soc_field_t f; 371 bcm_pbmp_t ports; 372 373 switch (priority) { 374 case 0: f = COS0f; break; 375 case 1: f = COS1f; break; 376 case 2: f = COS2f; break; 377 case 3: f = COS3f; break; 378 case 4: f = COS4f; break; 379 case 5: f = COS5f; break; 380 case 6: f = COS6f; break; 381 case 7: f = COS7f; break; 382 case 8: f = COS8f; break; 383 case 9: f = COS9f; break; 384 case 10: f = COS10f; break; 385 case 11: f = COS11f; break; 386 case 12: f = COS12f; break; 387 case 13: f = COS13f; break; 388 case 14: f = COS14f; break; 389 case 15: f = COS15f; break; 390 default: return BCM_E_PARAM; 391 } 392 393 if ((cosq < 0 || cosq >= 8) && cosq != HB_SC_COS && cosq != HB_QM_COS) { 394 return (BCM_E_PARAM); 395 } 396 397 if (port == -1) { /* all ports */ 398 BCM_PBMP_ASSIGN(ports, PBMP_ALL(unit)); 399 } else if (SOC_PORT_VALID(unit, port) && IS_ALL_PORT(unit, port)) { 400 BCM_PBMP_CLEAR(ports); 401 BCM_PBMP_PORT_ADD(ports, port); 402 } else { 403 return BCM_E_PORT; 404 } 405 406 PBMP_ITER(ports, port) { 407 if (priority < 8) { 408 SOC_IF_ERROR_RETURN(READ_COS_SELr(unit, port, &cval32)); 409 oval32 = cval32; 410 soc_reg_field_set(unit, COS_SELr, &cval32, f, cosq); 411 if (cval32 != oval32) { 412 SOC_IF_ERROR_RETURN(WRITE_COS_SELr(unit, port, cval32)); 413 } 414 if (port == CMIC_PORT(unit) && 415 SOC_REG_IS_VALID(unit, CPU_COS_SELr)) { 416 SOC_IF_ERROR_RETURN(READ_CPU_COS_SELr(unit, &cval32)); 417 oval32 = cval32; 418 soc_reg_field_set(unit, CPU_COS_SELr, &cval32, f, cosq); 419 if (cval32 != oval32) { 420 SOC_IF_ERROR_RETURN(WRITE_CPU_COS_SELr(unit, cval32)); 421 } 422 } 423 #ifndef BCM_COSQ_HIGIG_MAP_DISABLE 424 if (IS_HG_PORT(unit, port) || port == CMIC_PORT(unit)) { 425 SOC_IF_ERROR_RETURN(READ_ICOS_SELr(unit, port, &cval32)); 426 oval32 = cval32; 427 soc_reg_field_set(unit, ICOS_SELr, &cval32, f, cosq); 428 if (cval32 != oval32) { 429 SOC_IF_ERROR_RETURN(WRITE_ICOS_SELr(unit, port, cval32)); 430 } 431 } 432 #endif 433 } else { 434 SOC_IF_ERROR_RETURN(READ_COS_SEL_2r(unit, port, &cval32)); 435 oval32 = cval32; 436 soc_reg_field_set(unit, COS_SEL_2r, &cval32, f, cosq); 437 if (cval32 != oval32) { 438 SOC_IF_ERROR_RETURN(WRITE_COS_SEL_2r(unit, port, cval32)); 439 } 440 441 if (port == CMIC_PORT(unit) && 442 SOC_REG_IS_VALID(unit, CPU_COS_SEL_2r)) { 443 SOC_IF_ERROR_RETURN(READ_CPU_COS_SEL_2r(unit, &cval32)); 444 oval32 = cval32; 445 soc_reg_field_set(unit, CPU_COS_SEL_2r, &cval32, f, cosq); 446 if (cval32 != oval32) { 447 SOC_IF_ERROR_RETURN(WRITE_CPU_COS_SEL_2r(unit, cval32)); 448 } 449 } 450 #ifndef BCM_COSQ_HIGIG_MAP_DISABLE 451 if (IS_HG_PORT(unit, port) || port == CMIC_PORT(unit)) { 452 SOC_IF_ERROR_RETURN(READ_ICOS_SEL_2r(unit, port, &cval32)); 453 oval32 = cval32; 454 soc_reg_field_set(unit, ICOS_SEL_2r, &cval32, f, cosq); 455 if (cval32 != oval32) { 456 SOC_IF_ERROR_RETURN(WRITE_ICOS_SEL_2r(unit, port, cval32)); 457 } 458 } 459 #endif 460 } 461 } 462 463 return BCM_E_NONE; 464 } 465 466 /* 467 * Function: 468 * bcm_bradley_cosq_mapping_get 469 * Purpose: 470 * Determine which COS queue a given priority currently maps to. 471 * Parameters: 472 * unit - StrataSwitch unit number. 473 * priority - Priority value 474 * cosq - (Output) COS queue number 475 * Returns: 476 * BCM_E_XXX 477 */ 478 479 int 480 bcm_bradley_cosq_mapping_get(int unit, bcm_port_t port, 481 bcm_cos_t priority, bcm_cos_queue_t *cosq) 482 { 483 uint32 cval32; 484 soc_field_t f; 485 486 switch (priority) { 487 case 0: f = COS0f; break; 488 case 1: f = COS1f; break; 489 case 2: f = COS2f; break; 490 case 3: f = COS3f; break; 491 case 4: f = COS4f; break; 492 case 5: f = COS5f; break; 493 case 6: f = COS6f; break; 494 case 7: f = COS7f; break; 495 case 8: f = COS8f; break; 496 case 9: f = COS9f; break; 497 case 10: f = COS10f; break; 498 case 11: f = COS11f; break; 499 case 12: f = COS12f; break; 500 case 13: f = COS13f; break; 501 case 14: f = COS14f; break; 502 case 15: f = COS15f; break; 503 default: return BCM_E_PARAM; 504 } 505 506 if (port == -1) { 507 port = REG_PORT_ANY; 508 } else if (!SOC_PORT_VALID(unit, port) || !IS_ALL_PORT(unit, port)) { 509 return BCM_E_PORT; 510 } 511 512 if (priority < 8) { 513 SOC_IF_ERROR_RETURN(READ_COS_SELr(unit, port, &cval32)); 514 *cosq = soc_reg_field_get(unit, COS_SELr, cval32, f); 515 } else { 516 SOC_IF_ERROR_RETURN(READ_COS_SEL_2r(unit, port, &cval32)); 517 *cosq = soc_reg_field_get(unit, COS_SEL_2r, cval32, f); 518 } 519 return BCM_E_NONE; 520 } 521 522 /* 523 * Function: 524 * bcm_bradley_cosq_config_get 525 * Purpose: 526 * Get the number of cos queues 527 * Parameters: 528 * unit - StrataSwitch unit number. 529 * numq - (Output) number of cosq 530 * Returns: 531 * BCM_E_XXX 532 */ 533 534 int 535 bcm_bradley_cosq_config_get(int unit, int *numq) 536 { 537 if (_num_cosq[unit] == 0) { 538 return BCM_E_INIT; 539 } 540 541 if (numq != NULL) { 542 *numq = _num_cosq[unit]; 543 } 544 545 return BCM_E_NONE; 546 } 547 548 /* 549 * Function: 550 * bcm_bradley_cosq_port_sched_set 551 * Purpose: 552 * Set up class-of-service policy and corresponding weights and delay 553 * Parameters: 554 * unit - StrataSwitch unit number. 555 * pbm - port bitmap 556 * mode - Scheduling mode, one of BCM_COSQ_xxx 557 * weights - Weights for each COS queue 558 * Only for BCM_COSQ_WEIGHTED_FAIR_ROUND_ROBIN mode. 559 * For DRR Weight is specified in Kbytes 560 * delay - This parameter is not used in 56504 561 * Returns: 562 * BCM_E_XXX 563 */ 564 565 int 566 bcm_bradley_cosq_port_sched_set(int unit, bcm_pbmp_t pbm, 567 int mode, const int weights[], int delay) 568 { 569 int port, t, i; 570 uint32 wrr, escfg, minsp; 571 int mbits = 0; 572 int enc_weights[8]; 573 574 switch (mode) { 575 case BCM_COSQ_STRICT: 576 mbits = 0; 577 break; 578 case BCM_COSQ_ROUND_ROBIN: 579 mbits = 1; 580 break; 581 case BCM_COSQ_WEIGHTED_ROUND_ROBIN: 582 mbits = 2; 583 /* 584 * All weight values must fit within 7 bits. 585 * If weight is 0, this queue is run in strict mode, 586 * others run in WRR mode. 587 */ 588 589 t = weights[0] | weights[1] | weights[2] | weights[3] | 590 weights[4] | weights[5] | weights[6] | weights[7]; 591 592 if ((t & ~0x7f) != 0) { 593 return BCM_E_PARAM; 594 } 595 for(i = 0; i < 8; i++) { 596 enc_weights[i] = weights[i]; 597 } 598 break; 599 case BCM_COSQ_DEFICIT_ROUND_ROBIN: 600 mbits = 3; 601 for(i = 0; i < 8; i++) { 602 enc_weights[i] = _bcm_hb_cos_drr_kbytes_to_weight(weights[i]); 603 } 604 break; 605 case BCM_COSQ_BOUNDED_DELAY: /* not supported in xgs */ 606 default: 607 return BCM_E_PARAM; 608 } 609 610 PBMP_ITER(pbm, port) { 611 SOC_IF_ERROR_RETURN 612 (READ_ESCONFIGr(unit, port, &escfg)); 613 soc_reg_field_set(unit, ESCONFIGr, &escfg, SCHEDULING_SELECTf, mbits); 614 SOC_IF_ERROR_RETURN 615 (WRITE_ESCONFIGr(unit, port, escfg)); 616 } 617 618 if ((mode == BCM_COSQ_WEIGHTED_ROUND_ROBIN) || 619 (mode == BCM_COSQ_DEFICIT_ROUND_ROBIN)) { 620 /* 621 * Weighted Fair Queueing scheduling among vaild COSs 622 */ 623 PBMP_ITER(pbm, port) { 624 SOC_IF_ERROR_RETURN 625 (READ_MINSPCONFIGr(unit, port, &minsp)); 626 for(i = 0; i < 8; i++) { 627 SOC_IF_ERROR_RETURN 628 (READ_COSWEIGHTSr(unit, port, i, &wrr)); 629 /* coverity[uninit_use_in_call : FALSE] */ 630 soc_reg_field_set(unit, COSWEIGHTSr, &wrr, 631 COSWEIGHTSf, enc_weights[i]); 632 SOC_IF_ERROR_RETURN 633 (WRITE_COSWEIGHTSr(unit, port, i, wrr)); 634 /* Set strict priority bit if weight is zero */ 635 if (enc_weights[i] == 0) { 636 minsp |= (1 << i); 637 } else { 638 minsp &= ~(1 << i); 639 } 640 } 641 SOC_IF_ERROR_RETURN 642 (WRITE_MINSPCONFIGr(unit, port, minsp)); 643 } 644 } 645 return BCM_E_NONE; 646 } 647 648 /* 649 * Function: 650 * bcm_bradley_cosq_port_sched_get 651 * Purpose: 652 * Retrieve class-of-service policy and corresponding weights and delay 653 * Parameters: 654 * unit - StrataSwitch unit number. 655 * pbm - port bitmap 656 * mode - (output) Scheduling mode, one of BCM_COSQ_xxx 657 * weights - (output) Weights for each COS queue 658 * Only for BCM_COSQ_WEIGHTED_ROUND_ROBIN and 659 * BCM_COSQ_DEFICIT_ROUND_ROBIN mode. 660 * For DRR Weight is specified in Kbytes 661 * delay - This parameter is not used in 56504 662 * Returns: 663 * BCM_E_XXX 664 * Notes: 665 * Actually just returns data for the first port in the bitmap 666 */ 667 668 int 669 bcm_bradley_cosq_port_sched_get(int unit, bcm_pbmp_t pbm, 670 int *mode, int weights[], int *delay) 671 { 672 uint32 escfg, wrr; 673 int mbits, port, i; 674 675 mbits = -1; 676 PBMP_ITER(pbm, port) { 677 SOC_IF_ERROR_RETURN 678 (READ_ESCONFIGr(unit, port, &escfg)); 679 mbits = soc_reg_field_get(unit, ESCONFIGr, escfg, SCHEDULING_SELECTf); 680 break; 681 } 682 683 switch (mbits) { 684 case 0: 685 *mode = BCM_COSQ_STRICT; 686 break; 687 case 1: 688 *mode = BCM_COSQ_ROUND_ROBIN; 689 break; 690 case 2: 691 *mode = BCM_COSQ_WEIGHTED_ROUND_ROBIN; 692 break; 693 case 3: 694 *mode = BCM_COSQ_DEFICIT_ROUND_ROBIN; 695 break; 696 default: 697 return BCM_E_INTERNAL; 698 } 699 700 if ((mbits == 2) || (mbits == 3)) { 701 wrr = 0; 702 PBMP_ITER(pbm, port) { 703 for(i = 0; i < 8; i++) { 704 SOC_IF_ERROR_RETURN 705 (READ_COSWEIGHTSr(unit, port, i, &wrr)); 706 weights[i] = soc_reg_field_get(unit, COSWEIGHTSr, wrr, 707 COSWEIGHTSf); 708 } 709 break; 710 } 711 712 if (mbits == 3) { 713 int i; 714 for(i = 0; i < 8; i++) { 715 weights[i] = _bcm_hb_cos_drr_weight_to_kbytes(weights[i]); 716 } 717 } 718 } 719 720 if (delay) { 721 *delay = 0; 722 } 723 return BCM_E_NONE; 724 } 725 726 /* 727 * Function: 728 * bcm_bradley_cosq_sched_weight_max_get 729 * Purpose: 730 * Retrieve maximum weights for given COS policy. 731 * Parameters: 732 * unit - StrataSwitch unit number. 733 * mode - Scheduling mode, one of BCM_COSQ_xxx 734 * weight_max - (output) Maximum weight for COS queue. 735 * For DRR mode Weight is specified in Kbytes 736 * 0 if mode is BCM_COSQ_STRICT. 737 * 1 if mode is BCM_COSQ_ROUND_ROBIN. 738 * -1 if not applicable to mode. 739 * Returns: 740 * BCM_E_XXX 741 */ 742 743 int 744 bcm_bradley_cosq_sched_weight_max_get(int unit, int mode, int *weight_max) 745 { 746 switch (mode) { 747 case BCM_COSQ_STRICT: 748 *weight_max = BCM_COSQ_WEIGHT_STRICT; 749 break; 750 case BCM_COSQ_ROUND_ROBIN: 751 *weight_max = BCM_COSQ_WEIGHT_MIN; 752 break; 753 case BCM_COSQ_WEIGHTED_ROUND_ROBIN: 754 *weight_max = HB_WRR_WEIGHT_MAX; 755 break; 756 case BCM_COSQ_DEFICIT_ROUND_ROBIN: 757 *weight_max = _bcm_hb_cos_drr_weight_to_kbytes(HB_DRR_WEIGHT_MAX); 758 break; 759 default: 760 *weight_max = BCM_COSQ_WEIGHT_UNLIMITED; 761 return BCM_E_PARAM; 762 } 763 764 return BCM_E_NONE; 765 } 766 767 #ifndef BCM_SW_STATE_DUMP_DISABLE 768 /* 769 * Function: 770 * bcm_bradley_cosq_sw_dump 771 * Purpose: 772 * Displays COS Queue information maintained by software. 773 * Parameters: 774 * unit - Device unit number 775 * Returns: 776 * None 777 */ 778 void 779 bcm_bradley_cosq_sw_dump(int unit) 780 { 781 LOG_CLI((BSL_META_U(unit, 782 "\nSW Information COSQ - Unit %d\n"), unit)); 783 LOG_CLI((BSL_META_U(unit, 784 " Number: %d\n"), _num_cosq[unit])); 785 786 return; 787 } 788 #endif /* BCM_SW_STATE_DUMP_DISABLE */ 789 790 #else /* BCM_BRADLEY_SUPPORT */ 791 int _bradley_cosq_not_empty; 792 #endif /* BCM_BRADLEY_SUPPORT */ 793