mpls.c (171289B)
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 * File: mpls.c 8 * Purpose: Manages MPLS functions 9 */ 10 11 #ifdef INCLUDE_L3 12 13 #include <sal/core/libc.h> 14 15 #include <soc/defs.h> 16 #include <soc/drv.h> 17 #include <soc/mem.h> 18 #include <soc/l2u.h> 19 #include <soc/l3x.h> 20 #include <soc/util.h> 21 #include <soc/debug.h> 22 #include <bcm/l2.h> 23 #include <bcm/l3.h> 24 #include <bcm/port.h> 25 #include <bcm/error.h> 26 #include <bcm/vlan.h> 27 #include <bcm/rate.h> 28 #include <bcm/ipmc.h> 29 #include <bcm/mpls.h> 30 #include <bcm/stack.h> 31 #include <bcm/topo.h> 32 33 #include <bcm_int/esw/virtual.h> 34 #include <bcm_int/esw/mbcm.h> 35 #include <bcm_int/esw/l3.h> 36 #include <bcm_int/esw/firebolt.h> 37 #if defined(BCM_TRIUMPH_SUPPORT) 38 #include <bcm_int/esw/triumph.h> 39 #endif /* BCM_TRIUMPH_SUPPORT */ 40 #if defined(BCM_TRIUMPH2_SUPPORT) 41 #include <bcm_int/esw/triumph2.h> 42 #endif /* BCM_TRIUMPH2_SUPPORT */ 43 #if defined(BCM_KATANA_SUPPORT) 44 #include <bcm_int/esw/katana.h> 45 #endif /* BCM_TRIUMPH_SUPPORT */ 46 #if (defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)) 47 #include <bcm_int/esw/xgs5.h> 48 #endif /* BCM_TOMAHAWK_SUPPORT */ 49 #if defined(BCM_TRIUMPH3_SUPPORT) 50 #include <bcm_int/esw/triumph3.h> 51 #endif /* BCM_TRIUMPH3_SUPPORT */ 52 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 53 #include <bcm_int/esw/trident2plus.h> 54 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 55 #if defined(BCM_TRIDENT3_SUPPORT) 56 #include <bcm_int/esw/trident3.h> 57 #endif /* BCM_TRIDENT3_SUPPORT */ 58 59 #include <bcm_int/esw_dispatch.h> 60 #include <bcm_int/esw/xgs3.h> 61 62 /* 63 * Function: 64 * bcm_mpls_init 65 * Purpose: 66 * Initialize the MPLS software module, clear all HW MPLS states 67 * Parameters: 68 * unit - Device Number 69 * Returns: 70 * BCM_E_XXXX 71 */ 72 73 int 74 bcm_esw_mpls_init(int unit) 75 { 76 #ifdef BCM_MPLS_SUPPORT 77 #ifdef BCM_TRIUMPH_SUPPORT 78 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 79 return bcm_tr_mpls_init(unit); 80 } 81 #endif 82 #endif 83 return BCM_E_UNAVAIL; 84 } 85 86 /* 87 * Function: 88 * bcm_mpls_cleanup 89 * Purpose: 90 * Detach the MPLS software module, clear all HW MPLS states 91 * Parameters: 92 * unit - Device Number 93 * Returns: 94 * BCM_E_XXXX 95 */ 96 97 int 98 bcm_esw_mpls_cleanup(int unit) 99 { 100 #ifdef BCM_MPLS_SUPPORT 101 #ifdef BCM_TRIUMPH_SUPPORT 102 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 103 return bcm_tr_mpls_cleanup(unit); 104 } 105 #endif 106 #endif 107 return BCM_E_NONE; 108 } 109 110 #ifdef BCM_WARM_BOOT_SUPPORT 111 int 112 _bcm_esw_mpls_sync(int unit) 113 { 114 #ifdef BCM_MPLS_SUPPORT 115 #ifdef BCM_TRIUMPH_SUPPORT 116 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 117 return bcm_tr_mpls_sync(unit); 118 } 119 #endif 120 #endif 121 122 return BCM_E_NONE; 123 } 124 125 int 126 _bcm_esw_mpls_match_key_recover(int unit) 127 { 128 #ifdef BCM_MPLS_SUPPORT 129 #ifdef BCM_TRIUMPH3_SUPPORT 130 if (SOC_IS_TRIUMPH3(unit)) { 131 return _bcm_tr3_mpls_match_key_recover(unit); 132 } else 133 #endif 134 #ifdef BCM_TRIUMPH_SUPPORT 135 { 136 return _bcm_tr_mpls_match_key_recover(unit); 137 } 138 #endif /* BCM_TRIUMPH_SUPPORT */ 139 #endif /* MPLS_SUPPORT */ 140 141 return BCM_E_NONE; 142 } 143 144 /* 145 * Function: 146 * _bcm_esw_mpls_tunnel_switch_traverse_no_lock 147 * Purpose: 148 * Traverse all valid MPLS label entries and call the 149 * supplied callback routine without lock. 150 * Parameters: 151 * unit - Device Number 152 * cb - User callback function, called once per MPLS entry. 153 * user_data - cookie 154 * Returns: 155 * BCM_E_XXX 156 */ 157 int 158 _bcm_esw_mpls_tunnel_switch_traverse_no_lock(int unit, 159 bcm_mpls_tunnel_switch_traverse_cb cb, 160 void *user_data) 161 { 162 int rv = BCM_E_NONE; 163 164 #ifdef BCM_MPLS_SUPPORT 165 #ifdef BCM_TRIUMPH3_SUPPORT 166 if (SOC_IS_TRIUMPH3(unit) && soc_feature(unit, soc_feature_mpls)) { 167 rv = bcm_tr3_mpls_tunnel_switch_traverse(unit, cb, user_data); 168 return rv; 169 } 170 #endif 171 172 #ifdef BCM_KATANA_SUPPORT 173 if (SOC_IS_KATANAX(unit) && soc_feature(unit, soc_feature_mpls)) { 174 rv = bcm_kt_mpls_tunnel_switch_traverse(unit, cb, user_data); 175 return rv; 176 } 177 #endif 178 179 #ifdef BCM_TRIUMPH_SUPPORT 180 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 181 if (soc_feature(unit, soc_feature_mpls_lsr_ecmp)) { 182 #if (defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)) 183 rv = bcmi_xgs5_mpls_tunnel_switch_traverse(unit, cb, user_data); 184 #endif 185 } else { 186 rv = bcm_tr_mpls_tunnel_switch_traverse(unit, cb, user_data); 187 } 188 return rv; 189 } 190 #endif 191 #endif 192 return rv; 193 } 194 195 #endif 196 197 /* 198 * Function: 199 * bcm_mpls_vpn_id_create 200 * Purpose: 201 * Create a VPN 202 * Parameters: 203 * unit - (IN) Device Number 204 * info - (IN/OUT) VPN configuration info 205 * Returns: 206 * BCM_E_XXXX 207 */ 208 int 209 bcm_esw_mpls_vpn_id_create(int unit, bcm_mpls_vpn_config_t *info) 210 { 211 int rv = BCM_E_UNAVAIL; 212 #ifdef BCM_MPLS_SUPPORT 213 #ifdef BCM_TRIUMPH_SUPPORT 214 #ifdef BCM_TOMAHAWK3_SUPPORT 215 if (soc_feature(unit, soc_feature_th3_style_simple_mpls) && 216 ((info->flags & BCM_MPLS_VPN_VPWS) || 217 (info->flags & BCM_MPLS_VPN_VPLS))) { 218 return BCM_E_UNAVAIL; 219 } 220 #endif 221 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 222 rv = bcm_tr_mpls_lock (unit) ; 223 if ( rv == BCM_E_NONE ) { 224 rv = bcm_tr_mpls_vpn_id_create(unit, info); 225 bcm_tr_mpls_unlock (unit); 226 } 227 return rv; 228 } 229 #endif 230 #endif 231 return rv; 232 } 233 234 /* 235 * Function: 236 * bcm_mpls_vpn_id_destroy 237 * Purpose: 238 * Destroy a VPN 239 * Parameters: 240 * unit - (IN) Device Number 241 * vpn - (IN) VPN instance 242 * Returns: 243 * BCM_E_XXXX 244 */ 245 int 246 bcm_esw_mpls_vpn_id_destroy(int unit, bcm_vpn_t vpn) 247 { 248 int rv = BCM_E_UNAVAIL; 249 #ifdef BCM_MPLS_SUPPORT 250 #ifdef BCM_TRIUMPH_SUPPORT 251 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 252 rv = bcm_tr_mpls_lock(unit); 253 if ( rv == BCM_E_NONE ) { 254 rv = bcm_tr_mpls_vpn_id_destroy(unit, vpn); 255 bcm_tr_mpls_unlock (unit); 256 } 257 return rv; 258 } 259 #endif 260 #endif 261 return rv; 262 } 263 264 /* 265 * Function: 266 * bcm_mpls_vpn_id_destroy_all 267 * Purpose: 268 * Destroy all VPNs 269 * Parameters: 270 * unit - (IN) Device Number 271 * Returns: 272 * BCM_E_XXXX 273 */ 274 int 275 bcm_esw_mpls_vpn_id_destroy_all(int unit) 276 { 277 int rv = BCM_E_UNAVAIL; 278 #ifdef BCM_MPLS_SUPPORT 279 #ifdef BCM_TRIUMPH_SUPPORT 280 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 281 rv = bcm_tr_mpls_lock(unit); 282 if ( rv == BCM_E_NONE ) { 283 rv = bcm_tr_mpls_vpn_id_destroy_all(unit); 284 bcm_tr_mpls_unlock (unit); 285 } 286 return rv; 287 } 288 #endif 289 #endif 290 return rv; 291 } 292 293 /* 294 * Function: 295 * bcm_mpls_vpn_id_get 296 * Purpose: 297 * Get a VPN 298 * Parameters: 299 * unit - (IN) Device Number 300 * vpn - (IN) VPN instance 301 * info - (OUT) VPN configuration info 302 * Returns: 303 * BCM_E_XXXX 304 */ 305 int 306 bcm_esw_mpls_vpn_id_get(int unit, bcm_vpn_t vpn, bcm_mpls_vpn_config_t *info) 307 { 308 int rv = BCM_E_UNAVAIL; 309 #ifdef BCM_MPLS_SUPPORT 310 #ifdef BCM_TRIUMPH_SUPPORT 311 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 312 rv = bcm_tr_mpls_lock(unit); 313 if ( rv == BCM_E_NONE ) { 314 rv = bcm_tr_mpls_vpn_id_get(unit, vpn, info); 315 bcm_tr_mpls_unlock (unit); 316 } 317 return rv; 318 } 319 #endif 320 #endif 321 return rv; 322 } 323 324 /* 325 * Function: 326 * bcm_mpls_vpn_traverse 327 * Purpose: 328 * MPLS VPN Traverse 329 * Parameters: 330 * unit - (IN) Device Number 331 * cb - (IN) User callback function, called once per entry 332 * user_data - (IN/OUT) Cookie 333 * Returns: 334 * BCM_E_XXXX 335 */ 336 int 337 bcm_esw_mpls_vpn_traverse(int unit, bcm_mpls_vpn_traverse_cb cb, 338 void *user_data) 339 { 340 int rv = BCM_E_UNAVAIL; 341 #ifdef BCM_MPLS_SUPPORT 342 #ifdef BCM_TRIUMPH_SUPPORT 343 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 344 rv = bcm_tr_mpls_lock(unit); 345 if ( rv == BCM_E_NONE ) { 346 rv = bcm_tr_mpls_vpn_traverse(unit, cb, user_data); 347 bcm_tr_mpls_unlock (unit); 348 } 349 return rv; 350 } 351 #endif 352 #endif 353 return rv; 354 } 355 356 /* 357 * Function: 358 * bcm_mpls_port_add 359 * Purpose: 360 * Add an mpls port to a VPN 361 * Parameters: 362 * unit - (IN) Device Number 363 * vpn - (IN) VPN instance ID 364 * mpls_port - (IN/OUT) mpls port information (OUT : mpls_port_id) 365 * Returns: 366 * BCM_E_XXX 367 */ 368 int 369 bcm_esw_mpls_port_add(int unit, bcm_vpn_t vpn, bcm_mpls_port_t *mpls_port) 370 { 371 int rv = BCM_E_UNAVAIL; 372 #ifdef BCM_MPLS_SUPPORT 373 #ifdef BCM_TRIUMPH_SUPPORT 374 #ifdef BCM_TOMAHAWK3_SUPPORT 375 if (soc_feature(unit, soc_feature_th3_style_simple_mpls)) { 376 return BCM_E_UNAVAIL; 377 } 378 #endif 379 380 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 381 L3_LOCK(unit); 382 rv = bcm_tr_mpls_lock(unit); 383 if ( rv == BCM_E_NONE ) { 384 rv = bcm_tr_mpls_port_add(unit, vpn, mpls_port); 385 bcm_tr_mpls_unlock (unit); 386 } 387 L3_UNLOCK(unit); 388 return rv; 389 } 390 #endif 391 #endif 392 return rv; 393 } 394 395 /* 396 * Function: 397 * bcm_mpls_port_delete 398 * Purpose: 399 * Delete an mpls port from a VPN 400 * Parameters: 401 * unit - (IN) Device Number 402 * vpn - (IN) VPN instance ID 403 * mpls_port_id - (IN) mpls port ID 404 * Returns: 405 * BCM_E_XXX 406 */ 407 int 408 bcm_esw_mpls_port_delete(int unit, bcm_vpn_t vpn, bcm_gport_t mpls_port_id) 409 { 410 int rv = BCM_E_UNAVAIL; 411 #ifdef BCM_MPLS_SUPPORT 412 #ifdef BCM_TRIUMPH_SUPPORT 413 #ifdef BCM_TOMAHAWK3_SUPPORT 414 if (soc_feature(unit, soc_feature_th3_style_simple_mpls)) { 415 return BCM_E_UNAVAIL; 416 } 417 #endif 418 419 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 420 L3_LOCK(unit); 421 rv = bcm_tr_mpls_lock(unit); 422 if ( rv == BCM_E_NONE ) { 423 rv = bcm_tr_mpls_port_delete(unit, vpn, mpls_port_id); 424 bcm_tr_mpls_unlock (unit); 425 } 426 L3_UNLOCK(unit); 427 return rv; 428 } 429 #endif 430 #endif 431 return rv; 432 } 433 434 /* 435 * Function: 436 * bcm_mpls_port_delete_all 437 * Purpose: 438 * Delete all mpls ports from a VPN 439 * Parameters: 440 * unit - Device Number 441 * vpn - VPN instance ID 442 * Returns: 443 * BCM_E_XXX 444 */ 445 int 446 bcm_esw_mpls_port_delete_all(int unit, bcm_vpn_t vpn) 447 { 448 int rv = BCM_E_UNAVAIL; 449 #ifdef BCM_MPLS_SUPPORT 450 #ifdef BCM_TRIUMPH_SUPPORT 451 #ifdef BCM_TOMAHAWK3_SUPPORT 452 if (soc_feature(unit, soc_feature_th3_style_simple_mpls)) { 453 return BCM_E_UNAVAIL; 454 } 455 #endif 456 457 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 458 L3_LOCK(unit); 459 rv = bcm_tr_mpls_lock(unit); 460 if ( rv == BCM_E_NONE ) { 461 rv = bcm_tr_mpls_port_delete_all(unit, vpn); 462 bcm_tr_mpls_unlock (unit); 463 } 464 L3_UNLOCK(unit); 465 return rv; 466 } 467 #endif 468 #endif 469 return rv; 470 } 471 472 /* 473 * Function: 474 * bcm_mpls_port_get 475 * Purpose: 476 * Get an mpls port from a VPN 477 * Parameters: 478 * unit - (IN) Device Number 479 * vpn - (IN) VPN instance ID 480 * mpls_port - (IN/OUT) mpls port information (IN : mpls_port_id) 481 */ 482 int 483 bcm_esw_mpls_port_get(int unit, bcm_vpn_t vpn, bcm_mpls_port_t *mpls_port) 484 { 485 int rv = BCM_E_UNAVAIL; 486 #ifdef BCM_MPLS_SUPPORT 487 #ifdef BCM_TRIUMPH_SUPPORT 488 489 #ifdef BCM_TOMAHAWK3_SUPPORT 490 if (soc_feature(unit, soc_feature_th3_style_simple_mpls)) { 491 return BCM_E_UNAVAIL; 492 } 493 #endif 494 495 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 496 rv = bcm_tr_mpls_lock(unit); 497 if ( rv == BCM_E_NONE ) { 498 rv = bcm_tr_mpls_port_get (unit, vpn, mpls_port); 499 bcm_tr_mpls_unlock (unit); 500 } 501 return rv; 502 } 503 #endif 504 #endif 505 return rv; 506 } 507 508 /* 509 * Function: 510 * bcm_mpls_port_get_all 511 * Purpose: 512 * Get an mpls port from a VPN 513 * Parameters: 514 * unit - (IN) Device Number 515 * vpn - (IN) VPN instance ID 516 * port_max - (IN) Maximum number of ports in array 517 * port_array - (OUT) Array of mpls ports 518 * port_count - (OUT) Number of ports returned in array 519 */ 520 int 521 bcm_esw_mpls_port_get_all(int unit, bcm_vpn_t vpn, int port_max, 522 bcm_mpls_port_t *port_array, int *port_count) 523 { 524 int rv = BCM_E_UNAVAIL; 525 #ifdef BCM_MPLS_SUPPORT 526 #ifdef BCM_TRIUMPH_SUPPORT 527 #ifdef BCM_TOMAHAWK3_SUPPORT 528 if (soc_feature(unit, soc_feature_th3_style_simple_mpls)) { 529 return BCM_E_UNAVAIL; 530 } 531 #endif 532 533 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 534 rv = bcm_tr_mpls_lock(unit); 535 if ( rv == BCM_E_NONE ) { 536 rv = bcm_tr_mpls_port_get_all(unit, vpn, port_max, 537 port_array, port_count); 538 bcm_tr_mpls_unlock (unit); 539 } 540 return rv; 541 } 542 #endif 543 #endif 544 return rv; 545 } 546 547 /* 548 * Function: 549 * bcm_mpls_tunnel_initiator_set 550 * Purpose: 551 * Set the MPLS tunnel initiator parameters for an L3 interface. 552 * Parameters: 553 * unit - Device Number 554 * intf - The egress L3 interface 555 * num_labels - Number of labels in the array 556 * label_array - Array of MPLS label and header information 557 * Returns: 558 * BCM_E_XXX 559 */ 560 int 561 bcm_esw_mpls_tunnel_initiator_set (int unit, bcm_if_t intf, int num_labels, 562 bcm_mpls_egress_label_t *label_array) 563 { 564 int rv = BCM_E_UNAVAIL; 565 #ifdef BCM_MPLS_SUPPORT 566 #ifdef BCM_TRIUMPH_SUPPORT 567 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 568 L3_LOCK(unit); 569 rv = bcm_tr_mpls_lock(unit); 570 if (rv == BCM_E_NONE ) { 571 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TOMAHAWK2_SUPPORT) || \ 572 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 573 if (soc_feature(unit, soc_feature_egr_ip_tnl_mpls_double_wide) || 574 (soc_feature(unit, soc_feature_th3_style_simple_mpls))) { 575 rv = bcmi_xgs5_mpls_tunnel_initiator_set(unit, intf, 576 num_labels, label_array); 577 } else 578 #endif 579 { 580 rv = bcm_tr_mpls_tunnel_initiator_set(unit, intf, 581 num_labels, label_array); 582 } 583 bcm_tr_mpls_unlock (unit); 584 } 585 L3_UNLOCK(unit); 586 return rv; 587 } 588 #endif 589 #endif 590 return rv; 591 } 592 593 /* 594 * Function: 595 * bcm_mpls_tunnel_initiator_clear 596 * Purpose: 597 * Clear the MPLS tunnel initiator parameters for an L3 interface. 598 * Parameters: 599 * unit - Device Number 600 * intf - The egress L3 interface 601 * Returns: 602 * BCM_E_XXX 603 */ 604 int 605 bcm_esw_mpls_tunnel_initiator_clear (int unit, bcm_if_t intf) 606 { 607 int rv = BCM_E_UNAVAIL; 608 #ifdef BCM_MPLS_SUPPORT 609 #ifdef BCM_TRIUMPH_SUPPORT 610 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 611 L3_LOCK(unit); 612 rv = bcm_tr_mpls_lock(unit); 613 if ( rv == BCM_E_NONE ) { 614 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TOMAHAWK2_SUPPORT) || \ 615 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 616 if (soc_feature(unit, soc_feature_egr_ip_tnl_mpls_double_wide) || 617 (soc_feature(unit, soc_feature_th3_style_simple_mpls))) { 618 rv = bcmi_xgs5_mpls_tunnel_initiator_clear(unit, intf); 619 } else 620 #endif 621 { 622 rv = bcm_tr_mpls_tunnel_initiator_clear(unit, intf); 623 } 624 bcm_tr_mpls_unlock (unit); 625 } 626 L3_UNLOCK(unit); 627 return rv; 628 } 629 #endif 630 #endif 631 return rv; 632 } 633 634 /* 635 * Function: 636 * bcm_mpls_tunnel_initiator_clear_all 637 * Purpose: 638 * Clear all the MPLS tunnel initiator parameters all L3 Interfaces 639 * Parameters: 640 * unit - Device Number 641 * Returns: 642 * BCM_E_XXX 643 */ 644 int 645 bcm_esw_mpls_tunnel_initiator_clear_all (int unit) 646 { 647 int rv = BCM_E_UNAVAIL; 648 #ifdef BCM_MPLS_SUPPORT 649 #ifdef BCM_TRIUMPH_SUPPORT 650 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 651 L3_LOCK(unit); 652 if ( bcm_tr_mpls_lock (unit) == BCM_E_NONE ) { 653 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TOMAHAWK2_SUPPORT) || \ 654 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 655 if (soc_feature(unit, soc_feature_egr_ip_tnl_mpls_double_wide) || 656 (soc_feature(unit, soc_feature_th3_style_simple_mpls))) { 657 rv = bcmi_xgs5_mpls_tunnel_initiator_clear_all(unit); 658 } else 659 #endif 660 { 661 rv = bcm_tr_mpls_tunnel_initiator_clear_all(unit); 662 } 663 bcm_tr_mpls_unlock (unit); 664 } 665 L3_UNLOCK(unit); 666 return rv; 667 } 668 #endif 669 #endif 670 return rv; 671 } 672 673 /* 674 * Function: 675 * bcm_mpls_tunnel_initiator_get 676 * Purpose: 677 * Get the the MPLS tunnel initiator parameters for an L3 interface. 678 * Parameters: 679 * unit - (IN) Device Number 680 * intf - (IN) The egress L3 interface 681 * label_max - (IN) Number of entries in label_array 682 * label_array - (OUT) MPLS header information 683 * label_count - (OUT) Actual number of labels returned 684 * Returns: 685 * BCM_E_XXX 686 */ 687 int 688 bcm_esw_mpls_tunnel_initiator_get (int unit, bcm_if_t intf, int label_max, 689 bcm_mpls_egress_label_t *label_array, 690 int *label_count) 691 { 692 int rv = BCM_E_UNAVAIL; 693 #ifdef BCM_MPLS_SUPPORT 694 #ifdef BCM_TRIUMPH_SUPPORT 695 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 696 L3_LOCK(unit); 697 rv = bcm_tr_mpls_lock(unit); 698 if ( rv == BCM_E_NONE ) { 699 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TOMAHAWK2_SUPPORT) || \ 700 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 701 if (soc_feature(unit, soc_feature_egr_ip_tnl_mpls_double_wide) || 702 (soc_feature(unit, soc_feature_th3_style_simple_mpls))) { 703 rv = bcmi_xgs5_mpls_tunnel_initiator_get(unit, 704 intf, label_max, 705 label_array, label_count); 706 } else 707 #endif 708 { 709 rv = bcm_tr_mpls_tunnel_initiator_get(unit, 710 intf, label_max, 711 label_array, label_count); 712 } 713 bcm_tr_mpls_unlock (unit); 714 } 715 L3_UNLOCK(unit); 716 return rv; 717 } 718 #endif 719 #endif 720 return rv; 721 } 722 723 /* 724 * Function: 725 * bcm_mpls_tunnel_switch_add 726 * Purpose: 727 * Add an MPLS label entry. 728 * Parameters: 729 * unit - Device Number 730 * info - Label (switch) information 731 * Returns: 732 * BCM_E_XXX 733 */ 734 int 735 bcm_esw_mpls_tunnel_switch_add (int unit, bcm_mpls_tunnel_switch_t *info) 736 { 737 int rv = BCM_E_UNAVAIL; 738 #ifdef BCM_MPLS_SUPPORT 739 #ifdef BCM_TRIUMPH3_SUPPORT 740 if (SOC_IS_TRIUMPH3(unit) && soc_feature(unit, soc_feature_mpls)) { 741 L3_LOCK(unit); 742 rv = bcm_tr_mpls_lock(unit); 743 if ( rv == BCM_E_NONE ) { 744 rv = bcm_tr3_mpls_tunnel_switch_add(unit, info); 745 bcm_tr_mpls_unlock (unit); 746 } 747 L3_UNLOCK(unit); 748 return rv; 749 } 750 #endif 751 #ifdef BCM_KATANA_SUPPORT 752 if (SOC_IS_KATANAX(unit) && soc_feature(unit, soc_feature_mpls)) { 753 L3_LOCK(unit); 754 rv = bcm_tr_mpls_lock(unit); 755 if ( rv == BCM_E_NONE ) { 756 rv = bcm_kt_mpls_tunnel_switch_add(unit, info); 757 bcm_tr_mpls_unlock (unit); 758 } 759 L3_UNLOCK(unit); 760 return rv; 761 } 762 #endif 763 #ifdef BCM_TRIUMPH_SUPPORT 764 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 765 L3_LOCK(unit); 766 rv = bcm_tr_mpls_lock(unit); 767 if ( rv == BCM_E_NONE ) { 768 if (soc_feature(unit, soc_feature_mpls_lsr_ecmp)) { 769 #if (defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)) 770 rv = bcmi_xgs5_mpls_tunnel_switch_add(unit, info); 771 #endif 772 } else { 773 rv = bcm_tr_mpls_tunnel_switch_add(unit, info); 774 } 775 } 776 bcm_tr_mpls_unlock (unit); 777 L3_UNLOCK(unit); 778 return rv; 779 } 780 #endif 781 #endif 782 return rv; 783 } 784 785 /* 786 * Function: 787 * bcm_mpls_tunnel_switch_delete 788 * Purpose: 789 * Delete an MPLS label entry. 790 * Parameters: 791 * unit - Device Number 792 * info - Label (switch) information 793 * Returns: 794 * BCM_E_XXX 795 */ 796 int 797 bcm_esw_mpls_tunnel_switch_delete (int unit, bcm_mpls_tunnel_switch_t *info) 798 { 799 int rv = BCM_E_UNAVAIL; 800 #ifdef BCM_MPLS_SUPPORT 801 #ifdef BCM_TRIUMPH3_SUPPORT 802 if (SOC_IS_TRIUMPH3(unit) && soc_feature(unit, soc_feature_mpls)) { 803 L3_LOCK(unit); 804 rv = bcm_tr_mpls_lock(unit); 805 if ( rv == BCM_E_NONE ) { 806 rv = bcm_tr3_mpls_tunnel_switch_delete(unit, info); 807 bcm_tr_mpls_unlock (unit); 808 } 809 L3_UNLOCK(unit); 810 return rv; 811 } 812 #endif 813 #ifdef BCM_KATANA_SUPPORT 814 if (SOC_IS_KATANAX(unit) && soc_feature(unit, soc_feature_mpls)) { 815 L3_LOCK(unit); 816 rv = bcm_tr_mpls_lock(unit); 817 if ( rv == BCM_E_NONE ) { 818 rv = bcm_kt_mpls_tunnel_switch_delete(unit, info); 819 bcm_tr_mpls_unlock (unit); 820 } 821 L3_UNLOCK(unit); 822 return rv; 823 } 824 #endif 825 #ifdef BCM_TRIUMPH_SUPPORT 826 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 827 L3_LOCK(unit); 828 rv = bcm_tr_mpls_lock(unit); 829 if ( rv == BCM_E_NONE ) { 830 if (soc_feature(unit, soc_feature_mpls_lsr_ecmp)) { 831 #if (defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)) 832 rv = bcmi_xgs5_mpls_tunnel_switch_delete(unit, info); 833 #endif 834 } else { 835 rv = bcm_tr_mpls_tunnel_switch_delete(unit, info); 836 } 837 } 838 bcm_tr_mpls_unlock (unit); 839 L3_UNLOCK(unit); 840 return rv; 841 } 842 #endif 843 #endif 844 return rv; 845 } 846 847 /* 848 * Function: 849 * bcm_mpls_tunnel_switch_delete_all 850 * Purpose: 851 * Delete all MPLS label entries. 852 * Parameters: 853 * unit - Device Number 854 * Returns: 855 * BCM_E_XXX 856 */ 857 int 858 bcm_esw_mpls_tunnel_switch_delete_all (int unit) 859 { 860 int rv = BCM_E_UNAVAIL; 861 #ifdef BCM_MPLS_SUPPORT 862 #ifdef BCM_TRIUMPH3_SUPPORT 863 if (SOC_IS_TRIUMPH3(unit) && soc_feature(unit, soc_feature_mpls)) { 864 L3_LOCK(unit); 865 rv = bcm_tr_mpls_lock(unit); 866 if ( rv == BCM_E_NONE ) { 867 rv = bcm_tr3_mpls_tunnel_switch_delete_all(unit); 868 bcm_tr_mpls_unlock (unit); 869 } 870 L3_UNLOCK(unit); 871 return rv; 872 } 873 #endif 874 #ifdef BCM_KATANA_SUPPORT 875 if (SOC_IS_KATANAX(unit) && soc_feature(unit, soc_feature_mpls)) { 876 L3_LOCK(unit); 877 rv = bcm_tr_mpls_lock(unit); 878 if ( rv == BCM_E_NONE ) { 879 rv = bcm_kt_mpls_tunnel_switch_delete_all(unit); 880 bcm_tr_mpls_unlock (unit); 881 } 882 L3_UNLOCK(unit); 883 return rv; 884 } 885 #endif 886 #ifdef BCM_TRIUMPH_SUPPORT 887 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 888 L3_LOCK(unit); 889 rv = bcm_tr_mpls_lock(unit); 890 if ( rv == BCM_E_NONE ) { 891 if (soc_feature(unit, soc_feature_mpls_lsr_ecmp)) { 892 #if (defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)) 893 rv = bcmi_xgs5_mpls_tunnel_switch_delete_all(unit); 894 #endif 895 } else { 896 rv = bcm_tr_mpls_tunnel_switch_delete_all(unit); 897 } 898 } 899 bcm_tr_mpls_unlock (unit); 900 L3_UNLOCK(unit); 901 return rv; 902 } 903 #endif 904 #endif 905 return rv; 906 } 907 908 /* 909 * Function: 910 * bcm_mpls_tunnel_switch_get 911 * Purpose: 912 * Get an MPLS label entry. 913 * Parameters: 914 * unit - Device Number 915 * info - Label (switch) information 916 * Returns: 917 * BCM_E_XXX 918 */ 919 int 920 bcm_esw_mpls_tunnel_switch_get (int unit, bcm_mpls_tunnel_switch_t *info) 921 { 922 int rv = BCM_E_UNAVAIL; 923 #ifdef BCM_MPLS_SUPPORT 924 #ifdef BCM_TRIUMPH3_SUPPORT 925 if (SOC_IS_TRIUMPH3(unit) && soc_feature(unit, soc_feature_mpls)) { 926 L3_LOCK(unit); 927 rv = bcm_tr_mpls_lock(unit); 928 if ( rv == BCM_E_NONE ) { 929 rv = bcm_tr3_mpls_tunnel_switch_get(unit, info); 930 bcm_tr_mpls_unlock (unit); 931 } 932 L3_UNLOCK(unit); 933 return rv; 934 } 935 #endif 936 #ifdef BCM_KATANA_SUPPORT 937 if (SOC_IS_KATANAX(unit) && soc_feature(unit, soc_feature_mpls)) { 938 rv = bcm_tr_mpls_lock(unit); 939 if ( rv == BCM_E_NONE ) { 940 rv = bcm_kt_mpls_tunnel_switch_get(unit, info); 941 bcm_tr_mpls_unlock (unit); 942 } 943 return rv; 944 } 945 #endif 946 #ifdef BCM_TRIUMPH_SUPPORT 947 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 948 rv = bcm_tr_mpls_lock(unit); 949 if ( rv == BCM_E_NONE ) { 950 if (soc_feature(unit, soc_feature_mpls_lsr_ecmp)) { 951 #if (defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)) 952 rv = bcmi_xgs5_mpls_tunnel_switch_get(unit, info); 953 #endif 954 } else { 955 rv = bcm_tr_mpls_tunnel_switch_get(unit, info); 956 } 957 } 958 bcm_tr_mpls_unlock (unit); 959 return rv; 960 } 961 #endif 962 #endif 963 return rv; 964 } 965 966 /* 967 * Function: 968 * bcm_mpls_tunnel_switch_traverse 969 * Purpose: 970 * Traverse all valid MPLS label entries and call the 971 * supplied callback routine. 972 * Parameters: 973 * unit - Device Number 974 * cb - User callback function, called once per MPLS entry. 975 * user_data - cookie 976 * Returns: 977 * BCM_E_XXX 978 */ 979 int 980 bcm_esw_mpls_tunnel_switch_traverse(int unit, 981 bcm_mpls_tunnel_switch_traverse_cb cb, 982 void *user_data) 983 { 984 int rv = BCM_E_UNAVAIL; 985 #ifdef BCM_MPLS_SUPPORT 986 #ifdef BCM_TRIUMPH3_SUPPORT 987 if (SOC_IS_TRIUMPH3(unit) && soc_feature(unit, soc_feature_mpls)) { 988 L3_LOCK(unit); 989 rv = bcm_tr_mpls_lock(unit); 990 if ( rv == BCM_E_NONE ) { 991 rv = bcm_tr3_mpls_tunnel_switch_traverse(unit, cb, user_data); 992 bcm_tr_mpls_unlock (unit); 993 } 994 L3_UNLOCK(unit); 995 return rv; 996 } 997 #endif 998 #ifdef BCM_KATANA_SUPPORT 999 if (SOC_IS_KATANAX(unit) && soc_feature(unit, soc_feature_mpls)) { 1000 rv = bcm_tr_mpls_lock(unit); 1001 if ( rv == BCM_E_NONE ) { 1002 rv = bcm_kt_mpls_tunnel_switch_traverse(unit, cb, user_data); 1003 bcm_tr_mpls_unlock (unit); 1004 } 1005 return rv; 1006 } 1007 #endif 1008 #ifdef BCM_TRIUMPH_SUPPORT 1009 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 1010 rv = bcm_tr_mpls_lock(unit); 1011 if ( rv == BCM_E_NONE ) { 1012 if (soc_feature(unit, soc_feature_mpls_lsr_ecmp)) { 1013 #if (defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT)) 1014 rv = bcmi_xgs5_mpls_tunnel_switch_traverse(unit, cb, user_data); 1015 #endif 1016 } else { 1017 rv = bcm_tr_mpls_tunnel_switch_traverse(unit, cb, user_data); 1018 } 1019 bcm_tr_mpls_unlock (unit); 1020 } 1021 return rv; 1022 } 1023 #endif 1024 #endif 1025 return rv; 1026 } 1027 1028 /* 1029 * Function: 1030 * _bcm_esw_mpls_port_source_vp_lag_set 1031 * Purpose: 1032 * Set source VP LAG for a mpls virtual port. 1033 * Parameters: 1034 * unit - (IN) SOC unit number. 1035 * gport - (IN) mpls virtual port GPORT ID. 1036 * vp_lag_vp - (IN) VP representing the VP LAG. 1037 * Returns: 1038 * BCM_X_XXX 1039 */ 1040 int 1041 _bcm_esw_mpls_port_source_vp_lag_set(int unit, bcm_gport_t gport, 1042 int vp_lag_vp) 1043 { 1044 int rv = BCM_E_UNAVAIL; 1045 1046 #if defined(BCM_TRIDENT2_SUPPORT) 1047 if (soc_feature(unit, soc_feature_mpls) 1048 && soc_feature(unit, soc_feature_vp_lag)) { 1049 rv = bcm_tr_mpls_lock(unit); 1050 if (rv == BCM_E_NONE) { 1051 rv = bcm_td2_mpls_port_source_vp_lag_set(unit, gport, vp_lag_vp); 1052 bcm_tr_mpls_unlock(unit); 1053 } 1054 } 1055 #endif /* BCM_TRIDENT2_SUPPORT */ 1056 1057 return rv; 1058 } 1059 1060 /* 1061 * Function: 1062 * _bcm_esw_mpls_port_source_vp_lag_clear 1063 * Purpose: 1064 * Clear source VP LAG for a mpls virtual port. 1065 * Parameters: 1066 * unit - (IN) SOC unit number. 1067 * gport - (IN) mpls virtual port GPORT ID. 1068 * vp_lag_vp - (IN) VP representing the VP LAG. 1069 * Returns: 1070 * BCM_X_XXX 1071 */ 1072 int 1073 _bcm_esw_mpls_port_source_vp_lag_clear(int unit, bcm_gport_t gport, 1074 int vp_lag_vp) 1075 { 1076 int rv = BCM_E_UNAVAIL; 1077 1078 #if defined(BCM_TRIDENT2_SUPPORT) 1079 if (soc_feature(unit, soc_feature_mpls) 1080 && soc_feature(unit, soc_feature_vp_lag)) { 1081 rv = bcm_tr_mpls_lock(unit); 1082 if (rv == BCM_E_NONE) { 1083 rv = bcm_td2_mpls_port_source_vp_lag_clear(unit, gport, vp_lag_vp); 1084 bcm_tr_mpls_unlock(unit); 1085 } 1086 } 1087 #endif /* BCM_TRIDENT2_SUPPORT */ 1088 1089 return rv; 1090 } 1091 1092 /* 1093 * Function: 1094 * _bcm_esw_mpls_port_source_vp_lag_get 1095 * Purpose: 1096 * Get source VP LAG for a mpls virtual port. 1097 * Parameters: 1098 * unit - (IN) SOC unit number. 1099 * gport - (IN) mpls virtual port GPORT ID. 1100 * vp_lag_vp - (OUT) VP representing the VP LAG. 1101 * Returns: 1102 * BCM_X_XXX 1103 */ 1104 int 1105 _bcm_esw_mpls_port_source_vp_lag_get(int unit, bcm_gport_t gport, 1106 int *vp_lag_vp) 1107 { 1108 int rv = BCM_E_UNAVAIL; 1109 1110 #if defined(BCM_TRIDENT2_SUPPORT) 1111 if (soc_feature(unit, soc_feature_mpls) 1112 && soc_feature(unit, soc_feature_vp_lag)) { 1113 rv = bcm_tr_mpls_lock(unit); 1114 if (rv == BCM_E_NONE) { 1115 rv = bcm_td2_mpls_port_source_vp_lag_get(unit, gport, vp_lag_vp); 1116 bcm_tr_mpls_unlock(unit); 1117 } 1118 } 1119 #endif /* BCM_TRIDENT2_SUPPORT */ 1120 1121 return rv; 1122 } 1123 1124 /* 1125 * Function: 1126 * bcm_mpls_entropy_identifier_add 1127 * Purpose: 1128 * Add an MPLS entropy label identifier 1129 * Parameters: 1130 * unit - Device Number 1131 * info - Entropy Label information 1132 * Returns: 1133 * BCM_E_XXX 1134 */ 1135 int 1136 bcm_esw_mpls_entropy_identifier_add( 1137 int unit, 1138 uint32 options, 1139 bcm_mpls_entropy_identifier_t *info) 1140 { 1141 int rv = BCM_E_UNAVAIL; 1142 #ifdef BCM_MPLS_SUPPORT 1143 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1144 if ((options & BCM_MPLS_ENTROPY_LABEL_IDENTIFIER_TOS) && 1145 soc_feature(unit, soc_feature_td2p_mpls_entropy_label)) { 1146 L3_LOCK(unit); 1147 rv = bcm_tr_mpls_lock(unit); 1148 if ( rv == BCM_E_NONE ) { 1149 rv = bcm_td2p_mpls_entropy_identifier_add(unit, options, 1150 info); 1151 bcm_tr_mpls_unlock (unit); 1152 } 1153 L3_UNLOCK(unit); 1154 return rv; 1155 } 1156 #endif 1157 #endif 1158 return rv; 1159 } 1160 1161 /* 1162 * Function: 1163 * bcm_mpls_entropy_identifier_delete 1164 * Purpose: 1165 * Delete an MPLS entropy label identifier 1166 * Parameters: 1167 * unit - Device Number 1168 * info - Entropy Label information 1169 * Returns: 1170 * BCM_E_XXX 1171 */ 1172 int 1173 bcm_esw_mpls_entropy_identifier_delete( 1174 int unit, 1175 bcm_mpls_entropy_identifier_t *info) 1176 { 1177 int rv = BCM_E_UNAVAIL; 1178 #ifdef BCM_MPLS_SUPPORT 1179 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1180 if (soc_feature(unit, soc_feature_td2p_mpls_entropy_label)) { 1181 L3_LOCK(unit); 1182 rv = bcm_tr_mpls_lock(unit); 1183 if ( rv == BCM_E_NONE ) { 1184 rv = bcm_td2p_mpls_entropy_identifier_delete(unit, info); 1185 bcm_tr_mpls_unlock (unit); 1186 } 1187 L3_UNLOCK(unit); 1188 return rv; 1189 } 1190 #endif 1191 #endif 1192 return rv; 1193 } 1194 1195 /* 1196 * Function: 1197 * bcm_mpls_entropy_identifier_delete_all 1198 * Purpose: 1199 * Delete all MPLS entropy label identifier entries. 1200 * Parameters: 1201 * unit - Device Number 1202 * Returns: 1203 * BCM_E_XXX 1204 */ 1205 int 1206 bcm_esw_mpls_entropy_identifier_delete_all( 1207 int unit) 1208 { 1209 int rv = BCM_E_UNAVAIL; 1210 #ifdef BCM_MPLS_SUPPORT 1211 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1212 if (soc_feature(unit, soc_feature_td2p_mpls_entropy_label)) { 1213 L3_LOCK(unit); 1214 rv = bcm_tr_mpls_lock(unit); 1215 if ( rv == BCM_E_NONE ) { 1216 rv = bcm_td2p_mpls_entropy_identifier_delete_all(unit); 1217 bcm_tr_mpls_unlock (unit); 1218 } 1219 L3_UNLOCK(unit); 1220 return rv; 1221 } 1222 #endif 1223 #endif 1224 return rv; 1225 } 1226 1227 /* 1228 * Function: 1229 * bcm_mpls_entropy_identifier_get 1230 * Purpose: 1231 * Get an MPLS entrpoy label identifier entry 1232 * Parameters: 1233 * unit - Device Number 1234 * info - Entropy Label information 1235 * Returns: 1236 * BCM_E_XXX 1237 */ 1238 int 1239 bcm_esw_mpls_entropy_identifier_get( 1240 int unit, 1241 bcm_mpls_entropy_identifier_t *info) 1242 { 1243 int rv = BCM_E_UNAVAIL; 1244 #ifdef BCM_MPLS_SUPPORT 1245 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1246 if (soc_feature(unit, soc_feature_td2p_mpls_entropy_label)) { 1247 L3_LOCK(unit); 1248 rv = bcm_tr_mpls_lock(unit); 1249 if ( rv == BCM_E_NONE ) { 1250 rv = bcm_td2p_mpls_entropy_identifier_get(unit, info); 1251 bcm_tr_mpls_unlock (unit); 1252 } 1253 L3_UNLOCK(unit); 1254 return rv; 1255 } 1256 #endif 1257 #endif 1258 return rv; 1259 } 1260 1261 /* 1262 * Function: 1263 * bcm_mpls_entropy_identifier_traverse 1264 * Purpose: 1265 * Traverse all valid MPLS entropy label identifier entries 1266 * and call the supplied callback routine. 1267 * Parameters: 1268 * unit - Device Number 1269 * cb - User callback function, called once per MPLS ELI entry. 1270 * user_data - cookie 1271 * Returns: 1272 * BCM_E_XXX 1273 */ 1274 int 1275 bcm_esw_mpls_entropy_identifier_traverse( 1276 int unit, 1277 bcm_mpls_entropy_identifier_traverse_cb cb, 1278 void *user_data) 1279 { 1280 int rv = BCM_E_UNAVAIL; 1281 #ifdef BCM_MPLS_SUPPORT 1282 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1283 if (soc_feature(unit, soc_feature_td2p_mpls_entropy_label)) { 1284 L3_LOCK(unit); 1285 rv = bcm_tr_mpls_lock(unit); 1286 if ( rv == BCM_E_NONE ) { 1287 rv = bcm_td2p_mpls_entropy_identifier_traverse(unit, cb, user_data); 1288 bcm_tr_mpls_unlock (unit); 1289 } 1290 L3_UNLOCK(unit); 1291 return rv; 1292 } 1293 #endif 1294 #endif 1295 return rv; 1296 } 1297 1298 /* 1299 * Function: 1300 * bcm_esw_mpls_exp_map_create 1301 * Purpose: 1302 * Create an MPLS EXP map instance. 1303 * Parameters: 1304 * unit - (IN) SOC unit # 1305 * flags - (IN) MPLS flags 1306 * exp_map_id - (OUT) Allocated EXP map ID 1307 * Returns: 1308 * BCM_E_XXX 1309 */ 1310 int 1311 bcm_esw_mpls_exp_map_create(int unit, uint32 flags, int *exp_map_id) 1312 { 1313 int rv = BCM_E_UNAVAIL; 1314 #ifdef BCM_MPLS_SUPPORT 1315 #ifdef BCM_TRIUMPH_SUPPORT 1316 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 1317 rv = bcm_tr_mpls_lock(unit); 1318 if ( rv == BCM_E_NONE ) { 1319 rv = bcm_tr_mpls_exp_map_create(unit, flags, exp_map_id); 1320 bcm_tr_mpls_unlock (unit); 1321 } 1322 return rv; 1323 } 1324 #endif 1325 #endif 1326 return rv; 1327 } 1328 1329 /* 1330 * Function: 1331 * bcm_esw_mpls_exp_map_destroy 1332 * Purpose: 1333 * Destroy an existing MPLS EXP map instance. 1334 * Parameters: 1335 * unit - (IN) SOC unit # 1336 * exp_map_id - (IN) EXP map ID 1337 * Returns: 1338 * BCM_E_XXX 1339 */ 1340 int 1341 bcm_esw_mpls_exp_map_destroy(int unit, int exp_map_id) 1342 { 1343 int rv = BCM_E_UNAVAIL; 1344 #ifdef BCM_MPLS_SUPPORT 1345 #ifdef BCM_TRIUMPH_SUPPORT 1346 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 1347 rv = bcm_tr_mpls_lock(unit); 1348 if ( rv == BCM_E_NONE ) { 1349 rv = bcm_tr_mpls_exp_map_destroy(unit, exp_map_id); 1350 bcm_tr_mpls_unlock (unit); 1351 } 1352 return rv; 1353 } 1354 #endif 1355 #endif 1356 return rv; 1357 } 1358 1359 /* 1360 * Function: 1361 * bcm_esw_mpls_exp_map_set 1362 * Purpose: 1363 * Set the mapping of { internal priority, color } 1364 * to a EXP value for MPLS headers 1365 * in the specified EXP map instance. 1366 * Parameters: 1367 * unit - (IN) SOC unit # 1368 * exp_map_id - (IN) EXP map ID 1369 * priority - (IN) Internal priority 1370 * color - (IN) bcmColor* 1371 * exp - (IN) EXP value 1372 * Returns: 1373 * BCM_E_XXX 1374 */ 1375 int 1376 bcm_esw_mpls_exp_map_set(int unit, int exp_map_id, 1377 bcm_mpls_exp_map_t *exp_map) 1378 { 1379 int rv = BCM_E_UNAVAIL; 1380 #ifdef BCM_MPLS_SUPPORT 1381 #ifdef BCM_TRIUMPH_SUPPORT 1382 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 1383 rv = bcm_tr_mpls_lock(unit); 1384 if ( rv == BCM_E_NONE ) { 1385 rv = bcm_tr_mpls_exp_map_set(unit, exp_map_id, exp_map); 1386 bcm_tr_mpls_unlock (unit); 1387 } 1388 return rv; 1389 } 1390 #endif 1391 #endif 1392 return rv; 1393 } 1394 1395 /* 1396 * Function: 1397 * bcm_esw_mpls_exp_map_get 1398 * Purpose: 1399 * Get the mapping of { internal priority, color } 1400 * to a EXP value for MPLS headers 1401 * in the specified EXP map instance. 1402 * Parameters: 1403 * unit - (IN) SOC unit # 1404 * exp_map_id - (IN) EXP map ID 1405 * priority - (IN) Internal priority 1406 * color - (IN) bcmColor* 1407 * exp - (OUT) EXP value 1408 * Returns: 1409 * BCM_E_XXX 1410 */ 1411 int 1412 bcm_esw_mpls_exp_map_get(int unit, int exp_map_id, 1413 bcm_mpls_exp_map_t *exp_map) 1414 { 1415 int rv = BCM_E_UNAVAIL; 1416 #ifdef BCM_MPLS_SUPPORT 1417 #ifdef BCM_TRIUMPH_SUPPORT 1418 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 1419 rv = bcm_tr_mpls_lock(unit); 1420 if ( rv == BCM_E_NONE ) { 1421 rv = bcm_tr_mpls_exp_map_get(unit, exp_map_id, exp_map); 1422 bcm_tr_mpls_unlock (unit); 1423 } 1424 return rv; 1425 } 1426 #endif 1427 #endif 1428 return rv; 1429 } 1430 1431 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1432 /* 1433 * Function: 1434 * bcmi_td2p_mpls_tunnel_stat_get_table_info 1435 * Description: 1436 * Provides relevant flex table information(table-name,index with 1437 * direction) based on the mpls tunnel info. 1438 * 1439 * Parameters: 1440 * unit - (IN) unit number 1441 * intf_id - (IN) Interface id of a egress L3 object. 1442 * num_of_tables - (OUT) Number of flex counter tables 1443 * table_info - (OUT) Flex counter tables information 1444 * 1445 * Return Value: 1446 * BCM_E_XXX 1447 */ 1448 static 1449 bcm_error_t bcmi_td2p_mpls_tunnel_stat_get_table_info( 1450 int unit, 1451 bcm_if_t intf_id, 1452 uint32 *num_of_tables, 1453 bcm_stat_flex_table_info_t *table_info) 1454 { 1455 bcm_l3_egress_t egr_intf = {0}; 1456 egr_l3_intf_entry_t if_entry; 1457 int mpls_index = 0; 1458 1459 (*num_of_tables) = 0; 1460 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 1461 return BCM_E_UNAVAIL; 1462 } 1463 BCM_IF_ERROR_RETURN(bcm_esw_l3_egress_get(unit, intf_id, &egr_intf)); 1464 1465 /* L3 interface info */ 1466 SOC_IF_ERROR_RETURN(READ_EGR_L3_INTFm(unit, 1467 MEM_BLOCK_ANY, egr_intf.intf, &if_entry)); 1468 mpls_index = soc_EGR_L3_INTFm_field32_get(unit, &if_entry, 1469 MPLS_TUNNEL_INDEXf); 1470 #if defined(BCM_TRIDENT3_SUPPORT) 1471 if (SOC_IS_TRIDENT3X(unit) && soc_feature(unit, soc_feature_td3_style_mpls)) { 1472 table_info[*num_of_tables].table = EGR_IP_TUNNEL_MPLS_DOUBLE_WIDEm; 1473 } else 1474 #endif 1475 { 1476 table_info[*num_of_tables].table = EGR_IP_TUNNEL_MPLSm; 1477 } 1478 table_info[*num_of_tables].index = mpls_index; 1479 table_info[*num_of_tables].direction = bcmStatFlexDirectionEgress; 1480 (*num_of_tables)++; 1481 return BCM_E_NONE; 1482 } 1483 1484 /* 1485 * Function: 1486 * bcmi_td2p_mpls_tunnel_stat_attach 1487 * 1488 * Description: 1489 * Attach counters entries to the mpls tunnel derived from the 1490 * given L3 Egress interface 1491 * 1492 * Parameters: 1493 * unit - (IN) unit number 1494 * intf_id - (IN) Interface id 1495 * stat_counter_id - (IN) Stat Counter ID 1496 * 1497 * Return Value: 1498 * BCM_E_XXX 1499 */ 1500 STATIC bcm_error_t bcmi_td2p_mpls_tunnel_stat_attach( 1501 int unit, 1502 bcm_if_t intf_id, 1503 uint32 stat_counter_id) 1504 { 1505 soc_mem_t table = 0; 1506 bcm_stat_flex_direction_t direction = bcmStatFlexDirectionEgress; 1507 uint32 pool_number = 0; 1508 uint32 base_index = 0; 1509 bcm_stat_flex_mode_t offset_mode = 0; 1510 bcm_stat_object_t object = bcmStatObjectEgrMplsTunnelLabel; 1511 bcm_stat_group_mode_t group_mode = bcmStatGroupModeSingle; 1512 uint32 count = 0; 1513 uint32 actual_num_tables = 0; 1514 uint32 num_of_tables = 0; 1515 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 1516 1517 _bcm_esw_stat_get_counter_id_info( 1518 unit, stat_counter_id, 1519 &group_mode, &object, 1520 &offset_mode, &pool_number, &base_index); 1521 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit, 1522 object, &direction)); 1523 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit, group_mode)); 1524 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_table_info(unit, 1525 object, 1, &actual_num_tables, &table, &direction)); 1526 1527 BCM_IF_ERROR_RETURN(bcmi_td2p_mpls_tunnel_stat_get_table_info( 1528 unit, intf_id, &num_of_tables, &table_info[0])); 1529 for (count = 0; count < num_of_tables ; count++) { 1530 if ((table_info[count].direction == direction) && 1531 (table_info[count].table == table) ) { 1532 if (direction == bcmStatFlexDirectionIngress) { 1533 return _bcm_esw_stat_flex_attach_ingress_table_counters( 1534 unit, 1535 table_info[count].table, 1536 table_info[count].index, 1537 offset_mode, 1538 base_index, 1539 pool_number); 1540 } else { 1541 return _bcm_esw_stat_flex_attach_egress_table_counters( 1542 unit, 1543 table_info[count].table, 1544 table_info[count].index, 1545 object, 1546 offset_mode, 1547 base_index, 1548 pool_number); 1549 } 1550 } 1551 } 1552 return BCM_E_NOT_FOUND; 1553 } 1554 1555 1556 /* 1557 * Function: 1558 * bcmi_td2p_mpls_tunnel_stat_detach 1559 * 1560 * Description: 1561 * Detach counters entries to the mpls tunnel derived from the 1562 * given L3 Egress interface. 1563 * 1564 * Parameters: 1565 * unit - (IN) unit number 1566 * intf_id - (IN) Interface id of a egress L3 object. 1567 * stat_counter_id - (IN) Stat Counter ID. 1568 * 1569 * Return Value: 1570 * BCM_E_XXX 1571 */ 1572 STATIC 1573 bcm_error_t bcmi_td2p_mpls_tunnel_stat_detach( 1574 int unit, 1575 bcm_if_t intf_id, 1576 uint32 stat_counter_id) 1577 { 1578 uint32 count = 0; 1579 uint32 num_of_tables = 0; 1580 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 1581 bcm_error_t rv = BCM_E_NONE; 1582 bcm_error_t err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE}; 1583 bcm_stat_group_mode_t group_mode = bcmStatGroupModeSingle; 1584 bcm_stat_object_t object = bcmStatObjectEgrMplsTunnelLabel; 1585 bcm_stat_flex_mode_t offset_mode = 0; 1586 uint32 pool_number = 0; 1587 uint32 base_index = 0; 1588 1589 BCM_IF_ERROR_RETURN(bcmi_td2p_mpls_tunnel_stat_get_table_info( 1590 unit, intf_id, &num_of_tables, &table_info[0])); 1591 if (stat_counter_id != 0) { 1592 _bcm_esw_stat_get_counter_id_info( 1593 unit, stat_counter_id, 1594 &group_mode, &object, 1595 &offset_mode, &pool_number, &base_index); 1596 } 1597 for (count = 0; count < num_of_tables ; count++) { 1598 if (table_info[count].direction == bcmStatFlexDirectionIngress) { 1599 rv = _bcm_esw_stat_flex_detach_ingress_table_counters( 1600 unit, table_info[count].table, table_info[count].index); 1601 if (BCM_E_NONE != rv && 1602 BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) { 1603 err_code[bcmStatFlexDirectionIngress] = rv; 1604 } 1605 } else { 1606 rv = _bcm_esw_stat_flex_detach_egress_table_counters( 1607 unit, object, 1608 table_info[count].table, table_info[count].index); 1609 if (BCM_E_NONE != rv && 1610 BCM_E_NONE == err_code[bcmStatFlexDirectionEgress]) { 1611 err_code[bcmStatFlexDirectionEgress] = 1; 1612 } 1613 } 1614 } 1615 1616 BCM_STAT_FLEX_DETACH_RETURN(err_code) 1617 } 1618 1619 /* 1620 * Function: 1621 * bcmi_td2p_mpls_tunnel_stat_counter_get 1622 * 1623 * Description: 1624 * Get the specified counter statistic for a mpls tunnel derived from the 1625 * given L3 Egress interface 1626 * if sync_mode is set, sync the sw accumulated count 1627 * with hw count value first, else return sw count. 1628 * 1629 * Parameters: 1630 * unit - (IN) unit number 1631 * sync_mode - (IN) hwcount is to be synced to sw count 1632 * intf_id - (IN) Interface id of a egress L3 object. 1633 * stat - (IN) Type of the counter to retrieve 1634 * I.e. ingress/egress byte/packet) 1635 * num_entries - (IN) Number of counter Entries 1636 * counter_indexes - (IN) Pointer to Counter indexes entries 1637 * counter_values - (OUT) Pointer to counter values 1638 * 1639 * Return Value: 1640 * BCM_E_XXX 1641 */ 1642 STATIC 1643 bcm_error_t bcmi_td2p_mpls_tunnel_stat_counter_get( 1644 int unit, 1645 int sync_mode, 1646 bcm_if_t intf_id, 1647 uint32 stat_counter_id, 1648 bcm_mpls_stat_t stat, 1649 uint32 num_entries, 1650 uint32 *counter_indexes, 1651 bcm_stat_value_t *counter_values) 1652 { 1653 uint32 table_count = 0; 1654 uint32 index_count = 0; 1655 uint32 num_of_tables = 0; 1656 bcm_stat_flex_direction_t direction = bcmStatFlexDirectionIngress; 1657 uint32 byte_flag = 0; 1658 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 1659 uint32 pool_number = 0; 1660 uint32 base_index = 0; 1661 bcm_stat_flex_mode_t offset_mode = 0; 1662 bcm_stat_object_t object = bcmStatObjectEgrMplsTunnelLabel; 1663 bcm_stat_group_mode_t group_mode = bcmStatGroupModeSingle; 1664 1665 if (stat_counter_id != 0) { 1666 _bcm_esw_stat_get_counter_id_info( 1667 unit, stat_counter_id, 1668 &group_mode, &object, 1669 &offset_mode, &pool_number, &base_index); 1670 } 1671 if ((stat == bcmMplsOutPkts) || 1672 (stat == bcmMplsOutBytes)) { 1673 direction = bcmStatFlexDirectionEgress; 1674 } else { 1675 direction = bcmStatFlexDirectionIngress; 1676 } 1677 if ((stat == bcmMplsInPkts)|| (stat == bcmMplsOutPkts)) { 1678 byte_flag = 0; 1679 } else { 1680 byte_flag = 1; 1681 } 1682 1683 BCM_IF_ERROR_RETURN(bcmi_td2p_mpls_tunnel_stat_get_table_info( 1684 unit, intf_id, &num_of_tables, &table_info[0])); 1685 1686 for (table_count = 0; table_count < num_of_tables ; table_count++) { 1687 if (table_info[table_count].direction == direction) { 1688 for (index_count = 0; index_count < num_entries ; index_count++) { 1689 BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_get( 1690 unit, sync_mode, 1691 table_info[table_count].index, 1692 table_info[table_count].table, 1693 object, 1694 byte_flag, 1695 counter_indexes[index_count], 1696 &counter_values[index_count])); 1697 } 1698 } 1699 } 1700 return BCM_E_NONE; 1701 } 1702 1703 1704 1705 /* 1706 * Function: 1707 * bcmi_td2p_mpls_tunnel_stat_counter_set 1708 * 1709 * Description: 1710 * Set the specified counter statistic for a mpls tunnel derived from the 1711 * given L3 Egress interface 1712 * 1713 * Parameters: 1714 * unit - (IN) unit number 1715 * intf_id - (IN) Interface id of a egress L3 object. 1716 * stat - (IN) Type of the counter to retrieve 1717 * I.e. ingress/egress byte/packet) 1718 * num_entries - (IN) Number of counter Entries 1719 * counter_indexes - (IN) Pointer to Counter indexes entries 1720 * counter_values - (IN) Pointer to counter values 1721 * 1722 * Return Value: 1723 * BCM_E_XXX 1724 */ 1725 STATIC 1726 bcm_error_t bcmi_td2p_mpls_tunnel_stat_counter_set( 1727 int unit, 1728 bcm_if_t intf_id, 1729 uint32 stat_counter_id, 1730 bcm_mpls_stat_t stat, 1731 uint32 num_entries, 1732 uint32 *counter_indexes, 1733 bcm_stat_value_t *counter_values) 1734 { 1735 uint32 table_count = 0; 1736 uint32 index_count = 0; 1737 uint32 num_of_tables = 0; 1738 bcm_stat_flex_direction_t direction = bcmStatFlexDirectionIngress; 1739 uint32 byte_flag = 0; 1740 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 1741 uint32 pool_number = 0; 1742 uint32 base_index = 0; 1743 bcm_stat_flex_mode_t offset_mode = 0; 1744 bcm_stat_object_t object = bcmStatObjectEgrMplsTunnelLabel; 1745 bcm_stat_group_mode_t group_mode = bcmStatGroupModeSingle; 1746 1747 if ((stat == bcmMplsOutPkts) || 1748 (stat == bcmMplsOutBytes)) { 1749 direction = bcmStatFlexDirectionEgress; 1750 } else { 1751 direction = bcmStatFlexDirectionIngress; 1752 } 1753 if ((stat == bcmMplsInPkts) || (stat == bcmMplsOutPkts)) { 1754 byte_flag = 0; 1755 } else { 1756 byte_flag = 1; 1757 } 1758 if (stat_counter_id != 0) { 1759 _bcm_esw_stat_get_counter_id_info( 1760 unit, stat_counter_id, 1761 &group_mode, &object, 1762 &offset_mode, &pool_number, &base_index); 1763 } 1764 BCM_IF_ERROR_RETURN(bcmi_td2p_mpls_tunnel_stat_get_table_info( 1765 unit, intf_id, &num_of_tables, &table_info[0])); 1766 1767 for (table_count = 0; table_count < num_of_tables ; table_count++) { 1768 if (table_info[table_count].direction == direction) { 1769 for (index_count = 0; index_count < num_entries ; index_count++) { 1770 BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_set( 1771 unit, 1772 table_info[table_count].index, 1773 table_info[table_count].table, 1774 object, 1775 byte_flag, 1776 counter_indexes[index_count], 1777 &counter_values[index_count])); 1778 } 1779 } 1780 } 1781 return BCM_E_NONE; 1782 } 1783 1784 1785 /* 1786 * Function: 1787 * bcmi_td2p_mpls_tunnel_stat_id_get 1788 * 1789 * Description: 1790 * Get stat counter id associated with given egress interface id 1791 * 1792 * Parameters: 1793 * unit - (IN) unit number 1794 * intf_id - (IN) Interface id of a egress L3 object. 1795 * stat - (IN) Type of the counter to retrieve 1796 * I.e. ingress/egress byte/packet) 1797 * Stat_counter_id - (OUT) Stat Counter ID 1798 * 1799 * Return Value: 1800 * BCM_E_XXX 1801 */ 1802 STATIC 1803 int bcmi_td2p_mpls_tunnel_stat_id_get( 1804 int unit, 1805 bcm_if_t intf_id, 1806 bcm_mpls_stat_t stat, 1807 uint32 *stat_counter_id) 1808 { 1809 bcm_stat_flex_direction_t direction = bcmStatFlexDirectionIngress; 1810 uint32 num_of_tables = 0; 1811 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 1812 uint32 index = 0; 1813 uint32 num_stat_counter_ids = 0; 1814 1815 if ((stat == bcmMplsInPkts) || 1816 (stat == bcmMplsInBytes)) { 1817 direction = bcmStatFlexDirectionIngress; 1818 } else { 1819 direction = bcmStatFlexDirectionEgress; 1820 } 1821 BCM_IF_ERROR_RETURN(bcmi_td2p_mpls_tunnel_stat_get_table_info( 1822 unit, intf_id, &num_of_tables, &table_info[0])); 1823 for (index = 0; index < num_of_tables ; index++) { 1824 if (table_info[index].direction == direction) 1825 return _bcm_esw_stat_flex_get_counter_id( 1826 unit, 1, &table_info[index], 1827 &num_stat_counter_ids, stat_counter_id); 1828 } 1829 return BCM_E_NOT_FOUND; 1830 } 1831 1832 /* 1833 * Function: 1834 * bcmi_td2p_mpls_tunnel_label_counter_id_num_get 1835 * 1836 * Description: 1837 * Get array of counters ids' attached to the mpls tunnel 1838 * 1839 * Parameters: 1840 * unit - (IN) unit number 1841 * intf_id - (IN) Interface id 1842 * num_counters - (IN) Number of counters attached 1843 * to the interface id 1844 * Stat_counter_id - (OUT) Array of stat counter ids 1845 * associated with the interface id 1846 * 1847 * Return Value: 1848 * BCM_E_XXX 1849 */ 1850 STATIC bcm_error_t bcmi_td2p_mpls_tunnel_label_counter_id_num_get( 1851 int unit, 1852 bcm_if_t intf_id, 1853 int *num_counters, 1854 uint32 *stat_counter_id) 1855 { 1856 uint32 num_of_tables = 0; 1857 int num_labels = 0; 1858 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 1859 1860 BCM_IF_ERROR_RETURN(bcmi_td2p_mpls_tunnel_stat_get_table_info( 1861 unit, intf_id, &num_of_tables, &table_info[0])); 1862 1863 BCM_IF_ERROR_RETURN(_bcm_tr_mpls_tunnel_chain_label_count_get(unit, 1864 table_info[0].index, &num_labels)); 1865 #if defined (INCLUDE_L3) 1866 if (*num_counters <= num_labels) { 1867 return _bcm_esw_stat_flex_get_multi_counter_id(unit,&table_info[0], 1868 num_counters, stat_counter_id); 1869 } else { 1870 return BCM_E_PARAM; 1871 } 1872 #endif 1873 return BCM_E_UNAVAIL; 1874 } 1875 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 1876 1877 /* 1878 * Function: 1879 * bcm_esw_mpls_tunnel_stat_attach 1880 * 1881 * Description: 1882 * Attach counters entries to the the mpls tunnel derived from the 1883 * given L3 Egress interface 1884 * 1885 * Parameters: 1886 * unit - (IN) unit number 1887 * intf_id - (IN) Interface id of a egress L3 object. 1888 * stat_counter_id - (IN) Stat Counter ID. 1889 * 1890 * Return Value: 1891 * BCM_E_XXX 1892 */ 1893 int bcm_esw_mpls_tunnel_stat_attach( 1894 int unit, 1895 bcm_if_t intf_id, 1896 uint32 stat_counter_id) 1897 { 1898 #ifdef BCM_MPLS_SUPPORT 1899 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1900 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 1901 return bcmi_td2p_mpls_tunnel_stat_attach(unit, intf_id, stat_counter_id); 1902 } 1903 #endif 1904 #endif 1905 return BCM_E_UNAVAIL; 1906 } 1907 /* 1908 * Function: 1909 * bcm_esw_mpls_tunnel_stat_detach 1910 * 1911 * Description: 1912 * Detach counters entries to the the mpls tunnel derived from the 1913 * given L3 Egress interface. 1914 * 1915 * Parameters: 1916 * unit - (IN) unit number 1917 * intf_id - (IN) Interface id of a egress L3 object. 1918 * stat_counter_id - (IN) Stat Counter ID. 1919 * 1920 * Return Value: 1921 * BCM_E_XXX 1922 */ 1923 int bcm_esw_mpls_tunnel_stat_detach( 1924 int unit, 1925 bcm_if_t intf_id) 1926 { 1927 #ifdef BCM_MPLS_SUPPORT 1928 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1929 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 1930 return bcmi_td2p_mpls_tunnel_stat_detach(unit, intf_id, 0); 1931 } 1932 #endif 1933 #endif 1934 return BCM_E_UNAVAIL; 1935 } 1936 1937 /* 1938 * Function: 1939 * bcm_esw_mpls_tunnel_stat_counter_get 1940 * 1941 * Description: 1942 * Get the specified counter statistic for a mpls tunnel derived from the 1943 * given L3 Egress interface 1944 * 1945 * Parameters: 1946 * unit - (IN) unit number 1947 * intf_id - (IN) Interface id of a egress L3 object. 1948 * stat - (IN) Type of the counter to retrieve 1949 * I.e. ingress/egress byte/packet) 1950 * num_entries - (IN) Number of counter Entries 1951 * counter_indexes - (IN) Pointer to Counter indexes entries 1952 * counter_values - (OUT) Pointer to counter values 1953 * 1954 * Return Value: 1955 * BCM_E_XXX 1956 */ 1957 int bcm_esw_mpls_tunnel_stat_counter_get( 1958 int unit, 1959 bcm_if_t intf_id, 1960 bcm_mpls_stat_t stat, 1961 uint32 num_entries, 1962 uint32 *counter_indexes, 1963 bcm_stat_value_t *counter_values) 1964 { 1965 #ifdef BCM_MPLS_SUPPORT 1966 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1967 return bcmi_td2p_mpls_tunnel_stat_counter_get(unit, 0, intf_id, 0, stat, 1968 num_entries, 1969 counter_indexes, 1970 counter_values); 1971 #endif 1972 #endif 1973 1974 return BCM_E_UNAVAIL; 1975 } 1976 1977 /* 1978 * Function: 1979 * bcm_esw_mpls_tunnel_stat_counter_sync_get 1980 * 1981 * Description: 1982 * Retrieve set of counter statistics for a mpls tunnel derived from the 1983 * given L3 Egress interface 1984 * sw accumulated counters synced with hw count. 1985 * 1986 * Parameters: 1987 * unit - (IN) unit number 1988 * intf_id - (IN) Interface id of a egress L3 object. 1989 * stat - (IN) Type of the counter to retrieve 1990 * I.e. ingress/egress byte/packet) 1991 * num_entries - (IN) Number of counter Entries 1992 * counter_indexes - (IN) Pointer to Counter indexes entries 1993 * counter_values - (OUT) Pointer to counter values 1994 * 1995 * Return Value: 1996 * BCM_E_XXX 1997 */ 1998 int bcm_esw_mpls_tunnel_stat_counter_sync_get( 1999 int unit, 2000 bcm_if_t intf_id, 2001 bcm_mpls_stat_t stat, 2002 uint32 num_entries, 2003 uint32 *counter_indexes, 2004 bcm_stat_value_t *counter_values) 2005 { 2006 #ifdef BCM_MPLS_SUPPORT 2007 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2008 return bcmi_td2p_mpls_tunnel_stat_counter_get(unit, 1, intf_id, 0, stat, 2009 num_entries, counter_indexes, 2010 counter_values); 2011 #endif 2012 #endif 2013 return BCM_E_UNAVAIL; 2014 } 2015 /* 2016 * Function: 2017 * bcm_esw_mpls_tunnel_stat_counter_set 2018 * 2019 * Description: 2020 * Set the specified counter statistic for a mpls tunnel derived from the 2021 * given L3 Egress interface 2022 * 2023 * Parameters: 2024 * unit - (IN) unit number 2025 * intf_id - (IN) Interface id of a egress L3 object. 2026 * stat - (IN) Type of the counter to retrieve 2027 * I.e. ingress/egress byte/packet) 2028 * num_entries - (IN) Number of counter Entries 2029 * counter_indexes - (IN) Pointer to Counter indexes entries 2030 * counter_values - (IN) Pointer to counter values 2031 * 2032 * Return Value: 2033 * BCM_E_XXX 2034 */ 2035 int bcm_esw_mpls_tunnel_stat_counter_set( 2036 int unit, 2037 bcm_if_t intf_id, 2038 bcm_mpls_stat_t stat, 2039 uint32 num_entries, 2040 uint32 *counter_indexes, 2041 bcm_stat_value_t *counter_values) 2042 { 2043 #ifdef BCM_MPLS_SUPPORT 2044 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2045 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 2046 return bcmi_td2p_mpls_tunnel_stat_counter_set(unit, intf_id, 0, stat, 2047 num_entries, counter_indexes, counter_values); 2048 } 2049 #endif 2050 #endif 2051 return BCM_E_UNAVAIL; 2052 } 2053 2054 /* 2055 * Function: 2056 * bcm_esw_mpls_tunnel_stat_id_get 2057 * 2058 * Description: 2059 * Get stat counter id associated with given egress interface id 2060 * 2061 * Parameters: 2062 * unit - (IN) unit number 2063 * intf_id - (IN) Interface id of a egress L3 object. 2064 * stat - (IN) Type of the counter to retrieve 2065 * I.e. ingress/egress byte/packet) 2066 * Stat_counter_id - (OUT) Stat Counter ID 2067 * 2068 * Return Value: 2069 * BCM_E_XXX 2070 */ 2071 int bcm_esw_mpls_tunnel_stat_id_get( 2072 int unit, 2073 bcm_if_t intf_id, 2074 bcm_mpls_stat_t stat, 2075 uint32 *stat_counter_id) 2076 { 2077 #ifdef BCM_MPLS_SUPPORT 2078 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2079 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 2080 return bcmi_td2p_mpls_tunnel_stat_id_get(unit, intf_id, stat, 2081 stat_counter_id); 2082 } 2083 #endif 2084 #endif 2085 return BCM_E_UNAVAIL; 2086 } 2087 2088 /* 2089 * Function: 2090 * bcm_esw_mpls_tunnel_label_counter_id_detach 2091 * 2092 * Description: 2093 * Detach counter entry of the specific mpls tunnel label pointed 2094 * to by the given stat counter id. 2095 * 2096 * Parameters: 2097 * unit - (IN) unit number 2098 * intf_id - (IN) Interface id of a egress L3 object. 2099 * stat_counter_id - (IN) Stat Counter ID. 2100 * 2101 * Return Value: 2102 * BCM_E_XXX 2103 */ 2104 int bcm_esw_mpls_tunnel_label_counter_id_detach( 2105 int unit, 2106 bcm_if_t intf_id, 2107 uint32 stat_counter_id) 2108 { 2109 #ifdef BCM_MPLS_SUPPORT 2110 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2111 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 2112 return bcmi_td2p_mpls_tunnel_stat_detach(unit, intf_id, stat_counter_id); 2113 } 2114 #endif 2115 #endif 2116 return BCM_E_UNAVAIL; 2117 } 2118 2119 /* 2120 * Function: 2121 * bcm_esw_mpls_tunnel_label_counter_id_stat_get 2122 * 2123 * Description: 2124 * Get the specified counter statistic for the given mpls tunnel 2125 * label and counter id associated with it 2126 * 2127 * Parameters: 2128 * unit - (IN) unit number 2129 * intf_id - (IN) Interface id of a egress L3 object. 2130 * stat_counter_id - (IN) Stat Counter Id 2131 * stat_info - (IN/OUT) Mpls Stat Info Structure 2132 * 2133 * Return Value: 2134 * BCM_E_XXX 2135 */ 2136 int bcm_esw_mpls_tunnel_label_counter_id_stat_get( 2137 int unit, 2138 bcm_if_t intf_id, 2139 uint32 stat_counter_id, 2140 bcm_mpls_stat_info_t *stat_info) 2141 { 2142 #ifdef BCM_MPLS_SUPPORT 2143 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2144 return bcmi_td2p_mpls_tunnel_stat_counter_get(unit, 0, intf_id, stat_counter_id, 2145 stat_info->stat,stat_info->num_entries, 2146 stat_info->counter_indexes, 2147 stat_info->counter_values); 2148 #endif 2149 #endif 2150 2151 return BCM_E_UNAVAIL; 2152 } 2153 2154 /* 2155 * Function: 2156 * bcm_esw_mpls_tunnel_label_counter_id_stat_sync_get 2157 * 2158 * Description: 2159 * Get the specified counter statistic for the given mpls tunnel 2160 * label and counter id associated with it 2161 * sw accumulated counters synced with hw count. 2162 * 2163 * Parameters: 2164 * unit - (IN) unit number 2165 * intf_id - (IN) Interface id of a egress L3 object. 2166 * stat_counter_id - (IN) Stat Counter Id 2167 * stat_info - (IN/OUT) Mpls Stat Info Structure 2168 * 2169 * Return Value: 2170 * BCM_E_XXX 2171 */ 2172 int bcm_esw_mpls_tunnel_label_counter_id_stat_sync_get( 2173 int unit, 2174 bcm_if_t intf_id, 2175 uint32 stat_counter_id, 2176 bcm_mpls_stat_info_t *stat_info) 2177 { 2178 #ifdef BCM_MPLS_SUPPORT 2179 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2180 return bcmi_td2p_mpls_tunnel_stat_counter_get(unit, 1, intf_id, stat_counter_id, 2181 stat_info->stat,stat_info->num_entries, 2182 stat_info->counter_indexes, 2183 stat_info->counter_values); 2184 #endif 2185 #endif 2186 return BCM_E_UNAVAIL; 2187 } 2188 2189 /* 2190 * Function: 2191 * bcm_esw_mpls_tunnel_label_counter_id_stat_set 2192 * 2193 * Description: 2194 * Set the specified counter statistic for the given mpls tunnel 2195 * label and counter id associated with it 2196 * 2197 * Parameters: 2198 * unit - (IN) unit number 2199 * intf_id - (IN) Interface id of a egress L3 object. 2200 * stat_counter_id - (IN) Stat Counter Id 2201 * stat_info - (IN) Mpls Stat Info Structure 2202 * 2203 * Return Value: 2204 * BCM_E_XXX 2205 */ 2206 int bcm_esw_mpls_tunnel_label_counter_id_stat_set( 2207 int unit, 2208 bcm_if_t intf_id, 2209 uint32 stat_counter_id, 2210 bcm_mpls_stat_info_t *stat_info) 2211 { 2212 #ifdef BCM_MPLS_SUPPORT 2213 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2214 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 2215 return bcmi_td2p_mpls_tunnel_stat_counter_set(unit, intf_id, 2216 stat_counter_id,stat_info->stat, stat_info->num_entries, 2217 stat_info->counter_indexes,stat_info->counter_values); 2218 } 2219 #endif 2220 #endif 2221 return BCM_E_UNAVAIL; 2222 } 2223 2224 /* 2225 * Function: 2226 * bcm_esw_mpls_tunnel_label_counter_id_num_get 2227 * 2228 * Description: 2229 * Get stat counter id associated with given egress interface id 2230 * 2231 * Parameters: 2232 * unit - (IN) unit number 2233 * intf_id - (IN) Interface id of a egress L3 object. 2234 * num_counters - (IN/OUT) Number of counters attached 2235 * to the interface id 2236 * Stat_counter_id - (OUT) Array of stat counter ids 2237 * associated with the interface id 2238 * 2239 * Return Value: 2240 * BCM_E_XXX 2241 */ 2242 int bcm_esw_mpls_tunnel_label_counter_id_num_get( 2243 int unit, 2244 bcm_if_t intf_id, 2245 int *num_counters, 2246 uint32 *stat_counter_id) 2247 { 2248 #ifdef BCM_MPLS_SUPPORT 2249 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2250 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 2251 return bcmi_td2p_mpls_tunnel_label_counter_id_num_get(unit, intf_id, 2252 num_counters,stat_counter_id); 2253 } 2254 #endif 2255 #endif 2256 return BCM_E_UNAVAIL; 2257 } 2258 #if defined(BCM_TRIDENT2_SUPPORT) 2259 2260 /* Duplicated from Katana code 2261 * This should also serve as default MPLS flex stat counter support. 2262 */ 2263 2264 /* 2265 * Function: 2266 * td2_mpls_port_stat_get_table_info 2267 * Description: 2268 * Provides relevant flex table information(table-name,index with 2269 * direction) for specific vpn and gport 2270 * 2271 * Parameters: 2272 * unit - (IN) unit number 2273 * vpn - (IN) VPN Id 2274 * port - (IN) MPLS GPORT ID 2275 * num_of_tables - (OUT) Number of flex counter tables 2276 * table_info - (OUT) Flex counter tables information 2277 * 2278 * Return Value: 2279 * BCM_E_XXX 2280 * Notes: 2281 */ 2282 STATIC 2283 bcm_error_t td2_mpls_port_stat_get_table_info( 2284 int unit, 2285 bcm_vpn_t vpn, 2286 bcm_gport_t port, 2287 uint32 *num_of_tables, 2288 bcm_stat_flex_table_info_t *table_info) 2289 { 2290 int vp=0; 2291 ing_dvp_table_entry_t dvp={{0}}; 2292 int nh_index=0; 2293 initial_prot_nhi_table_entry_t prot_entry; 2294 int vpless_failover_port = FALSE; 2295 int rv; 2296 2297 if (_BCM_MPLS_GPORT_FAILOVER_VPLESS_GET(port)) { 2298 vpless_failover_port = TRUE; 2299 port = _BCM_MPLS_GPORT_FAILOVER_VPLESS_CLEAR(port); 2300 } 2301 2302 (*num_of_tables)=0; 2303 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 2304 return BCM_E_UNAVAIL; 2305 } 2306 if (soc_feature(unit, soc_feature_mpls)) { 2307 BCM_IF_ERROR_RETURN(bcm_tr_mpls_lock(unit)); 2308 if (!_BCM_MPLS_VPN_IS_VPLS(vpn) && 2309 !_BCM_MPLS_VPN_IS_VPWS(vpn)) { 2310 bcm_tr_mpls_unlock (unit); 2311 return BCM_E_PARAM; 2312 } 2313 vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 2314 if (vp == -1) { 2315 bcm_tr_mpls_unlock (unit); 2316 return BCM_E_PARAM; 2317 } 2318 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 2319 bcm_tr_mpls_unlock (unit); 2320 return BCM_E_NOT_FOUND; 2321 } 2322 table_info[*num_of_tables].table= SOURCE_VPm; 2323 table_info[*num_of_tables].index=vp; 2324 table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress; 2325 (*num_of_tables)++; 2326 if(READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp) == BCM_E_NONE) { 2327 nh_index=soc_ING_DVP_TABLEm_field32_get(unit, &dvp, NEXT_HOP_INDEXf); 2328 rv = BCM_E_NONE; 2329 if (vpless_failover_port == TRUE) { 2330 rv = READ_INITIAL_PROT_NHI_TABLEm(unit,MEM_BLOCK_ANY, nh_index, &prot_entry); 2331 if (BCM_SUCCESS(rv)) { 2332 nh_index = soc_INITIAL_PROT_NHI_TABLEm_field32_get(unit,&prot_entry, 2333 PROT_NEXT_HOP_INDEXf); 2334 } 2335 } 2336 if (BCM_SUCCESS(rv)) { 2337 table_info[*num_of_tables].table= EGR_L3_NEXT_HOPm; 2338 table_info[*num_of_tables].index=nh_index; 2339 table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress; 2340 (*num_of_tables)++; 2341 } 2342 } 2343 bcm_tr_mpls_unlock (unit); 2344 return BCM_E_NONE; 2345 } 2346 return BCM_E_UNAVAIL; 2347 } 2348 2349 #ifdef BCM_TOMAHAWK3_SUPPORT 2350 /* Convert key part of application format to HW entry. */ 2351 STATIC int 2352 th3_mpls_entry_set_key(int unit, bcm_mpls_tunnel_switch_t *info, 2353 mpls_entry_entry_t *ment) 2354 { 2355 bcm_module_t mod_out; 2356 bcm_port_t port_out; 2357 bcm_trunk_t trunk_id; 2358 int rv, gport_id; 2359 soc_mem_t mem = MPLS_ENTRY_SINGLEm; 2360 sal_memset(ment, 0, sizeof(mpls_entry_entry_t)); 2361 2362 if (info->port == BCM_GPORT_INVALID) { 2363 /* Global label, mod/port not part of lookup key */ 2364 soc_mem_field32_set(unit, mem, ment, PORT_NUMf, 0); 2365 if (BCM_XGS3_L3_MPLS_LBL_VALID(info->label)) { 2366 soc_mem_field32_set(unit, mem, ment, MPLS__MPLS_LABELf, info->label); 2367 } else { 2368 return BCM_E_PARAM; 2369 } 2370 2371 soc_mem_field32_set(unit, mem, ment, BASE_VALIDf, 1); 2372 return BCM_E_NONE; 2373 } 2374 2375 rv = _bcm_esw_gport_resolve(unit, info->port, &mod_out, 2376 &port_out, &trunk_id, &gport_id); 2377 BCM_IF_ERROR_RETURN(rv); 2378 2379 if (BCM_GPORT_IS_TRUNK(info->port)) { 2380 soc_mem_field32_set(unit, mem, ment, Tf, 1); 2381 soc_mem_field32_set(unit, mem, ment, TGIDf, trunk_id); 2382 } else { 2383 soc_mem_field32_set(unit, mem, ment, PORT_NUMf, port_out); 2384 } 2385 if (BCM_XGS3_L3_MPLS_LBL_VALID(info->label)) { 2386 soc_mem_field32_set(unit, mem, ment, MPLS__MPLS_LABELf, info->label); 2387 } else { 2388 return BCM_E_PARAM; 2389 } 2390 2391 soc_mem_field32_set(unit, mem, ment, BASE_VALIDf, 1); 2392 2393 return BCM_E_NONE; 2394 } 2395 #endif 2396 2397 /* Convert key part of application format to HW entry. */ 2398 STATIC int 2399 td2_mpls_entry_set_key(int unit, bcm_mpls_tunnel_switch_t *info, 2400 mpls_entry_entry_t *ment) 2401 { 2402 bcm_module_t mod_out; 2403 bcm_port_t port_out; 2404 bcm_trunk_t trunk_id; 2405 int rv, gport_id; 2406 2407 sal_memset(ment, 0, sizeof(mpls_entry_entry_t)); 2408 2409 if (info->port == BCM_GPORT_INVALID) { 2410 /* Global label, mod/port not part of lookup key */ 2411 soc_MPLS_ENTRYm_field32_set(unit, ment, MODULE_IDf, 0); 2412 soc_MPLS_ENTRYm_field32_set(unit, ment, PORT_NUMf, 0); 2413 if (BCM_XGS3_L3_MPLS_LBL_VALID(info->label)) { 2414 soc_MPLS_ENTRYm_field32_set(unit, ment, MPLS_LABELf, info->label); 2415 } else { 2416 return BCM_E_PARAM; 2417 } 2418 2419 if (soc_feature(unit, soc_feature_td3_style_mpls)) { 2420 soc_MPLS_ENTRYm_field32_set(unit, ment, BASE_VALID_0f, 3); 2421 soc_MPLS_ENTRYm_field32_set(unit, ment, BASE_VALID_1f, 7); 2422 } else { 2423 soc_MPLS_ENTRYm_field32_set(unit, ment, VALIDf, 1); 2424 } 2425 return BCM_E_NONE; 2426 } 2427 2428 rv = _bcm_esw_gport_resolve(unit, info->port, &mod_out, 2429 &port_out, &trunk_id, &gport_id); 2430 BCM_IF_ERROR_RETURN(rv); 2431 2432 if (BCM_GPORT_IS_TRUNK(info->port)) { 2433 soc_MPLS_ENTRYm_field32_set(unit, ment, Tf, 1); 2434 soc_MPLS_ENTRYm_field32_set(unit, ment, TGIDf, trunk_id); 2435 } else { 2436 soc_MPLS_ENTRYm_field32_set(unit, ment, MODULE_IDf, mod_out); 2437 soc_MPLS_ENTRYm_field32_set(unit, ment, PORT_NUMf, port_out); 2438 } 2439 if (BCM_XGS3_L3_MPLS_LBL_VALID(info->label)) { 2440 soc_MPLS_ENTRYm_field32_set(unit, ment, MPLS_LABELf, info->label); 2441 } else { 2442 return BCM_E_PARAM; 2443 } 2444 2445 if (soc_feature(unit, soc_feature_td3_style_mpls)) { 2446 soc_MPLS_ENTRYm_field32_set(unit, ment, BASE_VALID_0f, 3); 2447 soc_MPLS_ENTRYm_field32_set(unit, ment, BASE_VALID_1f, 7); 2448 } else { 2449 soc_MPLS_ENTRYm_field32_set(unit, ment, VALIDf, 1); 2450 } 2451 2452 return BCM_E_NONE; 2453 } 2454 2455 /* 2456 * Function: 2457 * td2_mpls_label_stat_get_table_info 2458 * Description: 2459 * Provides relevant flex table information(table-name,index with 2460 * direction) for given mpls label and gport 2461 * 2462 * Parameters: 2463 * unit - (IN) unit number 2464 * label - (IN) MPLS Label 2465 * port - (IN) MPLS Gport 2466 * object - (IN) Stat Object 2467 * num_of_tables - (OUT) Number of flex counter tables 2468 * table_info - (OUT) Flex counter tables information 2469 * 2470 * Return Value: 2471 * BCM_E_XXX 2472 * Notes: 2473 */ 2474 2475 STATIC 2476 bcm_error_t td2_mpls_label_stat_get_table_info( 2477 int unit, 2478 bcm_mpls_label_t label, 2479 bcm_gport_t port, 2480 bcm_stat_object_t object, 2481 uint32 *num_of_tables, 2482 bcm_stat_flex_table_info_t *table_info) 2483 { 2484 bcm_error_t rv=BCM_E_NOT_FOUND; 2485 bcm_mpls_tunnel_switch_t mpls_tunnel_switch={0}; 2486 mpls_entry_entry_t ment={{0}}; 2487 int index=0; 2488 soc_mem_t mem = MPLS_ENTRYm; 2489 int found = -1; 2490 2491 (*num_of_tables)=0; 2492 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 2493 return BCM_E_UNAVAIL; 2494 } 2495 if (!soc_feature(unit, soc_feature_mpls)) { 2496 return BCM_E_UNAVAIL; 2497 } 2498 2499 #ifdef BCM_TOMAHAWK3_SUPPORT 2500 if (soc_feature(unit, soc_feature_th3_style_simple_mpls)) { 2501 mem = MPLS_ENTRY_SINGLEm; 2502 } 2503 #endif 2504 sal_memset(&ment, 0, sizeof(mpls_entry_entry_t)); 2505 2506 mpls_tunnel_switch.port = port; 2507 if (BCM_XGS3_L3_MPLS_LBL_VALID(label)) { 2508 mpls_tunnel_switch.label = label; 2509 } else { 2510 return BCM_E_PARAM; 2511 } 2512 if ((object == bcmStatObjectIngMplsSwitchLabel) || 2513 (object == bcmStatObjectIngMplsSwitchSecondLabel)) { 2514 if (!soc_feature(unit, soc_feature_th3_style_simple_mpls)) { 2515 BCM_IF_ERROR_RETURN(td2_mpls_entry_set_key(unit, 2516 &mpls_tunnel_switch,&ment)); 2517 } 2518 #ifdef BCM_TOMAHAWK3_SUPPORT 2519 else { 2520 BCM_IF_ERROR_RETURN(th3_mpls_entry_set_key(unit, 2521 &mpls_tunnel_switch,&ment)); 2522 } 2523 #endif 2524 if ((rv=soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index, 2525 &ment, &ment, 0)) == BCM_E_NONE) { 2526 found = 1; 2527 } 2528 } else if ((object == bcmStatObjectIngMplsFrrLabel) && 2529 (soc_feature(unit, soc_feature_mpls_frr_lookup))){ 2530 mem = L3_TUNNELm; 2531 rv = _bcm_tr3_mpls_tunnel_switch_frr_get(unit, &mpls_tunnel_switch, &index); 2532 if (rv == BCM_E_NONE) { 2533 found = 1; 2534 } 2535 } else if (object == bcmStatObjectMaxValue) { 2536 if (!soc_feature(unit, soc_feature_th3_style_simple_mpls)) { 2537 BCM_IF_ERROR_RETURN(td2_mpls_entry_set_key(unit, 2538 &mpls_tunnel_switch,&ment)); 2539 } 2540 #ifdef BCM_TOMAHAWK3_SUPPORT 2541 else { 2542 BCM_IF_ERROR_RETURN(th3_mpls_entry_set_key(unit, 2543 &mpls_tunnel_switch,&ment)); 2544 } 2545 #endif 2546 if ((rv=soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index, 2547 &ment, &ment, 0)) == BCM_E_NONE) { 2548 mem = MPLS_ENTRYm; 2549 #ifdef BCM_TOMAHAWK3_SUPPORT 2550 if (soc_feature(unit, soc_feature_th3_style_simple_mpls)) { 2551 mem = MPLS_ENTRY_SINGLEm; 2552 } 2553 #endif 2554 } else if (soc_feature(unit, soc_feature_mpls_frr_lookup)) { 2555 if ((rv= _bcm_tr3_mpls_tunnel_switch_frr_get(unit, 2556 &mpls_tunnel_switch, &index)) == BCM_E_NONE) { 2557 mem = L3_TUNNELm; 2558 } else { 2559 return rv; 2560 } 2561 } else { 2562 return rv; 2563 } 2564 found = 1; 2565 } 2566 2567 if (found == 1) { 2568 table_info[*num_of_tables].table= mem; 2569 table_info[*num_of_tables].index=index; 2570 table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress; 2571 (*num_of_tables)++; 2572 } 2573 return rv; 2574 } 2575 2576 2577 /* 2578 * Function: 2579 * td2_mpls_port_stat_attach 2580 * Description: 2581 * Attach counters entries to the given mpls gport and vpn 2582 * 2583 * Parameters: 2584 * unit - (IN) unit number 2585 * vpn - (IN) VPN Id 2586 * port - (IN) MPLS GPORT ID 2587 * stat_counter_id - (IN) Stat Counter ID. 2588 * 2589 * Return Value: 2590 * BCM_E_XXX 2591 * Notes: 2592 */ 2593 STATIC 2594 bcm_error_t td2_mpls_port_stat_attach( 2595 int unit, 2596 bcm_vpn_t vpn, 2597 bcm_gport_t port, 2598 uint32 stat_counter_id) 2599 { 2600 soc_mem_t table=0; 2601 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 2602 uint32 pool_number=0; 2603 uint32 base_index=0; 2604 bcm_stat_flex_mode_t offset_mode=0; 2605 bcm_stat_object_t object=bcmStatObjectIngPort; 2606 bcm_stat_group_mode_t group_mode= bcmStatGroupModeSingle; 2607 uint32 count=0; 2608 uint32 actual_num_tables=0; 2609 uint32 num_of_tables=0; 2610 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 2611 2612 _bcm_esw_stat_get_counter_id_info( 2613 unit, stat_counter_id, 2614 &group_mode,&object,&offset_mode,&pool_number,&base_index); 2615 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit,object,&direction)); 2616 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit,group_mode)); 2617 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_table_info( 2618 unit,object,1,&actual_num_tables,&table,&direction)); 2619 2620 BCM_IF_ERROR_RETURN(td2_mpls_port_stat_get_table_info( 2621 unit, vpn,port,&num_of_tables,&table_info[0])); 2622 for (count=0; count < num_of_tables ; count++) { 2623 if ((table_info[count].direction == direction) && 2624 (table_info[count].table == table) ) { 2625 if (direction == bcmStatFlexDirectionIngress) { 2626 return _bcm_esw_stat_flex_attach_ingress_table_counters( 2627 unit, 2628 table_info[count].table, 2629 table_info[count].index, 2630 offset_mode, 2631 base_index, 2632 pool_number); 2633 } else { 2634 return _bcm_esw_stat_flex_attach_egress_table_counters( 2635 unit, 2636 table_info[count].table, 2637 table_info[count].index, 2638 0, 2639 offset_mode, 2640 base_index, 2641 pool_number); 2642 } 2643 } 2644 } 2645 return BCM_E_UNAVAIL; 2646 } 2647 /* 2648 * Function: 2649 * td2_mpls_port_stat_detach 2650 * Description: 2651 * Detach counters entries to the given mpls port and vpn 2652 * 2653 * Parameters: 2654 * unit - (IN) unit number 2655 * vpn - (IN) VPN Id 2656 * port - (IN) MPLS GPORT ID 2657 * 2658 * Return Value: 2659 * BCM_E_XXX 2660 * Notes: 2661 */ 2662 STATIC 2663 bcm_error_t td2_mpls_port_stat_detach( 2664 int unit, 2665 bcm_vpn_t vpn, 2666 bcm_gport_t port) 2667 { 2668 uint32 count=0; 2669 uint32 num_of_tables=0; 2670 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 2671 bcm_error_t rv = BCM_E_NONE; 2672 bcm_error_t err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE}; 2673 2674 BCM_IF_ERROR_RETURN(td2_mpls_port_stat_get_table_info( 2675 unit, vpn,port,&num_of_tables,&table_info[0])); 2676 2677 for (count=0; count < num_of_tables ; count++) { 2678 if (table_info[count].direction == bcmStatFlexDirectionIngress) { 2679 rv = _bcm_esw_stat_flex_detach_ingress_table_counters( 2680 unit, table_info[count].table, table_info[count].index); 2681 if (BCM_E_NONE != rv && 2682 BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) { 2683 err_code[bcmStatFlexDirectionIngress] = rv; 2684 } 2685 } else { 2686 rv = _bcm_esw_stat_flex_detach_egress_table_counters( 2687 unit, 0, table_info[count].table, table_info[count].index); 2688 if (BCM_E_NONE != rv && 2689 BCM_E_NONE == err_code[bcmStatFlexDirectionEgress]) { 2690 err_code[bcmStatFlexDirectionEgress] = rv; 2691 } 2692 } 2693 } 2694 2695 BCM_STAT_FLEX_DETACH_RETURN(err_code) 2696 } 2697 /* 2698 * Function: 2699 * td2_mpls_port_stat_counter_get 2700 * Description: 2701 * Get counter statistic values for specific vpn and gport 2702 * if sync_mode is set, sync the sw accumulated count 2703 * with hw count value first, else return sw count. 2704 * 2705 * Parameters: 2706 * unit - (IN) unit number 2707 * sync_mode - (IN) hwcount is to be synced to sw count 2708 * vpn - (IN) VPN Id 2709 * port - (IN) MPLS GPORT ID 2710 * stat - (IN) Type of the counter to retrieve 2711 * I.e. ingress/egress byte/packet) 2712 * num_entries - (IN) Number of counter Entries 2713 * counter_indexes - (IN) Pointer to Counter indexes entries 2714 * counter_values - (OUT) Pointer to counter values 2715 * 2716 * Return Value: 2717 * BCM_E_XXX 2718 * Notes: 2719 */ 2720 STATIC 2721 bcm_error_t td2_mpls_port_stat_counter_get( 2722 int unit, 2723 int sync_mode, 2724 bcm_vpn_t vpn, 2725 bcm_gport_t port, 2726 bcm_mpls_stat_t stat, 2727 uint32 num_entries, 2728 uint32 *counter_indexes, 2729 bcm_stat_value_t *counter_values) 2730 { 2731 uint32 table_count=0; 2732 uint32 index_count=0; 2733 uint32 num_of_tables=0; 2734 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 2735 uint32 byte_flag=0; 2736 bcm_stat_flex_table_info_t table_info[ 2737 BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 2738 2739 if ((stat == bcmMplsInBytes) || 2740 (stat == bcmMplsInPkts)) { 2741 direction = bcmStatFlexDirectionIngress; 2742 } else { 2743 direction = bcmStatFlexDirectionEgress; 2744 } 2745 if ((stat == bcmMplsInPkts) || 2746 (stat == bcmMplsOutPkts)) { 2747 byte_flag=0; 2748 } else { 2749 byte_flag=1; 2750 } 2751 2752 BCM_IF_ERROR_RETURN(td2_mpls_port_stat_get_table_info( 2753 unit, vpn,port,&num_of_tables,&table_info[0])); 2754 2755 for (table_count=0; table_count < num_of_tables ; table_count++) { 2756 if (table_info[table_count].direction == direction) { 2757 for (index_count=0; index_count < num_entries ; index_count++) { 2758 BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_get( 2759 unit, sync_mode, 2760 table_info[table_count].index, 2761 table_info[table_count].table, 2762 0, byte_flag, 2763 counter_indexes[index_count], 2764 &counter_values[index_count])); 2765 } 2766 } 2767 } 2768 return BCM_E_NONE; 2769 } 2770 /* 2771 * Function: 2772 * td2_mpls_port_stat_counter_set 2773 * Description: 2774 * Set counter statistic values for specific vpn and gport 2775 * 2776 * Parameters: 2777 * unit - (IN) unit number 2778 * vpn - (IN) VPN Id 2779 * port - (IN) MPLS GPORT ID 2780 * stat - (IN) Type of the counter to retrieve 2781 * I.e. ingress/egress byte/packet) 2782 * num_entries - (IN) Number of counter Entries 2783 * counter_indexes - (IN) Pointer to Counter indexes entries 2784 * counter_values - (OUT) Pointer to counter values 2785 * 2786 * Return Value: 2787 * BCM_E_XXX 2788 * Notes: 2789 */ 2790 STATIC 2791 bcm_error_t td2_mpls_port_stat_counter_set( 2792 int unit, 2793 bcm_vpn_t vpn, 2794 bcm_gport_t port, 2795 bcm_mpls_stat_t stat, 2796 uint32 num_entries, 2797 uint32 *counter_indexes, 2798 bcm_stat_value_t *counter_values) 2799 { 2800 uint32 table_count=0; 2801 uint32 index_count=0; 2802 uint32 num_of_tables=0; 2803 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 2804 uint32 byte_flag=0; 2805 bcm_stat_flex_table_info_t table_info[ 2806 BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 2807 2808 if ((stat == bcmMplsInBytes) || 2809 (stat == bcmMplsInPkts)) { 2810 direction = bcmStatFlexDirectionIngress; 2811 } else { 2812 direction = bcmStatFlexDirectionEgress; 2813 } 2814 if ((stat == bcmMplsInPkts) || 2815 (stat == bcmMplsOutPkts)) { 2816 byte_flag=0; 2817 } else { 2818 byte_flag=1; 2819 } 2820 2821 BCM_IF_ERROR_RETURN(td2_mpls_port_stat_get_table_info( 2822 unit, vpn,port,&num_of_tables,&table_info[0])); 2823 2824 for (table_count=0; table_count < num_of_tables ; table_count++) { 2825 if (table_info[table_count].direction == direction) { 2826 for (index_count=0; index_count < num_entries ; index_count++) { 2827 BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_set( 2828 unit, 2829 table_info[table_count].index, 2830 table_info[table_count].table, 2831 0, byte_flag, 2832 counter_indexes[index_count], 2833 &counter_values[index_count])); 2834 } 2835 } 2836 } 2837 return BCM_E_NONE; 2838 } 2839 /* 2840 * Function: 2841 * td2_mpls_port_stat_id_get 2842 * Description: 2843 * Get stat counter id associated with specific vpn and gport 2844 * 2845 * Parameters: 2846 * unit - (IN) unit number 2847 * vpn - (IN) VPN Id 2848 * port - (IN) MPLS GPORT ID 2849 * stat - (IN) Type of the counter to retrieve 2850 * I.e. ingress/egress byte/packet) 2851 * Stat_counter_id - (OUT) Stat Counter ID 2852 * 2853 * Return Value: 2854 * BCM_E_XXX 2855 * Notes: 2856 */ 2857 STATIC 2858 bcm_error_t td2_mpls_port_stat_id_get( 2859 int unit, 2860 bcm_vpn_t vpn, 2861 bcm_gport_t port, 2862 bcm_mpls_stat_t stat, 2863 uint32 *stat_counter_id) 2864 { 2865 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 2866 uint32 num_of_tables=0; 2867 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 2868 uint32 index=0; 2869 uint32 num_stat_counter_ids=0; 2870 2871 if ((stat == bcmMplsInBytes) || 2872 (stat == bcmMplsInPkts)) { 2873 direction = bcmStatFlexDirectionIngress; 2874 } else { 2875 direction = bcmStatFlexDirectionEgress; 2876 } 2877 BCM_IF_ERROR_RETURN(td2_mpls_port_stat_get_table_info( 2878 unit,vpn,port,&num_of_tables,&table_info[0])); 2879 for (index=0; index < num_of_tables ; index++) { 2880 if (table_info[index].direction == direction) 2881 return _bcm_esw_stat_flex_get_counter_id( 2882 unit, 1, &table_info[index], 2883 &num_stat_counter_ids,stat_counter_id); 2884 } 2885 return BCM_E_NOT_FOUND; 2886 } 2887 /* 2888 * Function: 2889 * td2_mpls_label_stat_attach 2890 * Description: 2891 * Attach counters entries to the given mpls label and gport 2892 * 2893 * Parameters: 2894 * unit - (IN) unit number 2895 * label - (IN) MPLS Label 2896 * port - (IN) MPLS Gport 2897 * stat_counter_id - (IN) Stat Counter ID. 2898 * 2899 * Return Value: 2900 * BCM_E_XXX 2901 * Notes: 2902 */ 2903 STATIC 2904 bcm_error_t td2_mpls_label_stat_attach( 2905 int unit, 2906 bcm_mpls_label_t label, 2907 bcm_gport_t port, 2908 uint32 stat_counter_id) 2909 { 2910 soc_mem_t table=0; 2911 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 2912 uint32 pool_number=0; 2913 uint32 base_index=0; 2914 bcm_stat_flex_mode_t offset_mode=0; 2915 bcm_stat_object_t object=bcmStatObjectIngPort; 2916 bcm_stat_group_mode_t group_mode= bcmStatGroupModeSingle; 2917 uint32 count=0; 2918 uint32 actual_num_tables=0; 2919 uint32 num_of_tables=0; 2920 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 2921 2922 _bcm_esw_stat_get_counter_id_info( 2923 unit, stat_counter_id, 2924 &group_mode,&object,&offset_mode,&pool_number,&base_index); 2925 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit,object,&direction)); 2926 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit,group_mode)); 2927 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_table_info( 2928 unit,object,1,&actual_num_tables,&table,&direction)); 2929 2930 if (!BCM_XGS3_L3_MPLS_LBL_VALID(label)) { 2931 return BCM_E_PARAM; 2932 } 2933 2934 BCM_IF_ERROR_RETURN(td2_mpls_label_stat_get_table_info( 2935 unit, label,port, object, &num_of_tables,&table_info[0])); 2936 for (count=0; count < num_of_tables ; count++) { 2937 if ((table_info[count].direction == direction) && 2938 (table_info[count].table == table) ) { 2939 if (direction == bcmStatFlexDirectionIngress) { 2940 return _bcm_esw_stat_flex_attach_ingress_table_counters( 2941 unit, 2942 table_info[count].table, 2943 table_info[count].index, 2944 offset_mode, 2945 base_index, 2946 pool_number); 2947 } else { 2948 return _bcm_esw_stat_flex_attach_egress_table_counters( 2949 unit, 2950 table_info[count].table, 2951 table_info[count].index, 2952 0, 2953 offset_mode, 2954 base_index, 2955 pool_number); 2956 } 2957 } 2958 } 2959 return BCM_E_NOT_FOUND; 2960 } 2961 /* 2962 * Function: 2963 * td2_mpls_label_stat_detach 2964 * Description: 2965 * Detach counters entries to the given mpls label and gport 2966 * 2967 * Parameters: 2968 * unit - (IN) unit number 2969 * label - (IN) MPLS Label 2970 * port - (IN) MPLS Gport 2971 * 2972 * Return Value: 2973 * BCM_E_XXX 2974 * Notes: 2975 */ 2976 STATIC 2977 bcm_error_t td2_mpls_label_stat_detach( 2978 int unit, 2979 bcm_mpls_label_t label, 2980 bcm_gport_t port) 2981 { 2982 uint32 count=0; 2983 uint32 num_of_tables=0; 2984 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 2985 bcm_error_t rv = BCM_E_NONE; 2986 bcm_error_t err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE}; 2987 2988 if (!BCM_XGS3_L3_MPLS_LBL_VALID(label)) { 2989 return BCM_E_PARAM; 2990 } 2991 2992 BCM_IF_ERROR_RETURN(td2_mpls_label_stat_get_table_info( 2993 unit, label,port, bcmStatObjectMaxValue, &num_of_tables,&table_info[0])); 2994 2995 for (count=0; count < num_of_tables ; count++) { 2996 if (table_info[count].direction == bcmStatFlexDirectionIngress) { 2997 rv = _bcm_esw_stat_flex_detach_ingress_table_counters( 2998 unit, table_info[count].table, table_info[count].index); 2999 if (BCM_E_NONE != rv && 3000 BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) { 3001 err_code[bcmStatFlexDirectionIngress] = rv; 3002 } 3003 } else { 3004 rv = _bcm_esw_stat_flex_detach_egress_table_counters( 3005 unit, 0, table_info[count].table, table_info[count].index); 3006 if (BCM_E_NONE != rv && 3007 BCM_E_NONE == err_code[bcmStatFlexDirectionEgress]) { 3008 err_code[bcmStatFlexDirectionEgress] = rv; 3009 } 3010 } 3011 } 3012 3013 BCM_STAT_FLEX_DETACH_RETURN(err_code) 3014 } 3015 /* 3016 * Function: 3017 * td2_mpls_label_stat_counter_get 3018 * Description: 3019 * Get counter statistic values for specific MPLS label and gport 3020 * Get counter statistic values for specific vpn and gport 3021 * if sync_mode is set, sync the sw accumulated count 3022 * 3023 * Parameters: 3024 * unit - (IN) unit number 3025 * sync_mode - (IN) hwcount is to be synced to sw count 3026 * label - (IN) MPLS Label 3027 * port - (IN) MPLS Gport 3028 * stat - (IN) Type of the counter to retrieve 3029 * I.e. ingress/egress byte/packet) 3030 * num_entries - (IN) Number of counter Entries 3031 * counter_indexes - (IN) Pointer to Counter indexes entries 3032 * counter_values - (OUT) Pointer to counter values 3033 * 3034 * Return Value: 3035 * BCM_E_XXX 3036 * Notes: 3037 */ 3038 STATIC 3039 bcm_error_t td2_mpls_label_stat_counter_get( 3040 int unit, 3041 int sync_mode, 3042 bcm_mpls_label_t label, 3043 bcm_gport_t port, 3044 bcm_mpls_stat_t stat, 3045 uint32 num_entries, 3046 uint32 *counter_indexes, 3047 bcm_stat_value_t *counter_values) 3048 { 3049 uint32 table_count=0; 3050 uint32 index_count=0; 3051 uint32 num_of_tables=0; 3052 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 3053 uint32 byte_flag=0; 3054 bcm_stat_flex_table_info_t table_info[ 3055 BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 3056 3057 if ((stat == bcmMplsInBytes) || 3058 (stat == bcmMplsInPkts)) { 3059 direction = bcmStatFlexDirectionIngress; 3060 } else { 3061 direction = bcmStatFlexDirectionEgress; 3062 } 3063 if ((stat == bcmMplsInPkts) || 3064 (stat == bcmMplsOutPkts)) { 3065 byte_flag=0; 3066 } else { 3067 byte_flag=1; 3068 } 3069 3070 if (!BCM_XGS3_L3_MPLS_LBL_VALID(label)) { 3071 return BCM_E_PARAM; 3072 } 3073 3074 BCM_IF_ERROR_RETURN(td2_mpls_label_stat_get_table_info( 3075 unit, label,port,bcmStatObjectMaxValue,&num_of_tables,&table_info[0])); 3076 3077 for (table_count=0; table_count < num_of_tables ; table_count++) { 3078 if (table_info[table_count].direction == direction) { 3079 for (index_count=0; index_count < num_entries ; index_count++) { 3080 BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_get( 3081 unit, sync_mode, 3082 table_info[table_count].index, 3083 table_info[table_count].table, 3084 0, byte_flag, 3085 counter_indexes[index_count], 3086 &counter_values[index_count])); 3087 } 3088 } 3089 } 3090 return BCM_E_NONE; 3091 } 3092 /* 3093 * Function: 3094 * td2_mpls_label_stat_counter_set 3095 * Description: 3096 * Set counter statistic values for specific MPLS label and gport 3097 * 3098 * Parameters: 3099 * unit - (IN) unit number 3100 * label - (IN) MPLS Label 3101 * port - (IN) MPLS Gport 3102 * stat - (IN) Type of the counter to retrieve 3103 * I.e. ingress/egress byte/packet) 3104 * num_entries - (IN) Number of counter Entries 3105 * counter_indexes - (IN) Pointer to Counter indexes entries 3106 * counter_values - (IN) Pointer to counter values 3107 * 3108 * Return Value: 3109 * BCM_E_XXX 3110 * Notes: 3111 */ 3112 STATIC 3113 bcm_error_t td2_mpls_label_stat_counter_set( 3114 int unit, 3115 bcm_mpls_label_t label, 3116 bcm_gport_t port, 3117 bcm_mpls_stat_t stat, 3118 uint32 num_entries, 3119 uint32 *counter_indexes, 3120 bcm_stat_value_t *counter_values) 3121 { 3122 uint32 table_count=0; 3123 uint32 index_count=0; 3124 uint32 num_of_tables=0; 3125 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 3126 uint32 byte_flag=0; 3127 bcm_stat_flex_table_info_t table_info[ 3128 BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 3129 bcm_vpn_t vpn = 0; 3130 3131 if ((stat == bcmMplsInBytes) || 3132 (stat == bcmMplsInPkts)) { 3133 direction = bcmStatFlexDirectionIngress; 3134 } else { 3135 direction = bcmStatFlexDirectionEgress; 3136 } 3137 if ((stat == bcmMplsInPkts) || 3138 (stat == bcmMplsOutPkts)) { 3139 byte_flag=0; 3140 } else { 3141 byte_flag=1; 3142 } 3143 3144 if (BCM_GPORT_IS_MPLS_PORT(port)) { 3145 /* Just create a valid vpn id to pass the check */ 3146 _BCM_MPLS_VPN_SET(vpn, _BCM_MPLS_VPN_TYPE_VPWS, 1); 3147 BCM_IF_ERROR_RETURN(td2_mpls_port_stat_get_table_info( 3148 unit, vpn, port, &num_of_tables, &table_info[0])); 3149 } else { 3150 if (!BCM_XGS3_L3_MPLS_LBL_VALID(label)) { 3151 return BCM_E_PARAM; 3152 } 3153 BCM_IF_ERROR_RETURN(td2_mpls_label_stat_get_table_info( 3154 unit, label, port, bcmStatObjectMaxValue, &num_of_tables, &table_info[0])); 3155 } 3156 3157 for (table_count=0; table_count < num_of_tables ; table_count++) { 3158 if (table_info[table_count].direction == direction) { 3159 for (index_count=0; index_count < num_entries ; index_count++) { 3160 BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_set( 3161 unit, 3162 table_info[table_count].index, 3163 table_info[table_count].table, 3164 0, byte_flag, 3165 counter_indexes[index_count], 3166 &counter_values[index_count])); 3167 } 3168 } 3169 } 3170 return BCM_E_NONE; 3171 } 3172 /* 3173 * Function: 3174 * td2_mpls_label_stat_id_get 3175 * Description: 3176 * Get stat counter id associated with given vlan 3177 * 3178 * Parameters: 3179 * unit - (IN) unit number 3180 * label - (IN) MPLS Label 3181 * port - (IN) MPLS Gport 3182 * stat - (IN) Type of the counter to retrieve 3183 * I.e. ingress/egress byte/packet) 3184 * Stat_counter_id - (OUT) Stat Counter ID 3185 * 3186 * Return Value: 3187 * BCM_E_XXX 3188 * Notes: 3189 */ 3190 STATIC 3191 bcm_error_t td2_mpls_label_stat_id_get( 3192 int unit, 3193 bcm_mpls_label_t label, 3194 bcm_gport_t port, 3195 bcm_mpls_stat_t stat, 3196 uint32 *stat_counter_id) 3197 { 3198 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 3199 uint32 num_of_tables=0; 3200 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 3201 uint32 index=0; 3202 uint32 num_stat_counter_ids=0; 3203 3204 if (!BCM_XGS3_L3_MPLS_LBL_VALID(label)) { 3205 return BCM_E_PARAM; 3206 } 3207 3208 if ((stat == bcmMplsInBytes) || 3209 (stat == bcmMplsInPkts)) { 3210 direction = bcmStatFlexDirectionIngress; 3211 } else { 3212 direction = bcmStatFlexDirectionEgress; 3213 } 3214 BCM_IF_ERROR_RETURN(td2_mpls_label_stat_get_table_info( 3215 unit,label,port,bcmStatObjectMaxValue,&num_of_tables,&table_info[0])); 3216 for (index=0; index < num_of_tables ; index++) { 3217 if (table_info[index].direction == direction) 3218 return _bcm_esw_stat_flex_get_counter_id( 3219 unit, 1, &table_info[index], 3220 &num_stat_counter_ids,stat_counter_id); 3221 } 3222 return BCM_E_NOT_FOUND; 3223 } 3224 /* 3225 * Function: 3226 * td2_mpls_label_stat_enable_set 3227 * Purpose: 3228 * Enable statistics collection for MPLS label or MPLS gport 3229 * Parameters: 3230 * unit - (IN) Unit number. 3231 * label - (IN) MPLS label 3232 * port - (IN) MPLS gport 3233 * enable - (IN) Non-zero to enable counter collection, zero to disable. 3234 * Returns: 3235 * BCM_E_xxx 3236 * Notes: 3237 */ 3238 STATIC 3239 int td2_mpls_label_stat_enable_set( 3240 int unit, 3241 bcm_mpls_label_t label, 3242 bcm_gport_t port, 3243 int enable) 3244 { 3245 uint32 num_of_tables=0; 3246 uint32 num_stat_counter_ids=0; 3247 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 3248 bcm_stat_object_t object=bcmStatObjectIngPort; 3249 uint32 stat_counter_id[ 3250 BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]={0}; 3251 uint32 num_entries=0; 3252 int index=0; 3253 3254 if (BCM_GPORT_IS_MPLS_PORT(port)) { 3255 /* When the gport is an MPLS port, we'll turn on the 3256 * port-based tracking to comply with API definition. 3257 */ 3258 3259 int vpn; 3260 3261 /* just create a valid vpn id to pass the check */ 3262 _BCM_MPLS_VPN_SET(vpn, _BCM_MPLS_VPN_TYPE_VPWS, 1); 3263 BCM_IF_ERROR_RETURN(td2_mpls_port_stat_get_table_info( 3264 unit,vpn,port,&num_of_tables,&table_info[0])); 3265 if (enable ) { 3266 for(index=0;index < num_of_tables ;index++) { 3267 if (table_info[index].direction == bcmStatFlexDirectionIngress) { 3268 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_ingress_object( 3269 unit,table_info[index].table, 3270 table_info[index].index,NULL,&object)); 3271 } else { 3272 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_egress_object( 3273 unit,table_info[index].table, 3274 table_info[index].table,NULL,&object)); 3275 } 3276 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_create( 3277 unit,object,bcmStatGroupModeSingle, 3278 &stat_counter_id[table_info[index].direction], 3279 &num_entries)); 3280 BCM_IF_ERROR_RETURN(td2_mpls_port_stat_attach( 3281 unit,vpn,port, 3282 stat_counter_id[table_info[index].direction])); 3283 } 3284 return BCM_E_NONE; 3285 } else { 3286 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_counter_id( 3287 unit, num_of_tables,&table_info[0], 3288 &num_stat_counter_ids,&stat_counter_id[0])); 3289 if ((stat_counter_id[bcmStatFlexDirectionIngress] == 0) && 3290 (stat_counter_id[bcmStatFlexDirectionEgress] == 0)) { 3291 return BCM_E_PARAM; 3292 } 3293 BCM_IF_ERROR_RETURN(td2_mpls_port_stat_detach(unit,vpn,port)); 3294 if (stat_counter_id[bcmStatFlexDirectionIngress] != 0) { 3295 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy( 3296 unit, 3297 stat_counter_id[bcmStatFlexDirectionIngress])); 3298 } 3299 if (stat_counter_id[bcmStatFlexDirectionEgress] != 0) { 3300 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy( 3301 unit, 3302 stat_counter_id[bcmStatFlexDirectionEgress])); 3303 } 3304 return BCM_E_NONE; 3305 } 3306 3307 } 3308 3309 if (!BCM_XGS3_L3_MPLS_LBL_VALID(label)) { 3310 return BCM_E_PARAM; 3311 } 3312 3313 BCM_IF_ERROR_RETURN(td2_mpls_label_stat_get_table_info( 3314 unit,label,port,bcmStatObjectMaxValue,&num_of_tables,&table_info[0])); 3315 if (enable ) { 3316 for(index=0;index < num_of_tables ;index++) { 3317 if (table_info[index].direction == bcmStatFlexDirectionIngress) { 3318 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_ingress_object( 3319 unit,table_info[index].table, 3320 table_info[index].index,NULL,&object)); 3321 } else { 3322 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_egress_object( 3323 unit,table_info[index].table, 3324 table_info[index].table,NULL,&object)); 3325 } 3326 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_create( 3327 unit,object,bcmStatGroupModeSingle, 3328 &stat_counter_id[table_info[index].direction], 3329 &num_entries)); 3330 BCM_IF_ERROR_RETURN(bcm_esw_mpls_label_stat_attach( 3331 unit,label,port, 3332 stat_counter_id[table_info[index].direction])); 3333 } 3334 return BCM_E_NONE; 3335 } else { 3336 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_counter_id( 3337 unit, num_of_tables,&table_info[0], 3338 &num_stat_counter_ids,&stat_counter_id[0])); 3339 if ((stat_counter_id[bcmStatFlexDirectionIngress] == 0) && 3340 (stat_counter_id[bcmStatFlexDirectionEgress] == 0)) { 3341 return BCM_E_PARAM; 3342 } 3343 BCM_IF_ERROR_RETURN(bcm_esw_mpls_label_stat_detach(unit,label,port)); 3344 if (stat_counter_id[bcmStatFlexDirectionIngress] != 0) { 3345 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy( 3346 unit, 3347 stat_counter_id[bcmStatFlexDirectionIngress])); 3348 } 3349 if (stat_counter_id[bcmStatFlexDirectionEgress] != 0) { 3350 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy( 3351 unit, 3352 stat_counter_id[bcmStatFlexDirectionEgress])); 3353 } 3354 return BCM_E_NONE; 3355 } 3356 3357 } 3358 /* 3359 * Function: 3360 * td2_mpls_label_stat_get 3361 * Purpose: 3362 * Get L2 MPLS PW Stats 3363 * Parameters: 3364 * unit - (IN) SOC unit # 3365 * label - (IN) MPLS label 3366 * port - (IN) MPLS gport 3367 * stat - (IN) specify the Stat type 3368 * val - (OUT) 64-bit Stats value 3369 * Returns: 3370 * BCM_E_XXX 3371 */ 3372 3373 STATIC 3374 int td2_mpls_label_stat_get( 3375 int unit, 3376 int sync_mode, 3377 bcm_mpls_label_t label, 3378 bcm_gport_t port, 3379 bcm_mpls_stat_t stat, 3380 uint64 *val) 3381 { 3382 uint32 counter_indexes=0 ; 3383 bcm_stat_value_t counter_values={0}; 3384 3385 if (BCM_GPORT_IS_MPLS_PORT(port)) { 3386 int vpn; 3387 3388 /* just create a valid vpn id to pass the check */ 3389 _BCM_MPLS_VPN_SET(vpn, _BCM_MPLS_VPN_TYPE_VPWS, 1); 3390 3391 BCM_IF_ERROR_RETURN(td2_mpls_port_stat_counter_get(unit, sync_mode, 3392 vpn, port, stat, 3393 1, &counter_indexes, 3394 &counter_values)); 3395 } else { 3396 if (!BCM_XGS3_L3_MPLS_LBL_VALID(label)) { 3397 return BCM_E_PARAM; 3398 } 3399 3400 BCM_IF_ERROR_RETURN(td2_mpls_label_stat_counter_get( 3401 unit, sync_mode, label, port, stat, 1, 3402 &counter_indexes, &counter_values)); 3403 } 3404 3405 if ((stat == bcmMplsInPkts) || 3406 (stat == bcmMplsOutPkts)) { 3407 COMPILER_64_SET(*val, 3408 COMPILER_64_HI(counter_values.packets64), 3409 COMPILER_64_LO(counter_values.packets64)); 3410 } else { 3411 COMPILER_64_SET(*val, 3412 COMPILER_64_HI(counter_values.bytes), 3413 COMPILER_64_LO(counter_values.bytes)); 3414 } 3415 return BCM_E_NONE; 3416 } 3417 3418 /* 3419 * Function: 3420 * td2_mpls_label_stat_get32 3421 * Purpose: 3422 * Get L2 MPLS PW Stats 3423 * if sync_mode is set, sync the sw accumulated count 3424 * with hw count value first, else return sw count. 3425 * Parameters: 3426 * unit - (IN) SOC unit # 3427 * sync_mode - (IN) hwcount is to be synced to sw count 3428 * label - (IN) MPLS label 3429 * port - (IN) MPLS gport 3430 * stat - (IN) specify the Stat type 3431 * val - (OUT) 32-bit Stats value 3432 * Returns: 3433 * BCM_E_XXX 3434 */ 3435 3436 STATIC 3437 int td2_mpls_label_stat_get32( 3438 int unit, 3439 int sync_mode, 3440 bcm_mpls_label_t label, 3441 bcm_gport_t port, 3442 bcm_mpls_stat_t stat, 3443 uint32 *val) 3444 { 3445 uint32 counter_indexes=0; 3446 bcm_stat_value_t counter_values={0}; 3447 3448 if (BCM_GPORT_IS_MPLS_PORT(port)) { 3449 int vpn; 3450 3451 /* just create a valid vpn id to pass the check */ 3452 _BCM_MPLS_VPN_SET(vpn, _BCM_MPLS_VPN_TYPE_VPWS, 1); 3453 3454 BCM_IF_ERROR_RETURN(td2_mpls_port_stat_counter_get( 3455 unit, sync_mode, vpn, port, stat, 1, 3456 &counter_indexes, &counter_values)); 3457 } else { 3458 3459 if (!BCM_XGS3_L3_MPLS_LBL_VALID(label)) { 3460 return BCM_E_PARAM; 3461 } 3462 3463 BCM_IF_ERROR_RETURN(td2_mpls_label_stat_counter_get( 3464 unit, sync_mode, label, port, stat, 1, 3465 &counter_indexes, &counter_values)); 3466 } 3467 3468 if ((stat == bcmMplsInPkts) || 3469 (stat == bcmMplsOutPkts)) { 3470 *val = counter_values.packets; 3471 } else { 3472 /* Ignoring Hi bytes value */ 3473 *val = COMPILER_64_LO(counter_values.bytes); 3474 } 3475 return BCM_E_NONE; 3476 } 3477 3478 /* 3479 * Function: 3480 * td2_mpls_label_stat_clear 3481 * Purpose: 3482 * Clear L2 MPLS PW Stats 3483 * Parameters: 3484 * unit - (IN) SOC unit # 3485 * label - (IN) MPLS label 3486 * port - (IN) MPLS gport 3487 * stat - (IN) specify the Stat type 3488 * Returns: 3489 * BCM_E_XXX 3490 */ 3491 3492 STATIC 3493 int td2_mpls_label_stat_clear( 3494 int unit, 3495 bcm_mpls_label_t label, 3496 bcm_gport_t port, 3497 bcm_mpls_stat_t stat) 3498 { 3499 uint32 counter_indexes=0 ; 3500 bcm_stat_value_t counter_values={0}; 3501 3502 if (!BCM_XGS3_L3_MPLS_LBL_VALID(label)) { 3503 return BCM_E_PARAM; 3504 } 3505 3506 BCM_IF_ERROR_RETURN(bcm_esw_mpls_label_stat_counter_set( 3507 unit,label,port,stat,1, 3508 &counter_indexes,&counter_values)); 3509 return BCM_E_NONE; 3510 } 3511 3512 3513 #endif /* BCM_TRIDENT2_SUPPORT */ 3514 3515 /* 3516 * Function: 3517 * bcm_esw_mpls_label_stat_enable_set 3518 * Purpose: 3519 * Enable statistics collection for MPLS label or MPLS gport 3520 * Parameters: 3521 * unit - (IN) Unit number. 3522 * label - (IN) MPLS label 3523 * port - (IN) MPLS gport 3524 * enable - (IN) Non-zero to enable counter collection, zero to disable. 3525 * Returns: 3526 * BCM_E_xxx 3527 * Notes: 3528 */ 3529 int 3530 bcm_esw_mpls_label_stat_enable_set(int unit, bcm_mpls_label_t label, 3531 bcm_gport_t port, int enable) 3532 { 3533 int rv = BCM_E_UNAVAIL; 3534 #ifdef BCM_MPLS_SUPPORT 3535 #ifdef BCM_TRIUMPH2_SUPPORT 3536 if (soc_feature(unit, soc_feature_gport_service_counters) && 3537 soc_feature(unit, soc_feature_mpls)) { 3538 rv = bcm_tr_mpls_lock(unit); 3539 if (BCM_E_NONE == rv) { 3540 rv = bcm_tr2_mpls_label_stat_enable_set(unit, label, 3541 port, enable,0); 3542 bcm_tr_mpls_unlock(unit); 3543 } 3544 } 3545 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 3546 defined(BCM_TRIDENT2_SUPPORT) 3547 else if (soc_feature(unit,soc_feature_advanced_flex_counter) && 3548 soc_feature(unit, soc_feature_mpls)) { 3549 BCM_IF_ERROR_RETURN(bcm_tr_mpls_lock(unit)); 3550 #if defined(BCM_KATANA_SUPPORT) 3551 if (SOC_IS_KATANAX(unit)) { 3552 rv = bcm_kt_mpls_label_stat_enable_set(unit, label, 3553 port, enable); 3554 } else 3555 #endif 3556 #if defined(BCM_TRIUMPH3_SUPPORT) 3557 if (SOC_IS_TRIUMPH3(unit)) { 3558 rv = bcm_tr3_mpls_label_stat_enable_set(unit, label, 3559 port, enable); 3560 } else 3561 #endif 3562 { 3563 #if defined(BCM_TRIDENT2_SUPPORT) 3564 rv = td2_mpls_label_stat_enable_set(unit, label, 3565 port, enable); 3566 #endif 3567 } 3568 bcm_tr_mpls_unlock(unit); 3569 } 3570 #endif 3571 #if defined(BCM_MONTEREY_SUPPORT) 3572 else if(SOC_IS_MONTEREY(unit)) { 3573 /* Flex counters not supported in Monterey */ 3574 return rv; 3575 } 3576 #endif 3577 #endif 3578 #endif 3579 return rv; 3580 } 3581 3582 /* 3583 * Function: 3584 * _bcm_esw_mpls_label_stat_get 3585 * Purpose: 3586 * Get L2 MPLS PW Stats 3587 * if sync_mode is set, sync the sw accumulated count 3588 * with hw count value first, else return sw count. 3589 * Parameters: 3590 * unit - (IN) SOC unit # 3591 * sync_mode - (IN) hwcount is to be synced to sw count 3592 * label - (IN) MPLS label 3593 * port - (IN) MPLS gport 3594 * stat - (IN) specify the Stat type 3595 * val - (OUT) 64-bit Stats value 3596 * Returns: 3597 * BCM_E_XXX 3598 */ 3599 3600 int 3601 _bcm_esw_mpls_label_stat_get(int unit, int sync_mode, 3602 bcm_mpls_label_t label, 3603 bcm_gport_t port, 3604 bcm_mpls_stat_t stat, 3605 uint64 *val) 3606 { 3607 int rv = BCM_E_UNAVAIL; 3608 #ifdef BCM_MPLS_SUPPORT 3609 #ifdef BCM_TRIUMPH_SUPPORT 3610 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 3611 defined(BCM_TRIDENT2_SUPPORT) 3612 if (soc_feature(unit,soc_feature_advanced_flex_counter) && 3613 soc_feature(unit, soc_feature_mpls)) { 3614 BCM_IF_ERROR_RETURN(bcm_tr_mpls_lock(unit)); 3615 #if defined(BCM_KATANA_SUPPORT) 3616 if (SOC_IS_KATANAX(unit)) { 3617 rv = bcm_kt_mpls_label_stat_get(unit, sync_mode, 3618 label, port, 3619 stat, val); 3620 } else 3621 #endif 3622 #if defined(BCM_TRIUMPH3_SUPPORT) 3623 if (SOC_IS_TRIUMPH3(unit)) { 3624 rv = bcm_tr3_mpls_label_stat_get(unit, sync_mode, 3625 label, port, 3626 stat, val); 3627 } else 3628 #endif 3629 { 3630 #if defined(BCM_TRIDENT2_SUPPORT) 3631 rv = td2_mpls_label_stat_get(unit, sync_mode, 3632 label, port, 3633 stat, val); 3634 #endif 3635 } 3636 bcm_tr_mpls_unlock(unit); 3637 } else 3638 #endif 3639 #if defined(BCM_MONTEREY_SUPPORT) 3640 if(SOC_IS_MONTEREY(unit)) { 3641 /* Flex counters not supported in Monterey */ 3642 return rv; 3643 } else 3644 #endif 3645 if ((SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) || 3646 (soc_feature(unit, soc_feature_mpls) && 3647 soc_feature(unit, soc_feature_gport_service_counters))) { 3648 rv = bcm_tr_mpls_lock(unit); 3649 if ( rv == BCM_E_NONE ) { 3650 rv = bcm_tr_mpls_label_stat_get(unit, sync_mode, 3651 label, port, 3652 stat, val); 3653 bcm_tr_mpls_unlock (unit); 3654 } 3655 return rv; 3656 } 3657 #endif 3658 #endif 3659 return rv; 3660 } 3661 3662 3663 /* 3664 * Function: 3665 * bcm_esw_mpls_label_stat_get 3666 * Purpose: 3667 * Get L2 MPLS PW Stats 3668 * Parameters: 3669 * unit - (IN) SOC unit # 3670 * label - (IN) MPLS label 3671 * port - (IN) MPLS gport 3672 * stat - (IN) specify the Stat type 3673 * val - (OUT) 64-bit Stats value 3674 * Returns: 3675 * BCM_E_XXX 3676 */ 3677 int 3678 bcm_esw_mpls_label_stat_get(int unit, bcm_mpls_label_t label, 3679 bcm_gport_t port, bcm_mpls_stat_t stat, 3680 uint64 *val) 3681 { 3682 int rv = BCM_E_UNAVAIL; 3683 3684 rv = _bcm_esw_mpls_label_stat_get(unit, 0, label, port, stat, val); 3685 3686 return rv; 3687 } 3688 3689 3690 /* 3691 * Function: 3692 * bcm_esw_mpls_label_stat_sync_get 3693 * Purpose: 3694 * Get L2 MPLS PW Stats 3695 * sw accumulated counters synced with hw count. 3696 * Parameters: 3697 * unit - (IN) SOC unit # 3698 * label - (IN) MPLS label 3699 * port - (IN) MPLS gport 3700 * stat - (IN) specify the Stat type 3701 * val - (OUT) 64-bit Stats value 3702 * Returns: 3703 * BCM_E_XXX 3704 */ 3705 int 3706 bcm_esw_mpls_label_stat_sync_get(int unit, bcm_mpls_label_t label, 3707 bcm_gport_t port, bcm_mpls_stat_t stat, 3708 uint64 *val) 3709 { 3710 int rv = BCM_E_UNAVAIL; 3711 3712 rv = _bcm_esw_mpls_label_stat_get(unit, 1, label, port, stat, val); 3713 3714 return rv; 3715 } 3716 3717 3718 /* 3719 * Function: 3720 * bcm_esw_mpls_label_stat_get32 3721 * Purpose: 3722 * Get L2 MPLS PW Stats 3723 * Parameters: 3724 * unit - (IN) SOC unit # 3725 * sync_mode - (IN) hwcount is to be synced to sw count 3726 * label - (IN) MPLS label 3727 * port - (IN) MPLS gport 3728 * stat - (IN) specify the Stat type 3729 * val - (OUT) 64-bit Stats value 3730 * Returns: 3731 * BCM_E_XXX 3732 */ 3733 int 3734 _bcm_esw_mpls_label_stat_get32(int unit, int sync_mode, 3735 bcm_mpls_label_t label, 3736 bcm_gport_t port, 3737 bcm_mpls_stat_t stat, 3738 uint32 *val) 3739 { 3740 int rv = BCM_E_UNAVAIL; 3741 #ifdef BCM_MPLS_SUPPORT 3742 #ifdef BCM_TRIUMPH_SUPPORT 3743 3744 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 3745 defined(BCM_TRIDENT2_SUPPORT) 3746 if (soc_feature(unit,soc_feature_advanced_flex_counter) && 3747 soc_feature(unit, soc_feature_mpls)) { 3748 BCM_IF_ERROR_RETURN(bcm_tr_mpls_lock(unit)); 3749 #if defined(BCM_KATANA_SUPPORT) 3750 if (SOC_IS_KATANAX(unit)) { 3751 rv = bcm_kt_mpls_label_stat_get32(unit, sync_mode, 3752 label, port, 3753 stat, val); 3754 } else 3755 #endif 3756 #if defined(BCM_TRIUMPH3_SUPPORT) 3757 if (SOC_IS_TRIUMPH3(unit)) { 3758 rv = bcm_tr3_mpls_label_stat_get32(unit, sync_mode, 3759 label, port, 3760 stat, val); 3761 } else 3762 #endif 3763 { 3764 #if defined(BCM_TRIDENT2_SUPPORT) 3765 rv = td2_mpls_label_stat_get32(unit, sync_mode, 3766 label, port, 3767 stat, val); 3768 #endif 3769 } 3770 bcm_tr_mpls_unlock(unit); 3771 } else 3772 #endif 3773 #if defined(BCM_MONTEREY_SUPPORT) 3774 if(SOC_IS_MONTEREY(unit)) { 3775 /* Flex counters not supported in Monterey */ 3776 return rv; 3777 } else 3778 #endif 3779 if ((SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) || 3780 (soc_feature(unit, soc_feature_mpls) && 3781 soc_feature(unit, soc_feature_gport_service_counters))) { 3782 rv = bcm_tr_mpls_lock(unit); 3783 if ( rv == BCM_E_NONE ) { 3784 rv = bcm_tr_mpls_label_stat_get32(unit, sync_mode, 3785 label, port, 3786 stat, val); 3787 bcm_tr_mpls_unlock (unit); 3788 } 3789 return rv; 3790 } 3791 #endif 3792 #endif 3793 return rv; 3794 } 3795 3796 3797 int 3798 bcm_esw_mpls_label_stat_get32(int unit, bcm_mpls_label_t label, 3799 bcm_gport_t port, 3800 bcm_mpls_stat_t stat, 3801 uint32 *val) 3802 { 3803 int rv = BCM_E_UNAVAIL; 3804 3805 rv = _bcm_esw_mpls_label_stat_get32(unit, 0, label, port, stat, val); 3806 3807 return rv; 3808 } 3809 3810 3811 int 3812 bcm_esw_mpls_label_stat_sync_get32(int unit, bcm_mpls_label_t label, 3813 bcm_gport_t port, 3814 bcm_mpls_stat_t stat, 3815 uint32 *val) 3816 { 3817 int rv = BCM_E_UNAVAIL; 3818 3819 rv = _bcm_esw_mpls_label_stat_get32(unit, 1, label, port, stat, val); 3820 3821 return rv; 3822 } 3823 3824 /* 3825 * Function: 3826 * bcm_esw_mpls_label_stat_clear 3827 * Purpose: 3828 * Clear L2 MPLS PW Stats 3829 * Parameters: 3830 * unit - (IN) SOC unit # 3831 * label - (IN) MPLS label 3832 * port - (IN) MPLS gport 3833 * stat - (IN) specify the Stat type 3834 * Returns: 3835 * BCM_E_XXX 3836 */ 3837 3838 int 3839 bcm_esw_mpls_label_stat_clear(int unit, bcm_mpls_label_t label, bcm_gport_t port, 3840 bcm_mpls_stat_t stat) 3841 { 3842 int rv = BCM_E_UNAVAIL; 3843 #ifdef BCM_MPLS_SUPPORT 3844 #ifdef BCM_TRIUMPH_SUPPORT 3845 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 3846 defined(BCM_TRIDENT2_SUPPORT) 3847 if (soc_feature(unit,soc_feature_advanced_flex_counter) && 3848 soc_feature(unit, soc_feature_mpls)) { 3849 BCM_IF_ERROR_RETURN(bcm_tr_mpls_lock(unit)); 3850 #if defined(BCM_KATANA_SUPPORT) 3851 if (SOC_IS_KATANAX(unit)) { 3852 rv = bcm_kt_mpls_label_stat_clear(unit,label,port, stat); 3853 } else 3854 #endif 3855 #if defined(BCM_TRIUMPH3_SUPPORT) 3856 if (SOC_IS_TRIUMPH3(unit)) { 3857 rv = bcm_tr3_mpls_label_stat_clear(unit,label,port,stat); 3858 } else 3859 #endif 3860 { 3861 #if defined(BCM_TRIDENT2_SUPPORT) 3862 rv = td2_mpls_label_stat_clear(unit,label,port,stat); 3863 #endif 3864 } 3865 bcm_tr_mpls_unlock(unit); 3866 } else 3867 #endif 3868 #if defined(BCM_MONTEREY_SUPPORT) 3869 if(SOC_IS_MONTEREY(unit)) { 3870 /* Flex counters not supported in Monterey */ 3871 return rv; 3872 } else 3873 #endif 3874 if ((SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) || 3875 (soc_feature(unit, soc_feature_mpls) && 3876 soc_feature(unit, soc_feature_gport_service_counters))) { 3877 rv = bcm_tr_mpls_lock(unit); 3878 if ( rv == BCM_E_NONE ) { 3879 rv = bcm_tr_mpls_label_stat_clear(unit, label, port, stat); 3880 bcm_tr_mpls_unlock (unit); 3881 } 3882 return rv; 3883 } 3884 #endif 3885 #endif 3886 return rv; 3887 } 3888 3889 /* 3890 * Function: 3891 * _bcm_esw_mpls_trunk_member_add 3892 * Purpose: 3893 * Set Mpls state for trunk members joining a trunk group. 3894 * Parameters: 3895 * unit - (IN) Device Number 3896 * trunk_id - (IN) Trunk Group ID 3897 * trunk_member_count - (IN) Count of Trunk members to be added 3898 * trunk_member_array - (IN) Trunk member ports to be added 3899 * Returns: 3900 * BCM_E_XXX 3901 */ 3902 int 3903 _bcm_esw_mpls_trunk_member_add(int unit, bcm_trunk_t trunk_id, 3904 int trunk_member_count, bcm_port_t *trunk_member_array) 3905 { 3906 int rv = BCM_E_UNAVAIL; 3907 #ifdef BCM_MPLS_SUPPORT 3908 #ifdef BCM_TRIUMPH_SUPPORT 3909 if (soc_feature(unit, soc_feature_mpls)) { 3910 rv = bcm_tr_mpls_trunk_member_add(unit, trunk_id, 3911 trunk_member_count, trunk_member_array); 3912 } 3913 #endif 3914 #endif 3915 return rv; 3916 } 3917 3918 /* 3919 * Function: 3920 * _bcm_esw_mpls_trunk_member_delete 3921 * Purpose: 3922 * Clear Mpls state for trunk members leaving a trunk group. 3923 * Parameters: 3924 * unit - (IN) Device Number 3925 * trunk_id - (IN) Trunk Group ID 3926 * trunk_member_count - (IN) Count of Trunk members to be deleted 3927 * trunk_member_array - (IN) Trunk member ports to be deleted 3928 * Returns: 3929 * BCM_E_XXX 3930 */ 3931 int 3932 _bcm_esw_mpls_trunk_member_delete(int unit, bcm_trunk_t trunk_id, 3933 int trunk_member_count, bcm_port_t *trunk_member_array) 3934 { 3935 int rv = BCM_E_UNAVAIL; 3936 #ifdef BCM_MPLS_SUPPORT 3937 #ifdef BCM_TRIUMPH_SUPPORT 3938 if (soc_feature(unit, soc_feature_mpls)) { 3939 rv = bcm_tr_mpls_trunk_member_delete(unit, trunk_id, 3940 trunk_member_count, trunk_member_array); 3941 } 3942 #endif 3943 #endif 3944 return rv; 3945 } 3946 3947 /* 3948 * Function: 3949 * _bcm_esw_mpls_match_add 3950 * Purpose: 3951 * Assign match criteria of an MPLS port 3952 * Parameters: 3953 * unit - (IN) Device Number 3954 * mpls_port - (IN) mpls port information 3955 * vp - (IN) Source Virtual Port 3956 * vpn - (IN) VPN 3957 * Returns: 3958 * BCM_E_XXX 3959 */ 3960 3961 int 3962 _bcm_esw_mpls_match_add(int unit, bcm_mpls_port_t *mpls_port, int vp, int vpn, 3963 int hw_update) 3964 { 3965 int rv = BCM_E_UNAVAIL; 3966 3967 #ifdef BCM_MPLS_SUPPORT 3968 #ifdef BCM_TRIUMPH3_SUPPORT 3969 if (SOC_IS_TRIUMPH3(unit)) { 3970 rv = _bcm_tr3_mpls_match_add(unit, mpls_port, vp, hw_update); 3971 return rv; 3972 } 3973 #endif 3974 #ifdef BCM_TRIUMPH_SUPPORT 3975 if (SOC_IS_TR_VL(unit)) { 3976 rv = _bcm_tr_mpls_match_add(unit, mpls_port, vp, vpn, hw_update); 3977 return rv; 3978 } 3979 #endif 3980 #endif 3981 return rv; 3982 3983 } 3984 3985 /* 3986 * Function: 3987 * _bcm_esw_mpls_match_delete 3988 * Purpose: 3989 * Delete match criteria of an MPLS port 3990 * Parameters: 3991 * unit - (IN) Device Number 3992 * vp - (IN) Source Virtual Port 3993 * Returns: 3994 * BCM_E_XXX 3995 */ 3996 3997 int 3998 _bcm_esw_mpls_match_delete(int unit, int vp, int sw_clear) 3999 { 4000 int rv = BCM_E_UNAVAIL; 4001 4002 #ifdef BCM_MPLS_SUPPORT 4003 #ifdef BCM_TRIUMPH3_SUPPORT 4004 if (SOC_IS_TRIUMPH3(unit)) { 4005 rv = _bcm_tr3_mpls_match_delete(unit, vp, sw_clear); 4006 return rv; 4007 } 4008 #endif 4009 #ifdef BCM_TRIUMPH_SUPPORT 4010 if (SOC_IS_TR_VL(unit)) { 4011 rv = _bcm_tr_mpls_match_delete(unit, vp, NULL, sw_clear); 4012 return rv; 4013 } 4014 #endif 4015 #endif 4016 return rv; 4017 4018 } 4019 4020 /* 4021 * Function: 4022 * _bcm_esw_mpls_match_failover_update 4023 * Purpose: 4024 * Search mpls entry with provided source vp 4025 * and replace with failover vp 4026 * Parameters: 4027 * unit - (IN) Device Number 4028 * vp - (IN) Source Virtual Port 4029 * fo_vp - (IN) Failover Virtual Port 4030 * Returns: 4031 * BCM_E_XXX 4032 */ 4033 4034 int 4035 _bcm_esw_mpls_match_failover_update(int unit, int vp, int fo_vp) 4036 { 4037 int rv = BCM_E_NONE; 4038 #ifdef BCM_MPLS_SUPPORT 4039 #if defined(BCM_TRIUMPH3_SUPPORT) 4040 if (SOC_IS_TRIUMPH3(unit) || SOC_IS_METROLITE(unit)) { 4041 rv = _bcm_tr3_mpls_match_failover_update(unit, vp, fo_vp); 4042 return rv; 4043 } 4044 #endif 4045 #endif 4046 return rv; 4047 } 4048 4049 /* 4050 * Function: 4051 * _bcm_esw_mpls_failover_nw_port_match_get 4052 * Purpose: 4053 * Get match criteria of an MPLS port 4054 * Parameters: 4055 * unit - (IN) Device Number 4056 * mpls_port - (IN) mpls port 4057 * vp - (IN) Source Virtual Port 4058 * return_ment - (OUT) matched mpls entry. 4059 * Returns: 4060 * BCM_E_XXX 4061 */ 4062 4063 int 4064 _bcm_esw_mpls_failover_nw_port_match_get(int unit, bcm_mpls_port_t *mpls_port, 4065 int vp, mpls_entry_entry_t *return_ment) 4066 4067 { 4068 int rv = BCM_E_NOT_FOUND; 4069 4070 #ifdef BCM_MPLS_SUPPORT 4071 #ifdef BCM_TRIUMPH3_SUPPORT 4072 if (SOC_IS_TRIUMPH3(unit)) { 4073 rv = _bcm_tr3_mpls_failover_nw_port_match_get(unit, mpls_port, vp, 4074 return_ment); 4075 return rv; 4076 } 4077 #endif 4078 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) 4079 if (soc_feature(unit, soc_feature_mpls_xgs5_nw_port_match)) { 4080 rv = bcmi_xgs5_mpls_failover_nw_port_match_get(unit, mpls_port, vp, 4081 return_ment); 4082 return rv; 4083 } 4084 #endif 4085 #ifdef BCM_TRIUMPH_SUPPORT 4086 if (SOC_IS_TR_VL(unit)) { 4087 rv = _bcm_tr_mpls_failover_nw_port_match_get(unit, mpls_port, vp, 4088 return_ment); 4089 return rv; 4090 } 4091 #endif 4092 #endif 4093 4094 return rv; 4095 } 4096 4097 /* 4098 * Function: 4099 * _bcm_esw_mpls_match_get 4100 * Purpose: 4101 * Get match criteria of an MPLS port 4102 * Parameters: 4103 * unit - (IN) Device Number 4104 * vp - (IN) Source Virtual Port 4105 * Returns: 4106 * BCM_E_XXX 4107 */ 4108 4109 int 4110 _bcm_esw_mpls_match_get(int unit, bcm_mpls_port_t *mpls_port, int vp) 4111 { 4112 int rv = BCM_E_UNAVAIL; 4113 4114 #ifdef BCM_MPLS_SUPPORT 4115 #ifdef BCM_TRIUMPH3_SUPPORT 4116 if (SOC_IS_TRIUMPH3(unit)) { 4117 rv = _bcm_tr3_mpls_match_get(unit, mpls_port, vp); 4118 return rv; 4119 } 4120 #endif 4121 #ifdef BCM_TRIUMPH_SUPPORT 4122 if (SOC_IS_TR_VL(unit)) { 4123 rv = _bcm_tr_mpls_match_get(unit, mpls_port, vp); 4124 return rv; 4125 } 4126 #endif 4127 #endif 4128 return rv; 4129 4130 } 4131 4132 /* 4133 * Function: 4134 * _bcm_mpls_tunnel_switch_delete_all 4135 * Purpose: 4136 * Delete all MPLS label entries. 4137 * Parameters: 4138 * unit - Device Number 4139 * Returns: 4140 * BCM_E_XXX 4141 */ 4142 int 4143 _bcm_esw_mpls_tunnel_switch_delete_all (int unit) 4144 { 4145 int rv = BCM_E_UNAVAIL; 4146 #ifdef BCM_MPLS_SUPPORT 4147 #ifdef BCM_TRIUMPH3_SUPPORT 4148 if (SOC_IS_TRIUMPH3(unit) && soc_feature(unit, soc_feature_mpls)) { 4149 rv = bcm_tr3_mpls_tunnel_switch_delete_all(unit); 4150 return rv; 4151 } 4152 #endif 4153 #ifdef BCM_KATANA_SUPPORT 4154 if (SOC_IS_KATANAX(unit) && soc_feature(unit, soc_feature_mpls)) { 4155 rv = bcm_kt_mpls_tunnel_switch_delete_all(unit); 4156 return rv; 4157 } 4158 #endif 4159 #ifdef BCM_TRIUMPH_SUPPORT 4160 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls)) { 4161 #if (defined(BCM_TOMAHAWK3_SUPPORT)) 4162 if (SOC_IS_TOMAHAWK3(unit)) { 4163 rv = bcmi_xgs5_mpls_tunnel_switch_delete_all(unit); 4164 } else 4165 #endif 4166 { 4167 rv = bcm_tr_mpls_tunnel_switch_delete_all(unit); 4168 } 4169 return rv; 4170 } 4171 #endif 4172 #endif 4173 return rv; 4174 } 4175 4176 /* 4177 * Function: 4178 * bcm_esw_mpls_port_stat_attach 4179 * Description: 4180 * Attach counters entries to the given mpls gport and vpn 4181 * 4182 * Parameters: 4183 * unit - (IN) unit number 4184 * vpn - (IN) VPN Id 4185 * port - (IN) MPLS GPORT ID 4186 * stat_counter_id - (IN) Stat Counter ID. 4187 * 4188 * Return Value: 4189 * BCM_E_XXX 4190 * Notes: 4191 */ 4192 int bcm_esw_mpls_port_stat_attach( 4193 int unit, 4194 bcm_vpn_t vpn, 4195 bcm_gport_t port, 4196 uint32 stat_counter_id) 4197 { 4198 #ifdef BCM_KATANA_SUPPORT 4199 if (SOC_IS_KATANAX(unit)) { 4200 return bcm_kt_mpls_port_stat_attach( 4201 unit,vpn,port,stat_counter_id); 4202 } else 4203 #endif 4204 #ifdef BCM_TRIUMPH3_SUPPORT 4205 if (SOC_IS_TRIUMPH3(unit)) { 4206 return bcm_tr3_mpls_port_stat_attach( 4207 unit,vpn,port,stat_counter_id); 4208 } else 4209 #endif 4210 { 4211 #ifdef BCM_TRIDENT2_SUPPORT 4212 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 4213 return td2_mpls_port_stat_attach( 4214 unit,vpn,port,stat_counter_id); 4215 } 4216 #endif 4217 } 4218 #if defined(BCM_MPLS_SUPPORT) 4219 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 4220 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_TRIDENT(unit)) { 4221 if (soc_feature(unit, soc_feature_gport_service_counters) && 4222 soc_feature(unit, soc_feature_mpls)) { 4223 _bcm_flex_stat_type_t fs_type; 4224 uint32 fs_inx; 4225 uint32 flag; 4226 int rv; 4227 4228 fs_type = _BCM_FLEX_STAT_TYPE(stat_counter_id); 4229 fs_inx = _BCM_FLEX_STAT_COUNT_INX(stat_counter_id); 4230 if (((fs_type != _bcmFlexStatTypeEgressGport) && 4231 (fs_type != _bcmFlexStatTypeGport)) || (!fs_inx)) { 4232 return BCM_E_PARAM; 4233 } 4234 flag = fs_type==_bcmFlexStatTypeGport? _BCM_FLEX_STAT_HW_INGRESS: 4235 _BCM_FLEX_STAT_HW_EGRESS; 4236 4237 rv = _bcm_esw_flex_stat_enable_set(unit, fs_type, 4238 _bcm_esw_port_flex_stat_hw_index_set, 4239 INT_TO_PTR(flag), 4240 port, TRUE,fs_inx); 4241 return rv; 4242 } 4243 } 4244 #endif 4245 #endif 4246 return BCM_E_UNAVAIL; 4247 } 4248 4249 /* 4250 * Function: 4251 * bcm_esw_mpls_port_stat_detach 4252 * Description: 4253 * Detach counters entries to the given mpls port and vpn 4254 * 4255 * Parameters: 4256 * unit - (IN) unit number 4257 * vpn - (IN) VPN Id 4258 * port - (IN) MPLS GPORT ID 4259 * 4260 * Return Value: 4261 * BCM_E_XXX 4262 * Notes: 4263 */ 4264 int bcm_esw_mpls_port_stat_detach( 4265 int unit, 4266 bcm_vpn_t vpn, 4267 bcm_gport_t port) 4268 { 4269 #ifdef BCM_KATANA_SUPPORT 4270 if (SOC_IS_KATANAX(unit)) { 4271 return bcm_kt_mpls_port_stat_detach(unit,vpn,port); 4272 } else 4273 #endif 4274 #ifdef BCM_TRIUMPH3_SUPPORT 4275 if (SOC_IS_TRIUMPH3(unit)) { 4276 return bcm_tr3_mpls_port_stat_detach(unit,vpn,port); 4277 } else 4278 #endif 4279 { 4280 #ifdef BCM_TRIDENT2_SUPPORT 4281 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 4282 return td2_mpls_port_stat_detach(unit,vpn,port); 4283 } 4284 #endif 4285 } 4286 #if defined(BCM_MPLS_SUPPORT) 4287 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 4288 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_TRIDENT(unit)) { 4289 if (soc_feature(unit, soc_feature_gport_service_counters) && 4290 soc_feature(unit, soc_feature_mpls)) { 4291 uint32 flag; 4292 int rv; 4293 int rv1; 4294 4295 flag= _BCM_FLEX_STAT_HW_INGRESS; 4296 rv = _bcm_esw_flex_stat_enable_set(unit, _bcmFlexStatTypeGport, 4297 _bcm_esw_port_flex_stat_hw_index_set, 4298 INT_TO_PTR(flag), 4299 port, FALSE,1); 4300 flag= _BCM_FLEX_STAT_HW_EGRESS; 4301 rv1 = _bcm_esw_flex_stat_enable_set(unit, 4302 _bcmFlexStatTypeEgressGport, 4303 _bcm_esw_port_flex_stat_hw_index_set, 4304 INT_TO_PTR(flag), 4305 port, FALSE,1); 4306 if (BCM_SUCCESS(rv) && BCM_SUCCESS(rv1)) { 4307 return BCM_E_NONE; 4308 } else { 4309 return BCM_E_NOT_FOUND; 4310 } 4311 } 4312 } 4313 #endif 4314 #endif 4315 return BCM_E_UNAVAIL; 4316 } 4317 4318 /* 4319 * Function: 4320 * _bcm_esw_mpls_port_stat_counter_get 4321 * Description: 4322 * Get counter statistic values for specific vpn and gport 4323 * if sync_mode is set, sync the sw accumulated count 4324 * with hw count value first, else return sw count. 4325 * 4326 * Parameters: 4327 * unit - (IN) unit number 4328 * sync_mode - (IN) hwcount is to be synced to sw count 4329 * vpn - (IN) VPN Id 4330 * port - (IN) MPLS GPORT ID 4331 * stat - (IN) Type of the counter to retrieve 4332 * I.e. ingress/egress byte/packet) 4333 * num_entries - (IN) Number of counter Entries 4334 * counter_indexes - (IN) Pointer to Counter indexes entries 4335 * counter_values - (OUT) Pointer to counter values 4336 * 4337 * Return Value: 4338 * BCM_E_XXX 4339 * Notes: 4340 */ 4341 4342 int 4343 _bcm_esw_mpls_port_stat_counter_get( 4344 int unit, 4345 int sync_mode, 4346 bcm_vpn_t vpn, 4347 bcm_gport_t port, 4348 bcm_mpls_stat_t stat, 4349 uint32 num_entries, 4350 uint32 *counter_indexes, 4351 bcm_stat_value_t *counter_values) 4352 { 4353 #ifdef BCM_KATANA_SUPPORT 4354 if (SOC_IS_KATANAX(unit)) { 4355 return bcm_kt_mpls_port_stat_counter_get( 4356 unit, sync_mode, vpn, port, stat, num_entries, 4357 counter_indexes,counter_values); 4358 } else 4359 #endif 4360 #ifdef BCM_TRIUMPH3_SUPPORT 4361 if (SOC_IS_TRIUMPH3(unit)) { 4362 return bcm_tr3_mpls_port_stat_counter_get( 4363 unit, sync_mode, vpn, port, stat, num_entries, 4364 counter_indexes,counter_values); 4365 } else 4366 #endif 4367 { 4368 #ifdef BCM_TRIDENT2_SUPPORT 4369 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 4370 return td2_mpls_port_stat_counter_get( 4371 unit, sync_mode, vpn, port, stat, num_entries, 4372 counter_indexes,counter_values); 4373 } 4374 #endif 4375 } 4376 #if defined(BCM_MPLS_SUPPORT) 4377 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 4378 if ((SOC_IS_TRIUMPH2(unit) || SOC_IS_TRIDENT(unit)) && 4379 soc_feature(unit, soc_feature_mpls) && 4380 soc_feature(unit, soc_feature_gport_service_counters)) { 4381 uint64 val; 4382 int rv = BCM_E_NONE; 4383 bcm_port_stat_t flex_stat=0; 4384 4385 switch (stat) { 4386 case bcmMplsInPkts: 4387 flex_stat = bcmPortStatIngressPackets; 4388 break; 4389 case bcmMplsInBytes: 4390 flex_stat = bcmPortStatIngressBytes; 4391 break; 4392 case bcmMplsOutPkts: 4393 flex_stat = bcmPortStatEgressPackets; 4394 break; 4395 case bcmMplsOutBytes: 4396 flex_stat = bcmPortStatEgressBytes; 4397 break; 4398 default: 4399 return BCM_E_PARAM; 4400 break; 4401 } 4402 4403 rv = _bcm_esw_flex_stat_get(unit, 0, 4404 ((flex_stat == bcmPortStatIngressPackets) || 4405 (flex_stat == bcmPortStatIngressBytes)) ? 4406 _bcmFlexStatTypeGport:_bcmFlexStatTypeEgressGport, 4407 port, (_bcm_flex_stat_t)flex_stat, &val); 4408 4409 if ((flex_stat == bcmPortStatIngressPackets) || 4410 (flex_stat == bcmPortStatEgressPackets)) { 4411 counter_values->packets = COMPILER_64_LO(val); 4412 } else { 4413 COMPILER_64_SET(counter_values->bytes, 4414 COMPILER_64_HI(val), 4415 COMPILER_64_LO(val)); 4416 } 4417 return rv; 4418 } 4419 #endif 4420 #endif 4421 return BCM_E_UNAVAIL; 4422 } 4423 4424 /* 4425 * Function: 4426 * bcm_esw_mpls_port_stat_counter_get 4427 * Description: 4428 * Get counter statistic values for specific vpn and gport 4429 * 4430 * Parameters: 4431 * unit - (IN) unit number 4432 * vpn - (IN) VPN Id 4433 * port - (IN) MPLS GPORT ID 4434 * stat - (IN) Type of the counter to retrieve 4435 * I.e. ingress/egress byte/packet) 4436 * num_entries - (IN) Number of counter Entries 4437 * counter_indexes - (IN) Pointer to Counter indexes entries 4438 * counter_values - (OUT) Pointer to counter values 4439 * 4440 * Return Value: 4441 * BCM_E_XXX 4442 * Notes: 4443 */ 4444 4445 int 4446 bcm_esw_mpls_port_stat_counter_get(int unit, 4447 bcm_vpn_t vpn, 4448 bcm_gport_t port, 4449 bcm_mpls_stat_t stat, 4450 uint32 num_entries, 4451 uint32 *counter_indexes, 4452 bcm_stat_value_t *counter_values) 4453 { 4454 return _bcm_esw_mpls_port_stat_counter_get(unit, 0, vpn, port, stat, 4455 num_entries, 4456 counter_indexes, 4457 counter_values); 4458 } 4459 4460 /* 4461 * Function: 4462 * bcm_esw_mpls_port_stat_counter_sync_get 4463 * Description: 4464 * Get counter statistic values for specific vpn and gport 4465 * sync the sw accumulated count with hw count value 4466 * 4467 * Parameters: 4468 * unit - (IN) unit number 4469 * vpn - (IN) VPN Id 4470 * port - (IN) MPLS GPORT ID 4471 * stat - (IN) Type of the counter to retrieve 4472 * I.e. ingress/egress byte/packet) 4473 * num_entries - (IN) Number of counter Entries 4474 * counter_indexes - (IN) Pointer to Counter indexes entries 4475 * counter_values - (OUT) Pointer to counter values 4476 * 4477 * Return Value: 4478 * BCM_E_XXX 4479 * Notes: 4480 */ 4481 4482 4483 int 4484 bcm_esw_mpls_port_stat_counter_sync_get(int unit, 4485 bcm_vpn_t vpn, 4486 bcm_gport_t port, 4487 bcm_mpls_stat_t stat, 4488 uint32 num_entries, 4489 uint32 *counter_indexes, 4490 bcm_stat_value_t *counter_values) 4491 { 4492 return _bcm_esw_mpls_port_stat_counter_get(unit, 1, vpn, port, stat, 4493 num_entries, 4494 counter_indexes, 4495 counter_values); 4496 } 4497 4498 4499 /* 4500 * Function: 4501 * bcm_esw_mpls_port_stat_counter_set 4502 * Description: 4503 * Set counter statistic values for specific vpn and gport 4504 * 4505 * Parameters: 4506 * unit - (IN) unit number 4507 * vpn - (IN) VPN Id 4508 * port - (IN) MPLS GPORT ID 4509 * stat - (IN) Type of the counter to retrieve 4510 * I.e. ingress/egress byte/packet) 4511 * num_entries - (IN) Number of counter Entries 4512 * counter_indexes - (IN) Pointer to Counter indexes entries 4513 * counter_values - (OUT) Pointer to counter values 4514 * 4515 * Return Value: 4516 * BCM_E_XXX 4517 * Notes: 4518 */ 4519 int bcm_esw_mpls_port_stat_counter_set( 4520 int unit, 4521 bcm_vpn_t vpn, 4522 bcm_gport_t port, 4523 bcm_mpls_stat_t stat, 4524 uint32 num_entries, 4525 uint32 *counter_indexes, 4526 bcm_stat_value_t *counter_values) 4527 { 4528 #ifdef BCM_KATANA_SUPPORT 4529 if (SOC_IS_KATANAX(unit)) { 4530 return bcm_kt_mpls_port_stat_counter_set( 4531 unit,vpn,port,stat,num_entries,counter_indexes,counter_values); 4532 } else 4533 #endif 4534 #ifdef BCM_TRIUMPH3_SUPPORT 4535 if (SOC_IS_TRIUMPH3(unit)) { 4536 return bcm_tr3_mpls_port_stat_counter_set( 4537 unit,vpn,port,stat,num_entries,counter_indexes,counter_values); 4538 } else 4539 #endif 4540 { 4541 #ifdef BCM_TRIDENT2_SUPPORT 4542 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 4543 return td2_mpls_port_stat_counter_set( 4544 unit,vpn,port,stat,num_entries,counter_indexes,counter_values); 4545 } 4546 #endif 4547 } 4548 #if defined(BCM_MPLS_SUPPORT) 4549 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 4550 if ((SOC_IS_TRIUMPH2(unit) || SOC_IS_TRIDENT(unit)) && 4551 soc_feature(unit, soc_feature_mpls) && 4552 soc_feature(unit, soc_feature_gport_service_counters)) { 4553 uint64 val; 4554 int rv = BCM_E_NONE; 4555 bcm_port_stat_t flex_stat=0; 4556 4557 switch (stat) { 4558 case bcmMplsInPkts: 4559 flex_stat = bcmPortStatIngressPackets; 4560 break; 4561 case bcmMplsInBytes: 4562 flex_stat = bcmPortStatIngressBytes; 4563 break; 4564 case bcmMplsOutPkts: 4565 flex_stat = bcmPortStatEgressPackets; 4566 break; 4567 case bcmMplsOutBytes: 4568 flex_stat = bcmPortStatEgressBytes; 4569 break; 4570 default: 4571 return BCM_E_PARAM; 4572 break; 4573 } 4574 4575 if ((flex_stat == bcmPortStatIngressPackets) || 4576 (flex_stat == bcmPortStatEgressPackets)) { 4577 COMPILER_64_SET(val,0,counter_values->packets); 4578 } else { 4579 COMPILER_64_SET(val, 4580 COMPILER_64_HI(counter_values->bytes), 4581 COMPILER_64_LO(counter_values->bytes)); 4582 } 4583 rv = _bcm_esw_flex_stat_set(unit, 4584 ((flex_stat == bcmPortStatIngressPackets) || 4585 (flex_stat == bcmPortStatIngressBytes)) ? 4586 _bcmFlexStatTypeGport:_bcmFlexStatTypeEgressGport, 4587 port, (_bcm_flex_stat_t) flex_stat, val); 4588 return rv; 4589 } 4590 #endif 4591 #endif 4592 return BCM_E_UNAVAIL; 4593 } 4594 /* 4595 * Function: 4596 * bcm_esw_mpls_port_stat_id_get 4597 * Description: 4598 * Get stat counter id associated with specific vpn and gport 4599 * 4600 * Parameters: 4601 * unit - (IN) unit number 4602 * vpn - (IN) VPN Id 4603 * port - (IN) MPLS GPORT ID 4604 * stat - (IN) Type of the counter to retrieve 4605 * I.e. ingress/egress byte/packet) 4606 * Stat_counter_id - (OUT) Stat Counter ID 4607 * Return Value: 4608 * BCM_E_XXX 4609 * Notes: 4610 */ 4611 int bcm_esw_mpls_port_stat_id_get( 4612 int unit, 4613 bcm_vpn_t vpn, 4614 bcm_gport_t port, 4615 bcm_mpls_stat_t stat, 4616 uint32 *stat_counter_id) 4617 { 4618 #ifdef BCM_KATANA_SUPPORT 4619 if (SOC_IS_KATANAX(unit)) { 4620 return bcm_kt_mpls_port_stat_id_get( 4621 unit,vpn,port,stat,stat_counter_id); 4622 } else 4623 #endif 4624 #ifdef BCM_TRIUMPH3_SUPPORT 4625 if (SOC_IS_TRIUMPH3(unit)) { 4626 return bcm_tr3_mpls_port_stat_id_get( 4627 unit,vpn,port,stat,stat_counter_id); 4628 } else 4629 #endif 4630 { 4631 #ifdef BCM_TRIDENT2_SUPPORT 4632 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 4633 return td2_mpls_port_stat_id_get( 4634 unit,vpn,port,stat,stat_counter_id); 4635 } 4636 #endif 4637 } 4638 return BCM_E_UNAVAIL; 4639 } 4640 4641 /* 4642 * Function: 4643 * bcm_esw_mpls_label_stat_attach 4644 * Description: 4645 * Attach counters entries to the given mpls label and gport 4646 * 4647 * Parameters: 4648 * unit - (IN) unit number 4649 * label - (IN) MPLS Label 4650 * port - (IN) MPLS Gport 4651 * stat_counter_id - (IN) Stat Counter ID. 4652 * 4653 * Return Value: 4654 * BCM_E_XXX 4655 * Notes: 4656 */ 4657 int bcm_esw_mpls_label_stat_attach( 4658 int unit, 4659 bcm_mpls_label_t label, 4660 bcm_gport_t port, 4661 uint32 stat_counter_id) 4662 { 4663 #if defined(BCM_KATANA_SUPPORT) 4664 if (SOC_IS_KATANAX(unit)) { 4665 return bcm_kt_mpls_label_stat_attach( 4666 unit,label,port,stat_counter_id); 4667 } else 4668 #endif 4669 #if defined(BCM_TRIUMPH3_SUPPORT) 4670 if (SOC_IS_TRIUMPH3(unit)) { 4671 return bcm_tr3_mpls_label_stat_attach( 4672 unit,label,port,stat_counter_id); 4673 } else 4674 #endif 4675 { 4676 #if defined(BCM_TRIDENT2_SUPPORT) 4677 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 4678 return td2_mpls_label_stat_attach( 4679 unit,label,port,stat_counter_id); 4680 } 4681 #endif 4682 } 4683 #if defined(BCM_MPLS_SUPPORT) 4684 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 4685 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_TRIDENT(unit)) { 4686 if (soc_feature(unit, soc_feature_gport_service_counters) && 4687 soc_feature(unit, soc_feature_mpls)) { 4688 _bcm_flex_stat_type_t fs_type; 4689 uint32 fs_inx; 4690 int rv; 4691 4692 fs_type = _BCM_FLEX_STAT_TYPE(stat_counter_id); 4693 fs_inx = _BCM_FLEX_STAT_COUNT_INX(stat_counter_id); 4694 if ((fs_type != _bcmFlexStatTypeMplsLabel) || (!fs_inx)) { 4695 return BCM_E_PARAM; 4696 } 4697 4698 rv = bcm_tr_mpls_lock(unit); 4699 if (BCM_E_NONE == rv) { 4700 rv = bcm_tr2_mpls_label_stat_enable_set(unit, label, 4701 port, TRUE, fs_inx); 4702 bcm_tr_mpls_unlock(unit); 4703 } 4704 return rv; 4705 } 4706 } 4707 #endif 4708 #endif 4709 return BCM_E_UNAVAIL; 4710 } 4711 /* 4712 * Function: 4713 * bcm_esw_mpls_label_stat_detach 4714 * Description: 4715 * Detach counters entries to the given mpls label and gport 4716 * 4717 * Parameters: 4718 * unit - (IN) unit number 4719 * label - (IN) MPLS Label 4720 * port - (IN) MPLS Gport 4721 * 4722 * Return Value: 4723 * BCM_E_XXX 4724 * Notes: 4725 */ 4726 int bcm_esw_mpls_label_stat_detach( 4727 int unit, 4728 bcm_mpls_label_t label, 4729 bcm_gport_t port) 4730 { 4731 #if defined(BCM_KATANA_SUPPORT) 4732 if (SOC_IS_KATANAX(unit)) { 4733 return bcm_kt_mpls_label_stat_detach( 4734 unit,label,port); 4735 } else 4736 #endif 4737 #if defined(BCM_TRIUMPH3_SUPPORT) 4738 if (SOC_IS_TRIUMPH3(unit)) { 4739 return bcm_tr3_mpls_label_stat_detach( 4740 unit,label,port); 4741 } else 4742 #endif 4743 { 4744 #if defined(BCM_TRIDENT2_SUPPORT) 4745 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 4746 return td2_mpls_label_stat_detach( 4747 unit,label,port); 4748 } 4749 #endif 4750 } 4751 #if defined(BCM_MPLS_SUPPORT) 4752 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 4753 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_TRIDENT(unit)) { 4754 if (soc_feature(unit, soc_feature_gport_service_counters) && 4755 soc_feature(unit, soc_feature_mpls)) { 4756 int rv; 4757 4758 rv = bcm_tr_mpls_lock(unit); 4759 if (BCM_E_NONE == rv) { 4760 rv = bcm_tr2_mpls_label_stat_enable_set(unit, label, 4761 port, FALSE, 1); 4762 bcm_tr_mpls_unlock(unit); 4763 } 4764 return rv; 4765 } 4766 } 4767 #endif 4768 #endif 4769 return BCM_E_UNAVAIL; 4770 } 4771 4772 /* 4773 * Function: 4774 * _bcm_esw_mpls_label_stat_counter_get 4775 * Description: 4776 * Get counter statistic values for specific MPLS label and gport 4777 * if sync_mode is set, sync the sw accumulated count 4778 * with hw count value first, else return sw count. 4779 * 4780 * Parameters: 4781 * unit - (IN) unit number 4782 * sync_mode - (IN) hwcount is to be synced to sw count 4783 * label - (IN) MPLS Label 4784 * port - (IN) MPLS Gport 4785 * stat - (IN) Type of the counter to retrieve 4786 * I.e. ingress/egress byte/packet) 4787 * num_entries - (IN) Number of counter Entries 4788 * counter_indexes - (IN) Pointer to Counter indexes entries 4789 * counter_values - (OUT) Pointer to counter values 4790 * 4791 * Return Value: 4792 * BCM_E_XXX 4793 * Notes: 4794 */ 4795 int 4796 _bcm_esw_mpls_label_stat_counter_get(int unit, 4797 int sync_mode, 4798 bcm_mpls_label_t label, 4799 bcm_gport_t port, 4800 bcm_mpls_stat_t stat, 4801 uint32 num_entries, 4802 uint32 *counter_indexes, 4803 bcm_stat_value_t *counter_values) 4804 { 4805 #if defined(BCM_KATANA_SUPPORT) 4806 if (SOC_IS_KATANAX(unit)) { 4807 return bcm_kt_mpls_label_stat_counter_get( 4808 unit, sync_mode, label, port, stat, num_entries, 4809 counter_indexes,counter_values); 4810 } else 4811 #endif 4812 #if defined(BCM_TRIUMPH3_SUPPORT) 4813 if (SOC_IS_TRIUMPH3(unit)) { 4814 return bcm_tr3_mpls_label_stat_counter_get( 4815 unit, sync_mode, label, port, stat, 4816 num_entries, counter_indexes, counter_values); 4817 } else 4818 #endif 4819 { 4820 #if defined(BCM_TRIDENT2_SUPPORT) 4821 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 4822 return td2_mpls_label_stat_counter_get( 4823 unit, sync_mode, label, port, stat, 4824 num_entries, counter_indexes, counter_values); 4825 } 4826 #endif 4827 } 4828 #ifdef BCM_MPLS_SUPPORT 4829 #ifdef BCM_TRIUMPH_SUPPORT 4830 if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_mpls) && 4831 soc_feature(unit, soc_feature_gport_service_counters)) { 4832 uint64 val; 4833 int rv; 4834 4835 rv = bcm_tr_mpls_lock(unit); 4836 if (rv == BCM_E_NONE ) { 4837 rv = bcm_tr_mpls_label_stat_get(unit, sync_mode, label, 4838 port, stat, &val); 4839 bcm_tr_mpls_unlock (unit); 4840 if ((stat == bcmMplsInPkts) || (stat == bcmMplsOutPkts)) { 4841 counter_values->packets = COMPILER_64_LO(val); 4842 } else { 4843 COMPILER_64_SET(counter_values->bytes, 4844 COMPILER_64_HI(val), 4845 COMPILER_64_LO(val)); 4846 } 4847 } 4848 return rv; 4849 } 4850 #endif 4851 #endif 4852 4853 return BCM_E_UNAVAIL; 4854 } 4855 4856 /* 4857 * Function: 4858 * bcm_esw_mpls_label_stat_counter_get 4859 * Description: 4860 * Get counter statistic values for specific MPLS label and gport 4861 * 4862 * Parameters: 4863 * unit - (IN) unit number 4864 * label - (IN) MPLS Label 4865 * port - (IN) MPLS Gport 4866 * stat - (IN) Type of the counter to retrieve 4867 * I.e. ingress/egress byte/packet) 4868 * num_entries - (IN) Number of counter Entries 4869 * counter_indexes - (IN) Pointer to Counter indexes entries 4870 * counter_values - (OUT) Pointer to counter values 4871 * 4872 * Return Value: 4873 * BCM_E_XXX 4874 * Notes: 4875 */ 4876 int 4877 bcm_esw_mpls_label_stat_counter_get(int unit, 4878 bcm_mpls_label_t label, 4879 bcm_gport_t port, 4880 bcm_mpls_stat_t stat, 4881 uint32 num_entries, 4882 uint32 *counter_indexes, 4883 bcm_stat_value_t *counter_values) 4884 { 4885 return _bcm_esw_mpls_label_stat_counter_get(unit, 0, label, port, stat, 4886 num_entries, counter_indexes, 4887 counter_values); 4888 } 4889 4890 /* 4891 * Function: 4892 * bcm_esw_mpls_label_stat_counter_sync_get 4893 * Description: 4894 * Get counter statistic values for specific MPLS label and gport 4895 * sync the sw accumulated count with hw count value 4896 * 4897 * Parameters: 4898 * unit - (IN) unit number 4899 * label - (IN) MPLS Label 4900 * port - (IN) MPLS Gport 4901 * stat - (IN) Type of the counter to retrieve 4902 * I.e. ingress/egress byte/packet) 4903 * num_entries - (IN) Number of counter Entries 4904 * counter_indexes - (IN) Pointer to Counter indexes entries 4905 * counter_values - (OUT) Pointer to counter values 4906 * 4907 * Return Value: 4908 * BCM_E_XXX 4909 * Notes: 4910 */ 4911 int 4912 bcm_esw_mpls_label_stat_counter_sync_get(int unit, 4913 bcm_mpls_label_t label, 4914 bcm_gport_t port, 4915 bcm_mpls_stat_t stat, 4916 uint32 num_entries, 4917 uint32 *counter_indexes, 4918 bcm_stat_value_t *counter_values) 4919 { 4920 return _bcm_esw_mpls_label_stat_counter_get(unit, 1, label, port, stat, 4921 num_entries, counter_indexes, 4922 counter_values); 4923 } 4924 /* 4925 * Function: 4926 * bcm_esw_mpls_label_stat_counter_set 4927 * Description: 4928 * Set counter statistic values for specific MPLS label and gport 4929 * 4930 * Parameters: 4931 * unit - (IN) unit number 4932 * label - (IN) MPLS Label 4933 * port - (IN) MPLS Gport 4934 * stat - (IN) Type of the counter to retrieve 4935 * I.e. ingress/egress byte/packet) 4936 * num_entries - (IN) Number of counter Entries 4937 * counter_indexes - (IN) Pointer to Counter indexes entries 4938 * counter_values - (IN) Pointer to counter values 4939 * 4940 * Return Value: 4941 * BCM_E_XXX 4942 * Notes: 4943 */ 4944 int bcm_esw_mpls_label_stat_counter_set( 4945 int unit, 4946 bcm_mpls_label_t label, 4947 bcm_gport_t port, 4948 bcm_mpls_stat_t stat, 4949 uint32 num_entries, 4950 uint32 *counter_indexes, 4951 bcm_stat_value_t *counter_values) 4952 { 4953 #if defined(BCM_KATANA_SUPPORT) 4954 if (SOC_IS_KATANAX(unit)) { 4955 return bcm_kt_mpls_label_stat_counter_set( 4956 unit,label,port,stat,num_entries,counter_indexes,counter_values); 4957 } else 4958 #endif 4959 #if defined(BCM_TRIUMPH3_SUPPORT) 4960 if (SOC_IS_TRIUMPH3(unit)) { 4961 return bcm_tr3_mpls_label_stat_counter_set( 4962 unit,label,port,stat,num_entries,counter_indexes,counter_values); 4963 } else 4964 #endif 4965 { 4966 #if defined(BCM_TRIDENT2_SUPPORT) 4967 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 4968 return td2_mpls_label_stat_counter_set( 4969 unit,label,port,stat,num_entries,counter_indexes,counter_values); 4970 } 4971 #endif 4972 } 4973 return BCM_E_UNAVAIL; 4974 } 4975 /* 4976 * Function: 4977 * bcm_esw_mpls_label_stat_id_get 4978 * Description: 4979 * Get stat counter id associated with specific MPLS label and gport 4980 * 4981 * Parameters: 4982 * unit - (IN) unit number 4983 * label - (IN) MPLS Label 4984 * port - (IN) MPLS Gport 4985 * stat - (IN) Type of the counter to retrieve 4986 * I.e. ingress/egress byte/packet) 4987 * Stat_counter_id - (OUT) Stat Counter ID 4988 * Return Value: 4989 * BCM_E_XXX 4990 * Notes: 4991 */ 4992 int bcm_esw_mpls_label_stat_id_get( 4993 int unit, 4994 bcm_mpls_label_t label, 4995 bcm_gport_t port, 4996 bcm_mpls_stat_t stat, 4997 uint32 *stat_counter_id) 4998 { 4999 #if defined(BCM_KATANA_SUPPORT) 5000 if (SOC_IS_KATANAX(unit)) { 5001 return bcm_kt_mpls_label_stat_id_get( 5002 unit,label,port,stat,stat_counter_id); 5003 } else 5004 #endif 5005 #if defined(BCM_TRIUMPH3_SUPPORT) 5006 if (SOC_IS_TRIUMPH3(unit)) { 5007 return bcm_tr3_mpls_label_stat_id_get( 5008 unit,label,port,stat,stat_counter_id); 5009 } else 5010 #endif 5011 { 5012 #if defined(BCM_TRIDENT2_SUPPORT) 5013 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 5014 return td2_mpls_label_stat_id_get( 5015 unit,label,port,stat,stat_counter_id); 5016 } 5017 #endif 5018 } 5019 return BCM_E_UNAVAIL; 5020 } 5021 5022 5023 /* 5024 * Function: 5025 * bcm_esw_mpls_special_label_identifier_add 5026 * Description: 5027 * Add identifier entry of special label. 5028 * 5029 * Parameters: 5030 * unit - (IN) unit number 5031 * label_type - (IN) MPLS Label 5032 * label_info - (IN) MPLS Gport 5033 * Return Value: 5034 * BCM_E_XXX 5035 * Notes: 5036 */ 5037 int 5038 bcm_esw_mpls_special_label_identifier_add(int unit, 5039 bcm_mpls_special_label_type_t label_type, 5040 bcm_mpls_special_label_t label_info) 5041 { 5042 int rv = BCM_E_NONE; 5043 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 5044 #ifdef BCM_SPECIAL_LABEL_SUPPORT 5045 5046 if ((!soc_feature(unit, soc_feature_mpls)) || 5047 (!(soc_feature(unit, soc_feature_mpls_special_label)))) { 5048 return BCM_E_UNAVAIL; 5049 } 5050 rv = bcm_tr_mpls_lock(unit); 5051 if (BCM_E_NONE == rv) { 5052 rv = bcmi_mpls_special_label_identifier_add(unit, label_type, 5053 label_info); 5054 } 5055 bcm_tr_mpls_unlock(unit); 5056 #endif /* BCM_TRIUMPH2_SUPPORT || BCM_TRIDENT_SUPPORT */ 5057 #endif /*BCM_SPECIAL_LABEL_SUPPORT*/ 5058 5059 return rv; 5060 } 5061 5062 /* 5063 * Function: 5064 * bcm_esw_mpls_special_label_identifier_get 5065 * Description: 5066 * Get identifier entry of special label. 5067 * 5068 * Parameters: 5069 * unit - (IN) unit number 5070 * label_type - (IN) MPLS Label 5071 * label_info - (IN) MPLS Gport 5072 * Return Value: 5073 * BCM_E_XXX 5074 * Notes: 5075 */ 5076 int 5077 bcm_esw_mpls_special_label_identifier_get(int unit, 5078 bcm_mpls_special_label_type_t label_type, 5079 bcm_mpls_special_label_t *label_info) 5080 { 5081 int rv = BCM_E_NONE; 5082 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 5083 #ifdef BCM_SPECIAL_LABEL_SUPPORT 5084 5085 if ((!soc_feature(unit, soc_feature_mpls)) || 5086 (!(soc_feature(unit, soc_feature_mpls_special_label)))) { 5087 return BCM_E_UNAVAIL; 5088 } 5089 rv = bcm_tr_mpls_lock(unit); 5090 if (BCM_E_NONE == rv) { 5091 rv = bcmi_mpls_special_label_identifier_get(unit, label_type, 5092 label_info); 5093 } 5094 bcm_tr_mpls_unlock(unit); 5095 #endif /* BCM_TRIUMPH2_SUPPORT || BCM_TRIDENT_SUPPORT */ 5096 #endif /*BCM_SPECIAL_LABEL_SUPPORT*/ 5097 5098 return rv; 5099 } 5100 5101 /* 5102 * Function: 5103 * bcm_esw_mpls_special_label_identifier_delete 5104 * Description: 5105 * Delete identifiers of special label. 5106 * 5107 * Parameters: 5108 * unit - (IN) unit number 5109 * label_type - (IN) MPLS Label 5110 * label_info - (IN) MPLS Gport 5111 * Return Value: 5112 * BCM_E_XXX 5113 * Notes: 5114 */ 5115 int 5116 bcm_esw_mpls_special_label_identifier_delete(int unit, 5117 bcm_mpls_special_label_type_t label_type, 5118 bcm_mpls_special_label_t label_info) 5119 { 5120 int rv = BCM_E_NONE; 5121 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 5122 #ifdef BCM_SPECIAL_LABEL_SUPPORT 5123 5124 if ((!soc_feature(unit, soc_feature_mpls)) || 5125 (!(soc_feature(unit, soc_feature_mpls_special_label)))) { 5126 return BCM_E_UNAVAIL; 5127 } 5128 rv = bcm_tr_mpls_lock(unit); 5129 if (BCM_E_NONE == rv) { 5130 rv = bcmi_mpls_special_label_identifier_delete(unit, label_type, 5131 label_info); 5132 } 5133 bcm_tr_mpls_unlock(unit); 5134 #endif /* BCM_TRIUMPH2_SUPPORT || BCM_TRIDENT_SUPPORT */ 5135 #endif /*BCM_SPECIAL_LABEL_SUPPORT*/ 5136 5137 return rv; 5138 5139 } 5140 5141 /* 5142 * Function: 5143 * bcm_esw_mpls_special_label_identifier_delete_all 5144 * Description: 5145 * Delete all identifiers ofs pecial labels. 5146 * 5147 * Parameters: 5148 * unit - (IN) unit number 5149 * label_type - (IN) MPLS Label 5150 * label_info - (IN) MPLS Gport 5151 * Return Value: 5152 * BCM_E_XXX 5153 * Notes: 5154 */ 5155 int 5156 bcm_esw_mpls_special_label_identifier_delete_all(int unit) 5157 { 5158 int rv = BCM_E_NONE; 5159 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 5160 #ifdef BCM_SPECIAL_LABEL_SUPPORT 5161 5162 if ((!soc_feature(unit, soc_feature_mpls)) || 5163 (!(soc_feature(unit, soc_feature_mpls_special_label)))) { 5164 return BCM_E_UNAVAIL; 5165 } 5166 rv = bcm_tr_mpls_lock(unit); 5167 if (BCM_E_NONE == rv) { 5168 rv = bcmi_mpls_special_label_identifier_delete_all(unit); 5169 } 5170 bcm_tr_mpls_unlock(unit); 5171 #endif /* BCM_TRIUMPH2_SUPPORT || BCM_TRIDENT_SUPPORT */ 5172 #endif /*BCM_SPECIAL_LABEL_SUPPORT*/ 5173 5174 return rv; 5175 } 5176 5177 /* 5178 * Function: 5179 * bcm_esw_mpls_special_label_identifier_traverse 5180 * Description: 5181 * Traverse and call user call back for all special labels identifiers. 5182 * 5183 * Parameters: 5184 * unit - (IN) unit number 5185 * cb - (IN) user callback 5186 * user data - (IN) option user data 5187 * Return Value: 5188 * BCM_E_XXX 5189 * Notes: 5190 */ 5191 int bcm_esw_mpls_special_label_identifier_traverse(int unit, 5192 bcm_mpls_special_label_identifier_traverse_cb cb, void *user_data) 5193 { 5194 int rv = BCM_E_NONE; 5195 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 5196 #ifdef BCM_SPECIAL_LABEL_SUPPORT 5197 5198 if ((!soc_feature(unit, soc_feature_mpls)) || 5199 (!(soc_feature(unit, soc_feature_mpls_special_label)))) { 5200 return BCM_E_UNAVAIL; 5201 } 5202 rv = bcm_tr_mpls_lock(unit); 5203 if (BCM_E_NONE == rv) { 5204 rv = bcmi_mpls_special_label_identifier_traverse(unit, cb, user_data); 5205 } 5206 bcm_tr_mpls_unlock(unit); 5207 #endif /* BCM_TRIUMPH2_SUPPORT || BCM_TRIDENT_SUPPORT */ 5208 #endif /*BCM_SPECIAL_LABEL_SUPPORT*/ 5209 5210 return rv; 5211 } 5212 /* 5213 * Function: 5214 * bcm_esw_mpls_special_label_egress_add 5215 * Description: 5216 * Add special label in MPLS stack for packets 5217 * going into MPLS tunnel. 5218 * 5219 * Parameters: 5220 * unit - (IN) unit number 5221 * label_type - (IN) MPLS Label 5222 * label_info - (IN) MPLS Gport 5223 * Return Value: 5224 * BCM_E_XXX 5225 * Notes: 5226 */ 5227 int 5228 bcm_esw_mpls_special_label_egress_add(int unit, 5229 bcm_mpls_special_label_type_t label_type, 5230 bcm_mpls_special_label_t label_info) 5231 { 5232 int rv = BCM_E_NONE; 5233 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 5234 #ifdef BCM_SPECIAL_LABEL_SUPPORT 5235 5236 if ((!soc_feature(unit, soc_feature_mpls)) || 5237 (!(soc_feature(unit, soc_feature_mpls_special_label)))) { 5238 return BCM_E_UNAVAIL; 5239 } 5240 rv = bcm_tr_mpls_lock(unit); 5241 if (BCM_E_NONE == rv) { 5242 rv = bcmi_mpls_special_label_egress_add(unit, label_type, label_info); 5243 } 5244 bcm_tr_mpls_unlock(unit); 5245 #endif /* BCM_TRIUMPH2_SUPPORT || BCM_TRIDENT_SUPPORT */ 5246 #endif /*BCM_SPECIAL_LABEL_SUPPORT*/ 5247 5248 return rv; 5249 } 5250 5251 /* 5252 * Function: 5253 * bcm_esw_mpls_special_label_egress_get 5254 * Description: 5255 * Get special label in MPLS stack for packets 5256 * going into MPLS tunnel. 5257 * 5258 * Parameters: 5259 * unit - (IN) unit number 5260 * label_type - (IN) MPLS Label 5261 * label_info - (IN) MPLS Gport 5262 * Return Value: 5263 * BCM_E_XXX 5264 * Notes: 5265 */ 5266 int 5267 bcm_esw_mpls_special_label_egress_get(int unit, 5268 bcm_mpls_special_label_type_t label_type, 5269 bcm_mpls_special_label_t *label_info) 5270 { 5271 int rv = BCM_E_NONE; 5272 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 5273 #ifdef BCM_SPECIAL_LABEL_SUPPORT 5274 5275 if ((!soc_feature(unit, soc_feature_mpls)) || 5276 (!(soc_feature(unit, soc_feature_mpls_special_label)))) { 5277 return BCM_E_UNAVAIL; 5278 } 5279 rv = bcm_tr_mpls_lock(unit); 5280 if (BCM_E_NONE == rv) { 5281 rv = bcmi_mpls_special_label_egress_get(unit, label_type, label_info); 5282 } 5283 bcm_tr_mpls_unlock(unit); 5284 #endif /* BCM_TRIUMPH2_SUPPORT || BCM_TRIDENT_SUPPORT */ 5285 #endif /*BCM_SPECIAL_LABEL_SUPPORT*/ 5286 return rv; 5287 } 5288 5289 /* 5290 * Function: 5291 * bcm_esw_mpls_special_label_egress_delete 5292 * Description: 5293 * Delete special label in MPLS stack for packets 5294 * going into MPLS tunnel. 5295 * 5296 * Parameters: 5297 * unit - (IN) unit number 5298 * label_type - (IN) MPLS Label 5299 * label_info - (IN) MPLS Gport 5300 * Return Value: 5301 * BCM_E_XXX 5302 * Notes: 5303 */ 5304 int 5305 bcm_esw_mpls_special_label_egress_delete(int unit, 5306 bcm_mpls_special_label_type_t label_type, 5307 bcm_mpls_special_label_t label_info) 5308 { 5309 int rv = BCM_E_NONE; 5310 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 5311 #ifdef BCM_SPECIAL_LABEL_SUPPORT 5312 5313 if ((!soc_feature(unit, soc_feature_mpls)) || 5314 (!(soc_feature(unit, soc_feature_mpls_special_label)))) { 5315 return BCM_E_UNAVAIL; 5316 } 5317 rv = bcm_tr_mpls_lock(unit); 5318 if (BCM_E_NONE == rv) { 5319 rv = bcmi_mpls_special_label_egress_delete(unit, label_type, label_info); 5320 } 5321 bcm_tr_mpls_unlock(unit); 5322 #endif /* BCM_TRIUMPH2_SUPPORT || BCM_TRIDENT_SUPPORT */ 5323 #endif /*BCM_SPECIAL_LABEL_SUPPORT*/ 5324 5325 return rv; 5326 } 5327 5328 /* 5329 * Function: 5330 * bcm_esw_mpls_special_label_egress_delete_all 5331 * Description: 5332 * Delete all special labels in MPLS stack for packets 5333 * going into MPLS tunnel. 5334 * 5335 * Parameters: 5336 * unit - (IN) unit number 5337 * label_type - (IN) MPLS Label 5338 * label_info - (IN) MPLS Gport 5339 * Return Value: 5340 * BCM_E_XXX 5341 * Notes: 5342 */ 5343 int 5344 bcm_esw_mpls_special_label_egress_delete_all(int unit) 5345 { 5346 int rv = BCM_E_NONE; 5347 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 5348 #ifdef BCM_SPECIAL_LABEL_SUPPORT 5349 5350 if ((!soc_feature(unit, soc_feature_mpls)) || 5351 (!(soc_feature(unit, soc_feature_mpls_special_label)))) { 5352 return BCM_E_UNAVAIL; 5353 } 5354 rv = bcm_tr_mpls_lock(unit); 5355 if (BCM_E_NONE == rv) { 5356 rv = bcmi_mpls_special_label_egress_delete_all(unit); 5357 } 5358 bcm_tr_mpls_unlock(unit); 5359 #endif /* BCM_TRIUMPH2_SUPPORT || BCM_TRIDENT_SUPPORT */ 5360 #endif /*BCM_SPECIAL_LABEL_SUPPORT*/ 5361 5362 return rv; 5363 } 5364 5365 /* 5366 * Function: 5367 * bcm_esw_mpls_special_label_egress_traverse 5368 * Description: 5369 * Traverse and call user call back for all special labels 5370 * going into MPLS tunnel. 5371 * 5372 * Parameters: 5373 * unit - (IN) unit number 5374 * cb - (IN) user callback 5375 * user data - (IN) option user data 5376 * Return Value: 5377 * BCM_E_XXX 5378 * Notes: 5379 */ 5380 int bcm_esw_mpls_special_label_egress_traverse(int unit, 5381 bcm_mpls_special_label_egress_traverse_cb cb,void *user_data) 5382 { 5383 int rv = BCM_E_NONE; 5384 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 5385 #ifdef BCM_SPECIAL_LABEL_SUPPORT 5386 5387 if ((!soc_feature(unit, soc_feature_mpls)) || 5388 (!(soc_feature(unit, soc_feature_mpls_special_label)))) { 5389 return BCM_E_UNAVAIL; 5390 } 5391 rv = bcm_tr_mpls_lock(unit); 5392 if (BCM_E_NONE == rv) { 5393 rv = bcmi_mpls_special_label_egress_traverse(unit, cb, user_data); 5394 } 5395 bcm_tr_mpls_unlock(unit); 5396 #endif /* BCM_TRIUMPH2_SUPPORT || BCM_TRIDENT_SUPPORT */ 5397 #endif /*BCM_SPECIAL_LABEL_SUPPORT*/ 5398 5399 return rv; 5400 } 5401 /* 5402 * Function: 5403 * bcm_esw_mpls_special_label_push_action_set 5404 * Description: 5405 * Set mpls push action in MPLS objects. 5406 * going into MPLS tunnel. 5407 * 5408 * Parameters: 5409 * unit - (IN) unit number 5410 * element - (IN) MPLS object 5411 * push_type - (IN) push action 5412 * Return Value: 5413 * BCM_E_XXX 5414 * Notes: 5415 */ 5416 int 5417 bcm_esw_mpls_special_label_push_action_set(int unit, 5418 bcm_mpls_special_label_push_element_t *element, 5419 int push_type) 5420 { 5421 int rv = BCM_E_NONE; 5422 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 5423 #ifdef BCM_SPECIAL_LABEL_SUPPORT 5424 5425 if ((!soc_feature(unit, soc_feature_mpls)) || 5426 (!(soc_feature(unit, soc_feature_mpls_special_label)))) { 5427 return BCM_E_UNAVAIL; 5428 } 5429 rv = bcm_tr_mpls_lock(unit); 5430 if (BCM_E_NONE == rv) { 5431 5432 rv = bcmi_mpls_special_label_push_action_set( 5433 unit, element, (bcm_mpls_special_label_push_type_t)push_type); 5434 } 5435 bcm_tr_mpls_unlock(unit); 5436 #endif /* BCM_TRIUMPH2_SUPPORT || BCM_TRIDENT_SUPPORT */ 5437 #endif /*BCM_SPECIAL_LABEL_SUPPORT*/ 5438 return rv; 5439 } 5440 /* 5441 * Function: 5442 * bcm_esw_mpls_special_label_push_action_get 5443 * Description: 5444 * Get mpls push action in MPLS objects. 5445 * going into MPLS tunnel. 5446 * 5447 * Parameters: 5448 * unit - (IN) unit number 5449 * element - (IN) MPLS object 5450 * push_type - (OUT) push action 5451 * Return Value: 5452 * BCM_E_XXX 5453 * Notes: 5454 */ 5455 int 5456 bcm_esw_mpls_special_label_push_action_get(int unit, 5457 bcm_mpls_special_label_push_element_t *element, 5458 int *push_type) 5459 { 5460 int rv = BCM_E_NONE; 5461 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 5462 #ifdef BCM_SPECIAL_LABEL_SUPPORT 5463 5464 if ((!soc_feature(unit, soc_feature_mpls)) || 5465 (!(soc_feature(unit, soc_feature_mpls_special_label)))) { 5466 return BCM_E_UNAVAIL; 5467 } 5468 if (push_type == NULL) { 5469 return BCM_E_PARAM; 5470 } 5471 5472 rv = bcm_tr_mpls_lock(unit); 5473 if (BCM_E_NONE == rv) { 5474 5475 rv = bcmi_mpls_special_label_push_action_get( 5476 unit, element, (bcm_mpls_special_label_push_type_t *)push_type); 5477 } 5478 bcm_tr_mpls_unlock(unit); 5479 #endif /* BCM_TRIUMPH2_SUPPORT || BCM_TRIDENT_SUPPORT */ 5480 #endif /*BCM_SPECIAL_LABEL_SUPPORT*/ 5481 return rv; 5482 } 5483 5484 #else /* INCLUDE_L3 */ 5485 int bcm_esw_mpls_not_empty; 5486 #endif /* INCLUDE_L3 */ 5487