preemption.c (50638B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 */ 7 8 #include <soc/drv.h> 9 #include <bcm/port.h> 10 #include <bcm/error.h> 11 #include <bcm/types.h> 12 #include <bcm_int/esw_dispatch.h> 13 #include <bcm_int/esw/port.h> 14 #include <bcm_int/esw/preemption.h> 15 #if defined(BCM_GREYHOUND2_SUPPORT) 16 #include <bcm_int/esw/greyhound2.h> 17 #endif 18 #include <bcm_int/esw/portctrl.h> 19 #if defined(BCM_MONTEREY_SUPPORT) 20 #include <bcm_int/esw/monterey.h> 21 #endif 22 23 24 #if defined(BCM_WARM_BOOT_SUPPORT) 25 #include <bcm/module.h> 26 #include <bcm_int/esw/switch.h> 27 #endif /* BCM_WARM_BOOT_SUPPORT */ 28 29 #if defined(BCM_PREEMPTION_SUPPORT) 30 soc_pbmp_t pbmp_verify_enable_cache[SOC_MAX_NUM_DEVICES]; 31 sal_mutex_t verify_enable_cache_mutex[SOC_MAX_NUM_DEVICES]; 32 33 #define PREEMPTION_LOCK(_unit_) \ 34 sal_mutex_take(verify_enable_cache_mutex[(_unit_)], sal_mutex_FOREVER); 35 #define PREEMPTION_UNLOCK(_unit_) \ 36 sal_mutex_give(verify_enable_cache_mutex[(_unit_)]); 37 38 /* 39 * Function: 40 * bcmi_esw_preemption_unimac_enable_tx_set 41 * Purpose: 42 * set preemption tx enable or not on unimac 43 * Parameters: 44 * unit - (IN) unit number. 45 * port - (IN) port number 46 * value - (IN) value 47 * Returns: 48 * BCM_E_XXX 49 * Notes: 50 */ 51 STATIC int 52 bcmi_esw_preemption_unimac_enable_tx_set(int unit, bcm_port_t port, 53 uint32 value) 54 { 55 return soc_reg_field32_modify(unit, MAC_MERGE_CONFIGr, 56 port, PREEMPT_ENABLEf, 57 value ? 1 : 0); 58 } 59 60 /* 61 * Function: 62 * bcmi_esw_preemption_xlmac_enable_tx_set 63 * Purpose: 64 * set preemption tx enable or not on xlmac 65 * Parameters: 66 * unit - (IN) unit number. 67 * port - (IN) port number 68 * value - (IN) value 69 * Returns: 70 * BCM_E_XXX 71 * Notes: 72 */ 73 STATIC int 74 bcmi_esw_preemption_xlmac_enable_tx_set(int unit, bcm_port_t port, 75 uint32 value) 76 { 77 return soc_reg_field32_modify(unit, XLMAC_MERGE_CONFIGr, 78 port, PREEMPT_ENABLEf, 79 value ? 1 : 0); 80 } 81 82 /* 83 * Function: 84 * bcmi_esw_preemption_unimac_enable_verify_set 85 * Purpose: 86 * set preemption verify enable or not on unimac 87 * Parameters: 88 * unit - (IN) unit number. 89 * port - (IN) port number 90 * value - (IN) value 91 * Returns: 92 * BCM_E_XXX 93 * Notes: 94 */ 95 STATIC int 96 bcmi_esw_preemption_unimac_enable_verify_set(int unit, bcm_port_t port, 97 uint32 value) 98 { 99 return soc_reg_field32_modify(unit, MAC_MERGE_CONFIGr, 100 port, VERIFY_ENABLEf, 101 value ? 1 : 0); 102 } 103 104 /* 105 * Function: 106 * bcmi_esw_preemption_xlmac_enable_verify_set 107 * Purpose: 108 * set preemption verify enable or not on xlmac 109 * Parameters: 110 * unit - (IN) unit number. 111 * port - (IN) port number 112 * value - (IN) value 113 * Returns: 114 * BCM_E_XXX 115 * Notes: 116 */ 117 STATIC int 118 bcmi_esw_preemption_xlmac_enable_verify_set(int unit, bcm_port_t port, 119 uint32 value) 120 { 121 return soc_reg_field32_modify(unit, XLMAC_MERGE_CONFIGr, 122 port, VERIFY_ENABLEf, 123 value ? 1 : 0); 124 } 125 126 /* 127 * Function: 128 * bcmi_esw_preemption_unimac_enable_tx_get 129 * Purpose: 130 * get preemption tx enable or not on unimac 131 * Parameters: 132 * unit - (IN) unit number. 133 * port - (IN) port number 134 * value - (OUT) value 135 * Returns: 136 * BCM_E_XXX 137 * Notes: 138 */ 139 STATIC int 140 bcmi_esw_preemption_unimac_enable_tx_get(int unit, bcm_port_t port, 141 uint32* value) 142 { 143 uint64 regval64; 144 145 if (NULL == value) { 146 return SOC_E_PARAM; 147 } 148 BCM_IF_ERROR_RETURN(soc_reg_get(unit, MAC_MERGE_CONFIGr, port, 149 0, ®val64)); 150 *value = soc_reg64_field32_get(unit, MAC_MERGE_CONFIGr, 151 regval64, PREEMPT_ENABLEf); 152 return BCM_E_NONE; 153 } 154 155 /* 156 * Function: 157 * bcmi_esw_preemption_xlmac_enable_tx_get 158 * Purpose: 159 * get preemption tx enable or not on xlmac 160 * Parameters: 161 * unit - (IN) unit number. 162 * port - (IN) port number 163 * value - (OUT) value 164 * Returns: 165 * BCM_E_XXX 166 * Notes: 167 */ 168 STATIC int 169 bcmi_esw_preemption_xlmac_enable_tx_get(int unit, bcm_port_t port, 170 uint32* value) 171 { 172 uint64 regval64; 173 174 if (NULL == value) { 175 return SOC_E_PARAM; 176 } 177 BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_MERGE_CONFIGr, port, 178 0, ®val64)); 179 *value = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr, 180 regval64, PREEMPT_ENABLEf); 181 return BCM_E_NONE; 182 } 183 184 /* 185 * Function: 186 * bcmi_esw_preemption_unimac_mode_set 187 * Purpose: 188 * set preemption mode on unimac 189 * Parameters: 190 * unit - (IN) unit number. 191 * port - (IN) port number 192 * value - (IN) value 193 * Returns: 194 * BCM_E_XXX 195 * Notes: 196 */ 197 STATIC int 198 bcmi_esw_preemption_unimac_mode_set(int unit, bcm_port_t port, 199 uint32 value) 200 { 201 return soc_reg_field32_modify(unit, MAC_MERGE_CONFIGr, 202 port, PREEMPTION_MODEf, 203 value ? 1 : 0); 204 } 205 206 /* 207 * Function: 208 * bcmi_esw_preemption_xlmac_mode_set 209 * Purpose: 210 * set preemption mode on xlmac 211 * Parameters: 212 * unit - (IN) unit number. 213 * port - (IN) port number 214 * value - (IN) value 215 * Returns: 216 * BCM_E_XXX 217 * Notes: 218 */ 219 STATIC int 220 bcmi_esw_preemption_xlmac_mode_set(int unit, bcm_port_t port, 221 uint32 value) 222 { 223 return soc_reg_field32_modify(unit, XLMAC_MERGE_CONFIGr, 224 port, PREEMPTION_MODEf, 225 value ? 1 : 0); 226 } 227 228 /* 229 * Function: 230 * bcmi_esw_preemption_unimac_mode_get 231 * Purpose: 232 * get preemption mode on unimac 233 * Parameters: 234 * unit - (IN) unit number. 235 * port - (IN) port number 236 * value - (OUT) value 237 * Returns: 238 * BCM_E_XXX 239 * Notes: 240 */ 241 STATIC int 242 bcmi_esw_preemption_unimac_mode_get(int unit, bcm_port_t port, 243 uint32* value) 244 { 245 uint64 regval64; 246 247 if (NULL == value) { 248 return SOC_E_PARAM; 249 } 250 BCM_IF_ERROR_RETURN(soc_reg_get(unit, MAC_MERGE_CONFIGr, port, 251 0, ®val64)); 252 *value = soc_reg64_field32_get(unit, MAC_MERGE_CONFIGr, 253 regval64, PREEMPTION_MODEf); 254 return BCM_E_NONE; 255 } 256 257 /* 258 * Function: 259 * bcmi_esw_preemption_xlmac_mode_get 260 * Purpose: 261 * get preemption mode on xlmac 262 * Parameters: 263 * unit - (IN) unit number. 264 * port - (IN) port number 265 * value - (OUT) value 266 * Returns: 267 * BCM_E_XXX 268 * Notes: 269 */ 270 STATIC int 271 bcmi_esw_preemption_xlmac_mode_get(int unit, bcm_port_t port, 272 uint32* value) 273 { 274 uint64 regval64; 275 276 if (NULL == value) { 277 return SOC_E_PARAM; 278 } 279 BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_MERGE_CONFIGr, port, 280 0, ®val64)); 281 *value = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr, 282 regval64, PREEMPTION_MODEf); 283 return BCM_E_NONE; 284 } 285 286 /* 287 * Function: 288 * bcmi_esw_preemption_unimac_verify_config_set 289 * Purpose: 290 * set preemption verify config on unimac 291 * Parameters: 292 * unit - (IN) unit number. 293 * port - (IN) port number 294 * type - (IN) bcmPortPreemptControlXXXX 295 * value - (OUT) value 296 * Returns: 297 * BCM_E_XXX 298 * Notes: 299 */ 300 STATIC int 301 bcmi_esw_preemption_unimac_verify_config_set(int unit, bcm_port_t port, 302 bcm_port_preempt_control_t type, 303 uint32 value) 304 305 { 306 uint32 hw_value; 307 soc_field_t field; 308 309 switch(type) { 310 case bcmPortPreemptControlVerifyTime: 311 field = VERIFY_TIMEf; 312 break; 313 case bcmPortPreemptControlVerifyAttempts: 314 field = VERIFY_ATTEMPT_LIMITf; 315 break; 316 default: 317 return BCM_E_PARAM; 318 } 319 320 if (value < 1) { 321 return BCM_E_PARAM; 322 } 323 if (value > (1 << soc_reg_field_length(unit, MAC_MERGE_CONFIGr, 324 field))) { 325 return BCM_E_PARAM; 326 } 327 hw_value = value - 1; 328 return soc_reg_field32_modify(unit, MAC_MERGE_CONFIGr, port, 329 field, hw_value); 330 } 331 332 /* 333 * Function: 334 * bcmi_esw_preemption_xlmac_verify_config_set 335 * Purpose: 336 * set preemption verify config on xlmac 337 * Parameters: 338 * unit - (IN) unit number. 339 * port - (IN) port number 340 * type - (IN) bcmPortPreemptControlXXXX 341 * value - (IN) value 342 * Returns: 343 * BCM_E_XXX 344 * Notes: 345 */ 346 STATIC int 347 bcmi_esw_preemption_xlmac_verify_config_set(int unit, bcm_port_t port, 348 bcm_port_preempt_control_t type, 349 uint32 value) 350 351 { 352 uint32 hw_value; 353 soc_field_t field; 354 355 switch(type) { 356 case bcmPortPreemptControlVerifyTime: 357 field = VERIFY_TIMEf; 358 break; 359 case bcmPortPreemptControlVerifyAttempts: 360 field = VERIFY_ATTEMPT_LIMITf; 361 break; 362 default: 363 return BCM_E_PARAM; 364 } 365 366 if (value < 1) { 367 return BCM_E_PARAM; 368 } 369 if (value > (1 << soc_reg_field_length(unit, XLMAC_MERGE_CONFIGr, 370 field))) { 371 return BCM_E_PARAM; 372 } 373 hw_value = value - 1; 374 return soc_reg_field32_modify(unit, XLMAC_MERGE_CONFIGr, port, 375 field, hw_value); 376 } 377 378 379 /* 380 * Function: 381 * bcmi_esw_preemption_unimac_verify_config_get 382 * Purpose: 383 * get preemption verify config on unimac 384 * Parameters: 385 * unit - (IN) unit number. 386 * port - (IN) port number 387 * type - (IN) bcmPortPreemptControlXXXX 388 * value - (OUT) value 389 * Returns: 390 * BCM_E_XXX 391 * Notes: 392 */ 393 STATIC int 394 bcmi_esw_preemption_unimac_verify_config_get(int unit, bcm_port_t port, 395 bcm_port_preempt_control_t type, 396 uint32* value) 397 398 { 399 uint64 regval64; 400 soc_field_t field; 401 402 if (NULL == value) { 403 return SOC_E_PARAM; 404 } 405 switch(type) { 406 case bcmPortPreemptControlVerifyTime: 407 field = VERIFY_TIMEf; 408 break; 409 case bcmPortPreemptControlVerifyAttempts: 410 field = VERIFY_ATTEMPT_LIMITf; 411 break; 412 default: 413 return BCM_E_PARAM; 414 } 415 BCM_IF_ERROR_RETURN(soc_reg_get(unit, MAC_MERGE_CONFIGr, port, 416 0, ®val64)); 417 *value = soc_reg64_field32_get(unit, MAC_MERGE_CONFIGr, 418 regval64, field) + 1; 419 return BCM_E_NONE; 420 } 421 422 /* 423 * Function: 424 * bcmi_esw_preemption_xlmac_verify_config_get 425 * Purpose: 426 * get preemption verify config on xlmac 427 * Parameters: 428 * unit - (IN) unit number. 429 * port - (IN) port number 430 * type - (IN) bcmPortPreemptControlXXXX 431 * value - (OUT) value 432 * Returns: 433 * BCM_E_XXX 434 * Notes: 435 */ 436 STATIC int 437 bcmi_esw_preemption_xlmac_verify_config_get(int unit, bcm_port_t port, 438 bcm_port_preempt_control_t type, 439 uint32* value) 440 441 { 442 uint64 regval64; 443 soc_field_t field; 444 445 if (NULL == value) { 446 return SOC_E_PARAM; 447 } 448 switch(type) { 449 case bcmPortPreemptControlVerifyTime: 450 field = VERIFY_TIMEf; 451 break; 452 case bcmPortPreemptControlVerifyAttempts: 453 field = VERIFY_ATTEMPT_LIMITf; 454 break; 455 default: 456 return BCM_E_PARAM; 457 } 458 BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_MERGE_CONFIGr, port, 459 0, ®val64)); 460 *value = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr, 461 regval64, field) + 1; 462 return BCM_E_NONE; 463 } 464 465 /* 466 * Function: 467 * bcmi_esw_preemption_unimac_frag_config_rx_set 468 * Purpose: 469 * set preemption fragment config on unimac 470 * Parameters: 471 * unit - (IN) unit number. 472 * port - (IN) port number 473 * type - (IN) bcmPortPreemptControlXXXX 474 * value - (IN) value 475 * Returns: 476 * BCM_E_XXX 477 * Notes: 478 */ 479 STATIC int 480 bcmi_esw_preemption_unimac_frag_config_rx_set(int unit, bcm_port_t port, 481 bcm_port_preempt_control_t type, 482 uint32 value) 483 { 484 uint32 hw_value; 485 bcm_port_t phy_port = port; 486 int i,pindex = -1; 487 int found = 0; 488 int is_final = 1; 489 soc_reg_t reg[8]={GE0_MIN_FRAG_SIZEr, 490 GE1_MIN_FRAG_SIZEr, 491 GE2_MIN_FRAG_SIZEr, 492 GE3_MIN_FRAG_SIZEr, 493 GE4_MIN_FRAG_SIZEr, 494 GE5_MIN_FRAG_SIZEr, 495 GE6_MIN_FRAG_SIZEr, 496 GE7_MIN_FRAG_SIZEr}; 497 498 switch (type) { 499 case bcmPortPreemptControlNonFinalFragSizeRx: 500 is_final = 0; 501 /* coverity[fallthrough:FALSE] */ 502 case bcmPortPreemptControlFinalFragSizeRx: 503 if (value > 512 || value < 64 || value % 8) { 504 return BCM_E_PARAM; 505 } 506 hw_value = value / 8; 507 if (soc_feature(unit, soc_feature_logical_port_num)) { 508 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 509 } 510 for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) { 511 int block = SOC_PORT_IDX_BLOCK(unit, phy_port, i); 512 if (SOC_BLK_GPORT == SOC_BLOCK_TYPE(unit, block)) { 513 pindex = SOC_PORT_IDX_BINDEX(unit, phy_port, i); 514 found = 1; 515 break; 516 } 517 } 518 if (0 == found || pindex < 0 || pindex > 7) { 519 return BCM_E_INTERNAL; 520 } 521 return soc_reg_field32_modify(unit, reg[pindex], port, 522 (is_final ? FINAL_FRAGf: 523 NON_FINAL_FRAGf), 524 hw_value); 525 default: 526 return BCM_E_PARAM; 527 } 528 } 529 530 /* 531 * Function: 532 * bcmi_esw_preemption_xlmac_frag_config_rx_set 533 * Purpose: 534 * set preemption fragment config on xlmac 535 * Parameters: 536 * unit - (IN) unit number. 537 * port - (IN) port number 538 * type - (IN) bcmPortPreemptControlXXXX 539 * value - (IN) value 540 * Returns: 541 * BCM_E_XXX 542 * Notes: 543 */ 544 STATIC int 545 bcmi_esw_preemption_xlmac_frag_config_rx_set(int unit, bcm_port_t port, 546 bcm_port_preempt_control_t type, 547 uint32 value) 548 { 549 uint32 hw_value; 550 int is_final = 1; 551 552 switch (type) { 553 case bcmPortPreemptControlNonFinalFragSizeRx: 554 is_final = 0; 555 /* coverity[fallthrough:FALSE] */ 556 case bcmPortPreemptControlFinalFragSizeRx: 557 if (value > 512 || value < 64 || value % 8) { 558 return BCM_E_PARAM; 559 } 560 hw_value = value / 8; 561 return soc_reg_field32_modify(unit, XLPORT_MIB_MIN_FRAG_SIZEr, port, 562 (is_final ? MIN_FINAL_FRAG_SIZEf: 563 MIN_NON_FINAL_FRAG_SIZEf), 564 hw_value); 565 default: 566 return BCM_E_PARAM; 567 } 568 } 569 570 /* 571 * Function: 572 * bcmi_esw_preemption_unimac_frag_config_rx_get 573 * Purpose: 574 * get preemption fragment config on unimac 575 * Parameters: 576 * unit - (IN) unit number. 577 * port - (IN) port number 578 * type - (IN) bcmPortPreemptControlXXXX 579 * value - (OUT) value 580 * Returns: 581 * BCM_E_XXX 582 * Notes: 583 */ 584 STATIC int 585 bcmi_esw_preemption_unimac_frag_config_rx_get(int unit, bcm_port_t port, 586 bcm_port_preempt_control_t type, 587 uint32* value) 588 { 589 bcm_port_t phy_port = port; 590 int i,pindex = -1; 591 int found = 0; 592 uint64 regval64; 593 soc_reg_t reg[8]={GE0_MIN_FRAG_SIZEr, 594 GE1_MIN_FRAG_SIZEr, 595 GE2_MIN_FRAG_SIZEr, 596 GE3_MIN_FRAG_SIZEr, 597 GE4_MIN_FRAG_SIZEr, 598 GE5_MIN_FRAG_SIZEr, 599 GE6_MIN_FRAG_SIZEr, 600 GE7_MIN_FRAG_SIZEr}; 601 int is_final = 1; 602 603 if (NULL == value) { 604 return SOC_E_PARAM; 605 } 606 switch (type) { 607 case bcmPortPreemptControlNonFinalFragSizeRx: 608 is_final = 0; 609 /* coverity[fallthrough:FALSE] */ 610 case bcmPortPreemptControlFinalFragSizeRx: 611 if (soc_feature(unit, soc_feature_logical_port_num)) { 612 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 613 } 614 for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) { 615 int block = SOC_PORT_IDX_BLOCK(unit, phy_port, i); 616 if (SOC_BLK_GPORT == SOC_BLOCK_TYPE(unit, block)) { 617 pindex = SOC_PORT_IDX_BINDEX(unit, phy_port, i); 618 found = 1; 619 break; 620 } 621 } 622 if (0 == found || pindex < 0 || pindex > 7) { 623 return BCM_E_INTERNAL; 624 } 625 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg[pindex], 626 port, 0, ®val64)); 627 *value = soc_reg64_field32_get(unit, reg[pindex], regval64, 628 (is_final ? FINAL_FRAGf: 629 NON_FINAL_FRAGf)) * 8; 630 break; 631 default: 632 return BCM_E_PARAM; 633 } 634 return BCM_E_NONE; 635 } 636 637 /* 638 * Function: 639 * bcmi_esw_preemption_xlmac_frag_config_rx_get 640 * Purpose: 641 * get preemption fragment config on xlmac 642 * Parameters: 643 * unit - (IN) unit number. 644 * port - (IN) port number 645 * type - (IN) bcmPortPreemptControlXXXX 646 * value - (OUT) value 647 * Returns: 648 * BCM_E_XXX 649 * Notes: 650 */ 651 STATIC int 652 bcmi_esw_preemption_xlmac_frag_config_rx_get(int unit, bcm_port_t port, 653 bcm_port_preempt_control_t type, 654 uint32* value) 655 { 656 int is_final = 1; 657 uint64 regval64; 658 659 if (NULL == value) { 660 return SOC_E_PARAM; 661 } 662 switch (type) { 663 case bcmPortPreemptControlNonFinalFragSizeRx: 664 is_final = 0; 665 /* coverity[fallthrough:FALSE] */ 666 case bcmPortPreemptControlFinalFragSizeRx: 667 BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLPORT_MIB_MIN_FRAG_SIZEr, 668 port, 0, ®val64)); 669 *value = soc_reg64_field32_get(unit, 670 XLPORT_MIB_MIN_FRAG_SIZEr, 671 regval64, 672 (is_final ? MIN_FINAL_FRAG_SIZEf: 673 MIN_NON_FINAL_FRAG_SIZEf)) * 8; 674 break; 675 default: 676 return BCM_E_UNAVAIL; 677 } 678 return BCM_E_NONE; 679 } 680 681 /* 682 * Function: 683 * bcmi_esw_preemption_unimac_status_tx_get 684 * Purpose: 685 * get preemption tx status on unimac 686 * Parameters: 687 * unit - (IN) unit number. 688 * port - (IN) port number 689 * type - (IN) bcmPortPreemptControlXXXX 690 * value - (OUT) value 691 * Returns: 692 * BCM_E_XXX 693 * Notes: 694 */ 695 STATIC int 696 bcmi_esw_preemption_unimac_status_tx_get(int unit, bcm_port_t port, 697 uint32* value) 698 { 699 uint64 regval64; 700 701 if (NULL == value) { 702 return SOC_E_PARAM; 703 } 704 BCM_IF_ERROR_RETURN(soc_reg_get(unit, MAC_MERGE_VERIFY_STATEr, port, 705 0, ®val64)); 706 *value = soc_reg64_field32_get(unit, MAC_MERGE_VERIFY_STATEr, 707 regval64, PREEMPTION_TX_STATUSf); 708 if (*value > bcmPortPreemptStatusTxActive) { 709 return BCM_E_INTERNAL; 710 } else { 711 return BCM_E_NONE; 712 } 713 } 714 715 /* 716 * Function: 717 * bcmi_esw_preemption_xlmac_status_tx_get 718 * Purpose: 719 * get preemption tx status on xlmac 720 * Parameters: 721 * unit - (IN) unit number. 722 * port - (IN) port number 723 * type - (IN) bcmPortPreemptControlXXXX 724 * value - (OUT) value 725 * Returns: 726 * BCM_E_XXX 727 * Notes: 728 */ 729 STATIC int 730 bcmi_esw_preemption_xlmac_status_tx_get(int unit, bcm_port_t port, 731 uint32* value) 732 { 733 uint64 regval64; 734 735 if (NULL == value) { 736 return SOC_E_PARAM; 737 } 738 BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_MERGE_VERIFY_STATEr, port, 739 0, ®val64)); 740 *value = soc_reg64_field32_get(unit, XLMAC_MERGE_VERIFY_STATEr, 741 regval64, PREEMPTION_TX_STATUSf); 742 if (*value > bcmPortPreemptStatusTxActive) { 743 return BCM_E_INTERNAL; 744 } else { 745 return BCM_E_NONE; 746 } 747 } 748 749 /* 750 * Function: 751 * bcmi_esw_preemption_unimac_status_verify_get 752 * Purpose: 753 * get preemption verify status on unimac 754 * Parameters: 755 * unit - (IN) unit number. 756 * port - (IN) port number 757 * type - (IN) bcmPortPreemptControlXXXX 758 * value - (OUT) value 759 * Returns: 760 * BCM_E_XXX 761 * Notes: 762 */ 763 STATIC int 764 bcmi_esw_preemption_unimac_status_verify_get(int unit, bcm_port_t port, 765 uint32* value) 766 { 767 uint64 regval64; 768 769 if (NULL == value) { 770 return SOC_E_PARAM; 771 } 772 BCM_IF_ERROR_RETURN(soc_reg_get(unit, MAC_MERGE_VERIFY_STATEr, port, 773 0, ®val64)); 774 *value = soc_reg64_field32_get(unit, MAC_MERGE_VERIFY_STATEr, 775 regval64, PREEMPTION_VERIFY_STATUSf); 776 if (*value > bcmPortPreemptStatusVerifyFailed) { 777 return BCM_E_INTERNAL; 778 } else { 779 return BCM_E_NONE; 780 } 781 } 782 783 /* 784 * Function: 785 * bcmi_esw_preemption_xlmac_status_verify_get 786 * Purpose: 787 * get preemption verify status on xlmac 788 * Parameters: 789 * unit - (IN) unit number. 790 * port - (IN) port number 791 * type - (IN) bcmPortPreemptControlXXXX 792 * value - (OUT) value 793 * Returns: 794 * BCM_E_XXX 795 * Notes: 796 */ 797 STATIC int 798 bcmi_esw_preemption_xlmac_status_verify_get(int unit, bcm_port_t port, 799 uint32* value) 800 { 801 uint64 regval64; 802 803 if (NULL == value) { 804 return SOC_E_PARAM; 805 } 806 BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_MERGE_VERIFY_STATEr, port, 807 0, ®val64)); 808 *value = soc_reg64_field32_get(unit, XLMAC_MERGE_VERIFY_STATEr, 809 regval64, PREEMPTION_VERIFY_STATUSf); 810 if (*value > bcmPortPreemptStatusVerifyFailed) { 811 return BCM_E_INTERNAL; 812 } else { 813 return BCM_E_NONE; 814 } 815 } 816 817 /* 818 * Function: 819 * bcmi_esw_preemption_enable_tx_set 820 * Purpose: 821 * set preemption tx enable or not 822 * Parameters: 823 * unit - (IN) unit number. 824 * port - (IN) port number 825 * value - (IN) value 826 * Returns: 827 * BCM_E_XXX 828 * Notes: 829 */ 830 STATIC int 831 bcmi_esw_preemption_enable_tx_set(int unit, bcm_port_t port, uint32 value) 832 { 833 bcmi_port_mac_type_t mac_type; 834 835 BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port, 836 &mac_type)); 837 838 if (bcmiPortMacTypeXLmac == mac_type) { 839 return bcmi_esw_preemption_xlmac_enable_tx_set(unit, port, value); 840 } else if (bcmiPortMacTypeUnimac == mac_type) { 841 return bcmi_esw_preemption_unimac_enable_tx_set(unit, port, value); 842 } else { 843 return BCM_E_UNAVAIL; 844 } 845 } 846 847 /* 848 * Function: 849 * _bcmi_esw_preemption_enable_verify_set 850 * Purpose: 851 * helper function to set preemption verify enable or not in hw 852 * Parameters: 853 * unit - (IN) unit number. 854 * port - (IN) port number 855 * value - (IN) value 856 * Returns: 857 * BCM_E_XXX 858 * Notes: 859 */ 860 STATIC int 861 _bcmi_esw_preemption_enable_verify_set(int unit, bcm_port_t port, uint32 value) 862 { 863 bcmi_port_mac_type_t mac_type; 864 865 BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port, 866 &mac_type)); 867 if (bcmiPortMacTypeXLmac == mac_type) { 868 return bcmi_esw_preemption_xlmac_enable_verify_set(unit, port, value); 869 } else if (bcmiPortMacTypeUnimac == mac_type) { 870 return bcmi_esw_preemption_unimac_enable_verify_set(unit, port, value); 871 } else { 872 return BCM_E_UNAVAIL; 873 } 874 } 875 876 /* 877 * Function: 878 * bcmi_esw_preemption_enable_verify_set 879 * Purpose: 880 * set preemption verify enable or not 881 * write sw cache first, then write hw only when port link up 882 * Parameters: 883 * unit - (IN) unit number. 884 * port - (IN) port number 885 * value - (IN) value 886 * Returns: 887 * BCM_E_XXX 888 * Notes: 889 */ 890 STATIC int 891 bcmi_esw_preemption_enable_verify_set(int unit, bcm_port_t port, uint32 value) 892 { 893 bcmi_port_mac_type_t mac_type; 894 895 BCM_IF_ERROR_RETURN( 896 bcmi_esw_port_mac_type_get(unit, port, &mac_type)); 897 898 if (bcmiPortMacTypeXLmac == mac_type || bcmiPortMacTypeUnimac == mac_type) { 899 int link_up; 900 901 BCM_IF_ERROR_RETURN( 902 bcm_esw_port_link_status_get(unit, port, &link_up)); 903 904 if (link_up) { 905 /* write it into hw only when port is link up */ 906 BCM_IF_ERROR_RETURN( 907 _bcmi_esw_preemption_enable_verify_set(unit, port, value)); 908 } 909 910 PREEMPTION_LOCK(unit); 911 if (value) { 912 SOC_PBMP_PORT_ADD(pbmp_verify_enable_cache[unit], port); 913 } else { 914 SOC_PBMP_PORT_REMOVE(pbmp_verify_enable_cache[unit], port); 915 } 916 PREEMPTION_UNLOCK(unit); 917 } else { 918 return BCM_E_UNAVAIL; 919 } 920 921 return BCM_E_NONE; 922 } 923 924 /* 925 * Function: 926 * bcmi_esw_preemption_mode_set 927 * Purpose: 928 * set preemption mode 929 * Parameters: 930 * unit - (IN) unit number. 931 * port - (IN) port number 932 * value - (IN) value 933 * Returns: 934 * BCM_E_XXX 935 * Notes: 936 */ 937 STATIC int 938 bcmi_esw_preemption_mode_set(int unit, bcm_port_t port, uint32 value) 939 { 940 bcmi_port_mac_type_t mac_type; 941 942 BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port, 943 &mac_type)); 944 if (bcmiPortMacTypeXLmac == mac_type) { 945 return bcmi_esw_preemption_xlmac_mode_set(unit, port, value); 946 } else if (bcmiPortMacTypeUnimac == mac_type) { 947 return bcmi_esw_preemption_unimac_mode_set(unit, port, value); 948 } else { 949 return BCM_E_UNAVAIL; 950 } 951 } 952 953 /* 954 * Function: 955 * bcmi_esw_preemption_verify_config_set 956 * Purpose: 957 * set preemption verify config 958 * Parameters: 959 * unit - (IN) unit number. 960 * port - (IN) port number 961 * value - (IN) value 962 * Returns: 963 * BCM_E_XXX 964 * Notes: 965 */ 966 STATIC int 967 bcmi_esw_preemption_verify_config_set(int unit, bcm_port_t port, 968 bcm_port_preempt_control_t type, 969 uint32 value) 970 { 971 bcmi_port_mac_type_t mac_type; 972 973 BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port, 974 &mac_type)); 975 if (bcmiPortMacTypeXLmac == mac_type) { 976 return bcmi_esw_preemption_xlmac_verify_config_set(unit, port, type, value); 977 } else if (bcmiPortMacTypeUnimac == mac_type) { 978 return bcmi_esw_preemption_unimac_verify_config_set(unit, port, type, value); 979 } else { 980 return BCM_E_UNAVAIL; 981 } 982 } 983 984 /* 985 * Function: 986 * bcmi_esw_preemption_frag_config_rx_set 987 * Purpose: 988 * set preemption fragment config 989 * Parameters: 990 * unit - (IN) unit number. 991 * port - (IN) port number 992 * value - (IN) value 993 * Returns: 994 * BCM_E_XXX 995 * Notes: 996 */ 997 STATIC int 998 bcmi_esw_preemption_frag_config_rx_set(int unit, bcm_port_t port, 999 bcm_port_preempt_control_t type, 1000 uint32 value) 1001 { 1002 bcmi_port_mac_type_t mac_type; 1003 1004 BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port, 1005 &mac_type)); 1006 if (bcmiPortMacTypeXLmac == mac_type) { 1007 return bcmi_esw_preemption_xlmac_frag_config_rx_set(unit, port, type, value); 1008 } else if (bcmiPortMacTypeUnimac == mac_type) { 1009 return bcmi_esw_preemption_unimac_frag_config_rx_set(unit, port, type, value); 1010 } else { 1011 return BCM_E_UNAVAIL; 1012 } 1013 } 1014 1015 /* 1016 * Function: 1017 * bcmi_esw_preemption_enable_tx_get 1018 * Purpose: 1019 * get preemption tx enable or not 1020 * Parameters: 1021 * unit - (IN) unit number. 1022 * port - (IN) port number 1023 * value - (OUT) value 1024 * Returns: 1025 * BCM_E_XXX 1026 * Notes: 1027 */ 1028 STATIC int 1029 bcmi_esw_preemption_enable_tx_get(int unit, bcm_port_t port, uint32* value) 1030 { 1031 bcmi_port_mac_type_t mac_type; 1032 1033 BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port, 1034 &mac_type)); 1035 if (bcmiPortMacTypeXLmac == mac_type) { 1036 return bcmi_esw_preemption_xlmac_enable_tx_get(unit, port, value); 1037 } else if (bcmiPortMacTypeUnimac == mac_type) { 1038 return bcmi_esw_preemption_unimac_enable_tx_get(unit, port, value); 1039 } else { 1040 return BCM_E_UNAVAIL; 1041 } 1042 } 1043 1044 /* 1045 * Function: 1046 * bcmi_esw_preemption_enable_verify_get 1047 * Purpose: 1048 * get preemption verify enable or not 1049 * Parameters: 1050 * unit - (IN) unit number. 1051 * port - (IN) port number 1052 * value - (OUT) value 1053 * Returns: 1054 * BCM_E_XXX 1055 * Notes: 1056 */ 1057 STATIC int 1058 bcmi_esw_preemption_enable_verify_get(int unit, bcm_port_t port, uint32* value) 1059 { 1060 bcmi_port_mac_type_t mac_type; 1061 1062 if (NULL == value) { 1063 return BCM_E_PARAM; 1064 } 1065 BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port, 1066 &mac_type)); 1067 1068 if (bcmiPortMacTypeXLmac == mac_type || bcmiPortMacTypeUnimac == mac_type) { 1069 PREEMPTION_LOCK(unit); 1070 if (SOC_PBMP_MEMBER(pbmp_verify_enable_cache[unit], port)) { 1071 *value = 1; 1072 } else { 1073 *value = 0; 1074 } 1075 PREEMPTION_UNLOCK(unit); 1076 } else { 1077 return BCM_E_UNAVAIL; 1078 } 1079 1080 return BCM_E_NONE; 1081 } 1082 1083 /* 1084 * Function: 1085 * bcmi_esw_preemption_mode_get 1086 * Purpose: 1087 * get preemption mode 1088 * Parameters: 1089 * unit - (IN) unit number. 1090 * port - (IN) port number 1091 * value - (OUT) value 1092 * Returns: 1093 * BCM_E_XXX 1094 * Notes: 1095 */ 1096 STATIC int 1097 bcmi_esw_preemption_mode_get(int unit, bcm_port_t port, uint32* value) 1098 { 1099 bcmi_port_mac_type_t mac_type; 1100 1101 BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port, 1102 &mac_type)); 1103 if (bcmiPortMacTypeXLmac == mac_type) { 1104 return bcmi_esw_preemption_xlmac_mode_get(unit, port, value); 1105 } else if (bcmiPortMacTypeUnimac == mac_type) { 1106 return bcmi_esw_preemption_unimac_mode_get(unit, port, value); 1107 } else { 1108 return BCM_E_UNAVAIL; 1109 } 1110 } 1111 1112 /* 1113 * Function: 1114 * bcmi_esw_preemption_verify_config_get 1115 * Purpose: 1116 * get preemption verify config 1117 * Parameters: 1118 * unit - (IN) unit number. 1119 * port - (IN) port number 1120 * type - (IN) Preemption control type 1121 * value - (OUT) value 1122 * Returns: 1123 * BCM_E_XXX 1124 * Notes: 1125 */ 1126 STATIC int 1127 bcmi_esw_preemption_verify_config_get(int unit, bcm_port_t port, 1128 bcm_port_preempt_control_t type, 1129 uint32* value) 1130 { 1131 bcmi_port_mac_type_t mac_type; 1132 1133 BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port, 1134 &mac_type)); 1135 if (bcmiPortMacTypeXLmac == mac_type) { 1136 return bcmi_esw_preemption_xlmac_verify_config_get(unit, port, type, value); 1137 } else if (bcmiPortMacTypeUnimac == mac_type) { 1138 return bcmi_esw_preemption_unimac_verify_config_get(unit, port, type, value); 1139 } else { 1140 return BCM_E_UNAVAIL; 1141 } 1142 } 1143 1144 /* 1145 * Function: 1146 * bcmi_esw_preemption_frag_config_rx_get 1147 * Purpose: 1148 * get preemption fragment config 1149 * Parameters: 1150 * unit - (IN) unit number. 1151 * port - (IN) port number 1152 * type - (IN) Preemption control type 1153 * value - (OUT) value 1154 * Returns: 1155 * BCM_E_XXX 1156 * Notes: 1157 */ 1158 STATIC int 1159 bcmi_esw_preemption_frag_config_rx_get(int unit, bcm_port_t port, 1160 bcm_port_preempt_control_t type, 1161 uint32* value) 1162 { 1163 bcmi_port_mac_type_t mac_type; 1164 1165 BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port, 1166 &mac_type)); 1167 if (bcmiPortMacTypeXLmac == mac_type) { 1168 return bcmi_esw_preemption_xlmac_frag_config_rx_get(unit, port, type, value); 1169 } else if (bcmiPortMacTypeUnimac == mac_type) { 1170 return bcmi_esw_preemption_unimac_frag_config_rx_get(unit, port, type, value); 1171 } else { 1172 return BCM_E_UNAVAIL; 1173 } 1174 } 1175 1176 /* 1177 * Function: 1178 * bcmi_esw_preemption_status_tx_get 1179 * Purpose: 1180 * get preemption tx status 1181 * Parameters: 1182 * unit - (IN) unit number. 1183 * port - (IN) port number 1184 * value - (OUT) value 1185 * Returns: 1186 * BCM_E_XXX 1187 * Notes: 1188 */ 1189 int 1190 bcmi_esw_preemption_status_tx_get(int unit, bcm_port_t port, 1191 uint32* value) 1192 { 1193 bcmi_port_mac_type_t mac_type; 1194 1195 if (SOC_USE_PORTCTRL(unit)) { 1196 BCM_IF_ERROR_RETURN(bcmi_esw_portctrl_preemption_status_tx_get 1197 (unit, port, value)); 1198 return BCM_E_NONE; 1199 } 1200 BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port, 1201 &mac_type)); 1202 if (bcmiPortMacTypeXLmac == mac_type) { 1203 return bcmi_esw_preemption_xlmac_status_tx_get(unit, port, value); 1204 } else if (bcmiPortMacTypeUnimac == mac_type) { 1205 return bcmi_esw_preemption_unimac_status_tx_get(unit, port, value); 1206 } else { 1207 return BCM_E_UNAVAIL; 1208 } 1209 } 1210 1211 /* 1212 * Function: 1213 * bcmi_esw_preemption_status_verify_get 1214 * Purpose: 1215 * get preemption verify status 1216 * Parameters: 1217 * unit - (IN) unit number. 1218 * port - (IN) port number 1219 * value - (OUT) value 1220 * Returns: 1221 * BCM_E_XXX 1222 * Notes: 1223 */ 1224 int 1225 bcmi_esw_preemption_status_verify_get(int unit, bcm_port_t port, 1226 uint32* value) 1227 { 1228 bcmi_port_mac_type_t mac_type; 1229 if (SOC_USE_PORTCTRL(unit)) { 1230 BCM_IF_ERROR_RETURN(bcmi_esw_portctrl_preemption_status_verify_get 1231 (unit, port, value)); 1232 return BCM_E_NONE; 1233 } 1234 1235 BCM_IF_ERROR_RETURN(bcmi_esw_port_mac_type_get(unit, port, 1236 &mac_type)); 1237 if (bcmiPortMacTypeXLmac == mac_type) { 1238 return bcmi_esw_preemption_xlmac_status_verify_get(unit, port, value); 1239 } else if (bcmiPortMacTypeUnimac == mac_type) { 1240 return bcmi_esw_preemption_unimac_status_verify_get(unit, port, value); 1241 } else { 1242 return BCM_E_UNAVAIL; 1243 } 1244 } 1245 1246 /* 1247 * Function: 1248 * bcmi_esw_preemption_mac_config_set 1249 * Purpose: 1250 * set preemption mac config 1251 * Parameters: 1252 * unit - (IN) unit number. 1253 * port - (IN) port number 1254 * type - (IN) Preemption control type 1255 * arg - (IN) value 1256 * Returns: 1257 * BCM_E_XXX 1258 * Notes: 1259 */ 1260 int 1261 bcmi_esw_preemption_mac_config_set(int unit, bcm_port_t port, 1262 bcm_port_preempt_control_t type, 1263 uint32 arg) 1264 { 1265 1266 if (SOC_USE_PORTCTRL(unit)) { 1267 #if defined(BCM_MONTEREY_SUPPORT) 1268 if (SOC_IS_MONTEREY(unit) && 1269 ((type == bcmPortPreemptControlFinalFragSizeRx) || 1270 (type == bcmPortPreemptControlNonFinalFragSizeRx))) { 1271 if ((arg < 64) || (arg > 512)) { 1272 return BCM_E_PARAM; 1273 } 1274 arg = (arg + 7) / 8; 1275 } 1276 #endif 1277 BCM_IF_ERROR_RETURN(bcmi_esw_portctrl_preemption_mac_config_set 1278 (unit, port ,type, arg)); 1279 return BCM_E_NONE; 1280 } 1281 switch (type) { 1282 case bcmPortPreemptControlPreemptionSupport: 1283 return bcmi_esw_preemption_mode_set(unit, port, arg); 1284 1285 case bcmPortPreemptControlEnableTx: 1286 return bcmi_esw_preemption_enable_tx_set(unit, port, arg); 1287 1288 case bcmPortPreemptControlVerifyEnable: 1289 return bcmi_esw_preemption_enable_verify_set(unit, port, arg); 1290 1291 case bcmPortPreemptControlVerifyTime: 1292 case bcmPortPreemptControlVerifyAttempts: 1293 return bcmi_esw_preemption_verify_config_set(unit, port, 1294 type, arg); 1295 case bcmPortPreemptControlNonFinalFragSizeRx: 1296 case bcmPortPreemptControlFinalFragSizeRx: 1297 return bcmi_esw_preemption_frag_config_rx_set(unit, port, 1298 type, arg); 1299 default: 1300 return BCM_E_UNAVAIL; 1301 } 1302 } 1303 1304 /* 1305 * Function: 1306 * bcmi_esw_preemption_mac_config_get 1307 * Purpose: 1308 * get preemption mac config 1309 * Parameters: 1310 * unit - (IN) unit number. 1311 * port - (IN) port number 1312 * type - (IN) Preemption control type 1313 * arg - (OUT) value 1314 * Returns: 1315 * BCM_E_XXX 1316 * Notes: 1317 */ 1318 int 1319 bcmi_esw_preemption_mac_config_get(int unit, bcm_port_t port, 1320 bcm_port_preempt_control_t type, 1321 uint32* arg) 1322 { 1323 if (SOC_USE_PORTCTRL(unit)) { 1324 BCM_IF_ERROR_RETURN(bcmi_esw_portctrl_preemption_mac_config_get 1325 (unit, port ,type, arg)); 1326 #if defined(BCM_MONTEREY_SUPPORT) 1327 if (SOC_IS_MONTEREY(unit) && 1328 ((type == bcmPortPreemptControlFinalFragSizeRx) || 1329 (type == bcmPortPreemptControlNonFinalFragSizeRx))) { 1330 *arg = *arg * 8; 1331 } 1332 #endif 1333 return BCM_E_NONE; 1334 } 1335 switch (type) { 1336 case bcmPortPreemptControlPreemptionSupport: 1337 return bcmi_esw_preemption_mode_get(unit, port, arg); 1338 1339 case bcmPortPreemptControlEnableTx: 1340 return bcmi_esw_preemption_enable_tx_get(unit, port, arg); 1341 1342 case bcmPortPreemptControlVerifyEnable: 1343 return bcmi_esw_preemption_enable_verify_get(unit, port, arg); 1344 1345 case bcmPortPreemptControlVerifyTime: 1346 case bcmPortPreemptControlVerifyAttempts: 1347 return bcmi_esw_preemption_verify_config_get(unit, port, 1348 type, arg); 1349 case bcmPortPreemptControlNonFinalFragSizeRx: 1350 case bcmPortPreemptControlFinalFragSizeRx: 1351 return bcmi_esw_preemption_frag_config_rx_get(unit, port, 1352 type, arg); 1353 default: 1354 return BCM_E_UNAVAIL; 1355 } 1356 } 1357 1358 /* 1359 * Function: 1360 * bcmi_esw_preemption_hold_request_mode_set 1361 * Purpose: 1362 * set preemption hold request mode 1363 * Parameters: 1364 * unit - (IN) unit number. 1365 * port - (IN) port number 1366 * arg - (IN) value 1367 * Returns: 1368 * BCM_E_XXX 1369 * Notes: 1370 */ 1371 int 1372 bcmi_esw_preemption_hold_request_mode_set(int unit, bcm_port_t port, 1373 uint32 arg) 1374 { 1375 #if defined(BCM_GREYHOUND2_SUPPORT) 1376 if (SOC_IS_GREYHOUND2(unit)) { 1377 return bcmi_gh2_preemption_hold_request_mode_set(unit, port, arg); 1378 } else 1379 #endif /* BCM_GREYHOUND2_SUPPORT */ 1380 { 1381 return BCM_E_UNAVAIL; 1382 } 1383 } 1384 1385 /* 1386 * Function: 1387 * bcmi_esw_preemption_capability_set 1388 * Purpose: 1389 * set preemption capability 1390 * Parameters: 1391 * unit - (IN) unit number. 1392 * port - (IN) port number 1393 * arg - (IN) value 1394 * Returns: 1395 * BCM_E_XXX 1396 * Notes: 1397 */ 1398 int 1399 bcmi_esw_preemption_capability_set(int unit, bcm_port_t port, 1400 uint32 arg) 1401 { 1402 int rv; 1403 1404 #if defined(BCM_GREYHOUND2_SUPPORT) 1405 if (SOC_IS_GREYHOUND2(unit)) { 1406 rv = bcmi_gh2_preemption_capability_set(unit, port, arg); 1407 } else 1408 #endif /* BCM_GREYHOUND2_SUPPORT */ 1409 #if defined(BCM_MONTEREY_SUPPORT) 1410 if (SOC_IS_MONTEREY(unit)) { 1411 rv = bcmi_mn_preemption_capability_set(unit, port, arg); 1412 } else 1413 #endif /* BCM_GREYHOUND2_SUPPORT */ 1414 { 1415 rv = BCM_E_UNAVAIL; 1416 } 1417 1418 if (BCM_SUCCESS(rv)) { 1419 rv = bcmi_esw_preemption_mac_config_set( 1420 unit, port, 1421 bcmPortPreemptControlPreemptionSupport, 1422 arg); 1423 } 1424 1425 return rv; 1426 } 1427 1428 /* 1429 * Function: 1430 * bcmi_esw_preemption_frag_config_tx_set 1431 * Purpose: 1432 * set preemption fragmentation config 1433 * Parameters: 1434 * unit - (IN) unit number. 1435 * port - (IN) port number 1436 * is_final - (IN) 1: final 0:non-final 1437 * arg - (IN) value 1438 * Returns: 1439 * BCM_E_XXX 1440 * Notes: 1441 */ 1442 int 1443 bcmi_esw_preemption_frag_config_tx_set(int unit, bcm_port_t port, 1444 int is_final, uint32 arg) 1445 { 1446 #if defined(BCM_GREYHOUND2_SUPPORT) 1447 if (SOC_IS_GREYHOUND2(unit)) { 1448 return bcmi_gh2_preemption_frag_config_tx_set(unit, port, is_final, arg); 1449 } 1450 #endif /* BCM_GREYHOUND2_SUPPORT */ 1451 #if defined(BCM_MONTEREY_SUPPORT) 1452 if (SOC_IS_MONTEREY(unit)) { 1453 return bcmi_mn_preemption_frag_config_tx_set(unit, port, is_final, arg); 1454 } 1455 #endif /* BCM_MONTEREY_SUPPORT */ 1456 { 1457 return BCM_E_UNAVAIL; 1458 } 1459 } 1460 1461 /* 1462 * Function: 1463 * bcmi_esw_preemption_queue_bitmap_set 1464 * Purpose: 1465 * set preemption queue bitmap 1466 * Parameters: 1467 * unit - (IN) unit number. 1468 * port - (IN) port number 1469 * arg - (IN) value 1470 * Returns: 1471 * BCM_E_XXX 1472 * Notes: 1473 */ 1474 int 1475 bcmi_esw_preemption_queue_bitmap_set(int unit, bcm_port_t port, 1476 uint32 arg) 1477 { 1478 #if defined(BCM_GREYHOUND2_SUPPORT) 1479 if (SOC_IS_GREYHOUND2(unit)) { 1480 return bcmi_gh2_preemption_queue_bitmap_set(unit, port, arg); 1481 } else 1482 #endif /* BCM_GREYHOUND2_SUPPORT */ 1483 #if defined(BCM_MONTEREY_SUPPORT) 1484 if (SOC_IS_MONTEREY(unit)) { 1485 return bcmi_mn_preemption_queue_bitmap_set(unit, port, arg); 1486 } else 1487 #endif /* BCM_MONTEREY_SUPPORT */ 1488 { 1489 return BCM_E_UNAVAIL; 1490 } 1491 } 1492 1493 /* 1494 * Function: 1495 * bcmi_esw_preemption_hold_request_mode_get 1496 * Purpose: 1497 * get preemption hold request mode 1498 * Parameters: 1499 * unit - (IN) unit number. 1500 * port - (IN) port number 1501 * arg - (OUT) value 1502 * Returns: 1503 * BCM_E_XXX 1504 * Notes: 1505 */ 1506 int 1507 bcmi_esw_preemption_hold_request_mode_get(int unit, bcm_port_t port, 1508 uint32* arg) 1509 { 1510 #if defined(BCM_GREYHOUND2_SUPPORT) 1511 if (SOC_IS_GREYHOUND2(unit)) { 1512 return bcmi_gh2_preemption_hold_request_mode_get(unit, port, arg); 1513 } else 1514 #endif /* BCM_GREYHOUND2_SUPPORT */ 1515 { 1516 return BCM_E_UNAVAIL; 1517 } 1518 } 1519 1520 /* 1521 * Function: 1522 * bcmi_esw_preemption_capability_get 1523 * Purpose: 1524 * get preemption capability 1525 * Parameters: 1526 * unit - (IN) unit number. 1527 * port - (IN) port number 1528 * arg - (OUT) value 1529 * Returns: 1530 * BCM_E_XXX 1531 * Notes: 1532 */ 1533 int 1534 bcmi_esw_preemption_capability_get(int unit, bcm_port_t port, 1535 uint32* arg) 1536 { 1537 #if defined(BCM_GREYHOUND2_SUPPORT) 1538 if (SOC_IS_GREYHOUND2(unit)) { 1539 return bcmi_gh2_preemption_capability_get(unit, port, arg); 1540 } else 1541 #endif /* BCM_GREYHOUND2_SUPPORT */ 1542 #if defined(BCM_MONTEREY_SUPPORT) 1543 if (SOC_IS_MONTEREY(unit)) { 1544 return bcmi_mn_preemption_capability_get(unit, port, arg); 1545 } else 1546 #endif /* BCM_MONTEREY_SUPPORT */ 1547 { 1548 return BCM_E_UNAVAIL; 1549 } 1550 } 1551 1552 /* 1553 * Function: 1554 * bcmi_esw_preemption_queue_bitmap_get 1555 * Purpose: 1556 * get preemption queue bitmap 1557 * Parameters: 1558 * unit - (IN) unit number. 1559 * port - (IN) port number 1560 * arg - (OUT) value 1561 * Returns: 1562 * BCM_E_XXX 1563 * Notes: 1564 */ 1565 int 1566 bcmi_esw_preemption_queue_bitmap_get(int unit, bcm_port_t port, 1567 uint32* arg) 1568 { 1569 #if defined(BCM_GREYHOUND2_SUPPORT) 1570 if (SOC_IS_GREYHOUND2(unit)) { 1571 return bcmi_gh2_preemption_queue_bitmap_get(unit, port, arg); 1572 } else 1573 #endif /* BCM_GREYHOUND2_SUPPORT */ 1574 #if defined(BCM_MONTEREY_SUPPORT) 1575 if (SOC_IS_MONTEREY(unit)) { 1576 return bcmi_mn_preemption_queue_bitmap_get(unit, port, arg); 1577 } else 1578 #endif /* BCM_MONTEREY_SUPPORT */ 1579 { 1580 return BCM_E_UNAVAIL; 1581 } 1582 } 1583 1584 /* 1585 * Function: 1586 * bcmi_esw_preemption_frag_config_tx_get 1587 * Purpose: 1588 * get preemption tx fragmentation config 1589 * Parameters: 1590 * unit - (IN) unit number. 1591 * port - (IN) port number 1592 * is_final - (IN) 1: final 0:non-final 1593 * arg - (OUT) value 1594 * Returns: 1595 * BCM_E_XXX 1596 * Notes: 1597 */ 1598 int 1599 bcmi_esw_preemption_frag_config_tx_get(int unit, bcm_port_t port, 1600 int is_final, uint32* arg) 1601 { 1602 #if defined(BCM_GREYHOUND2_SUPPORT) 1603 if (SOC_IS_GREYHOUND2(unit)) { 1604 return bcmi_gh2_preemption_frag_config_tx_get(unit, port, is_final, arg); 1605 } 1606 #endif /* BCM_GREYHOUND2_SUPPORT */ 1607 #if defined(BCM_MONTEREY_SUPPORT) 1608 if (SOC_IS_MONTEREY(unit)) { 1609 return bcmi_mn_preemption_frag_config_tx_get(unit, port, is_final, arg); 1610 } 1611 #endif /* BCM_MONTEREY_SUPPORT */ 1612 { 1613 return BCM_E_UNAVAIL; 1614 } 1615 } 1616 1617 1618 void bcmi_esw_preemption_linkscan_update(int unit, 1619 bcm_port_t port, 1620 bcm_port_info_t *portInfo) 1621 { 1622 int enable_in_cache; 1623 1624 PREEMPTION_LOCK(unit); 1625 enable_in_cache = SOC_PBMP_MEMBER(pbmp_verify_enable_cache[unit], port); 1626 PREEMPTION_UNLOCK(unit); 1627 1628 if (portInfo->linkstatus == BCM_PORT_LINK_STATUS_DOWN) { 1629 if (enable_in_cache) { 1630 int rv = _bcmi_esw_preemption_enable_verify_set(unit, port, 0); 1631 if (BCM_SUCCESS(rv)) { 1632 LOG_VERBOSE( 1633 BSL_LS_BCM_PORT, 1634 (BSL_META("Disable verify on port %d when link down\n"), 1635 port)); 1636 } 1637 } 1638 } else if (portInfo->linkstatus == BCM_PORT_LINK_STATUS_UP) { 1639 if (enable_in_cache) { 1640 int rv = _bcmi_esw_preemption_enable_verify_set(unit, port, 1); 1641 if (BCM_SUCCESS(rv)) { 1642 LOG_VERBOSE( 1643 BSL_LS_BCM_PORT, 1644 (BSL_META("re-enable verify on port %d when link up\n"), 1645 port)); 1646 } 1647 } 1648 } 1649 } 1650 1651 void bcmi_esw_preemption_cleanup(int unit) 1652 { 1653 if (NULL != verify_enable_cache_mutex[unit]) { 1654 sal_mutex_destroy(verify_enable_cache_mutex[unit]); 1655 verify_enable_cache_mutex[unit] = NULL; 1656 } 1657 } 1658 1659 int bcmi_esw_preemption_init(int unit) 1660 { 1661 #ifdef BCM_MONTEREY_SUPPORT 1662 if(SOC_IS_MONTEREY(unit)) { 1663 BCM_IF_ERROR_RETURN( 1664 bcmi_mn_preemption_init(unit)); 1665 } 1666 #endif 1667 1668 SOC_PBMP_CLEAR(pbmp_verify_enable_cache[unit]); 1669 1670 verify_enable_cache_mutex[unit] = sal_mutex_create("preempt_mutex"); 1671 if (NULL == verify_enable_cache_mutex[unit]) { 1672 bcmi_esw_preemption_cleanup(unit); 1673 return BCM_E_INTERNAL; 1674 } 1675 return BCM_E_NONE; 1676 } 1677 1678 #ifdef BCM_WARM_BOOT_SUPPORT 1679 int bcmi_esw_preemption_sync(int unit, 1680 soc_scache_handle_t scache_handle) 1681 { 1682 uint8 *scache_ptr = NULL; 1683 1684 BCM_IF_ERROR_RETURN( 1685 _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, sizeof(soc_pbmp_t), 1686 &scache_ptr, 1687 BCM_PORT_WB_DEFAULT_VERSION, NULL)); 1688 1689 if (NULL == scache_ptr) { 1690 return BCM_E_INTERNAL; 1691 } 1692 PREEMPTION_LOCK(unit); 1693 sal_memcpy(scache_ptr, &pbmp_verify_enable_cache[unit], sizeof(soc_pbmp_t)); 1694 PREEMPTION_UNLOCK(unit); 1695 1696 return BCM_E_NONE; 1697 } 1698 1699 int bcmi_esw_preemption_wb_alloc(int unit, 1700 soc_scache_handle_t scache_handle) 1701 { 1702 int rv; 1703 uint8 *scache_ptr = NULL; 1704 1705 rv = _bcm_esw_scache_ptr_get( 1706 unit, scache_handle, TRUE, sizeof(soc_pbmp_t), 1707 &scache_ptr, BCM_PORT_WB_DEFAULT_VERSION, NULL); 1708 1709 if (BCM_E_NOT_FOUND == rv) { 1710 /* Maybe proceed with Level 1 Warm Boot */ 1711 return BCM_E_NONE; 1712 } else if (BCM_E_NONE == rv) { 1713 if (NULL == scache_ptr) { 1714 return BCM_E_INTERNAL; 1715 } 1716 } 1717 return rv; 1718 } 1719 1720 int bcmi_esw_preemption_recover(int unit, 1721 soc_scache_handle_t scache_handle) 1722 { 1723 int rv; 1724 uint8 *scache_ptr = NULL; 1725 1726 rv = _bcm_esw_scache_ptr_get( 1727 unit, scache_handle, FALSE, sizeof(soc_pbmp_t), 1728 &scache_ptr, BCM_PORT_WB_DEFAULT_VERSION, NULL); 1729 1730 if (BCM_E_NOT_FOUND == rv) { 1731 /* Maybe proceed with Level 1 Warm Boot */ 1732 return BCM_E_NONE; 1733 } else if (BCM_E_NONE == rv) { 1734 if (NULL == scache_ptr) { 1735 rv = BCM_E_INTERNAL; 1736 } else { 1737 PREEMPTION_LOCK(unit); 1738 sal_memcpy(&pbmp_verify_enable_cache[unit], scache_ptr, 1739 sizeof(soc_pbmp_t)); 1740 PREEMPTION_UNLOCK(unit); 1741 } 1742 } 1743 1744 return rv; 1745 } 1746 #endif /* BCM_WARM_BOOT_SUPPORT */ 1747 1748 1749 #endif /* BCM_PREEMPTION_SUPPORT */ 1750