tsn_taf.c (83651B)
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 * Purpose: 8 * Manage common functionality for TSN TAF implementation. 9 */ 10 11 #include <shared/bsl.h> 12 #include <soc/drv.h> 13 #include <soc/scache.h> 14 #include <bcm/port.h> 15 #include <bcm/error.h> 16 #include <bcm/types.h> 17 #include <bcm/tsn.h> 18 #include <bcm_int/esw/tsn.h> 19 #include <bcm_int/esw/tsn_taf.h> 20 #if defined(BCM_GREYHOUND2_SUPPORT) 21 #include <bcm_int/esw/greyhound2.h> 22 #endif /* BCM_GREYHOUND2_SUPPORT */ 23 #if defined(BCM_WARM_BOOT_SUPPORT) 24 #include <bcm/module.h> 25 #include <bcm_int/esw/switch.h> 26 #endif /* BCM_WARM_BOOT_SUPPORT */ 27 28 #if defined(BCM_TSN_SUPPORT) 29 typedef struct bcmi_tsn_taf_control_s { 30 sal_mutex_t taf_mutex; 31 const bcmi_tsn_taf_dev_info_t *taf_dev_info; 32 } bcmi_tsn_taf_control_t; 33 34 /* TSN stat control */ 35 STATIC bcmi_tsn_taf_control_t *taf_control[BCM_MAX_NUM_UNITS]; 36 37 /* TSN calendar profile */ 38 STATIC bcmi_tsn_taf_profile_t *taf_profile_pending 39 [SOC_MAX_NUM_DEVICES][BCMI_TSN_TAF_GATE_NUM]; 40 STATIC bcmi_tsn_taf_profile_t *taf_profile_active 41 [SOC_MAX_NUM_DEVICES][BCMI_TSN_TAF_GATE_NUM]; 42 43 /* helper macro */ 44 #define TSN_TAF_LOCK(tc) \ 45 sal_mutex_take((tc)->taf_mutex, sal_mutex_FOREVER) 46 #define TSN_TAF_UNLOCK(tc) \ 47 sal_mutex_give((tc)->taf_mutex) 48 49 #define TSN_TAF_INIT_ERROR_WITH_CLEAN(_op_) \ 50 do { \ 51 int _rv_ = (_op_); \ 52 if (BCM_FAILURE(_rv_)) { \ 53 bcmi_esw_tsn_taf_cleanup(unit); \ 54 return (_rv_); \ 55 } \ 56 } while (0) 57 58 /* helper macro to execute dispatched specific device function */ 59 #define TSN_TAF_FUNC(_name_, _args_) \ 60 ((NULL == taf_control[unit]->taf_dev_info-> \ 61 tsn_taf_##_name_) ? BCM_E_INIT : \ 62 (taf_control[unit]->taf_dev_info-> \ 63 tsn_taf_##_name_)_args_) 64 65 #define TSN_TAF_DATA(_name_) \ 66 (taf_control[unit]->taf_dev_info-> \ 67 tsn_taf_##_name_) 68 69 /* 70 * Function: 71 * bcmi_esw_tsn_taf_instance_get 72 * Description: 73 * Helper function to retrieve TAF control pointer 74 * Parameters: 75 * unit - (IN) BCM device number 76 * tc - (OUT) TAF control data structure 77 * Returns: 78 * BCM_E_XXX 79 */ 80 STATIC int 81 bcmi_esw_tsn_taf_instance_get( 82 int unit, 83 bcmi_tsn_taf_control_t **tc) 84 { 85 if (NULL == tc) { 86 return BCM_E_PARAM; 87 } 88 89 if (!soc_feature(unit, soc_feature_tsn_taf)) { 90 return BCM_E_UNAVAIL; 91 } 92 93 if (NULL == taf_control[unit]) { 94 return BCM_E_INIT; 95 } 96 97 *tc = taf_control[unit]; 98 return BCM_E_NONE; 99 } 100 #endif /* BCM_TSN_SUPPORT */ 101 102 /* 103 * Function: 104 * bcm_esw_tsn_taf_gate_create 105 * Description: 106 * Allocate TAF gate 107 * Parameters: 108 * unit - (IN) Unit number 109 * flags - (IN) flags, BCM_TSN_TAF_XXXX 110 * taf_gate_id - (OUT) taf gate 111 * Returns: 112 * BCM_E_XXX 113 */ 114 int 115 bcm_esw_tsn_taf_gate_create(int unit, int flags, int *taf_gate_id) 116 { 117 int rv = BCM_E_UNAVAIL; 118 119 #if defined(BCM_TSN_SUPPORT) 120 bcmi_tsn_taf_control_t *tc; 121 122 BCM_IF_ERROR_RETURN( 123 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 124 125 TSN_TAF_LOCK(tc); 126 rv = TSN_TAF_FUNC(gate_create, (unit, flags, taf_gate_id)); 127 TSN_TAF_UNLOCK(tc); 128 #endif /* BCM_TSN_SUPPORT */ 129 130 return rv; 131 } 132 133 /* 134 * Function: 135 * bcm_esw_tsn_taf_gate_traverse 136 * Description: 137 * Allocate TAF gate 138 * Parameters: 139 * unit - (IN) Unit number 140 * cb - (IN) A pointer to callback function to call 141 * for each taf gate. 142 * user_data - (IN) Pointer to user data to supply in the callback 143 * Returns: 144 * BCM_E_XXX 145 */ 146 int 147 bcm_esw_tsn_taf_gate_traverse( 148 int unit, 149 bcm_tsn_taf_gate_traverse_cb cb, 150 void *user_data) 151 { 152 int rv = BCM_E_UNAVAIL; 153 154 #if defined(BCM_TSN_SUPPORT) 155 bcmi_tsn_taf_control_t *tc; 156 157 BCM_IF_ERROR_RETURN( 158 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 159 160 TSN_TAF_LOCK(tc); 161 rv = TSN_TAF_FUNC(gate_traverse, (unit, cb, user_data)); 162 TSN_TAF_UNLOCK(tc); 163 #endif /* BCM_TSN_SUPPORT */ 164 165 return rv; 166 } 167 168 /* 169 * Function: 170 * bcm_esw_tsn_taf_gate_destroy 171 * Description: 172 * Free TAF gate 173 * Parameters: 174 * unit - (IN) Unit number 175 * taf_gate_id - (IN) taf gate 176 * Returns: 177 * BCM_E_XXX 178 */ 179 int 180 bcm_esw_tsn_taf_gate_destroy(int unit, int taf_gate_id) 181 { 182 int rv = BCM_E_UNAVAIL; 183 184 #if defined(BCM_TSN_SUPPORT) 185 bcmi_tsn_taf_control_t *tc; 186 187 BCM_IF_ERROR_RETURN( 188 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 189 190 TSN_TAF_LOCK(tc); 191 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 192 193 if (BCM_SUCCESS(rv)) { 194 rv = TSN_TAF_FUNC(gate_destroy, (unit, taf_gate_id)); 195 } 196 TSN_TAF_UNLOCK(tc); 197 #endif /* BCM_TSN_SUPPORT */ 198 199 return rv; 200 } 201 202 /* 203 * Function: 204 * bcm_esw_tsn_taf_status_get 205 * Description: 206 * Get the TAF gate status 207 * Parameters: 208 * unit - (IN) Unit number 209 * taf_gate_id - (IN) taf gate 210 * type - (IN) status type 211 * arg - (OUT)parameter 212 * Returns: 213 * BCM_E_XXX 214 */ 215 int 216 bcm_esw_tsn_taf_status_get( 217 int unit, 218 int taf_gate_id, 219 bcm_tsn_taf_status_t type, 220 uint32 *arg) 221 { 222 int rv = BCM_E_UNAVAIL; 223 224 #if defined(BCM_TSN_SUPPORT) 225 bcmi_tsn_taf_control_t *tc; 226 227 BCM_IF_ERROR_RETURN( 228 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 229 230 TSN_TAF_LOCK(tc); 231 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 232 233 if (BCM_SUCCESS(rv)) { 234 rv = TSN_TAF_FUNC(status_get, (unit, taf_gate_id, type, arg)); 235 } 236 TSN_TAF_UNLOCK(tc); 237 #endif /* BCM_TSN_SUPPORT */ 238 239 return rv; 240 } 241 242 /* 243 * Function: 244 * bcmi_esw_tsn_taf_port_control_set 245 * Description: 246 * Set various TAF configurations at specific port 247 * Parameters: 248 * unit - (IN) Unit number 249 * gport - (IN) gport 250 * type - (IN) control type 251 * arg - (IN) parameter 252 * Returns: 253 * BCM_E_XXX 254 */ 255 int 256 bcmi_esw_tsn_taf_port_control_set( 257 int unit, 258 bcm_gport_t gport, 259 bcm_tsn_control_t type, 260 uint32 arg) 261 { 262 int rv = BCM_E_UNAVAIL; 263 264 #if defined(BCM_TSN_SUPPORT) 265 bcmi_tsn_taf_control_t *tc; 266 267 BCM_IF_ERROR_RETURN( 268 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 269 270 TSN_TAF_LOCK(tc); 271 rv = TSN_TAF_FUNC(port_control_set, (unit, gport, type, arg)); 272 TSN_TAF_UNLOCK(tc); 273 #endif /* BCM_TSN_SUPPORT */ 274 275 return rv; 276 } 277 278 /* 279 * Function: 280 * bcmi_esw_tsn_taf_port_control_get 281 * Description: 282 * Get various TAF configurations at specific port 283 * Parameters: 284 * unit - (IN) Unit number 285 * gport - (IN) gport 286 * type - (IN) control type 287 * arg - (OUT) parameter 288 * Returns: 289 * BCM_E_XXX 290 */ 291 int 292 bcmi_esw_tsn_taf_port_control_get( 293 int unit, 294 bcm_gport_t gport, 295 bcm_tsn_control_t type, 296 uint32 *arg) 297 { 298 int rv = BCM_E_UNAVAIL; 299 300 #if defined(BCM_TSN_SUPPORT) 301 bcmi_tsn_taf_control_t *tc; 302 303 BCM_IF_ERROR_RETURN( 304 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 305 306 TSN_TAF_LOCK(tc); 307 rv = TSN_TAF_FUNC(port_control_get, (unit, gport, type, arg)); 308 TSN_TAF_UNLOCK(tc); 309 #endif /* BCM_TSN_SUPPORT */ 310 311 return rv; 312 } 313 314 #if defined(BCM_TSN_SUPPORT) 315 /* 316 * Function: 317 * bcmi_esw_tsn_taf_gate_pri_map_valid 318 * Purpose: 319 * helper function to check config valid or not 320 * Parameters: 321 * config - (IN) Priority Map configuration 322 * Returns: 323 * BCM_E_XXX 324 */ 325 326 STATIC int 327 bcmi_esw_tsn_taf_gate_pri_map_valid( 328 int unit, 329 bcm_tsn_pri_map_config_t *config) 330 { 331 int i; 332 int no_assign_any_gate = 1; 333 334 if (NULL == config) { 335 return BCM_E_PARAM; 336 } 337 338 if (config->map_type != bcmTsnPriMapTypeTafGate) { 339 return BCM_E_PARAM; 340 } 341 342 if (config->num_map_entries != TSN_TAF_DATA(gate_intpri_num)) { 343 return BCM_E_PARAM; 344 } 345 346 for (i = 0; i < config->num_map_entries; i++) { 347 uint32 valid_flags; 348 349 valid_flags = BCM_BCM_TSN_PRI_MAP_ENTRY_TAF_GATE_EXPRESS | 350 BCM_BCM_TSN_PRI_MAP_ENTRY_TAF_GATE_PREEMPT; 351 if (config->map_entries[i].flags & (~valid_flags)) { 352 return BCM_E_PARAM; 353 } 354 if (config->map_entries[i].flags & 355 BCM_BCM_TSN_PRI_MAP_ENTRY_TAF_GATE_EXPRESS) { 356 no_assign_any_gate = 0; 357 break; 358 } 359 if (config->map_entries[i].flags & 360 BCM_BCM_TSN_PRI_MAP_ENTRY_TAF_GATE_PREEMPT) { 361 no_assign_any_gate = 0; 362 break; 363 } 364 } 365 366 if (1 == no_assign_any_gate) { 367 return BCM_E_PARAM; 368 } else { 369 return BCM_E_NONE; 370 } 371 } 372 373 /* 374 * Function: 375 * bcmi_esw_tsn_taf_gate_pri_map_set 376 * Purpose: 377 * Set the Priority Map configuration to hardware 378 * Parameters: 379 * unit - (IN) Unit number 380 * sw_idx - (IN) SW memory index 381 * config - (OUT) Priority Map configuration 382 * Returns: 383 * BCM_E_XXX 384 */ 385 STATIC int 386 bcmi_esw_tsn_taf_gate_pri_map_set( 387 int unit, 388 uint32 sw_idx, 389 bcm_tsn_pri_map_config_t *config) 390 { 391 int rv = BCM_E_NONE; 392 bcmi_tsn_taf_control_t *tc; 393 int i; 394 395 if (NULL == config) { 396 return BCM_E_PARAM; 397 } 398 399 BCM_IF_ERROR_RETURN( 400 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 401 402 BCM_IF_ERROR_RETURN( 403 bcmi_esw_tsn_taf_gate_pri_map_valid(unit, config)); 404 405 TSN_TAF_LOCK(tc); 406 /* check all taf_gate id has been allocated first */ 407 for (i = 0; i < config->num_map_entries; i++) { 408 409 if (config->map_entries[i].flags & 410 BCM_BCM_TSN_PRI_MAP_ENTRY_TAF_GATE_EXPRESS) { 411 rv = TSN_TAF_FUNC(gate_check, 412 (unit, config->map_entries[i].taf_gate_express)); 413 if (BCM_FAILURE(rv)) { 414 break; 415 } 416 } 417 418 if (config->map_entries[i].flags & 419 BCM_BCM_TSN_PRI_MAP_ENTRY_TAF_GATE_PREEMPT) { 420 rv = TSN_TAF_FUNC(gate_check, 421 (unit, config->map_entries[i].taf_gate_preempt)); 422 if (BCM_FAILURE(rv)) { 423 break; 424 } 425 } 426 } 427 428 /* set priority map */ 429 if (BCM_SUCCESS(rv)) { 430 rv = TSN_TAF_FUNC(gate_pri_map_set, (unit, sw_idx, config)); 431 } 432 TSN_TAF_UNLOCK(tc); 433 434 return rv; 435 } 436 437 /* 438 * Function: 439 * bcmi_esw_tsn_taf_gate_pri_map_get 440 * Purpose: 441 * Get the Priority Map configuration to hardware 442 * Parameters: 443 * unit - (IN) Unit number 444 * sw_idx - (IN) SW memory index 445 * config - (OUT) Priority Map configuration 446 * Returns: 447 * BCM_E_XXX 448 */ 449 STATIC int 450 bcmi_esw_tsn_taf_gate_pri_map_get( 451 int unit, 452 uint32 sw_idx, 453 bcm_tsn_pri_map_config_t *config) 454 { 455 int rv = BCM_E_NONE; 456 bcmi_tsn_taf_control_t *tc; 457 458 BCM_IF_ERROR_RETURN( 459 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 460 461 TSN_TAF_LOCK(tc); 462 rv = TSN_TAF_FUNC(gate_pri_map_get, (unit, sw_idx, config)); 463 TSN_TAF_UNLOCK(tc); 464 465 return rv; 466 } 467 468 /* 469 * Function: 470 * bcmi_esw_tsn_taf_gate_wb_hw_existed 471 * Purpose: 472 * check if the HW existed value or not 473 * Parameters: 474 * unit - (IN) Unit being initialized 475 * sw_idx - (IN) SW memory index 476 * Returns: 477 * BCM_E_NOT_FOUND means HW doesn't exist 478 * BCM_E_NONE means HW existed 479 */ 480 STATIC int 481 bcmi_esw_tsn_taf_gate_pri_map_wb_hw_existed( 482 int unit, 483 uint32 sw_idx) 484 { 485 int rv = BCM_E_NONE; 486 bcmi_tsn_taf_control_t *tc; 487 bcm_tsn_pri_map_config_t config; 488 489 BCM_IF_ERROR_RETURN( 490 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 491 492 TSN_TAF_LOCK(tc); 493 rv = TSN_TAF_FUNC(gate_pri_map_get, (unit, sw_idx, &config)); 494 TSN_TAF_UNLOCK(tc); 495 496 if (BCM_SUCCESS(rv)) { 497 rv = bcmi_esw_tsn_taf_gate_pri_map_valid(unit, &config); 498 } 499 return rv; 500 } 501 502 503 /* 504 * Function: 505 * bcmi_esw_tsn_taf_gate_pri_map_delete 506 * Purpose: 507 * Delete the Priority Map configuration on hardware 508 * Parameters: 509 * unit - (IN) Unit number 510 * sw_idx - (IN) SW memory index 511 * Returns: 512 * BCM_E_XXX 513 */ 514 STATIC int 515 bcmi_esw_tsn_taf_gate_pri_map_delete( 516 int unit, 517 uint32 sw_idx) 518 { 519 int rv = BCM_E_NONE; 520 bcmi_tsn_taf_control_t *tc; 521 522 BCM_IF_ERROR_RETURN( 523 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 524 525 TSN_TAF_LOCK(tc); 526 rv = TSN_TAF_FUNC(gate_pri_map_delete, (unit, sw_idx)); 527 TSN_TAF_UNLOCK(tc); 528 529 return rv; 530 } 531 532 /* 533 * Function: 534 * bcmi_esw_tsn_taf_gate_pri_map_hw_idx_get 535 * Purpose: 536 * Get HW memory base index 537 * Parameters: 538 * unit - (IN) Unit number 539 * sw_idx - (IN) SW memory index 540 * hw_index - (OUT) HW memory base index 541 * Returns: 542 * BCM_E_XXX 543 */ 544 STATIC int 545 bcmi_esw_tsn_taf_gate_pri_map_hw_idx_get( 546 int unit, 547 uint32 sw_idx, 548 uint32 *hw_idx) 549 { 550 int rv = BCM_E_UNAVAIL; 551 552 /* simple sw/hw index conversion need not be protected by TAF lock 553 * invoke device-dispatched function directly 554 */ 555 #if defined(BCM_GREYHOUND2_SUPPORT) 556 if (SOC_IS_GREYHOUND2(unit)) { 557 rv = bcmi_gh2_taf_gate_pri_map_hw_idx_get(unit, sw_idx, hw_idx); 558 } 559 #endif /* BCM_GREYHOUND2_SUPPORT */ 560 561 return rv; 562 } 563 564 /* 565 * Function: 566 * bcmi_esw_tsn_taf_gate_pri_map_sw_idx_get 567 * Purpose: 568 * Get SW memory index 569 * Parameters: 570 * unit - (IN) Unit number 571 * hw_index - (IN) HW memory base index 572 * sw_idx - (OUT) SW memory index 573 * Returns: 574 * BCM_E_XXX 575 */ 576 STATIC int 577 bcmi_esw_tsn_taf_gate_pri_map_sw_idx_get( 578 int unit, 579 uint32 hw_idx, 580 uint32 *sw_idx) 581 { 582 int rv = BCM_E_UNAVAIL; 583 584 /* simple sw/hw index conversion need not be protected by TAF lock 585 * invoke device-dispatched function directly 586 */ 587 #if defined(BCM_GREYHOUND2_SUPPORT) 588 if (SOC_IS_GREYHOUND2(unit)) { 589 rv = bcmi_gh2_taf_gate_pri_map_sw_idx_get(unit, hw_idx, sw_idx); 590 } 591 #endif /* BCM_GREYHOUND2_SUPPORT */ 592 593 return rv; 594 } 595 #endif /* BCM_TSN_SUPPORT */ 596 597 /* 598 * Function: 599 * bcm_esw_tsn_taf_profile_create 600 * Purpose: 601 * Create a profile by specifying the profile settings including calendar 602 * table, ptp time information for PTP mode. 603 * A profile id will be assigned along with the settings. 604 * Parameters: 605 * unit - (IN) unit number 606 * taf_gate - (IN) TAF gate 607 * profile - (IN) Pointer to profile structure which specifies 608 * entries in calendar table, ptp time information 609 * for PTP mode 610 * pid - (OUT) profile id 611 * Returns: 612 * BCM_E_XXX 613 */ 614 int 615 bcm_esw_tsn_taf_profile_create( 616 int unit, 617 int taf_gate, 618 bcm_tsn_taf_profile_t *profile, 619 bcm_tsn_taf_profile_id_t *pid) 620 { 621 int rv = BCM_E_UNAVAIL; 622 623 #if defined(BCM_TSN_SUPPORT) 624 bcmi_tsn_taf_control_t *tc; 625 bcmi_tsn_taf_profile_t *profile_i; 626 627 BCM_IF_ERROR_RETURN( 628 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 629 630 TSN_TAF_LOCK(tc); 631 632 /* parameter check */ 633 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate)); 634 635 if (BCM_SUCCESS(rv)) { 636 rv = TSN_TAF_FUNC( 637 calendar_param_check, (unit, taf_gate, profile)); 638 } 639 640 /* create a internal profile with a new pid */ 641 if (BCM_SUCCESS(rv)) { 642 rv = TSN_TAF_FUNC( 643 calendar_profile_create, (unit, profile, pid, &profile_i)); 644 } 645 646 /* increase the ref_cnt for maxbyte and CosQ profile 647 * which are specified by the user 648 */ 649 if (BCM_SUCCESS(rv)) { 650 rv = TSN_TAF_FUNC( 651 calendar_resource_alloc, (unit, taf_gate, profile)); 652 } 653 654 /* copy the user data into internal profile database 655 * , and set the status as "Init" 656 */ 657 if (BCM_SUCCESS(rv)) { 658 profile_i->taf_gate = taf_gate; 659 profile_i->status = bcmTsnTafProfileInit; 660 COMPILER_64_SET(profile_i->config_change_time.seconds, 0, 0); 661 profile_i->config_change_time.nanoseconds = 0; 662 sal_memcpy(&(profile_i->data), profile, sizeof(bcm_tsn_taf_profile_t)); 663 } 664 TSN_TAF_UNLOCK(tc); 665 #endif /* BCM_TSN_SUPPORT */ 666 667 return rv; 668 } 669 670 /* 671 * Function: 672 * bcm_esw_tsn_taf_profile_set 673 * Purpose: 674 * Modify the profile information 675 * Parameters: 676 * unit - (IN) unit number 677 * taf_gate - (IN) TAF gate 678 * pid - (IN) profile id 679 * profile - (IN) pointer to profile structure 680 * Returns: 681 * BCM_E_XXX 682 */ 683 int 684 bcm_esw_tsn_taf_profile_set( 685 int unit, 686 int taf_gate, 687 bcm_tsn_taf_profile_id_t pid, 688 bcm_tsn_taf_profile_t *profile) 689 { 690 int rv = BCM_E_UNAVAIL; 691 692 #if defined(BCM_TSN_SUPPORT) 693 int schedule_exist; 694 bcmi_tsn_taf_control_t *tc; 695 bcmi_tsn_taf_profile_t *profile_i; 696 697 BCM_IF_ERROR_RETURN( 698 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 699 700 if (pid < 0 || pid >= BCMI_TSN_TAF_PROFILE_NUM_MAX) { 701 return BCM_E_PARAM; 702 } 703 704 TSN_TAF_LOCK(tc); 705 706 /* For the new input, check the parameter */ 707 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate)); 708 709 if (BCM_SUCCESS(rv)) { 710 rv = TSN_TAF_FUNC(calendar_param_check, (unit, taf_gate, profile)); 711 } 712 713 /* Get the previous internal data */ 714 if (BCM_SUCCESS(rv)) { 715 rv = TSN_TAF_FUNC(calendar_profile_get, (unit, pid, &profile_i)); 716 } 717 718 if (BCM_SUCCESS(rv)) { 719 if (profile_i->taf_gate != taf_gate) { 720 rv = BCM_E_PARAM; 721 } 722 } 723 724 /* cannot change if this profile has been operated in 725 * Pending or Active status 726 */ 727 if (BCM_SUCCESS(rv)) { 728 if (profile_i->status == bcmTsnTafProfilePending || 729 profile_i->status == bcmTsnTafProfileActive) { 730 rv = BCM_E_BUSY; 731 } 732 } 733 734 /* if this profile has already be scheduled as Committed status 735 * ==> try to re-create a new schedule entry 736 */ 737 if (BCM_SUCCESS(rv)) { 738 rv = TSN_TAF_FUNC(schedule_exist, (unit, profile_i, &schedule_exist)); 739 } 740 741 if (BCM_SUCCESS(rv) && 1 == schedule_exist && 742 bcmTsnTafProfileCommitted == profile_i->status) { 743 #if 1 744 rv = TSN_TAF_FUNC(schedule_insert, 745 (unit, taf_gate, 746 &(profile->ptp_base_time), 747 profile_i)); 748 #endif 749 750 } 751 752 /* increase the ref_cnt for the new maxbyte and CosQ profile id 753 * which are specified by the user 754 */ 755 if (BCM_SUCCESS(rv)) { 756 rv = TSN_TAF_FUNC( 757 calendar_resource_alloc, (unit, taf_gate, profile)); 758 } 759 760 /* decrease the ref_cnt for the previous maxbyte and CosQ profile id */ 761 if (BCM_SUCCESS(rv)) { 762 rv = TSN_TAF_FUNC( 763 calendar_resource_free, (unit, taf_gate, &(profile_i->data))); 764 } 765 766 /* reset its status as Init */ 767 if (BCM_SUCCESS(rv)) { 768 profile_i->status = bcmTsnTafProfileInit; 769 sal_memcpy(&(profile_i->data), profile, sizeof(bcm_tsn_taf_profile_t)); 770 } 771 TSN_TAF_UNLOCK(tc); 772 #endif /* BCM_TSN_SUPPORT */ 773 774 return rv; 775 } 776 777 /* 778 * Function: 779 * bcm_esw_tsn_taf_profile_get 780 * Purpose: 781 * Get the profile information by specifying the profile id. 782 * Parameters: 783 * unit - (IN) unit number 784 * taf_gate - (IN) TAF gate 785 * pid - (IN) profile id 786 * profile - (OUT) pointer to profile structure 787 * Returns: 788 * BCM_E_XXX 789 */ 790 int 791 bcm_esw_tsn_taf_profile_get( 792 int unit, 793 int taf_gate, 794 bcm_tsn_taf_profile_id_t pid, 795 bcm_tsn_taf_profile_t *profile) 796 { 797 int rv = BCM_E_UNAVAIL; 798 799 #if defined(BCM_TSN_SUPPORT) 800 bcmi_tsn_taf_control_t *tc; 801 bcmi_tsn_taf_profile_t *profile_i; 802 803 if (NULL == profile) { 804 return BCM_E_PARAM; 805 } 806 bcm_tsn_taf_profile_t_init(profile); 807 808 BCM_IF_ERROR_RETURN( 809 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 810 811 if (pid < 0 || pid >= BCMI_TSN_TAF_PROFILE_NUM_MAX) { 812 return BCM_E_PARAM; 813 } 814 815 TSN_TAF_LOCK(tc); 816 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate)); 817 818 if (BCM_SUCCESS(rv)) { 819 rv = TSN_TAF_FUNC(calendar_profile_get, (unit, pid, &profile_i)); 820 } 821 822 if (BCM_SUCCESS(rv)) { 823 if (profile_i->taf_gate != taf_gate) { 824 rv = BCM_E_PARAM; 825 } 826 } 827 828 if (BCM_SUCCESS(rv)) { 829 sal_memcpy(profile, &(profile_i->data), sizeof(bcm_tsn_taf_profile_t)); 830 } 831 TSN_TAF_UNLOCK(tc); 832 #endif /* BCM_TSN_SUPPORT */ 833 834 return rv; 835 } 836 837 #if defined(BCM_TSN_SUPPORT) 838 /* 839 * Function: 840 * bcmi_esw_tsn_taf_profile_pick_pending 841 * Purpose: 842 * helper function for ptp-mode 843 * pick a candidate from timeline to act in pending status 844 * Parameters: 845 * unit - (IN) unit number 846 * taf_gate - (IN) TAF gate 847 * pid - (IN) profile id 848 * status - (OUT) pointer to profile status structure 849 * Returns: 850 * BCM_E_XXX 851 */ 852 STATIC int 853 bcmi_esw_tsn_taf_profile_pick_pending( 854 int unit, 855 int taf_gate) 856 { 857 bcmi_tsn_taf_profile_t *candidate = NULL; 858 859 if (NULL != taf_profile_pending[unit][taf_gate]) { 860 /* skip this if there has already existed a pending entry */ 861 return BCM_E_NONE; 862 } 863 864 #if 1 865 BCM_IF_ERROR_RETURN( 866 TSN_TAF_FUNC( 867 schedule_pick, (unit, taf_gate, 868 taf_profile_active[unit][taf_gate], &candidate))); 869 #endif 870 871 872 873 if (NULL != candidate) { 874 /* kick off this schedule according to the schedule time 875 * if candidate existes 876 */ 877 BCM_IF_ERROR_RETURN( 878 TSN_TAF_FUNC(calendar_kickoff, 879 (unit, taf_gate, candidate))); 880 881 /* record this schedule time as final config change time in database */ 882 BCM_IF_ERROR_RETURN( 883 TSN_TAF_FUNC(schedule_get, 884 (unit, candidate, &(candidate->config_change_time)))); 885 886 /* remove schedule and change its status to pending */ 887 BCM_IF_ERROR_RETURN( 888 TSN_TAF_FUNC(schedule_remove, 889 (unit, taf_gate, candidate))); 890 candidate->status = bcmTsnTafProfilePending; 891 892 /* udpate current pending profile */ 893 taf_profile_pending[unit][taf_gate] = candidate; 894 } 895 return BCM_E_NONE; 896 } 897 #endif /* BCM_TSN_SUPPORT */ 898 899 /* 900 * Function: 901 * bcm_esw_tsn_taf_profile_commit 902 * Purpose: 903 * Commit the profile to indicate the profile is ready to write to hardware. 904 * Parameters: 905 * unit - (IN) unit number 906 * taf_gate - (IN) TAF gate 907 * pid - (IN) profile id 908 * Returns: 909 * BCM_E_XXX 910 */ 911 int 912 bcm_esw_tsn_taf_profile_commit( 913 int unit, 914 int taf_gate, 915 bcm_tsn_taf_profile_id_t pid) 916 { 917 int rv = BCM_E_UNAVAIL; 918 919 #if defined(BCM_TSN_SUPPORT) 920 uint32 use_ptp; 921 bcmi_tsn_taf_control_t *tc; 922 bcmi_tsn_taf_profile_t *profile_i; 923 924 BCM_IF_ERROR_RETURN( 925 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 926 927 if (pid < 0 || pid >= BCMI_TSN_TAF_PROFILE_NUM_MAX) { 928 return BCM_E_PARAM; 929 } 930 931 TSN_TAF_LOCK(tc); 932 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate)); 933 934 if (BCM_SUCCESS(rv)) { 935 rv = TSN_TAF_FUNC(calendar_profile_get, (unit, pid, &profile_i)); 936 } 937 938 if (BCM_SUCCESS(rv)) { 939 if (profile_i->taf_gate != taf_gate) { 940 rv = BCM_E_PARAM; 941 } 942 } 943 944 if (BCM_SUCCESS(rv)) { 945 if (profile_i->status != bcmTsnTafProfileInit) { 946 /* we only accept to commit the profile with init state */ 947 rv = BCM_E_CONFIG; 948 } 949 } 950 951 if (BCM_SUCCESS(rv)) { 952 uint32 taf_enable; 953 954 rv = TSN_TAF_FUNC(gate_control_get, 955 (unit, taf_gate, bcmTsnTafControlEnable, &taf_enable)); 956 if (BCM_SUCCESS(rv) && 0 == taf_enable) { 957 /* need to enable TAF on this gate first before commit profile */ 958 rv = BCM_E_CONFIG; 959 } 960 } 961 962 if (BCM_SUCCESS(rv)) { 963 rv = TSN_TAF_FUNC(gate_control_get, 964 (unit, taf_gate, bcmTsnTafControlUsePTPTime, &use_ptp)); 965 } 966 967 if (BCM_SUCCESS(rv)) { 968 if (1 == use_ptp) { 969 uint32 is_locked; 970 /* if this taf gate is operated in PTP mode, 971 * create and insert a schedule entry into timeline 972 * , set its state as commit then wait scheduling 973 */ 974 975 976 /* if clock does not be locked, cannot commit */ 977 if (BCM_SUCCESS(rv)) { 978 rv = TSN_TAF_FUNC(global_control_get, 979 (unit, bcmTsnTafControlTAFPTPLock, 980 &is_locked)); 981 } 982 983 if (BCM_SUCCESS(rv) && 0 == is_locked) { 984 LOG_WARN(BSL_LS_BCMAPI_TSN, 985 (BSL_META_U(unit, "need to ensure TAF ptp lock\ 986 before commit\n"))); 987 rv = BCM_E_CONFIG; 988 } 989 990 /* insert this new schedule */ 991 if (BCM_SUCCESS(rv)) { 992 #if 1 993 rv = TSN_TAF_FUNC( 994 schedule_insert, (unit, taf_gate, 995 &(profile_i->data.ptp_base_time), 996 profile_i)); 997 #endif 998 999 } 1000 1001 /* try to see if there is any profile could be selected 1002 * as pending status 1003 */ 1004 if (BCM_SUCCESS(rv)) { 1005 profile_i->status = bcmTsnTafProfileCommitted; 1006 rv = bcmi_esw_tsn_taf_profile_pick_pending( 1007 unit, 1008 taf_gate); 1009 } 1010 1011 1012 } else { 1013 /* if this taf gate is operated in non-PTP mode, 1014 * setup into hw directly, and enter pending state 1015 */ 1016 if (NULL != taf_profile_pending[unit][taf_gate]) { 1017 rv = BCM_E_BUSY; 1018 } 1019 if (BCM_SUCCESS(rv)) { 1020 rv = TSN_TAF_FUNC(calendar_kickoff, 1021 (unit, taf_gate, profile_i)); 1022 } 1023 if (BCM_SUCCESS(rv)) { 1024 profile_i->status = bcmTsnTafProfilePending; 1025 taf_profile_pending[unit][taf_gate] = profile_i; 1026 } 1027 } 1028 } 1029 1030 TSN_TAF_UNLOCK(tc); 1031 #endif /* BCM_TSN_SUPPORT */ 1032 1033 return rv; 1034 } 1035 1036 #if defined(BCM_TSN_SUPPORT) 1037 /* 1038 * Function: 1039 * bcmi_esw_tsn_taf_profile_destroy 1040 * Purpose: 1041 * helper function to destroy profile 1042 */ 1043 STATIC int 1044 bcmi_esw_tsn_taf_profile_destroy( 1045 int unit, 1046 int taf_gate, 1047 bcm_tsn_taf_profile_id_t pid, 1048 void *user_data) 1049 { 1050 bcmi_tsn_taf_profile_t *profile_i; 1051 int schedule_exist; 1052 1053 if (pid < 0 || pid >= BCMI_TSN_TAF_PROFILE_NUM_MAX) { 1054 return BCM_E_PARAM; 1055 } 1056 1057 BCM_IF_ERROR_RETURN( 1058 TSN_TAF_FUNC(calendar_profile_get, (unit, pid, &profile_i))); 1059 1060 if (profile_i->taf_gate != taf_gate) { 1061 return BCM_E_PARAM; 1062 } 1063 1064 if (profile_i->status == bcmTsnTafProfilePending || 1065 profile_i->status == bcmTsnTafProfileActive) { 1066 return BCM_E_BUSY; 1067 } 1068 1069 BCM_IF_ERROR_RETURN( 1070 TSN_TAF_FUNC(schedule_exist, (unit, profile_i, &schedule_exist))); 1071 1072 if (1 == schedule_exist) { 1073 BCM_IF_ERROR_RETURN( 1074 TSN_TAF_FUNC(schedule_remove, (unit, taf_gate, profile_i))); 1075 } 1076 1077 BCM_IF_ERROR_RETURN( 1078 TSN_TAF_FUNC(calendar_resource_free, 1079 (unit, taf_gate, &(profile_i->data)))); 1080 1081 BCM_IF_ERROR_RETURN( 1082 TSN_TAF_FUNC(calendar_profile_destroy, (unit, pid))); 1083 1084 return BCM_E_NONE; 1085 } 1086 #endif /* BCM_TSN_SUPPORT */ 1087 1088 /* 1089 * Function: 1090 * bcm_esw_tsn_taf_profile_destroy 1091 * Purpose: 1092 * Destroy the profile and associated resources. 1093 * Parameters: 1094 * unit - (IN) unit number 1095 * taf_gate - (IN) TAF gate 1096 * pid - (IN) profile id 1097 * Returns: 1098 * BCM_E_XXX 1099 */ 1100 int 1101 bcm_esw_tsn_taf_profile_destroy( 1102 int unit, 1103 int taf_gate, 1104 bcm_tsn_taf_profile_id_t pid) 1105 { 1106 int rv = BCM_E_UNAVAIL; 1107 1108 #if defined(BCM_TSN_SUPPORT) 1109 bcmi_tsn_taf_control_t *tc; 1110 1111 BCM_IF_ERROR_RETURN( 1112 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 1113 1114 TSN_TAF_LOCK(tc); 1115 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate)); 1116 1117 if (BCM_SUCCESS(rv)) { 1118 rv = bcmi_esw_tsn_taf_profile_destroy(unit, taf_gate, pid, NULL); 1119 } 1120 TSN_TAF_UNLOCK(tc); 1121 #endif /* BCM_TSN_SUPPORT */ 1122 1123 return rv; 1124 } 1125 1126 1127 /* 1128 * Function: 1129 * bcm_esw_tsn_taf_profile_destroy_all 1130 * Purpose: 1131 * Destroy all the profile associated with the taf_gate. 1132 * Parameters: 1133 * unit - (IN) unit number 1134 * taf_gate - (IN) TAF gate 1135 * Returns: 1136 * BCM_E_XXX 1137 */ 1138 int 1139 bcm_esw_tsn_taf_profile_destroy_all( 1140 int unit, 1141 int taf_gate) 1142 { 1143 int rv = BCM_E_UNAVAIL; 1144 1145 #if defined(BCM_TSN_SUPPORT) 1146 bcmi_tsn_taf_control_t *tc; 1147 1148 BCM_IF_ERROR_RETURN( 1149 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 1150 1151 TSN_TAF_LOCK(tc); 1152 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate)); 1153 1154 if (BCM_SUCCESS(rv)) { 1155 rv = TSN_TAF_FUNC(calendar_profile_traverse, 1156 (unit, taf_gate, bcmi_esw_tsn_taf_profile_destroy, NULL)); 1157 } 1158 TSN_TAF_UNLOCK(tc); 1159 #endif /* BCM_TSN_SUPPORT */ 1160 1161 return rv; 1162 } 1163 1164 #if defined(BCM_TSN_SUPPORT) 1165 /* 1166 * Function: 1167 * bcmi_esw_tsn_taf_profile_reset 1168 * Purpose: 1169 * helper function to reset profile back to init status (is_init = 1) 1170 * or fall into error status (is_init = 0) 1171 * And need to cancel all schedule for commited profile 1172 * 1173 * is_init = 1 is_init = 0 1174 * INIT INIT INIT 1175 * ERROR INIT ERROR 1176 * EXPIRED INIT EXPIRED 1177 * COMMITTED INIT ERROR 1178 * PENDING INIT ERROR 1179 * ACTIVE INIT ERROR 1180 */ 1181 STATIC int 1182 bcmi_esw_tsn_taf_profile_reset( 1183 int unit, 1184 int taf_gate, 1185 bcm_tsn_taf_profile_id_t pid, 1186 void *user_data) 1187 { 1188 bcmi_tsn_taf_profile_t *profile_i; 1189 int is_init; 1190 1191 if (pid < 0 || pid >= BCMI_TSN_TAF_PROFILE_NUM_MAX) { 1192 return BCM_E_PARAM; 1193 } 1194 1195 if (NULL == user_data) { 1196 return BCM_E_INTERNAL; /* should not happen */ 1197 } 1198 is_init = *((int *)user_data); 1199 1200 BCM_IF_ERROR_RETURN( 1201 TSN_TAF_FUNC(calendar_profile_get, (unit, pid, &profile_i))); 1202 1203 if (profile_i->taf_gate != taf_gate) { 1204 return BCM_E_PARAM; 1205 } 1206 1207 switch (profile_i->status) { 1208 case bcmTsnTafProfileInit: 1209 /* skip profile with init status */ 1210 break; 1211 case bcmTsnTafProfileExpired: 1212 case bcmTsnTafProfileError: /* fall through */ 1213 if (1 == is_init) { 1214 profile_i->status = bcmTsnTafProfileInit; 1215 } 1216 break; 1217 case bcmTsnTafProfileCommitted: 1218 /* commit status only for ptp mode 1219 * so there should exist schedule entry 1220 */ 1221 BCM_IF_ERROR_RETURN( 1222 TSN_TAF_FUNC(schedule_remove, (unit, taf_gate, profile_i))); 1223 profile_i->status = (1 == is_init) ? bcmTsnTafProfileInit 1224 : bcmTsnTafProfileError; 1225 break; 1226 case bcmTsnTafProfilePending: 1227 if (taf_profile_pending[unit][taf_gate] != profile_i) { 1228 return BCM_E_INTERNAL; 1229 } 1230 taf_profile_pending[unit][taf_gate] = NULL; 1231 profile_i->status = (1 == is_init) ? bcmTsnTafProfileInit 1232 : bcmTsnTafProfileError; 1233 break; 1234 case bcmTsnTafProfileActive: 1235 if (taf_profile_active[unit][taf_gate] != profile_i) { 1236 return BCM_E_INTERNAL; 1237 } 1238 taf_profile_active[unit][taf_gate] = NULL; 1239 profile_i->status = (1 == is_init) ? bcmTsnTafProfileInit 1240 : bcmTsnTafProfileError; 1241 break; 1242 default: 1243 return BCM_E_INTERNAL; /* unknown status? */ 1244 } 1245 1246 return BCM_E_NONE; 1247 } 1248 1249 /* control data for bcmi_esw_tsn_taf_profile_reset_all */ 1250 #define BCMI_TSN_TAF_PROFILE_RESET_CONTROL_MODE_NON_PTP (0) 1251 #define BCMI_TSN_TAF_PROFILE_RESET_CONTROL_MODE_PTP (1) 1252 #define BCMI_TSN_TAF_PROFILE_RESET_CONTROL_MODE_BOTH (2) 1253 1254 typedef struct bcmi_tsn_taf_profile_reset_control_s { 1255 int is_init; /* 1 : reset status back to init status 1256 * 0 : fall into error status 1257 */ 1258 int active_mode; /* BCMI_TSN_TAF_PROFILE_RESET_CONTROL_MODE_XXX */ 1259 int need_event; /* 1 : need raise event 1260 * 0 : need not raise event 1261 */ 1262 bcm_tsn_taf_event_type_t event_type; /* event type if need_event = 1 */ 1263 } bcmi_tsn_taf_profile_reset_control_t; 1264 1265 /* 1266 * Function: 1267 * bcmi_esw_tsn_taf_profile_reset_all 1268 * Purpose: 1269 * Reset all the profile associated with the taf_gate. 1270 * Parameters: 1271 * unit - (IN) unit number 1272 * taf_gate - (IN) TAF gate 1273 * is_init - (IN) 1 : reset status back to init status 1274 * 0 : fall into error status 1275 * Returns: 1276 * BCM_E_XXX 1277 */ 1278 STATIC int 1279 bcmi_esw_tsn_taf_profile_reset_all( 1280 int unit, 1281 int taf_gate, 1282 void *control_data) 1283 { 1284 bcmi_tsn_taf_profile_reset_control_t *control_ptr; 1285 1286 if (NULL == control_data) { 1287 return BCM_E_PARAM; 1288 } 1289 control_ptr = (bcmi_tsn_taf_profile_reset_control_t *)control_data; 1290 1291 /* gate mode check, skip handling if not match */ 1292 if (control_ptr->active_mode != 1293 BCMI_TSN_TAF_PROFILE_RESET_CONTROL_MODE_BOTH) { 1294 1295 uint32 use_ptp; 1296 1297 BCM_IF_ERROR_RETURN( 1298 TSN_TAF_FUNC(gate_control_get, 1299 (unit, taf_gate, bcmTsnTafControlUsePTPTime, &use_ptp))); 1300 1301 if (control_ptr->active_mode == 1302 BCMI_TSN_TAF_PROFILE_RESET_CONTROL_MODE_NON_PTP && 1303 1 == use_ptp) { 1304 return BCM_E_NONE; 1305 } 1306 1307 if (control_ptr->active_mode == 1308 BCMI_TSN_TAF_PROFILE_RESET_CONTROL_MODE_PTP && 1309 0 == use_ptp) { 1310 return BCM_E_NONE; 1311 } 1312 } 1313 1314 /* reset profile status */ 1315 BCM_IF_ERROR_RETURN( 1316 TSN_TAF_FUNC(calendar_profile_traverse, 1317 (unit, taf_gate, bcmi_esw_tsn_taf_profile_reset, 1318 &(control_ptr->is_init)))); 1319 1320 /* raise event if need */ 1321 if (1 == control_ptr->need_event) { 1322 BCM_IF_ERROR_RETURN( 1323 TSN_TAF_FUNC(event_notify, 1324 (unit, taf_gate, control_ptr->event_type))); 1325 } 1326 1327 return BCM_E_NONE; 1328 } 1329 #endif /* BCM_TSN_SUPPORT */ 1330 1331 /* 1332 * Function: 1333 * bcm_esw_tsn_taf_profile_traverse 1334 * Purpose: 1335 * Traverse the set of profiles associated with the taf gate. 1336 * Parameters: 1337 * unit - (IN) unit number 1338 * taf_gate - (IN) TAF gate 1339 * cb - (IN) A pointer to callback function to call 1340 * for each profile in the specified taf gate. 1341 * user_data - (IN) Pointer to user data to supply in the callback 1342 * Returns: 1343 * BCM_E_XXX 1344 */ 1345 int 1346 bcm_esw_tsn_taf_profile_traverse( 1347 int unit, 1348 int taf_gate, 1349 bcm_tsn_taf_profile_traverse_cb cb, 1350 void *user_data) 1351 { 1352 int rv = BCM_E_UNAVAIL; 1353 1354 #if defined(BCM_TSN_SUPPORT) 1355 bcmi_tsn_taf_control_t *tc; 1356 1357 BCM_IF_ERROR_RETURN( 1358 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 1359 1360 TSN_TAF_LOCK(tc); 1361 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate)); 1362 1363 if (BCM_SUCCESS(rv)) { 1364 rv = TSN_TAF_FUNC(calendar_profile_traverse, (unit, taf_gate, cb, 1365 user_data)); 1366 } 1367 TSN_TAF_UNLOCK(tc); 1368 #endif /* BCM_TSN_SUPPORT */ 1369 1370 return rv; 1371 } 1372 1373 /* 1374 * Function: 1375 * bcm_esw_tsn_taf_profile_status_get 1376 * Purpose: 1377 * Get the profile status like profile state, config change time and 1378 * entries in the hardware calendar table. 1379 * Parameters: 1380 * unit - (IN) unit number 1381 * taf_gate - (IN) TAF gate 1382 * pid - (IN) profile id 1383 * status - (OUT) pointer to profile status structure 1384 * Returns: 1385 * BCM_E_XXX 1386 */ 1387 int 1388 bcm_esw_tsn_taf_profile_status_get( 1389 int unit, 1390 int taf_gate, 1391 bcm_tsn_taf_profile_id_t pid, 1392 bcm_tsn_taf_profile_status_t *status) 1393 { 1394 int rv = BCM_E_UNAVAIL; 1395 1396 #if defined(BCM_TSN_SUPPORT) 1397 bcmi_tsn_taf_control_t *tc; 1398 bcmi_tsn_taf_profile_t *profile_i; 1399 1400 BCM_IF_ERROR_RETURN( 1401 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 1402 1403 if (pid < 0 || pid >= BCMI_TSN_TAF_PROFILE_NUM_MAX || NULL == status) { 1404 return BCM_E_PARAM; 1405 } 1406 bcm_tsn_taf_profile_status_t_init(status); 1407 1408 TSN_TAF_LOCK(tc); 1409 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate)); 1410 1411 if (BCM_SUCCESS(rv)) { 1412 rv = TSN_TAF_FUNC(calendar_profile_get, (unit, pid, &profile_i)); 1413 } 1414 1415 if (BCM_SUCCESS(rv)) { 1416 if (profile_i->taf_gate != taf_gate) { 1417 rv = BCM_E_PARAM; 1418 } 1419 } 1420 1421 if (BCM_SUCCESS(rv)) { 1422 status->profile_state = profile_i->status; 1423 status->num_entries = profile_i->data.num_entries; 1424 COMPILER_64_COPY(status->config_change_time.seconds, 1425 profile_i->config_change_time.seconds); 1426 status->config_change_time.nanoseconds = 1427 profile_i->config_change_time.nanoseconds; 1428 sal_memcpy(status->entries, profile_i->data.entries, 1429 sizeof(bcm_tsn_taf_entry_t) * 1430 BCM_TSN_TAF_CALENDAR_TABLE_SIZE); 1431 } 1432 TSN_TAF_UNLOCK(tc); 1433 #endif /* BCM_TSN_SUPPORT */ 1434 1435 return rv; 1436 } 1437 1438 /* 1439 * Function: 1440 * bcm_esw_tsn_taf_control_set 1441 * Description: 1442 * Set various TAF configurations at specific gate 1443 * Parameters: 1444 * unit - (IN) Unit number 1445 * taf_gate_id - (IN) taf gate (-1 for global setting) 1446 * type - (IN) control type 1447 * arg - (IN) parameter 1448 * Returns: 1449 * BCM_E_XXX 1450 */ 1451 int 1452 bcm_esw_tsn_taf_control_set( 1453 int unit, 1454 int taf_gate_id, 1455 bcm_tsn_taf_control_t type, 1456 uint32 arg) 1457 { 1458 int rv = BCM_E_UNAVAIL; 1459 1460 #if defined(BCM_TSN_SUPPORT) 1461 bcmi_tsn_taf_control_t *tc; 1462 1463 BCM_IF_ERROR_RETURN( 1464 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 1465 1466 TSN_TAF_LOCK(tc); 1467 1468 if (bcmTsnTafControlTAFPTPLock == type) { 1469 /* PTP Lock is a global setting */ 1470 if (taf_gate_id != -1) { 1471 rv = BCM_E_PARAM; 1472 } else { 1473 rv = TSN_TAF_FUNC(global_control_set, (unit, type, arg)); 1474 } 1475 1476 /* if ptp clock is out-of-snyc during ptp mode 1477 * 1. let all profile enter into error status 1478 * 2. raise out-of-sync event 1479 */ 1480 if (BCM_SUCCESS(rv) && 0 == arg) { 1481 bcmi_tsn_taf_profile_reset_control_t control_data; 1482 1483 sal_memset(&control_data, 0, sizeof(control_data)); 1484 control_data.is_init = 0; /* reset to error status */ 1485 control_data.active_mode = 1486 BCMI_TSN_TAF_PROFILE_RESET_CONTROL_MODE_PTP; 1487 control_data.need_event = 1; 1488 control_data.event_type = bcmTsnTafEventTAFPTPOutOfSyncErr; 1489 rv = TSN_TAF_FUNC(gate_traverse, 1490 (unit, bcmi_esw_tsn_taf_profile_reset_all, &control_data)); 1491 } 1492 } else { 1493 int need_to_reset = 0; 1494 1495 /* For the other control type, check gate id first */ 1496 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 1497 1498 if (BCM_SUCCESS(rv)) { 1499 if (type == bcmTsnTafControlEnable || 1500 type == bcmTsnTafControlUsePTPTime) { 1501 1502 uint32 prev_arg; 1503 1504 rv = TSN_TAF_FUNC( 1505 gate_control_get, 1506 (unit, taf_gate_id, type, &prev_arg)); 1507 1508 if (BCM_SUCCESS(rv)) { 1509 if (type == bcmTsnTafControlEnable) { 1510 /* Reset all profiles after disable TAF */ 1511 if (prev_arg != arg && arg == 0) { 1512 need_to_reset = 1; 1513 } 1514 } else if (type == bcmTsnTafControlUsePTPTime) { 1515 /* If the user wants to change between ptp and 1516 * non-ptp mode, need to disable TAF first 1517 */ 1518 uint32 taf_enable; 1519 1520 rv = TSN_TAF_FUNC( 1521 gate_control_get, 1522 (unit, taf_gate_id, 1523 bcmTsnTafControlEnable, &taf_enable)); 1524 1525 if (BCM_SUCCESS(rv) && prev_arg != arg && 1526 1 == taf_enable) { 1527 LOG_WARN( 1528 BSL_LS_BCMAPI_TSN, 1529 (BSL_META_U(unit, "need to disable TAF first\ 1530 before change PTP mode\n"))); 1531 rv = BCM_E_CONFIG; 1532 } 1533 } 1534 } 1535 } 1536 } 1537 1538 if (BCM_SUCCESS(rv)) { 1539 rv = TSN_TAF_FUNC(gate_control_set, (unit, taf_gate_id, type, arg)); 1540 } 1541 if (BCM_SUCCESS(rv) && 1 == need_to_reset) { 1542 bcmi_tsn_taf_profile_reset_control_t control_data; 1543 1544 sal_memset(&control_data, 0, sizeof(control_data)); 1545 control_data.is_init = 1; /* reset to init status */ 1546 control_data.active_mode = 1547 BCMI_TSN_TAF_PROFILE_RESET_CONTROL_MODE_BOTH; 1548 control_data.need_event = 0; 1549 rv = bcmi_esw_tsn_taf_profile_reset_all(unit, taf_gate_id, 1550 &control_data); 1551 } 1552 } 1553 TSN_TAF_UNLOCK(tc); 1554 #endif /* BCM_TSN_SUPPORT */ 1555 1556 return rv; 1557 } 1558 1559 /* 1560 * Function: 1561 * bcm_esw_tsn_taf_control_get 1562 * Description: 1563 * Get various TAF configurations at specific gate 1564 * Parameters: 1565 * unit - (IN) Unit number 1566 * taf_gate_id - (IN) taf gate 1567 * type - (IN) control type 1568 * arg - (OUT)parameter 1569 * Returns: 1570 * BCM_E_XXX 1571 */ 1572 int 1573 bcm_esw_tsn_taf_control_get( 1574 int unit, 1575 int taf_gate_id, 1576 bcm_tsn_taf_control_t type, 1577 uint32 *arg) 1578 { 1579 int rv = BCM_E_UNAVAIL; 1580 1581 #if defined(BCM_TSN_SUPPORT) 1582 bcmi_tsn_taf_control_t *tc; 1583 1584 BCM_IF_ERROR_RETURN( 1585 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 1586 1587 TSN_TAF_LOCK(tc); 1588 if (bcmTsnTafControlTAFPTPLock == type) { 1589 /* PTP Lock is a global setting */ 1590 if (taf_gate_id != -1) { 1591 rv = BCM_E_PARAM; 1592 } else { 1593 rv = TSN_TAF_FUNC(global_control_get, (unit, type, arg)); 1594 } 1595 } else { 1596 /* For the other control type, check gate id first */ 1597 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 1598 1599 if (BCM_SUCCESS(rv)) { 1600 rv = TSN_TAF_FUNC(gate_control_get, (unit, taf_gate_id, type, arg)); 1601 } 1602 } 1603 TSN_TAF_UNLOCK(tc); 1604 #endif /* BCM_TSN_SUPPORT */ 1605 1606 return rv; 1607 } 1608 1609 #if defined(BCM_TSN_SUPPORT) 1610 STATIC int 1611 bcmi_esw_tsn_taf_interrupt_handle( 1612 int unit 1613 ) 1614 { 1615 int rv = BCM_E_NONE; 1616 soc_control_t *soc = SOC_CONTROL(unit); 1617 bcmi_tsn_taf_control_t *tc; 1618 int need_to_handle, taf_gate, start_handle; 1619 SHR_BITDCL gate_bitmap[_SHR_BITDCLSIZE(BCMI_TSN_TAF_GATE_NUM)]; 1620 1621 /* Start to handle interrupt after all modules are inited 1622 * Consider that some interrupt signal are shared with others in init phase 1623 */ 1624 if (soc == NULL || !(soc->soc_flags & SOC_F_ALL_MODULES_INITED)) { 1625 return BCM_E_NONE; 1626 } 1627 1628 BCM_IF_ERROR_RETURN( 1629 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 1630 1631 1632 TSN_TAF_LOCK(tc); 1633 1634 /* start to handle */ 1635 start_handle = 0; 1636 rv = TSN_TAF_FUNC(interrupt_handle_start, (unit)); 1637 1638 /* handle profile switch done */ 1639 if (BCM_SUCCESS(rv)) { 1640 start_handle = 1; 1641 rv = TSN_TAF_FUNC( 1642 interrupt_handle_switch, 1643 (unit, &need_to_handle, 1644 gate_bitmap, _SHR_BITDCLSIZE(BCMI_TSN_TAF_GATE_NUM))); 1645 } 1646 1647 if (BCM_SUCCESS(rv) && need_to_handle) { 1648 SHR_BIT_ITER(gate_bitmap, BCMI_TSN_TAF_GATE_NUM, taf_gate) { 1649 uint32 use_ptp; 1650 bcmi_tsn_taf_profile_t *p_act = taf_profile_active[unit][taf_gate]; 1651 bcmi_tsn_taf_profile_t *p_ped = taf_profile_pending[unit][taf_gate]; 1652 1653 if (NULL != p_act) { 1654 p_act->status = bcmTsnTafProfileExpired; 1655 taf_profile_active[unit][taf_gate] = NULL; 1656 } 1657 1658 if (NULL == p_ped) { 1659 LOG_WARN(BSL_LS_BCMAPI_TSN, 1660 (BSL_META_U(unit, "bcmi_esw_tsn_taf_interrupt_handle:\ 1661 no pending profile ?\n"))); 1662 rv = BCM_E_INTERNAL; /* there is no any pending profile ? */ 1663 break; 1664 } 1665 p_ped->status = bcmTsnTafProfileActive; 1666 taf_profile_pending[unit][taf_gate] = NULL; 1667 taf_profile_active[unit][taf_gate] = p_ped; 1668 1669 rv = TSN_TAF_FUNC(gate_control_get, 1670 (unit, taf_gate, bcmTsnTafControlUsePTPTime, &use_ptp)); 1671 if (BCM_FAILURE(rv)) { 1672 break; 1673 } 1674 1675 /* for ptp-mode, check whether to pick a new candidate profile 1676 * to be pending 1677 */ 1678 if (1 == use_ptp) { 1679 rv = bcmi_esw_tsn_taf_profile_pick_pending( 1680 unit, 1681 taf_gate); 1682 if (BCM_FAILURE(rv)) { 1683 break; 1684 } 1685 } 1686 } 1687 } 1688 1689 /* handle error of active profile */ 1690 if (BCM_SUCCESS(rv)) { 1691 rv = TSN_TAF_FUNC( 1692 interrupt_handle_error, 1693 (unit, &need_to_handle, 1694 gate_bitmap, _SHR_BITDCLSIZE(BCMI_TSN_TAF_GATE_NUM))); 1695 } 1696 if (BCM_SUCCESS(rv) && need_to_handle) { 1697 bcmi_tsn_taf_profile_reset_control_t control_data; 1698 1699 sal_memset(&control_data, 0, sizeof(control_data)); 1700 control_data.is_init = 0; /* reset to error status */ 1701 control_data.active_mode = 1702 BCMI_TSN_TAF_PROFILE_RESET_CONTROL_MODE_BOTH; 1703 control_data.need_event = 0; 1704 1705 SHR_BIT_ITER(gate_bitmap, BCMI_TSN_TAF_GATE_NUM, taf_gate) { 1706 rv = bcmi_esw_tsn_taf_profile_reset_all(unit, taf_gate, 1707 &control_data); 1708 if (BCM_FAILURE(rv)) { 1709 break; 1710 } 1711 } 1712 } 1713 1714 /* handle Tod Window event */ 1715 if (BCM_SUCCESS(rv)) { 1716 rv = TSN_TAF_FUNC(interrupt_handle_tod, (unit, &need_to_handle)); 1717 } 1718 if (BCM_SUCCESS(rv) && need_to_handle) { 1719 for (taf_gate = 0; taf_gate < BCMI_TSN_TAF_GATE_NUM; taf_gate++) { 1720 uint32 use_ptp; 1721 1722 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate)); 1723 if (BCM_FAILURE(rv)) { 1724 rv = BCM_E_NONE; 1725 continue; /* skip invalid gate */ 1726 } 1727 1728 rv = TSN_TAF_FUNC(gate_control_get, 1729 (unit, taf_gate, bcmTsnTafControlUsePTPTime, &use_ptp)); 1730 if (BCM_FAILURE(rv)) { 1731 break; 1732 } 1733 1734 if (0 == use_ptp) { 1735 continue; /* skip the gate operated in non-ptp mode */ 1736 } 1737 1738 /* check whether to pick a new candidate to pending status */ 1739 rv = bcmi_esw_tsn_taf_profile_pick_pending( 1740 unit, 1741 taf_gate); 1742 if (BCM_FAILURE(rv)) { 1743 break; 1744 } 1745 } 1746 } 1747 1748 /* invoke user registered callback */ 1749 if (BCM_SUCCESS(rv)) { 1750 rv = TSN_TAF_FUNC(interrupt_handle_user_cb, (unit)); 1751 } 1752 1753 /* finish handling no matter rv is BCM_E_NONE or not */ 1754 if (1 == start_handle) { 1755 (void)TSN_TAF_FUNC(interrupt_handle_finish, (unit)); 1756 } 1757 1758 TSN_TAF_UNLOCK(tc); 1759 return rv; 1760 } 1761 #endif /* BCM_TSN_SUPPORT */ 1762 1763 /* 1764 * Function: 1765 * bcm_esw_tsn_taf_event_register 1766 * Purpose: 1767 * The callback function registration by specifying port or traffic class to 1768 * handle the TAF events. 1769 * Parameters: 1770 * unit - (IN) unit number 1771 * event_types - (IN) The set of TAF events for which the specified 1772 * callback should be invoked. 1773 * taf_gate - (IN) taf gate 1774 * cb - (IN) callback function 1775 * user_data - (IN) Pinter to user data to supply in the callback. 1776 * Returns: 1777 * BCM_E_XXX 1778 */ 1779 int 1780 bcm_esw_tsn_taf_event_register( 1781 int unit, 1782 bcm_tsn_taf_event_types_t event_types, 1783 int taf_gate, 1784 bcm_tsn_taf_event_cb cb, 1785 void *user_data) 1786 { 1787 int rv = BCM_E_UNAVAIL; 1788 1789 #if defined(BCM_TSN_SUPPORT) 1790 bcmi_tsn_taf_control_t *tc; 1791 1792 BCM_IF_ERROR_RETURN( 1793 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 1794 1795 TSN_TAF_LOCK(tc); 1796 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate)); 1797 1798 if (BCM_SUCCESS(rv)) { 1799 rv = TSN_TAF_FUNC( 1800 event_register, (unit, taf_gate, event_types, cb, user_data)); 1801 } 1802 TSN_TAF_UNLOCK(tc); 1803 #endif /* BCM_TSN_SUPPORT */ 1804 1805 return rv; 1806 } 1807 1808 /* 1809 * Function: 1810 * bcm_esw_tsn_taf_event_unregister 1811 * Purpose: 1812 * The callback function unregistration of TAF events by specifying port or 1813 * traffic class. 1814 * Parameters: 1815 * unit - (IN) unit number 1816 * event_types - (IN) The set of TAF events for which the specified 1817 * callback should be invoked. 1818 * taf_gate - (IN) taf gate 1819 * cb - (IN) callback function 1820 * Returns: 1821 * BCM_E_XXX 1822 */ 1823 int 1824 bcm_esw_tsn_taf_event_unregister( 1825 int unit, 1826 bcm_tsn_taf_event_types_t event_types, 1827 int taf_gate, 1828 bcm_tsn_taf_event_cb cb) 1829 { 1830 int rv = BCM_E_UNAVAIL; 1831 1832 #if defined(BCM_TSN_SUPPORT) 1833 bcmi_tsn_taf_control_t *tc; 1834 1835 BCM_IF_ERROR_RETURN( 1836 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 1837 1838 TSN_TAF_LOCK(tc); 1839 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate)); 1840 1841 if (BCM_SUCCESS(rv)) { 1842 rv = TSN_TAF_FUNC( 1843 event_unregister, (unit, taf_gate, event_types, cb)); 1844 } 1845 TSN_TAF_UNLOCK(tc); 1846 #endif /* BCM_TSN_SUPPORT */ 1847 1848 return rv; 1849 } 1850 1851 /* 1852 * Function: 1853 * bcm_esw_tsn_taf_gate_max_bytes_profile_create 1854 * Purpose: 1855 * Create profile of maximum bytes that pass through the TAF gate 1856 * Parameters: 1857 * unit - (IN) unit number 1858 * taf_gate_id - (IN) taf gate 1859 * max_bytes - (IN) maximum bytes 1860 * profile_id - (OUT) profile id 1861 * Returns: 1862 * BCM_E_XXX 1863 */ 1864 int 1865 bcm_esw_tsn_taf_gate_max_bytes_profile_create( 1866 int unit, 1867 int taf_gate_id, 1868 uint64 max_bytes, 1869 int *profile_id) 1870 { 1871 int rv = BCM_E_UNAVAIL; 1872 1873 #if defined(BCM_TSN_SUPPORT) 1874 bcmi_tsn_taf_control_t *tc; 1875 1876 BCM_IF_ERROR_RETURN( 1877 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 1878 1879 TSN_TAF_LOCK(tc); 1880 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 1881 1882 if (BCM_SUCCESS(rv)) { 1883 rv = TSN_TAF_FUNC( 1884 gate_max_bytes_profile_create, 1885 (unit, taf_gate_id, max_bytes, profile_id)); 1886 } 1887 TSN_TAF_UNLOCK(tc); 1888 #endif /* BCM_TSN_SUPPORT */ 1889 1890 return rv; 1891 } 1892 1893 /* 1894 * Function: 1895 * bcm_esw_tsn_taf_gate_max_bytes_profile_set 1896 * Purpose: 1897 * Set profile of maximum bytes that pass through the TAF gate 1898 * Parameters: 1899 * unit - (IN) unit number 1900 * taf_gate_id - (IN) taf gate 1901 * profile_id - (IN) profile id 1902 * max_bytes - (IN) maximum bytes 1903 * Returns: 1904 * BCM_E_XXX 1905 */ 1906 int 1907 bcm_esw_tsn_taf_gate_max_bytes_profile_set( 1908 int unit, 1909 int taf_gate_id, 1910 int profile_id, 1911 uint64 max_bytes) 1912 { 1913 int rv = BCM_E_UNAVAIL; 1914 1915 #if defined(BCM_TSN_SUPPORT) 1916 bcmi_tsn_taf_control_t *tc; 1917 1918 BCM_IF_ERROR_RETURN( 1919 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 1920 1921 TSN_TAF_LOCK(tc); 1922 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 1923 1924 if (BCM_SUCCESS(rv)) { 1925 rv = TSN_TAF_FUNC( 1926 gate_max_bytes_profile_set, 1927 (unit, taf_gate_id, profile_id, max_bytes)); 1928 } 1929 TSN_TAF_UNLOCK(tc); 1930 #endif /* BCM_TSN_SUPPORT */ 1931 1932 return rv; 1933 } 1934 1935 /* 1936 * Function: 1937 * bcm_esw_tsn_taf_gate_max_bytes_profile_get 1938 * Purpose: 1939 * Get profile of maximum bytes that pass through the TAF gate 1940 * Parameters: 1941 * unit - (IN) unit number 1942 * taf_gate_id - (IN) taf gate 1943 * profile_id - (IN) profile id 1944 * max_bytes - (OUT) maximum bytes 1945 * Returns: 1946 * BCM_E_XXX 1947 */ 1948 int 1949 bcm_esw_tsn_taf_gate_max_bytes_profile_get( 1950 int unit, 1951 int taf_gate_id, 1952 int profile_id, 1953 uint64 *max_bytes) 1954 { 1955 int rv = BCM_E_UNAVAIL; 1956 1957 #if defined(BCM_TSN_SUPPORT) 1958 bcmi_tsn_taf_control_t *tc; 1959 1960 BCM_IF_ERROR_RETURN( 1961 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 1962 1963 TSN_TAF_LOCK(tc); 1964 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 1965 1966 if (BCM_SUCCESS(rv)) { 1967 rv = TSN_TAF_FUNC( 1968 gate_max_bytes_profile_get, 1969 (unit, taf_gate_id, profile_id, max_bytes)); 1970 } 1971 TSN_TAF_UNLOCK(tc); 1972 #endif /* BCM_TSN_SUPPORT */ 1973 1974 return rv; 1975 } 1976 1977 /* 1978 * Function: 1979 * bcm_esw_tsn_taf_gate_max_bytes_profile_destroy 1980 * Purpose: 1981 * Destroy profile of maximum bytes that pass through the TAF gate 1982 * Parameters: 1983 * unit - (IN) unit number 1984 * taf_gate_id - (IN) taf gate 1985 * profile_id - (IN) profile id 1986 * Returns: 1987 * BCM_E_XXX 1988 */ 1989 int 1990 bcm_esw_tsn_taf_gate_max_bytes_profile_destroy( 1991 int unit, 1992 int taf_gate_id, 1993 int profile_id) 1994 { 1995 int rv = BCM_E_UNAVAIL; 1996 1997 #if defined(BCM_TSN_SUPPORT) 1998 bcmi_tsn_taf_control_t *tc; 1999 2000 BCM_IF_ERROR_RETURN( 2001 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2002 2003 TSN_TAF_LOCK(tc); 2004 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 2005 2006 if (BCM_SUCCESS(rv)) { 2007 rv = TSN_TAF_FUNC( 2008 gate_max_bytes_profile_destroy, 2009 (unit, taf_gate_id, profile_id)); 2010 } 2011 TSN_TAF_UNLOCK(tc); 2012 #endif /* BCM_TSN_SUPPORT */ 2013 2014 return rv; 2015 } 2016 2017 /* 2018 * Function: 2019 * bcm_esw_tsn_taf_gate_max_bytes_profile_traverse 2020 * Purpose: 2021 * Traverse profile of maximum bytes that pass through the TAF gate 2022 * Parameters: 2023 * unit - (IN) unit number 2024 * taf_gate_id - (IN) taf gate 2025 * cb - (IN) callback function 2026 * user_data - (IN) user data 2027 * Returns: 2028 * BCM_E_XXX 2029 */ 2030 int 2031 bcm_esw_tsn_taf_gate_max_bytes_profile_traverse( 2032 int unit, 2033 int taf_gate_id, 2034 bcm_tsn_taf_gate_max_bytes_profile_traverse_cb cb, 2035 void *user_data) 2036 { 2037 int rv = BCM_E_UNAVAIL; 2038 2039 #if defined(BCM_TSN_SUPPORT) 2040 bcmi_tsn_taf_control_t *tc; 2041 2042 BCM_IF_ERROR_RETURN( 2043 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2044 2045 TSN_TAF_LOCK(tc); 2046 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 2047 2048 if (BCM_SUCCESS(rv)) { 2049 rv = TSN_TAF_FUNC( 2050 gate_max_bytes_profile_traverse, 2051 (unit, taf_gate_id, cb, user_data)); 2052 } 2053 TSN_TAF_UNLOCK(tc); 2054 #endif /* BCM_TSN_SUPPORT */ 2055 2056 return rv; 2057 } 2058 2059 /* 2060 * Function: 2061 * bcm_esw_tsn_taf_cosq_mapping_profile_create 2062 * Purpose: 2063 * Create TAF Cos mapping profile 2064 * Parameters: 2065 * unit - (IN) unit number 2066 * cosq_profile - (OUT) profile id 2067 * Returns: 2068 * BCM_E_XXX 2069 */ 2070 int 2071 bcm_esw_tsn_taf_cosq_mapping_profile_create( 2072 int unit, 2073 int *cosq_profile) 2074 { 2075 int rv = BCM_E_UNAVAIL; 2076 2077 #if defined(BCM_TSN_SUPPORT) 2078 bcmi_tsn_taf_control_t *tc; 2079 2080 BCM_IF_ERROR_RETURN( 2081 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2082 2083 TSN_TAF_LOCK(tc); 2084 rv = TSN_TAF_FUNC( 2085 cosq_mapping_profile_create, (unit, cosq_profile)); 2086 TSN_TAF_UNLOCK(tc); 2087 #endif /* BCM_TSN_SUPPORT */ 2088 2089 return rv; 2090 } 2091 2092 /* 2093 * Function: 2094 * bcm_esw_tsn_taf_cosq_mapping_profile_set 2095 * Purpose: 2096 * Set TAF Cos mapping profile 2097 * Parameters: 2098 * unit - (IN) unit number 2099 * cosq_profile - (IN) profile id 2100 * priority - (IN) internal priority 2101 * cosq - (IN) CosQ id 2102 * Returns: 2103 * BCM_E_XXX 2104 */ 2105 int 2106 bcm_esw_tsn_taf_cosq_mapping_profile_set( 2107 int unit, 2108 int cosq_profile, 2109 bcm_cos_t priority, 2110 bcm_cos_queue_t cosq) 2111 { 2112 int rv = BCM_E_UNAVAIL; 2113 2114 #if defined(BCM_TSN_SUPPORT) 2115 bcmi_tsn_taf_control_t *tc; 2116 2117 BCM_IF_ERROR_RETURN( 2118 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2119 2120 TSN_TAF_LOCK(tc); 2121 rv = TSN_TAF_FUNC( 2122 cosq_mapping_profile_set, (unit, cosq_profile, priority, cosq)); 2123 TSN_TAF_UNLOCK(tc); 2124 #endif /* BCM_TSN_SUPPORT */ 2125 2126 return rv; 2127 } 2128 2129 /* 2130 * Function: 2131 * bcm_esw_tsn_taf_cosq_mapping_profile_get 2132 * Purpose: 2133 * Get TAF Cos mapping profile 2134 * Parameters: 2135 * unit - (IN) unit number 2136 * cosq_profile - (IN) profile id 2137 * priority - (IN) internal priority 2138 * cosq - (OUT)CosQ id 2139 * Returns: 2140 * BCM_E_XXX 2141 */ 2142 int 2143 bcm_esw_tsn_taf_cosq_mapping_profile_get( 2144 int unit, 2145 int cosq_profile, 2146 bcm_cos_t priority, 2147 bcm_cos_queue_t *cosq) 2148 { 2149 int rv = BCM_E_UNAVAIL; 2150 2151 #if defined(BCM_TSN_SUPPORT) 2152 bcmi_tsn_taf_control_t *tc; 2153 2154 BCM_IF_ERROR_RETURN( 2155 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2156 2157 TSN_TAF_LOCK(tc); 2158 rv = TSN_TAF_FUNC( 2159 cosq_mapping_profile_get, (unit, cosq_profile, priority, cosq)); 2160 TSN_TAF_UNLOCK(tc); 2161 #endif /* BCM_TSN_SUPPORT */ 2162 2163 return rv; 2164 } 2165 2166 /* 2167 * Function: 2168 * bcm_esw_tsn_taf_cosq_mapping_profile_destroy 2169 * Purpose: 2170 * Destroy TAF Cos mapping profile 2171 * Parameters: 2172 * unit - (IN) unit number 2173 * cosq_profile - (IN) profile id 2174 * Returns: 2175 * BCM_E_XXX 2176 */ 2177 int 2178 bcm_esw_tsn_taf_cosq_mapping_profile_destroy( 2179 int unit, 2180 int cosq_profile) 2181 { 2182 int rv = BCM_E_UNAVAIL; 2183 2184 #if defined(BCM_TSN_SUPPORT) 2185 bcmi_tsn_taf_control_t *tc; 2186 2187 BCM_IF_ERROR_RETURN( 2188 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2189 2190 TSN_TAF_LOCK(tc); 2191 rv = TSN_TAF_FUNC( 2192 cosq_mapping_profile_destroy, (unit, cosq_profile)); 2193 TSN_TAF_UNLOCK(tc); 2194 #endif /* BCM_TSN_SUPPORT */ 2195 2196 return rv; 2197 } 2198 2199 /* 2200 * Function: 2201 * bcm_esw_tsn_taf_cosq_mapping_profile_traverse 2202 * Purpose: 2203 * Traverse TAF Cos mapping profile 2204 * Parameters: 2205 * unit - (IN) unit number 2206 * cb - (IN) callback function 2207 * user_data - (IN) user data 2208 * Returns: 2209 * BCM_E_XXX 2210 */ 2211 int 2212 bcm_esw_tsn_taf_cosq_mapping_profile_traverse( 2213 int unit, 2214 bcm_tsn_taf_cosq_mapping_profile_traverse_cb cb, 2215 void *user_data) 2216 { 2217 int rv = BCM_E_UNAVAIL; 2218 2219 #if defined(BCM_TSN_SUPPORT) 2220 bcmi_tsn_taf_control_t *tc; 2221 2222 BCM_IF_ERROR_RETURN( 2223 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2224 2225 TSN_TAF_LOCK(tc); 2226 rv = TSN_TAF_FUNC( 2227 cosq_mapping_profile_traverse, (unit, cb, user_data)); 2228 TSN_TAF_UNLOCK(tc); 2229 #endif /* BCM_TSN_SUPPORT */ 2230 2231 return rv; 2232 } 2233 2234 /* 2235 * Function: 2236 * bcm_esw_tsn_taf_gate_stat_set 2237 * Description: 2238 * Set 64-bit counter value for specified TAF gate statistic type 2239 * Parameters: 2240 * unit - (IN) unit number 2241 * taf_gate_id - (IN) TAF gate id 2242 * stat - (IN) TAF gate stat types 2243 * val - (IN) counter value 2244 * 2245 * Return Value: 2246 * BCM_E_XXX 2247 * Notes: 2248 */ 2249 int 2250 bcm_esw_tsn_taf_gate_stat_set( 2251 int unit, 2252 int taf_gate_id, 2253 bcm_tsn_taf_gate_stat_t stat, 2254 uint64 val) 2255 { 2256 int rv = BCM_E_UNAVAIL; 2257 2258 #if defined(BCM_TSN_SUPPORT) 2259 bcmi_tsn_taf_control_t *tc; 2260 2261 BCM_IF_ERROR_RETURN( 2262 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2263 2264 TSN_TAF_LOCK(tc); 2265 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 2266 2267 if (BCM_SUCCESS(rv)) { 2268 rv = TSN_TAF_FUNC(gate_stat_counter_access, 2269 (unit, taf_gate_id, 1, &stat, &val, 2270 bcmiTsnStatCounterActionWrite)); 2271 } 2272 TSN_TAF_UNLOCK(tc); 2273 #endif /* BCM_TSN_SUPPORT */ 2274 2275 return rv; 2276 } 2277 2278 /* 2279 * Function: 2280 * bcm_esw_tsn_taf_gate_stat_set32 2281 * Description: 2282 * Set lower 32-bit counter value for specified TAF gate statistic type 2283 * Parameters: 2284 * unit - (IN) unit number 2285 * taf_gate_id - (IN) TAF gate id 2286 * stat - (IN) TAF gate stat types 2287 * val - (IN) counter value 2288 * 2289 * Return Value: 2290 * BCM_E_XXX 2291 * Notes: 2292 */ 2293 int 2294 bcm_esw_tsn_taf_gate_stat_set32( 2295 int unit, 2296 int taf_gate_id, 2297 bcm_tsn_taf_gate_stat_t stat, 2298 uint32 val) 2299 { 2300 int rv = BCM_E_UNAVAIL; 2301 2302 #if defined(BCM_TSN_SUPPORT) 2303 bcmi_tsn_taf_control_t *tc; 2304 uint64 value64; 2305 2306 BCM_IF_ERROR_RETURN( 2307 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2308 2309 COMPILER_64_SET(value64, 0, val); 2310 2311 TSN_TAF_LOCK(tc); 2312 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 2313 2314 if (BCM_SUCCESS(rv)) { 2315 rv = TSN_TAF_FUNC(gate_stat_counter_access, 2316 (unit, taf_gate_id, 1, &stat, &value64, 2317 bcmiTsnStatCounterActionWrite)); 2318 } 2319 TSN_TAF_UNLOCK(tc); 2320 #endif /* BCM_TSN_SUPPORT */ 2321 2322 return rv; 2323 } 2324 2325 /* 2326 * Function: 2327 * bcm_esw_tsn_taf_gate_stat_get 2328 * Description: 2329 * Get 64-bit counter value for specified TAF gate statistic type 2330 * Parameters: 2331 * unit - (IN) unit number 2332 * taf_gate_id - (IN) TAF gate id 2333 * stat - (IN) TAF gate stat types 2334 * val - (OUT)counter value 2335 * 2336 * Return Value: 2337 * BCM_E_XXX 2338 * Notes: 2339 */ 2340 int 2341 bcm_esw_tsn_taf_gate_stat_get( 2342 int unit, 2343 int taf_gate_id, 2344 bcm_tsn_taf_gate_stat_t stat, 2345 uint64 *val) 2346 { 2347 int rv = BCM_E_UNAVAIL; 2348 2349 #if defined(BCM_TSN_SUPPORT) 2350 bcmi_tsn_taf_control_t *tc; 2351 2352 BCM_IF_ERROR_RETURN( 2353 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2354 2355 TSN_TAF_LOCK(tc); 2356 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 2357 2358 if (BCM_SUCCESS(rv)) { 2359 rv = TSN_TAF_FUNC(gate_stat_counter_access, 2360 (unit, taf_gate_id, 1, &stat, val, 2361 bcmiTsnStatCounterActionRead)); 2362 } 2363 TSN_TAF_UNLOCK(tc); 2364 #endif /* BCM_TSN_SUPPORT */ 2365 2366 return rv; 2367 } 2368 2369 /* 2370 * Function: 2371 * bcm_esw_tsn_taf_gate_stat_get32 2372 * Description: 2373 * Get lower 32-bit counter value for specified TAF gate statistic type 2374 * Parameters: 2375 * unit - (IN) unit number 2376 * taf_gate_id - (IN) TAF gate id 2377 * stat - (IN) TAF gate stat types 2378 * val - (OUT)counter value 2379 * 2380 * Return Value: 2381 * BCM_E_XXX 2382 * Notes: 2383 */ 2384 int 2385 bcm_esw_tsn_taf_gate_stat_get32( 2386 int unit, 2387 int taf_gate_id, 2388 bcm_tsn_taf_gate_stat_t stat, 2389 uint32 *val) 2390 { 2391 int rv = BCM_E_UNAVAIL; 2392 2393 #if defined(BCM_TSN_SUPPORT) 2394 bcmi_tsn_taf_control_t *tc; 2395 uint64 value64; 2396 2397 if (NULL == val) { 2398 return BCM_E_PARAM; 2399 } 2400 2401 BCM_IF_ERROR_RETURN( 2402 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2403 2404 TSN_TAF_LOCK(tc); 2405 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 2406 2407 if (BCM_SUCCESS(rv)) { 2408 rv = TSN_TAF_FUNC(gate_stat_counter_access, 2409 (unit, taf_gate_id, 1, &stat, &value64, 2410 bcmiTsnStatCounterActionRead)); 2411 } 2412 TSN_TAF_UNLOCK(tc); 2413 2414 if (BCM_SUCCESS(rv)) { 2415 *val = COMPILER_64_LO(value64); 2416 } 2417 #endif /* BCM_TSN_SUPPORT */ 2418 2419 return rv; 2420 } 2421 2422 /* 2423 * Function: 2424 * bcm_esw_tsn_taf_gate_stat_multi_set 2425 * Description: 2426 * Set 64-bit counter value for multiple TAF gate statistic types. 2427 * Parameters: 2428 * unit - (IN) unit number 2429 * taf_gate_id - (IN) TAF gate id 2430 * nstat - (IN) number of element in stat_arr and value_arr 2431 * stat_arr - (IN) TAF gate stat types 2432 * value_arr - (IN) counter value 2433 * 2434 * Return Value: 2435 * BCM_E_XXX 2436 * Notes: 2437 */ 2438 int 2439 bcm_esw_tsn_taf_gate_stat_multi_set( 2440 int unit, 2441 int taf_gate_id, 2442 int nstat, 2443 bcm_tsn_taf_gate_stat_t *stat_arr, 2444 uint64 *value_arr) 2445 { 2446 int rv = BCM_E_UNAVAIL; 2447 2448 #if defined(BCM_TSN_SUPPORT) 2449 bcmi_tsn_taf_control_t *tc; 2450 2451 if (nstat < 0 || nstat > bcmTsnTafGateStatCount) { 2452 return BCM_E_PARAM; 2453 } 2454 2455 BCM_IF_ERROR_RETURN( 2456 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2457 2458 TSN_TAF_LOCK(tc); 2459 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 2460 2461 if (BCM_SUCCESS(rv)) { 2462 rv = TSN_TAF_FUNC(gate_stat_counter_access, 2463 (unit, taf_gate_id, nstat, stat_arr, value_arr, 2464 bcmiTsnStatCounterActionWrite)); 2465 } 2466 TSN_TAF_UNLOCK(tc); 2467 #endif /* BCM_TSN_SUPPORT */ 2468 2469 return rv; 2470 } 2471 2472 /* 2473 * Function: 2474 * bcm_esw_tsn_taf_gate_stat_multi_set32 2475 * Description: 2476 * Set lower 32-bit counter value for multiple TAF gate statistic types. 2477 * Parameters: 2478 * unit - (IN) unit number 2479 * taf_gate_id - (IN) TAF gate id 2480 * nstat - (IN) number of element in stat_arr and value_arr 2481 * stat_arr - (IN) TAF gate stat types 2482 * value_arr - (IN) counter value 2483 * 2484 * Return Value: 2485 * BCM_E_XXX 2486 * Notes: 2487 */ 2488 int 2489 bcm_esw_tsn_taf_gate_stat_multi_set32( 2490 int unit, 2491 int taf_gate_id, 2492 int nstat, 2493 bcm_tsn_taf_gate_stat_t *stat_arr, 2494 uint32 *value_arr) 2495 { 2496 2497 int rv = BCM_E_UNAVAIL; 2498 2499 #if defined(BCM_TSN_SUPPORT) 2500 bcmi_tsn_taf_control_t *tc; 2501 uint64 *value64_arr = NULL; 2502 int i; 2503 2504 BCM_IF_ERROR_RETURN( 2505 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2506 2507 if (NULL == value_arr) { 2508 return BCM_E_PARAM; 2509 } 2510 2511 if (nstat < 0 || nstat > bcmTsnTafGateStatCount) { 2512 return BCM_E_PARAM; 2513 } 2514 2515 value64_arr = sal_alloc(nstat * sizeof(uint64), "value64_arr"); 2516 if (NULL == value64_arr) { 2517 return BCM_E_MEMORY; 2518 } 2519 for (i = 0; i < nstat ; i++) { 2520 COMPILER_64_SET(value64_arr[i], 0, value_arr[i]); 2521 } 2522 2523 TSN_TAF_LOCK(tc); 2524 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 2525 2526 if (BCM_SUCCESS(rv)) { 2527 rv = TSN_TAF_FUNC(gate_stat_counter_access, 2528 (unit, taf_gate_id, nstat, stat_arr, value64_arr, 2529 bcmiTsnStatCounterActionWrite)); 2530 } 2531 TSN_TAF_UNLOCK(tc); 2532 sal_free(value64_arr); 2533 #endif /* BCM_TSN_SUPPORT */ 2534 2535 return rv; 2536 2537 } 2538 2539 /* 2540 * Function: 2541 * bcm_esw_tsn_taf_gate_stat_multi_get 2542 * Description: 2543 * Get 64-bit counter value for multiple TAF gate statistic types. 2544 * Parameters: 2545 * unit - (IN) unit number 2546 * taf_gate_id - (IN) TAF gate id 2547 * nstat - (IN) size of stat_arr and value_arr 2548 * stat_arr - (IN) TAF gate stat types 2549 * value_arr - (OUT)counter value 2550 * 2551 * Return Value: 2552 * BCM_E_XXX 2553 * Notes: 2554 */ 2555 int 2556 bcm_esw_tsn_taf_gate_stat_multi_get( 2557 int unit, 2558 int taf_gate_id, 2559 int nstat, 2560 bcm_tsn_taf_gate_stat_t *stat_arr, 2561 uint64 *value_arr) 2562 { 2563 int rv = BCM_E_UNAVAIL; 2564 2565 #if defined(BCM_TSN_SUPPORT) 2566 bcmi_tsn_taf_control_t *tc; 2567 2568 if (nstat < 0 || nstat > bcmTsnTafGateStatCount) { 2569 return BCM_E_PARAM; 2570 } 2571 2572 BCM_IF_ERROR_RETURN( 2573 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2574 2575 TSN_TAF_LOCK(tc); 2576 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 2577 2578 if (BCM_SUCCESS(rv)) { 2579 rv = TSN_TAF_FUNC(gate_stat_counter_access, 2580 (unit, taf_gate_id, nstat, stat_arr, value_arr, 2581 bcmiTsnStatCounterActionRead)); 2582 } 2583 TSN_TAF_UNLOCK(tc); 2584 #endif /* BCM_TSN_SUPPORT */ 2585 2586 return rv; 2587 } 2588 2589 /* 2590 * Function: 2591 * bcm_esw_tsn_taf_gate_stat_multi_get32 2592 * Description: 2593 * Get lower 32-bit counter value for multiple TAF gate statistic types. 2594 * Parameters: 2595 * unit - (IN) unit number 2596 * taf_gate_id - (IN) TAF gate id 2597 * nstat - (IN) size of stat_arr and value_arr 2598 * stat_arr - (IN) TAF gate stat types 2599 * value_arr - (OUT)counter value 2600 * 2601 * Return Value: 2602 * BCM_E_XXX 2603 * Notes: 2604 */ 2605 int 2606 bcm_esw_tsn_taf_gate_stat_multi_get32( 2607 int unit, 2608 int taf_gate_id, 2609 int nstat, 2610 bcm_tsn_taf_gate_stat_t *stat_arr, 2611 uint32 *value_arr) 2612 { 2613 int rv = BCM_E_UNAVAIL; 2614 2615 #if defined(BCM_TSN_SUPPORT) 2616 bcmi_tsn_taf_control_t *tc; 2617 uint64 *value64_arr = NULL; 2618 int i; 2619 2620 BCM_IF_ERROR_RETURN( 2621 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2622 2623 if (NULL == value_arr) { 2624 return BCM_E_PARAM; 2625 } 2626 2627 if (nstat < 0 || nstat > bcmTsnTafGateStatCount) { 2628 return BCM_E_PARAM; 2629 } 2630 2631 value64_arr = sal_alloc(nstat * sizeof(uint64), "value64_arr"); 2632 if (NULL == value64_arr) { 2633 return BCM_E_MEMORY; 2634 } 2635 2636 TSN_TAF_LOCK(tc); 2637 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 2638 2639 if (BCM_SUCCESS(rv)) { 2640 rv = TSN_TAF_FUNC(gate_stat_counter_access, 2641 (unit, taf_gate_id, nstat, stat_arr, value64_arr, 2642 bcmiTsnStatCounterActionRead)); 2643 } 2644 TSN_TAF_UNLOCK(tc); 2645 2646 if (BCM_SUCCESS(rv)) { 2647 for (i = 0; i < nstat ; i++) { 2648 value_arr[i] = COMPILER_64_LO(value64_arr[i]); 2649 } 2650 } 2651 sal_free(value64_arr); 2652 #endif /* BCM_TSN_SUPPORT */ 2653 2654 return rv; 2655 } 2656 2657 /* 2658 * Function: 2659 * bcm_esw_tsn_taf_gate_stat_sync_get 2660 * Description: 2661 * Get the specified hardware statistics (64-bit) from the device. 2662 * Parameters: 2663 * unit - (IN) unit number 2664 * taf_gate_id - (IN) TAF gate id 2665 * stat - (IN) TAF gate stat types 2666 * val - (OUT)counter value 2667 * 2668 * Return Value: 2669 * BCM_E_XXX 2670 * Notes: 2671 */ 2672 int 2673 bcm_esw_tsn_taf_gate_stat_sync_get( 2674 int unit, 2675 int taf_gate_id, 2676 bcm_tsn_taf_gate_stat_t stat, 2677 uint64 *val) 2678 { 2679 int rv = BCM_E_UNAVAIL; 2680 2681 #if defined(BCM_TSN_SUPPORT) 2682 bcmi_tsn_taf_control_t *tc; 2683 2684 BCM_IF_ERROR_RETURN( 2685 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2686 2687 TSN_TAF_LOCK(tc); 2688 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 2689 2690 if (BCM_SUCCESS(rv)) { 2691 rv = TSN_TAF_FUNC(gate_stat_counter_access, 2692 (unit, taf_gate_id, 1, &stat, val, 2693 bcmiTsnStatCounterActionReadSync)); 2694 } 2695 TSN_TAF_UNLOCK(tc); 2696 #endif /* BCM_TSN_SUPPORT */ 2697 2698 return rv; 2699 } 2700 2701 /* 2702 * Function: 2703 * bcm_esw_tsn_taf_gate_stat_sync_get32 2704 * Description: 2705 * Get the specified hardware statistics (32-bit) from the device. 2706 * Parameters: 2707 * unit - (IN) unit number 2708 * taf_gate_id - (IN) TAF gate id 2709 * stat - (IN) TAF gate stat types 2710 * val - (OUT)counter value 2711 * 2712 * Return Value: 2713 * BCM_E_XXX 2714 * Notes: 2715 */ 2716 int 2717 bcm_esw_tsn_taf_gate_stat_sync_get32( 2718 int unit, 2719 int taf_gate_id, 2720 bcm_tsn_taf_gate_stat_t stat, 2721 uint32 *val) 2722 { 2723 int rv = BCM_E_UNAVAIL; 2724 2725 #if defined(BCM_TSN_SUPPORT) 2726 bcmi_tsn_taf_control_t *tc; 2727 uint64 value64; 2728 2729 BCM_IF_ERROR_RETURN( 2730 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2731 2732 if (NULL == val) { 2733 return BCM_E_PARAM; 2734 } 2735 2736 TSN_TAF_LOCK(tc); 2737 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 2738 2739 if (BCM_SUCCESS(rv)) { 2740 rv = TSN_TAF_FUNC(gate_stat_counter_access, 2741 (unit, taf_gate_id, 1, &stat, &value64, 2742 bcmiTsnStatCounterActionReadSync)); 2743 } 2744 TSN_TAF_UNLOCK(tc); 2745 2746 2747 if (BCM_SUCCESS(rv)) { 2748 *val = COMPILER_64_LO(value64); 2749 } 2750 #endif /* BCM_TSN_SUPPORT */ 2751 2752 return rv; 2753 } 2754 2755 /* 2756 * Function: 2757 * bcm_esw_tsn_taf_gate_stat_sync_multi_get 2758 * Description: 2759 * Get multiple hardware statistics (64-bit) from the device 2760 * Parameters: 2761 * unit - (IN) unit number 2762 * taf_gate_id - (IN) TAF gate id 2763 * nstat - (IN) size of stat_arr and value_arr 2764 * stat_arr - (IN) TAF gate stat types 2765 * value_arr - (OUT)counter value 2766 * 2767 * Return Value: 2768 * BCM_E_XXX 2769 * Notes: 2770 */ 2771 int 2772 bcm_esw_tsn_taf_gate_stat_sync_multi_get( 2773 int unit, 2774 int taf_gate_id, 2775 int nstat, 2776 bcm_tsn_taf_gate_stat_t *stat_arr, 2777 uint64 *value_arr) 2778 { 2779 int rv = BCM_E_UNAVAIL; 2780 2781 #if defined(BCM_TSN_SUPPORT) 2782 bcmi_tsn_taf_control_t *tc; 2783 2784 if (nstat < 0 || nstat > bcmTsnTafGateStatCount) { 2785 return BCM_E_PARAM; 2786 } 2787 2788 BCM_IF_ERROR_RETURN( 2789 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2790 2791 TSN_TAF_LOCK(tc); 2792 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 2793 2794 if (BCM_SUCCESS(rv)) { 2795 rv = TSN_TAF_FUNC(gate_stat_counter_access, 2796 (unit, taf_gate_id, nstat, stat_arr, value_arr, 2797 bcmiTsnStatCounterActionReadSync)); 2798 } 2799 TSN_TAF_UNLOCK(tc); 2800 #endif /* BCM_TSN_SUPPORT */ 2801 2802 return rv; 2803 } 2804 2805 /* 2806 * Function: 2807 * bcm_esw_tsn_taf_gate_stat_sync_multi_get32 2808 * Description: 2809 * Get multiple hardware statistics (32-bit) from the device 2810 * Parameters: 2811 * unit - (IN) unit number 2812 * taf_gate_id - (IN) TAF gate id 2813 * nstat - (IN) size of stat_arr and value_arr 2814 * stat_arr - (IN) TAF gate stat types 2815 * value_arr - (OUT)counter value 2816 * 2817 * Return Value: 2818 * BCM_E_XXX 2819 * Notes: 2820 */ 2821 int 2822 bcm_esw_tsn_taf_gate_stat_sync_multi_get32( 2823 int unit, 2824 int taf_gate_id, 2825 int nstat, 2826 bcm_tsn_taf_gate_stat_t *stat_arr, 2827 uint32 *value_arr) 2828 { 2829 int rv = BCM_E_UNAVAIL; 2830 2831 #if defined(BCM_TSN_SUPPORT) 2832 bcmi_tsn_taf_control_t *tc; 2833 uint64 *value64_arr = NULL; 2834 int i; 2835 2836 BCM_IF_ERROR_RETURN( 2837 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2838 2839 if (NULL == value_arr) { 2840 return BCM_E_PARAM; 2841 } 2842 2843 if (nstat < 0 || nstat > bcmTsnTafGateStatCount) { 2844 return BCM_E_PARAM; 2845 } 2846 2847 value64_arr = sal_alloc(nstat * sizeof(uint64), "value64_arr"); 2848 if (NULL == value64_arr) { 2849 return BCM_E_MEMORY; 2850 } 2851 2852 TSN_TAF_LOCK(tc); 2853 rv = TSN_TAF_FUNC(gate_check, (unit, taf_gate_id)); 2854 2855 if (BCM_SUCCESS(rv)) { 2856 rv = TSN_TAF_FUNC(gate_stat_counter_access, 2857 (unit, taf_gate_id, nstat, stat_arr, value64_arr, 2858 bcmiTsnStatCounterActionReadSync)); 2859 } 2860 TSN_TAF_UNLOCK(tc); 2861 2862 if (BCM_SUCCESS(rv)) { 2863 for (i = 0; i < nstat ; i++) { 2864 value_arr[i] = COMPILER_64_LO(value64_arr[i]); 2865 } 2866 } 2867 sal_free(value64_arr); 2868 #endif /* BCM_TSN_SUPPORT */ 2869 2870 return rv; 2871 } 2872 2873 #if defined(BCM_TSN_SUPPORT) 2874 /* 2875 * Function: 2876 * bcmi_esw_tsn_taf_gate_stat_sync 2877 * Description: 2878 * Callback function for counter collection on a specific gate 2879 * Parameters: 2880 * unit - (IN) Unit number 2881 * Returns: 2882 * BCM_E_XXX 2883 */ 2884 2885 STATIC int 2886 bcmi_esw_tsn_taf_gate_stat_sync( 2887 int unit, 2888 int taf_gate, 2889 void *user_data) 2890 { 2891 return TSN_TAF_FUNC(gate_stat_counter_sync, (unit, taf_gate)); 2892 } 2893 2894 /* 2895 * Function: 2896 * bcmi_esw_tsn_stat_counter_cb 2897 * Description: 2898 * Callback function for counter collection 2899 * Parameters: 2900 * unit - (IN) Unit number 2901 * Returns: 2902 * BCM_E_XXX 2903 */ 2904 STATIC void 2905 bcmi_esw_tsn_taf_gate_stat_cb(int unit) 2906 { 2907 bcmi_tsn_taf_control_t *tc; 2908 int rv; 2909 2910 rv = bcmi_esw_tsn_taf_instance_get(unit, &tc); 2911 if (BCM_FAILURE(rv)) { 2912 return; 2913 } 2914 2915 TSN_TAF_LOCK(tc); 2916 (void)TSN_TAF_FUNC(gate_traverse, 2917 (unit, bcmi_esw_tsn_taf_gate_stat_sync, NULL)); 2918 TSN_TAF_UNLOCK(tc); 2919 } 2920 2921 /* TAF gate Priority Map driver set */ 2922 tsn_pri_map_info_t bcmi_taf_gate_pri_map_info = { 2923 "taf_gate_priority_map", /* table_name */ 2924 0, /* table_size, 2925 * init at bcmi_esw_tsn_taf_init */ 2926 0, /* entry_size, 2927 * init at bcmi_esw_tsn_taf_init */ 2928 bcmi_esw_tsn_taf_gate_pri_map_set, /* tsn_pri_map_set */ 2929 bcmi_esw_tsn_taf_gate_pri_map_get, /* tsn_pri_map_get */ 2930 bcmi_esw_tsn_taf_gate_pri_map_delete, /* tsn_pri_map_delete */ 2931 bcmi_esw_tsn_taf_gate_pri_map_hw_idx_get, /* tsn_pri_map_hw_index_get */ 2932 bcmi_esw_tsn_taf_gate_pri_map_sw_idx_get, /* tsn_pri_map_sw_idx_get */ 2933 bcmi_esw_tsn_taf_gate_pri_map_wb_hw_existed /* tsn_pri_map_wb_hw_existed */ 2934 }; 2935 2936 #if defined(BCM_WARM_BOOT_SUPPORT) 2937 int 2938 bcmi_esw_tsn_taf_sync(int unit) 2939 { 2940 int rv = BCM_E_UNAVAIL; 2941 2942 #if defined(BCM_TSN_SUPPORT) 2943 bcmi_tsn_taf_control_t *tc; 2944 soc_scache_handle_t scache_handle; 2945 uint8 *scache_ptr; 2946 int scache_size; 2947 2948 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_TSN, 2949 BCM_TSN_WB_SCACHE_PART_TAF); 2950 2951 BCM_IF_ERROR_RETURN( 2952 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2953 2954 TSN_TAF_LOCK(tc); 2955 rv = TSN_TAF_FUNC(get_scache_size, (unit, &scache_size)); 2956 2957 if (BCM_SUCCESS(rv)) { 2958 rv = _bcm_esw_scache_ptr_get( 2959 unit, scache_handle, TRUE, 2960 scache_size, 2961 &scache_ptr, BCM_TSN_WB_DEFAULT_VERSION, NULL); 2962 } 2963 2964 if (BCM_SUCCESS(rv)) { 2965 rv = TSN_TAF_FUNC(sync, (unit, scache_ptr)); 2966 } 2967 TSN_TAF_UNLOCK(tc); 2968 #endif /* BCM_TSN_SUPPORT */ 2969 2970 return rv; 2971 } 2972 2973 int 2974 bcmi_esw_tsn_taf_reload(int unit) 2975 { 2976 int rv = BCM_E_UNAVAIL; 2977 2978 #if defined(BCM_TSN_SUPPORT) 2979 bcmi_tsn_taf_control_t *tc; 2980 soc_scache_handle_t scache_handle; 2981 uint8 *scache_ptr; 2982 int scache_size; 2983 2984 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_TSN, 2985 BCM_TSN_WB_SCACHE_PART_TAF); 2986 2987 BCM_IF_ERROR_RETURN( 2988 bcmi_esw_tsn_taf_instance_get(unit, &tc)); 2989 2990 TSN_TAF_LOCK(tc); 2991 rv = TSN_TAF_FUNC(get_scache_size, (unit, &scache_size)); 2992 2993 if (BCM_SUCCESS(rv)) { 2994 rv = _bcm_esw_scache_ptr_get( 2995 unit, scache_handle, FALSE, 2996 scache_size, 2997 &scache_ptr, BCM_TSN_WB_DEFAULT_VERSION, NULL); 2998 } 2999 3000 if (BCM_E_NOT_FOUND == rv) { 3001 /* Maybe proceed with Level 1 Warm Boot */ 3002 TSN_TAF_UNLOCK(tc); 3003 return BCM_E_NONE; 3004 } else if (BCM_E_NONE == rv) { 3005 if (NULL == scache_ptr) { 3006 rv = BCM_E_INTERNAL; 3007 } else { 3008 rv = TSN_TAF_FUNC(reload, (unit, scache_ptr)); 3009 } 3010 } 3011 3012 if (BCM_SUCCESS(rv)) { 3013 /* after reloading in chip level successfully, 3014 * all internal profile has already been recoverd 3015 * ==> start to recover taf_profile_pending/active in esw layer 3016 */ 3017 int gate_id, profile_id; 3018 3019 for (gate_id = 0; gate_id < BCMI_TSN_TAF_GATE_NUM; gate_id++) { 3020 rv = TSN_TAF_FUNC(gate_check, (unit, gate_id)); 3021 if (BCM_FAILURE(rv)) { 3022 rv = BCM_E_NONE; 3023 continue; /* skip invalid gate */ 3024 } 3025 3026 for (profile_id = 0; profile_id < BCMI_TSN_TAF_PROFILE_NUM_MAX; 3027 profile_id++) { 3028 3029 bcmi_tsn_taf_profile_t *profile_i; 3030 3031 rv = TSN_TAF_FUNC( 3032 calendar_profile_get, (unit, profile_id, 3033 &profile_i)); 3034 if (BCM_FAILURE(rv)) { 3035 rv = BCM_E_NONE; 3036 continue; /* skip invalid profile id */ 3037 } else if (profile_i->taf_gate != gate_id) { 3038 continue; /* skip the profile not owned by this gate */ 3039 } 3040 3041 if (profile_i->status == bcmTsnTafProfilePending) { 3042 taf_profile_pending[unit][gate_id] = profile_i; 3043 } else if (profile_i->status == bcmTsnTafProfileActive) { 3044 taf_profile_active[unit][gate_id] = profile_i; 3045 } 3046 } 3047 } 3048 } 3049 3050 TSN_TAF_UNLOCK(tc); 3051 3052 /* register handler to handle interrupt after recover database */ 3053 if (BCM_SUCCESS(rv)) { 3054 #if defined(BCM_GREYHOUND2_SUPPORT) 3055 if (SOC_IS_GREYHOUND2(unit)) { 3056 rv = soc_gh2_taf_event_handler_register( 3057 unit, bcmi_esw_tsn_taf_interrupt_handle); 3058 } 3059 #endif /* BCM_GREYHOUND2_SUPPORT */ 3060 } 3061 #endif /* BCM_TSN_SUPPORT */ 3062 3063 return rv; 3064 } 3065 #endif /* BCM_WARM_BOOT_SUPPORT */ 3066 3067 3068 /* 3069 * Function: 3070 * bcmi_esw_tsn_taf_cleanup 3071 * Description: 3072 * Clean and free all allocated TAF resources 3073 * Parameters: 3074 * unit - (IN) Unit number 3075 * Returns: 3076 * BCM_E_XXX 3077 */ 3078 void 3079 bcmi_esw_tsn_taf_cleanup(int unit) 3080 { 3081 if (taf_control[unit] != NULL) { 3082 int i; 3083 3084 if (NULL != taf_control[unit]->taf_dev_info) { 3085 TSN_TAF_FUNC(cleanup, (unit)); 3086 } 3087 3088 if (NULL != taf_control[unit]->taf_mutex) { 3089 sal_mutex_destroy(taf_control[unit]->taf_mutex); 3090 taf_control[unit]->taf_mutex = NULL; 3091 } 3092 3093 for (i = 0; i < BCMI_TSN_TAF_GATE_NUM; i++) { 3094 taf_profile_pending[unit][i] = NULL; 3095 taf_profile_active[unit][i] = NULL; 3096 } 3097 3098 #if defined(BCM_GREYHOUND2_SUPPORT) 3099 if (SOC_IS_GREYHOUND2(unit)) { 3100 soc_gh2_taf_event_handler_register(unit, NULL); 3101 } 3102 #endif /* BCM_GREYHOUND2_SUPPORT */ 3103 3104 soc_counter_extra_unregister(unit, bcmi_esw_tsn_taf_gate_stat_cb); 3105 3106 sal_free(taf_control[unit]); 3107 taf_control[unit] = NULL; 3108 } 3109 } 3110 3111 /* 3112 * Function: 3113 * bcmi_esw_tsn_taf_init 3114 * Description: 3115 * Initialize and allocate all required resources for TAF 3116 * in both coldboot and warmboot 3117 * Parameters: 3118 * unit - (IN) Unit number 3119 * Returns: 3120 * BCM_E_XXX 3121 */ 3122 int 3123 bcmi_esw_tsn_taf_init(int unit) 3124 { 3125 int rv = BCM_E_NONE; 3126 bcmi_tsn_taf_control_t *tc; 3127 3128 /* Clean up the TAF related resources */ 3129 if (taf_control[unit] != NULL) { 3130 bcmi_esw_tsn_taf_cleanup(unit); 3131 } 3132 3133 /* Allocate TAF resource for this unit. */ 3134 taf_control[unit] = sal_alloc(sizeof(bcmi_tsn_taf_control_t), 3135 "taf control"); 3136 tc = taf_control[unit]; 3137 if (NULL == tc) { 3138 TSN_TAF_INIT_ERROR_WITH_CLEAN(BCM_E_MEMORY); 3139 } 3140 sal_memset(tc, 0, sizeof(bcmi_tsn_taf_control_t)); 3141 3142 /* Get the chip bcmi_tsn_taf_dev_info_t structure. */ 3143 #if defined(BCM_GREYHOUND2_SUPPORT) 3144 if (SOC_IS_GREYHOUND2(unit)) { 3145 rv = bcmi_gh2_taf_info_init(unit, &tc->taf_dev_info); 3146 if (BCM_SUCCESS(rv) && NULL == tc->taf_dev_info) { 3147 TSN_TAF_INIT_ERROR_WITH_CLEAN(BCM_E_INIT); 3148 } 3149 } else 3150 #endif /* BCM_GREYHOUND2_SUPPORT */ 3151 { 3152 TSN_TAF_INIT_ERROR_WITH_CLEAN(BCM_E_UNAVAIL); 3153 } 3154 3155 tc->taf_mutex = sal_mutex_create("taf mutex"); 3156 if (NULL == tc->taf_mutex) { 3157 TSN_TAF_INIT_ERROR_WITH_CLEAN(BCM_E_RESOURCE); 3158 } 3159 3160 /* init functionality per-chip */ 3161 TSN_TAF_INIT_ERROR_WITH_CLEAN( 3162 TSN_TAF_FUNC(init, (unit))); 3163 3164 /* Register callback function for gate stat counter */ 3165 TSN_TAF_INIT_ERROR_WITH_CLEAN( 3166 soc_counter_extra_register(unit, bcmi_esw_tsn_taf_gate_stat_cb)); 3167 3168 /* setup primap driver parameter per-chip */ 3169 bcmi_taf_gate_pri_map_info.table_size = TSN_TAF_DATA(gate_profile_num); 3170 bcmi_taf_gate_pri_map_info.entry_size = TSN_TAF_DATA(gate_intpri_num); 3171 3172 return BCM_E_NONE; 3173 } 3174 3175 /* 3176 * Function: 3177 * bcmi_esw_tsn_taf_coldboot_init 3178 * Description: 3179 * Initialize and allocate all required resources for TAF in coldboot 3180 * Parameters: 3181 * unit - (IN) Unit number 3182 * Returns: 3183 * BCM_E_XXX 3184 */ 3185 int 3186 bcmi_esw_tsn_taf_coldboot_init(int unit) 3187 { 3188 /* register handler to handle interrupt */ 3189 #if defined(BCM_GREYHOUND2_SUPPORT) 3190 if (SOC_IS_GREYHOUND2(unit)) { 3191 TSN_TAF_INIT_ERROR_WITH_CLEAN( 3192 soc_gh2_taf_event_handler_register( 3193 unit, bcmi_esw_tsn_taf_interrupt_handle)); 3194 } 3195 #endif /* BCM_GREYHOUND2_SUPPORT */ 3196 3197 return BCM_E_NONE; 3198 } 3199 #endif /* BCM_TSN_SUPPORT */