bfd.c (18902B)
1 /* 2 * 3 * 4 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 5 * 6 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 7 * 8 * File: bfd.c 9 * Purpose: Bidirectional Forwarding Detection APIs. 10 * 11 * Notes: BFD functions will return BCM_E_UAVAIL unless the following 12 * feature is available: soc_feature_bfd 13 */ 14 15 #include <soc/defs.h> 16 #include <shared/bsl.h> 17 #if defined(INCLUDE_BFD) 18 19 #include <soc/drv.h> 20 #include <bcm_int/esw/bfd.h> 21 #include <bcm/bfd.h> 22 #include <bcm/error.h> 23 24 #if defined(BCM_KATANA_SUPPORT) 25 #include <bcm_int/esw/katana.h> 26 #endif /* BCM_KATANA_SUPPORT */ 27 #if defined(BCM_TRIUMPH3_SUPPORT) 28 #include <bcm_int/esw/triumph3.h> 29 #endif /* BCM_TRIUMPH3_SUPPORT */ 30 #if defined(BCM_TRIDENT2_SUPPORT) 31 #include <bcm_int/esw/trident2.h> 32 #endif /* BCM_TRIDENT2_SUPPORT */ 33 34 /* 35 * BFD Function Vector Driver 36 */ 37 bcm_esw_bfd_drv_t *bcm_esw_bfd_drv[BCM_MAX_NUM_UNITS] = {0}; 38 39 /* 40 * BFD Lock 41 */ 42 static sal_mutex_t mutex[BCM_MAX_NUM_UNITS]; 43 44 /* 45 * Macro: 46 * BFD_INIT 47 * Purpose: 48 * Causes a routine to return BCM_E_UNAVAIL (feature not available), or 49 * BCM_E_INIT (BFD not initialized). 50 */ 51 #define BFD_INIT(unit) \ 52 if (!soc_feature(unit, soc_feature_bfd)) { \ 53 return BCM_E_UNAVAIL; \ 54 } else if (BCM_ESW_BFD_DRV(unit) == NULL) { \ 55 return BCM_E_UNAVAIL; \ 56 } else if (mutex[unit] == NULL) { \ 57 return BCM_E_INIT; \ 58 } 59 60 61 #define BFD_LOCK(unit) sal_mutex_take(mutex[unit], sal_mutex_FOREVER) 62 #define BFD_UNLOCK(unit) sal_mutex_give(mutex[unit]) 63 64 65 /* 66 * Function: 67 * bcm_esw_bfd_init 68 * Purpose: 69 * Initialize the BFD subsystem 70 * Parameters: 71 * unit - (IN) Unit number. 72 * Returns: 73 * BCM_E_XXX 74 * Notes: 75 */ 76 int 77 bcm_esw_bfd_init(int unit) 78 { 79 int result = BCM_E_UNAVAIL; 80 81 if (soc_feature(unit, soc_feature_bfd)) { 82 if (SAL_BOOT_PLISIM) { 83 return SOC_E_NONE; 84 } 85 86 if (mutex[unit] == NULL) { 87 mutex[unit] = sal_mutex_create("bfd.mutex"); 88 89 if (mutex[unit] == NULL) { 90 return BCM_E_MEMORY; 91 } 92 } 93 94 #if defined(BCM_KATANA_SUPPORT) 95 if (SOC_IS_KATANAX(unit)) { 96 result = bcmi_kt_bfd_init(unit); 97 } else 98 #endif 99 #if defined(BCM_TRIUMPH3_SUPPORT) 100 if (SOC_IS_TRIUMPH3(unit)) { 101 result = bcmi_tr3_bfd_init(unit); 102 } else 103 #endif 104 #if defined(BCM_TRIDENT2_SUPPORT) 105 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TRIDENT3X(unit) || 106 SOC_IS_TOMAHAWKX(unit)) { 107 result = bcmi_td2_bfd_init(unit); 108 } else 109 #endif 110 { 111 LOG_CLI((BSL_META_U(unit, 112 "Not implemented.\n"))); 113 result = BCM_E_INTERNAL; 114 } 115 116 if (BCM_FAILURE(result)) { 117 sal_mutex_destroy(mutex[unit]); 118 mutex[unit] = NULL; 119 } 120 } 121 122 return result; 123 } 124 125 /* 126 * Function: 127 * bcm_esw_bfd_detach 128 * Purpose: 129 * Shut down the BFD subsystem 130 * Parameters: 131 * unit - (IN) Unit number. 132 * Returns: 133 * BCM_E_XXX 134 * Notes: 135 */ 136 int 137 bcm_esw_bfd_detach(int unit) 138 { 139 int result = BCM_E_UNAVAIL; 140 141 if (soc_feature(unit, soc_feature_bfd)) { 142 143 if (mutex[unit] == NULL) { 144 return BCM_E_NONE; 145 } 146 147 BFD_LOCK(unit); 148 149 if ((BCM_ESW_BFD_DRV(unit) != NULL) && 150 (BCM_ESW_BFD_DRV(unit)->detach != NULL)) { 151 result = BCM_ESW_BFD_DRV(unit)->detach(unit); 152 } 153 154 BFD_UNLOCK(unit); 155 156 sal_mutex_destroy(mutex[unit]); 157 mutex[unit] = NULL; 158 } 159 160 return result; 161 } 162 163 /* 164 * Function: 165 * bcm_esw_bfd_endpoint_create 166 * Purpose: 167 * Create or replace an BFD endpoint object 168 * Parameters: 169 * unit - (IN) Unit number. 170 * endpoint_info - (IN/OUT) Pointer to an BFD endpoint structure 171 * Returns: 172 * BCM_E_XXX 173 * Notes: 174 */ 175 int 176 bcm_esw_bfd_endpoint_create(int unit, 177 bcm_bfd_endpoint_info_t *endpoint_info) 178 { 179 int result = BCM_E_UNAVAIL; 180 181 BFD_INIT(unit); 182 183 BFD_LOCK(unit); 184 185 if (BCM_ESW_BFD_DRV(unit)->endpoint_create != NULL) { 186 result = BCM_ESW_BFD_DRV(unit)->endpoint_create(unit, endpoint_info); 187 } 188 189 BFD_UNLOCK(unit); 190 191 return result; 192 } 193 194 /* 195 * Function: 196 * bcm_esw_bfd_endpoint_get 197 * Purpose: 198 * Get an BFD endpoint object 199 * Parameters: 200 * unit - (IN) Unit number. 201 * endpoint - (IN) The ID of the endpoint object to get 202 * endpoint_info - (OUT) Pointer to an BFD endpoint structure to 203 * receive the data 204 * Returns: 205 * BCM_E_XXX 206 * Notes: 207 */ 208 int 209 bcm_esw_bfd_endpoint_get(int unit, 210 bcm_bfd_endpoint_t endpoint, 211 bcm_bfd_endpoint_info_t *endpoint_info) 212 { 213 int result = BCM_E_UNAVAIL; 214 215 BFD_INIT(unit); 216 217 BFD_LOCK(unit); 218 219 if (BCM_ESW_BFD_DRV(unit)->endpoint_get != NULL) { 220 result = BCM_ESW_BFD_DRV(unit)->endpoint_get(unit, endpoint, 221 endpoint_info); 222 } 223 224 BFD_UNLOCK(unit); 225 226 return result; 227 } 228 229 /* 230 * Function: 231 * bcm_esw_bfd_tx_start 232 * Purpose: 233 * Start all BFD endpoint TX PDUs 234 * Parameters: 235 * unit - (IN) Unit number. 236 * results: 237 * BCM_E_XXX 238 * Notes: 239 */ 240 int 241 bcm_esw_bfd_tx_start(int unit) 242 { 243 int result = BCM_E_UNAVAIL; 244 245 BFD_INIT(unit); 246 247 BFD_LOCK(unit); 248 249 if (BCM_ESW_BFD_DRV(unit)->tx_start != NULL) { 250 result = BCM_ESW_BFD_DRV(unit)->tx_start(unit); 251 } 252 253 BFD_UNLOCK(unit); 254 255 return result; 256 } 257 258 /* 259 * Function: 260 * bcm_esw_bfd_tx_stop 261 * Purpose: 262 * Stop all BFD endpoint TX PDUs 263 * Parameters: 264 * unit - (IN) Unit number. 265 * results: 266 * BCM_E_XXX 267 * Notes: 268 */ 269 int 270 bcm_esw_bfd_tx_stop(int unit) 271 { 272 int result = BCM_E_UNAVAIL; 273 274 BFD_INIT(unit); 275 276 BFD_LOCK(unit); 277 278 if (BCM_ESW_BFD_DRV(unit)->tx_stop != NULL) { 279 result = BCM_ESW_BFD_DRV(unit)->tx_stop(unit); 280 } 281 282 BFD_UNLOCK(unit); 283 284 return result; 285 } 286 287 /* 288 * Function: 289 * bcm_esw_bfd_endpoint_destroy 290 * Purpose: 291 * Destroy a BFD endpoint object 292 * Parameters: 293 * unit - (IN) Unit number. 294 * endpoint - (IN) The ID of the BFD endpoint object to destroy 295 * Returns: 296 * BCM_E_XXX 297 * Notes: 298 */ 299 int 300 bcm_esw_bfd_endpoint_destroy(int unit, 301 bcm_bfd_endpoint_t endpoint) 302 { 303 int result = BCM_E_UNAVAIL; 304 305 BFD_INIT(unit); 306 307 BFD_LOCK(unit); 308 309 if (BCM_ESW_BFD_DRV(unit)->endpoint_destroy != NULL) { 310 result = BCM_ESW_BFD_DRV(unit)->endpoint_destroy(unit, endpoint); 311 } 312 313 BFD_UNLOCK(unit); 314 315 return result; 316 } 317 318 /* 319 * Function: 320 * bcm_esw_bfd_endpoint_destroy_all 321 * Purpose: 322 * Destroy all BFD endpoint objects 323 * Parameters: 324 * unit - (IN) Unit number. 325 * results: 326 * BCM_E_XXX 327 * Notes: 328 */ 329 int 330 bcm_esw_bfd_endpoint_destroy_all(int unit) 331 { 332 int result = BCM_E_UNAVAIL; 333 334 BFD_INIT(unit); 335 336 BFD_LOCK(unit); 337 338 if (BCM_ESW_BFD_DRV(unit)->endpoint_destroy_all != NULL) { 339 result = BCM_ESW_BFD_DRV(unit)->endpoint_destroy_all(unit); 340 } 341 342 BFD_UNLOCK(unit); 343 344 return result; 345 } 346 347 /* 348 * Function: 349 * bcm_esw_bfd_endpoint_poll 350 * Purpose: 351 * Poll a BFD endpoint object 352 * Parameters: 353 * unit - (IN) Unit number. 354 * endpoint - (IN) The ID of the BFD endpoint object to poll 355 * Returns: 356 * BCM_E_XXX 357 * Notes: 358 */ 359 int 360 bcm_esw_bfd_endpoint_poll(int unit, 361 bcm_bfd_endpoint_t endpoint) 362 { 363 int result = BCM_E_UNAVAIL; 364 365 BFD_INIT(unit); 366 367 BFD_LOCK(unit); 368 369 if (BCM_ESW_BFD_DRV(unit)->endpoint_poll!= NULL) { 370 result = BCM_ESW_BFD_DRV(unit)->endpoint_poll(unit, endpoint); 371 } 372 373 BFD_UNLOCK(unit); 374 375 return result; 376 } 377 378 /* 379 * Function: 380 * bcm_esw_bfd_event_register 381 * Purpose: 382 * Register a callback for handling BFD events 383 * Parameters: 384 * unit - (IN) Unit number. 385 * event_types - (IN) The set of BFD events for which 386 * the specified callback should be called 387 * cb - (IN) A pointer to the callback function to call 388 * for the specified BFD events 389 * user_data - (IN) Pointer to user data to supply in the callback 390 * Returns: 391 * BCM_E_XXX 392 * Notes: 393 */ 394 int 395 bcm_esw_bfd_event_register(int unit, 396 bcm_bfd_event_types_t event_types, 397 bcm_bfd_event_cb cb, 398 void *user_data) 399 { 400 int result = BCM_E_UNAVAIL; 401 402 BFD_INIT(unit); 403 404 BFD_LOCK(unit); 405 406 if (BCM_ESW_BFD_DRV(unit)->event_register != NULL) { 407 result = BCM_ESW_BFD_DRV(unit)->event_register(unit, 408 event_types, 409 cb, user_data); 410 } 411 412 BFD_UNLOCK(unit); 413 414 return result; 415 } 416 417 /* 418 * Function: 419 * bcm_esw_bfd_event_unregister 420 * Purpose: 421 * Unregister a callback for handling BFD events 422 * Parameters: 423 * unit - (IN) Unit number. 424 * event_types - (IN) The set of BFD events for which the specified 425 * callback should not be called 426 * cb - (IN) A pointer to the callback function to 427 * unregister from the specified BFD events 428 * Returns: 429 * BCM_E_XXX 430 * Notes: 431 */ 432 int 433 bcm_esw_bfd_event_unregister(int unit, 434 bcm_bfd_event_types_t event_types, 435 bcm_bfd_event_cb cb) 436 { 437 int result = BCM_E_UNAVAIL; 438 439 BFD_INIT(unit); 440 441 BFD_LOCK(unit); 442 443 if (BCM_ESW_BFD_DRV(unit)->event_unregister != NULL) { 444 result = BCM_ESW_BFD_DRV(unit)->event_unregister(unit, 445 event_types, cb); 446 } 447 448 BFD_UNLOCK(unit); 449 450 return result; 451 } 452 453 /* 454 * Function: 455 * bcm_esw_bfd_endpoint_stat_get 456 * Purpose: 457 * Get BFD endpoint stats 458 * Parameters: 459 * unit - (IN) Unit number. 460 * endpoint - (IN) The ID of the endpoint object to get stats for 461 * ctr_info - (IN/OUT) Pointer to endpoint count structure to 462 * receive the data 463 * clear - (IN) If set, clear stats after read 464 * Returns: 465 * BCM_E_xxx 466 * Notes: 467 */ 468 int 469 bcm_esw_bfd_endpoint_stat_get(int unit, 470 bcm_bfd_endpoint_t endpoint, 471 bcm_bfd_endpoint_stat_t *ctr_info, 472 uint32 options) 473 { 474 int result = BCM_E_UNAVAIL; 475 476 BFD_INIT(unit); 477 478 BFD_LOCK(unit); 479 480 if (BCM_ESW_BFD_DRV(unit)->endpoint_stat_get != NULL) { 481 result = BCM_ESW_BFD_DRV(unit)->endpoint_stat_get(unit, endpoint, 482 ctr_info, options); 483 } 484 485 BFD_UNLOCK(unit); 486 487 return result; 488 } 489 /* 490 * Function: 491 * bcm_esw_bfd_auth_sha1_set 492 * Purpose: 493 * Set SHA1 authentication entry 494 * Parameters: 495 * unit - (IN) Unit number. 496 * index - (IN) Index of the SHA1 entry to configure 497 * sha1 - (IN) Pointer to SHA1 info structure 498 * Returns: 499 * BCM_E_xxx 500 * Notes: 501 */ 502 int 503 bcm_esw_bfd_auth_sha1_set(int unit, 504 int index, 505 bcm_bfd_auth_sha1_t *sha1) 506 { 507 int result = BCM_E_UNAVAIL; 508 509 BFD_INIT(unit); 510 511 BFD_LOCK(unit); 512 513 if (BCM_ESW_BFD_DRV(unit)->auth_sha1_set != NULL) { 514 result = BCM_ESW_BFD_DRV(unit)->auth_sha1_set(unit, index, sha1); 515 } 516 517 BFD_UNLOCK(unit); 518 519 return result; 520 } 521 522 /* 523 * Function: 524 * bcm_esw_bfd_auth_sha1_get 525 * Purpose: 526 * Get SHA1 authentication entry 527 * Parameters: 528 * unit - (IN) Unit number. 529 * index - (IN) Index of the SHA1 entry to retrieve 530 * sha1 - (IN/OUT) Pointer to SHA1 info structure to receive the data 531 * Returns: 532 * BCM_E_xxx 533 * Notes: 534 */ 535 int 536 bcm_esw_bfd_auth_sha1_get(int unit, 537 int index, 538 bcm_bfd_auth_sha1_t *sha1) 539 { 540 int result = BCM_E_UNAVAIL; 541 542 BFD_INIT(unit); 543 544 BFD_LOCK(unit); 545 546 if (BCM_ESW_BFD_DRV(unit)->auth_sha1_get != NULL) { 547 result = BCM_ESW_BFD_DRV(unit)->auth_sha1_get(unit, index, sha1); 548 } 549 550 BFD_UNLOCK(unit); 551 552 return result; 553 } 554 /* 555 * Function: 556 * bcm_esw_bfd_auth_simple_password_set 557 * Purpose: 558 * Set Simple Password authentication entry 559 * Parameters: 560 * unit - (IN) Unit number. 561 * index - (IN) Index of the Simple Password entry to configure 562 * sp - (IN) Pointer to Simple Password info structure 563 * Returns: 564 * BCM_E_xxx 565 * Notes: 566 */ 567 int 568 bcm_esw_bfd_auth_simple_password_set(int unit, 569 int index, 570 bcm_bfd_auth_simple_password_t *sp) 571 { 572 int result = BCM_E_UNAVAIL; 573 574 BFD_INIT(unit); 575 576 BFD_LOCK(unit); 577 578 if (BCM_ESW_BFD_DRV(unit)->auth_simple_password_set != NULL) { 579 result = BCM_ESW_BFD_DRV(unit)->auth_simple_password_set(unit, 580 index, sp); 581 } 582 583 BFD_UNLOCK(unit); 584 585 return result; 586 } 587 588 /* 589 * Function: 590 * bcm_esw_bfd_auth_simple_password_get 591 * Purpose: 592 * Get Simple Password authentication entry 593 * Parameters: 594 * unit - (IN) Unit number. 595 * index - (IN) Index of the Simple Password entry to retrieve 596 * sp - (IN/OUT) Pointer to Simple Password info structure 597 * to receive the data 598 * Returns: 599 * BCM_E_xxx 600 * Notes: 601 */ 602 int 603 bcm_esw_bfd_auth_simple_password_get(int unit, 604 int index, 605 bcm_bfd_auth_simple_password_t *sp) 606 { 607 int result = BCM_E_UNAVAIL; 608 609 BFD_INIT(unit); 610 611 BFD_LOCK(unit); 612 613 if (BCM_ESW_BFD_DRV(unit)->auth_simple_password_get != NULL) { 614 result = BCM_ESW_BFD_DRV(unit)->auth_simple_password_get(unit, 615 index, sp); 616 } 617 618 BFD_UNLOCK(unit); 619 620 return result; 621 } 622 623 /* 624 * Function: 625 * bcm_esw_bfd_status_multi_get 626 * Purpose: 627 * Get the BFD status 628 * Parameters: 629 * unit - (IN) Unit number. 630 * status_arr - (OUT) Index of the BFD Status 631 * count - (OUT) Pointer to the No of endpoints 632 * Returns: 633 * BCM_E_xxx 634 * Notes: 635 */ 636 int 637 bcm_esw_bfd_status_multi_get(int unit, int max_endpoints, 638 bcm_bfd_status_t *status_arr, 639 int *count) 640 { 641 int result = BCM_E_UNAVAIL; 642 643 BFD_INIT(unit); 644 645 BFD_LOCK(unit); 646 647 if (BCM_ESW_BFD_DRV(unit)->bfd_status_multi_get != NULL) { 648 result = BCM_ESW_BFD_DRV(unit)->bfd_status_multi_get(unit, max_endpoints, 649 status_arr, count); 650 } 651 652 BFD_UNLOCK(unit); 653 654 return result; 655 } 656 657 /* 658 * Function: 659 * bcm_esw_bfd_discard_stat_set 660 * Purpose: 661 * Reset the BFD discard statistics 662 * Parameters: 663 * unit - (IN) Unit number. 664 * discarded_info - (OUT) Pointer to discard info 665 * Returns: 666 * BCM_E_xxx 667 * Notes: 668 */ 669 int 670 bcm_esw_bfd_discard_stat_set(int unit, 671 bcm_bfd_discard_stat_t *discarded_info) 672 { 673 int result = BCM_E_UNAVAIL; 674 675 BFD_INIT(unit); 676 677 BFD_LOCK(unit); 678 679 if (BCM_ESW_BFD_DRV(unit)->bfd_discard_stat_set != NULL) { 680 result = BCM_ESW_BFD_DRV(unit)->bfd_discard_stat_set(unit, discarded_info); 681 } 682 683 BFD_UNLOCK(unit); 684 685 return result; 686 } 687 688 /* 689 * Function: 690 * bcm_esw_bfd_discard_stat_get 691 * Purpose: 692 * Get the BFD discard statistics 693 * Parameters: 694 * unit - (IN) Unit number. 695 * discarded_info - (OUT) Pointer to discard info 696 * Returns: 697 * BCM_E_xxx 698 * Notes: 699 */ 700 int 701 bcm_esw_bfd_discard_stat_get(int unit, 702 bcm_bfd_discard_stat_t *discarded_info) 703 { 704 int result = BCM_E_UNAVAIL; 705 706 BFD_INIT(unit); 707 708 BFD_LOCK(unit); 709 710 if (BCM_ESW_BFD_DRV(unit)->bfd_discard_stat_get != NULL) { 711 result = BCM_ESW_BFD_DRV(unit)->bfd_discard_stat_get(unit, discarded_info); 712 } 713 714 BFD_UNLOCK(unit); 715 716 return result; 717 } 718 719 #ifdef BCM_WARM_BOOT_SUPPORT 720 /* 721 * Function: 722 * _bcm_esw_bfd_sync 723 * Purpose: 724 * Warm boot BFD sync 725 * Parameters: 726 * unit - (IN) Unit number. 727 * result =s: 728 * BCM_E_XXX 729 * Notes: 730 */ 731 int 732 _bcm_esw_bfd_sync(int unit) 733 { 734 int result = BCM_E_UNAVAIL; 735 BFD_INIT(unit); 736 737 BFD_LOCK(unit); 738 if (BCM_ESW_BFD_DRV(unit)->bfd_sync != NULL) { 739 result = BCM_ESW_BFD_DRV(unit)->bfd_sync(unit); 740 } 741 BFD_UNLOCK(unit); 742 return result; 743 } 744 745 /* 746 * Function: 747 * _bcm_esw_bfd_wb_downgrade_config_set 748 * Purpose: 749 * BFD warmboot Downgrade configuration set 750 * Parameters: 751 * unit - (IN) Unit number. 752 * result =s: 753 * BCM_E_XXX 754 * Notes: 755 */ 756 int 757 _bcm_esw_bfd_wb_downgrade_config_set(int unit, uint32 warmboot_ver) 758 { 759 int result = BCM_E_UNAVAIL; 760 BFD_INIT(unit); 761 762 BFD_LOCK(unit); 763 if (BCM_ESW_BFD_DRV(unit)->_bfd_wb_downgrade_config_set != NULL) { 764 result = BCM_ESW_BFD_DRV(unit)->_bfd_wb_downgrade_config_set(unit, warmboot_ver); 765 } 766 BFD_UNLOCK(unit); 767 return result; 768 } 769 #endif /* BCM_WARM_BOOT_SUPPORT */ 770 771 #ifdef BCM_WARM_BOOT_SUPPORT_SW_DUMP 772 /* 773 * Function: 774 * _bcm_bfd_sw_dump 775 * Purpose: 776 * Displays BFD information 777 * Parameters: 778 * unit - Device unit number 779 * Returns: 780 * None 781 */ 782 void 783 _bcm_bfd_sw_dump(int unit) 784 { 785 if (!soc_feature(unit, soc_feature_bfd) || 786 (BCM_ESW_BFD_DRV(unit)== NULL) || (mutex[unit] == NULL)) { 787 return; 788 } 789 790 if ((BCM_ESW_BFD_DRV(unit) == NULL) || (mutex[unit] == NULL)) { 791 LOG_CLI((BSL_META_U(unit, "BFD was not initialized.\n"))); 792 return; 793 } 794 BFD_LOCK(unit); 795 796 if (BCM_ESW_BFD_DRV(unit)->bfd_sw_dump != NULL) { 797 BCM_ESW_BFD_DRV(unit)->bfd_sw_dump(unit); 798 } 799 800 BFD_UNLOCK(unit); 801 } 802 #endif /* BCM_WARM_BOOT_SUPPORT_SW_DUMP */ 803 804 /* 805 * Function: 806 * _bcm_bfd_dump_trace 807 * Purpose: 808 * Dump the BFD stack trace 809 * Parameters: 810 * unit - (IN) Unit number. 811 * Returns: 812 * None 813 * Notes: 814 */ 815 void _bcm_bfd_dump_trace(int unit) 816 { 817 if (!soc_feature(unit, soc_feature_bfd)) { 818 LOG_CLI((BSL_META_U(unit, "BFD not supported.\n"))); 819 return; 820 } 821 822 if ((BCM_ESW_BFD_DRV(unit) == NULL) || (mutex[unit] == NULL)) { 823 LOG_CLI((BSL_META_U(unit, "BFD not initialized.\n"))); 824 return; 825 } 826 BFD_LOCK(unit); 827 828 if (BCM_ESW_BFD_DRV(unit)->bfd_dump_trace != NULL) { 829 BCM_ESW_BFD_DRV(unit)->bfd_dump_trace(unit); 830 } 831 832 BFD_UNLOCK(unit); 833 } 834 835 #else /* INCLUDE_BFD */ 836 int bcm_esw_bfd_not_empty; 837 #endif /* INCLUDE_BFD */