trunk.c (22342B)
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: bcmx/trunk.c 8 * Purpose: BCMX Trunk APIs 9 * 10 * BCMX trunking takes place on switch ports, not fabric ports. 11 * Fabric port trunking may be controlled by the stack/toppology 12 * code, so we are careful to skip any fabric devices and ports. 13 */ 14 15 #include <sal/core/libc.h> 16 #include <sal/core/alloc.h> 17 18 #include <bcm/types.h> 19 20 #include <bcmx/trunk.h> 21 #include <bcmx/lport.h> 22 #include <bcmx/bcmx.h> 23 #include <bcmx/lplist.h> 24 25 #include <bcm_int/control.h> 26 #include "bcmx_int.h" 27 28 #define BCMX_TRUNK_INIT_CHECK BCMX_READY_CHECK 29 30 #define BCMX_TRUNK_ERROR_CHECK(_unit, _check, _rv) \ 31 BCMX_ERROR_CHECK(_unit, _check, _rv) 32 33 #define BCMX_TRUNK_SET_ERROR_CHECK(_unit, _check, _rv) \ 34 BCMX_SET_ERROR_CHECK(_unit, _check, _rv) 35 36 #define BCMX_TRUNK_DELETE_ERROR_CHECK(_unit, _check, _rv) \ 37 BCMX_DELETE_ERROR_CHECK(_unit, _check, _rv) 38 39 #define BCMX_TRUNK_GET_IS_VALID(_unit, _rv) \ 40 BCMX_ERROR_IS_VALID(_unit, _rv) 41 42 43 #define BCMX_TRUNK_MEMBER_T_PTR_TO_BCM(_trunk_member) \ 44 ((bcm_trunk_member_t *)(_trunk_member)) 45 46 47 /* 48 * Function: 49 * bcmx_trunk_add_info_t_init 50 * Purpose: 51 * Initialize the bcmx_trunk_add_info_t structure. 52 * Parameters: 53 * trunk_add_info - Pointer to structure to be initialized. 54 * Returns: 55 * None 56 * Notes: 57 * Memory is allocated for the port list member in this 58 * call. The corresponding 'free' API needs to be called 59 * when structure is no longer needed. 60 */ 61 void 62 bcmx_trunk_add_info_t_init(bcmx_trunk_add_info_t *trunk_add_info) 63 { 64 if (trunk_add_info != NULL) { 65 sal_memset(trunk_add_info, 0, sizeof(bcmx_trunk_add_info_t)); 66 bcmx_lplist_t_init(&trunk_add_info->ports); 67 } 68 } 69 70 71 /* 72 * Function: 73 * bcmx_trunk_add_info_t_free 74 * Purpose: 75 * Free memory allocated by bcmx_trunk_add_info_t_init(). 76 * Parameters: 77 * trunk_add_info - Pointer to structure to free memory. 78 * Returns: 79 * None 80 */ 81 void 82 bcmx_trunk_add_info_t_free(bcmx_trunk_add_info_t *trunk_add_info) 83 { 84 if (trunk_add_info != NULL) { 85 bcmx_lplist_free(&trunk_add_info->ports); 86 } 87 } 88 89 /* 90 * Function: 91 * bcmx_trunk_member_t_init 92 * Purpose: 93 * Trunk member structure initializer. 94 * Parameters: 95 * trunk_member - (IN/OUT) Pointer to structure to be initialized. 96 * Returns: 97 * None 98 */ 99 void 100 bcmx_trunk_member_t_init(bcmx_trunk_member_t *trunk_member) 101 { 102 if (trunk_member != NULL) { 103 bcm_trunk_member_t_init(BCMX_TRUNK_MEMBER_T_PTR_TO_BCM(trunk_member)); 104 } 105 } 106 107 108 /* 109 * Function: 110 * bcmx_trunk_init 111 */ 112 113 int 114 bcmx_trunk_init(void) 115 { 116 int rv = BCM_E_UNAVAIL, tmp_rv; 117 int i, bcm_unit; 118 119 BCMX_TRUNK_INIT_CHECK; 120 121 BCMX_UNIT_ITER(bcm_unit, i) { 122 if (BCM_IS_FABRIC(bcm_unit)) { 123 continue; 124 } 125 tmp_rv = bcm_trunk_init(bcm_unit); 126 BCM_IF_ERROR_RETURN(BCMX_TRUNK_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 127 } 128 129 return rv; 130 } 131 132 133 /* 134 * Function: 135 * bcmx_trunk_detach 136 */ 137 138 int 139 bcmx_trunk_detach(void) 140 { 141 int rv = BCM_E_UNAVAIL, tmp_rv; 142 int i, bcm_unit; 143 144 BCMX_TRUNK_INIT_CHECK; 145 146 BCMX_UNIT_ITER(bcm_unit, i) { 147 if (BCM_IS_FABRIC(bcm_unit)) { 148 continue; 149 } 150 tmp_rv = bcm_trunk_detach(bcm_unit); 151 BCM_IF_ERROR_RETURN(BCMX_TRUNK_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 152 } 153 154 return rv; 155 } 156 157 158 /* 159 * Function: 160 * bcmx_trunk_create 161 */ 162 163 int 164 bcmx_trunk_create(bcm_trunk_t *tid) 165 { 166 int rv = BCM_E_UNAVAIL, tmp_rv; 167 int i, bcm_unit; 168 169 BCMX_TRUNK_INIT_CHECK; 170 171 BCMX_UNIT_ITER(bcm_unit, i) { 172 if (BCM_IS_FABRIC(bcm_unit)) { 173 continue; 174 } 175 tmp_rv = bcm_trunk_create(bcm_unit, 0, tid); 176 BCM_IF_ERROR_RETURN(BCMX_TRUNK_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 177 } 178 179 return rv; 180 } 181 182 183 /* 184 * Function: 185 * bcmx_trunk_create_id 186 */ 187 188 int 189 bcmx_trunk_create_id(bcm_trunk_t tid) 190 { 191 int rv = BCM_E_UNAVAIL, tmp_rv; 192 int i, bcm_unit; 193 194 BCMX_TRUNK_INIT_CHECK; 195 196 BCMX_UNIT_ITER(bcm_unit, i) { 197 if (BCM_IS_FABRIC(bcm_unit)) { 198 continue; 199 } 200 tmp_rv = bcm_trunk_create(bcm_unit, BCM_TRUNK_FLAG_WITH_ID, &tid); 201 BCM_IF_ERROR_RETURN(BCMX_TRUNK_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 202 } 203 204 return rv; 205 } 206 207 208 /* 209 * Function: 210 * bcmx_trunk_psc_set 211 */ 212 213 int 214 bcmx_trunk_psc_set(bcm_trunk_t tid, int psc) 215 { 216 int rv = BCM_E_UNAVAIL, tmp_rv; 217 int i, bcm_unit; 218 219 BCMX_TRUNK_INIT_CHECK; 220 221 BCMX_UNIT_ITER(bcm_unit, i) { 222 if (BCM_IS_FABRIC(bcm_unit)) { 223 continue; 224 } 225 tmp_rv = bcm_trunk_psc_set(bcm_unit, tid, psc); 226 BCM_IF_ERROR_RETURN(BCMX_TRUNK_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 227 } 228 229 return rv; 230 } 231 232 233 /* 234 * Function: 235 * bcmx_trunk_psc_get 236 */ 237 238 int 239 bcmx_trunk_psc_get(bcm_trunk_t tid, int *psc) 240 { 241 int rv; 242 int i, bcm_unit; 243 244 BCMX_TRUNK_INIT_CHECK; 245 246 BCMX_PARAM_NULL_CHECK(psc); 247 248 BCMX_UNIT_ITER(bcm_unit, i) { 249 if (BCM_IS_FABRIC(bcm_unit)) { 250 continue; 251 } 252 rv = bcm_trunk_psc_get(bcm_unit, tid, psc); 253 if (BCMX_TRUNK_GET_IS_VALID(bcm_unit, rv)) { 254 return rv; 255 } 256 } 257 258 return BCM_E_UNAVAIL; 259 } 260 261 262 /* 263 * Function: 264 * bcmx_trunk_chip_info_get 265 * Notes: 266 * Returns the common denominator from all switch devices. 267 */ 268 269 int 270 bcmx_trunk_chip_info_get(bcm_trunk_chip_info_t *ta_info) 271 { 272 int rv = BCM_E_UNAVAIL, tmp_rv; 273 int i, bcm_unit; 274 bcm_trunk_chip_info_t tmp_info; 275 int first = TRUE; 276 277 BCMX_TRUNK_INIT_CHECK; 278 279 BCMX_PARAM_NULL_CHECK(ta_info); 280 281 BCMX_UNIT_ITER(bcm_unit, i) { 282 if (BCM_IS_FABRIC(bcm_unit)) { 283 continue; 284 } 285 286 tmp_rv = bcm_trunk_chip_info_get(bcm_unit, &tmp_info); 287 if (BCMX_TRUNK_GET_IS_VALID(bcm_unit, rv)) { 288 rv = tmp_rv; 289 290 BCM_IF_ERROR_RETURN(rv); 291 292 if (first) { 293 *ta_info = tmp_info; 294 first = FALSE; 295 continue; 296 } 297 298 if (tmp_info.trunk_group_count < ta_info->trunk_group_count) { 299 ta_info->trunk_group_count = tmp_info.trunk_group_count; 300 } 301 if (tmp_info.trunk_id_min > ta_info->trunk_id_min) { 302 ta_info->trunk_id_min = tmp_info.trunk_id_min; 303 } 304 if (tmp_info.trunk_id_max < ta_info->trunk_id_max) { 305 ta_info->trunk_id_max = tmp_info.trunk_id_max; 306 } 307 if (tmp_info.trunk_ports_max < ta_info->trunk_ports_max) { 308 ta_info->trunk_ports_max = tmp_info.trunk_ports_max; 309 } 310 if (tmp_info.trunk_fabric_id_min > ta_info->trunk_fabric_id_min) { 311 ta_info->trunk_fabric_id_min = tmp_info.trunk_fabric_id_min; 312 } 313 if (tmp_info.trunk_fabric_id_max < ta_info->trunk_fabric_id_max) { 314 ta_info->trunk_fabric_id_max = tmp_info.trunk_fabric_id_max; 315 } 316 if (tmp_info.trunk_fabric_ports_max < ta_info->trunk_fabric_ports_max) { 317 ta_info->trunk_fabric_ports_max = tmp_info.trunk_fabric_ports_max; 318 } 319 } 320 } 321 322 return rv; 323 } 324 325 326 /* 327 * Function: 328 * bcmx_trunk_set 329 */ 330 331 int 332 bcmx_trunk_set(bcm_trunk_t tid, bcmx_trunk_add_info_t *add_info) 333 { 334 int rv = BCM_E_UNAVAIL, tmp_rv; 335 bcm_trunk_info_t badd; 336 int i, bcm_unit, count; 337 bcmx_lport_t lport; 338 int member_count; 339 bcm_trunk_member_t *member_array = NULL; 340 bcm_module_t mod; 341 bcm_port_t port; 342 343 BCMX_TRUNK_INIT_CHECK; 344 345 BCMX_PARAM_NULL_CHECK(add_info); 346 347 sal_memset(&badd, 0, sizeof(bcm_trunk_info_t)); 348 badd.psc = add_info->psc; 349 badd.ipmc_psc = add_info->ipmc_psc; 350 badd.dlf_index = -1; 351 badd.mc_index = -1; 352 badd.ipmc_index = -1; 353 354 member_count = BCMX_LPLIST_COUNT(&(add_info->ports)); 355 member_array = sal_alloc(member_count * sizeof(bcm_trunk_member_t), 356 "trunk member array"); 357 if (NULL == member_array) { 358 return BCM_E_MEMORY; 359 } 360 sal_memset(member_array, 0, member_count * sizeof(bcm_trunk_member_t)); 361 362 BCMX_LPLIST_ITER(add_info->ports, lport, count) { 363 if (count >= BCM_TRUNK_MAX_PORTCNT) { 364 sal_free(member_array); 365 return BCM_E_PARAM; 366 } 367 if (lport == add_info->dlf_port) { 368 badd.dlf_index = count; 369 } 370 if (lport == add_info->mc_port) { 371 badd.mc_index = count; 372 } 373 if (lport == add_info->ipmc_port) { 374 badd.ipmc_index = count; 375 } 376 377 tmp_rv = _bcmx_dest_to_modid_port(lport, 378 &mod, &port, 379 BCMX_DEST_CONVERT_DEFAULT); 380 if (BCM_FAILURE(tmp_rv)) { 381 sal_free(member_array); 382 return tmp_rv; 383 } 384 385 bcm_trunk_member_t_init(&member_array[count]); 386 BCM_GPORT_MODPORT_SET(member_array[count].gport, mod, port); 387 } 388 389 BCMX_UNIT_ITER(bcm_unit, i) { 390 if (BCM_IS_FABRIC(bcm_unit)) { 391 continue; 392 } 393 tmp_rv = bcm_trunk_set(bcm_unit, tid, &badd, member_count, 394 member_array); 395 tmp_rv = BCMX_TRUNK_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv); 396 if (BCM_FAILURE(tmp_rv)) { 397 sal_free(member_array); 398 return tmp_rv; 399 } 400 } 401 402 sal_free(member_array); 403 return rv; 404 } 405 406 407 /* 408 * Function: 409 * bcmx_trunk_destroy 410 */ 411 412 int 413 bcmx_trunk_destroy(bcm_trunk_t tid) 414 { 415 int rv = BCM_E_UNAVAIL, tmp_rv; 416 int i, bcm_unit; 417 418 BCMX_TRUNK_INIT_CHECK; 419 420 BCMX_UNIT_ITER(bcm_unit, i) { 421 if (BCM_IS_FABRIC(bcm_unit)) { 422 continue; 423 } 424 tmp_rv = bcm_trunk_destroy(bcm_unit, tid); 425 BCM_IF_ERROR_RETURN 426 (BCMX_TRUNK_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 427 } 428 429 return rv; 430 } 431 432 433 /* 434 * Function: 435 * bcmx_trunk_get 436 */ 437 438 int 439 bcmx_trunk_get(bcm_trunk_t tid, bcmx_trunk_add_info_t *t_data) 440 { 441 bcm_trunk_info_t badd; 442 int rv, i, bcm_unit; 443 bcmx_lport_t lport; 444 int member_count, unused_count; 445 bcm_trunk_member_t *member_array = NULL; 446 bcm_module_t mod; 447 bcm_port_t port; 448 449 BCMX_TRUNK_INIT_CHECK; 450 451 BCMX_PARAM_NULL_CHECK(t_data); 452 453 BCMX_UNIT_ITER(bcm_unit, i) { 454 if (BCM_IS_FABRIC(bcm_unit)) { 455 continue; 456 } 457 458 rv = bcm_trunk_get(bcm_unit, tid, &badd, 0, NULL, &member_count); 459 if (!BCMX_TRUNK_GET_IS_VALID(bcm_unit, rv)) { 460 continue; 461 } 462 463 if (member_count > 0) { 464 member_array = sal_alloc(member_count * sizeof(bcm_trunk_member_t), 465 "trunk member array"); 466 if (NULL == member_array) { 467 return BCM_E_MEMORY; 468 } 469 } 470 rv = bcm_trunk_get(bcm_unit, tid, &badd, member_count, member_array, 471 &unused_count); 472 if (BCMX_TRUNK_GET_IS_VALID(bcm_unit, rv)) { 473 if (BCM_SUCCESS(rv)) { 474 sal_memset(t_data, 0, sizeof(bcmx_trunk_add_info_t)); 475 bcmx_lplist_init(&t_data->ports, member_count, 0); 476 t_data->psc = badd.psc; 477 t_data->ipmc_psc = badd.ipmc_psc; 478 t_data->dlf_port = BCMX_LPORT_INVALID; 479 t_data->mc_port = BCMX_LPORT_INVALID; 480 t_data->ipmc_port = BCMX_LPORT_INVALID; 481 482 for (i = 0; i < member_count; i++) { 483 /* Convert to lport */ 484 mod = BCM_GPORT_MODPORT_MODID_GET(member_array[i].gport); 485 port = BCM_GPORT_MODPORT_PORT_GET(member_array[i].gport); 486 rv = _bcmx_dest_from_modid_port(&lport, 487 mod, port, 488 BCMX_DEST_CONVERT_DEFAULT); 489 if (BCM_FAILURE(rv)) { 490 sal_free(member_array); 491 return rv; 492 } 493 bcmx_lplist_add(&t_data->ports, lport); 494 if (i == badd.dlf_index) { 495 t_data->dlf_port = lport; 496 } 497 if (i == badd.mc_index) { 498 t_data->mc_port = lport; 499 } 500 if (i == badd.ipmc_index) { 501 t_data->ipmc_port = lport; 502 } 503 } 504 } 505 506 if (NULL != member_array) { 507 sal_free(member_array); 508 } 509 return rv; 510 } 511 512 if (NULL != member_array) { 513 sal_free(member_array); 514 member_array = NULL; 515 } 516 } 517 518 return BCM_E_UNAVAIL; 519 } 520 521 522 523 /* 524 * Function: 525 * bcmx_trunk_mcast_join 526 */ 527 528 int 529 bcmx_trunk_mcast_join(bcm_trunk_t tid, 530 bcm_vlan_t vid, 531 bcm_mac_t mac) 532 { 533 int rv = BCM_E_UNAVAIL, tmp_rv; 534 int i, bcm_unit; 535 536 BCMX_TRUNK_INIT_CHECK; 537 538 BCMX_UNIT_ITER(bcm_unit, i) { 539 if (BCM_IS_FABRIC(bcm_unit)) { 540 continue; 541 } 542 tmp_rv = bcm_trunk_mcast_join(bcm_unit, tid, vid, mac); 543 BCM_IF_ERROR_RETURN(BCMX_TRUNK_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 544 } 545 546 return rv; 547 } 548 549 550 /* 551 * Function: 552 * bcmx_trunk_egress_set 553 */ 554 555 int 556 bcmx_trunk_egress_set(bcm_trunk_t tid, bcmx_lplist_t lplist) 557 { 558 int rv = BCM_E_UNAVAIL, tmp_rv; 559 bcm_pbmp_t pbm; 560 int bcm_unit, i; 561 562 BCMX_TRUNK_INIT_CHECK; 563 564 BCMX_UNIT_ITER(bcm_unit, i) { 565 if (BCM_IS_FABRIC(bcm_unit)) { 566 continue; 567 } 568 BCM_PBMP_CLEAR(pbm); 569 BCMX_LPLIST_TO_PBMP(lplist, bcm_unit, pbm); 570 tmp_rv = bcm_trunk_egress_set(bcm_unit, tid, pbm); 571 BCM_IF_ERROR_RETURN(BCMX_TRUNK_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 572 } 573 574 return rv; 575 } 576 577 578 /* 579 * Function: 580 * bcmx_trunk_egress_get 581 */ 582 583 int 584 bcmx_trunk_egress_get(bcm_trunk_t tid, bcmx_lplist_t *lplist) 585 { 586 int rv = BCM_E_UNAVAIL, tmp_rv; 587 bcm_pbmp_t pbm; 588 int bcm_unit, i; 589 590 BCMX_TRUNK_INIT_CHECK; 591 592 bcmx_lplist_clear(lplist); 593 BCMX_UNIT_ITER(bcm_unit, i) { 594 if (BCM_IS_FABRIC(bcm_unit)) { 595 continue; 596 } 597 598 tmp_rv = bcm_trunk_egress_get(bcm_unit, tid, &pbm); 599 if (BCMX_TRUNK_GET_IS_VALID(bcm_unit, tmp_rv)) { 600 rv = tmp_rv; 601 if (BCM_SUCCESS(tmp_rv)) { 602 BCMX_LPLIST_PBMP_ADD(lplist, bcm_unit, pbm); 603 } else { 604 break; 605 } 606 } 607 } 608 609 return rv; 610 } 611 612 /* 613 * Function: 614 * bcmx_trunk_find 615 */ 616 int 617 bcmx_trunk_find(bcmx_lport_t lport, bcm_trunk_t *tid) 618 { 619 int rv = BCM_E_UNAVAIL, bcm_unit, i; 620 bcm_module_t modid; 621 bcm_port_t modport; 622 623 BCMX_TRUNK_INIT_CHECK; 624 625 BCM_IF_ERROR_RETURN 626 (_bcmx_dest_to_modid_port(lport, &modid, &modport, 627 BCMX_DEST_CONVERT_DEFAULT)); 628 629 BCMX_UNIT_ITER(bcm_unit, i) { 630 rv = bcm_trunk_find(bcm_unit, 631 modid, 632 modport, 633 tid); 634 635 if (BCM_SUCCESS(rv)) { 636 break; 637 } 638 } 639 640 return rv; 641 } 642 643 /* 644 * Function: 645 * bcmx_trunk_failover_set 646 * Purpose: 647 * Assign the failover port list for a specific trunk port. 648 * Parameters: 649 * tid - Trunk id 650 * failport - Port in trunk for which to specify failover port list 651 * psc - Port selection criteria for failover port list 652 * flags - BCM_TRUNK_FLAG_FAILOVER_xxx 653 * count - Number of ports in failover port list 654 * fail_to_array - Failover port list 655 * Returns: 656 * BCM_E_XXX 657 * Notes: 658 */ 659 int 660 bcmx_trunk_failover_set(bcm_trunk_t tid, bcm_gport_t failport, 661 int psc, uint32 flags, int count, 662 bcm_gport_t *fail_to_array) 663 { 664 int bcm_unit; 665 bcm_port_t bcm_port; 666 667 BCMX_TRUNK_INIT_CHECK; 668 669 BCMX_PARAM_ARRAY_NULL_CHECK(count, fail_to_array); 670 671 BCM_IF_ERROR_RETURN(_bcmx_dest_to_unit_port(failport, &bcm_unit, &bcm_port, 672 BCMX_DEST_CONVERT_DEFAULT)); 673 674 return bcm_trunk_failover_set(bcm_unit, tid, failport, 675 psc, flags, count, fail_to_array); 676 } 677 678 /* 679 * Function: 680 * bcmx_trunk_failover_get 681 * Purpose: 682 * Retrieve the failover port list for a specific trunk port. 683 * Parameters: 684 * tid - Trunk id 685 * failport - Port in trunk for which to retrieve failover port list 686 * psc - (OUT) Port selection criteria for failover port list 687 * flags - (OUT) BCM_TRUNK_FLAG_FAILOVER_xxx 688 * array_size - Maximum number of ports in provided failover port list 689 * fail_to_array - (OUT) Failover port list 690 * array_count - (OUT) Number of ports in returned failover port list 691 * Returns: 692 * BCM_E_XXX 693 * Notes: 694 */ 695 int 696 bcmx_trunk_failover_get(bcm_trunk_t tid, bcm_gport_t failport, 697 int *psc, uint32 *flags, int array_size, 698 bcm_gport_t *fail_to_array, int *array_count) 699 { 700 int bcm_unit; 701 bcm_port_t bcm_port; 702 703 BCMX_TRUNK_INIT_CHECK; 704 705 BCMX_PARAM_NULL_CHECK(psc); 706 BCMX_PARAM_NULL_CHECK(flags); 707 BCMX_PARAM_ARRAY_NULL_CHECK(array_size, fail_to_array); 708 BCMX_PARAM_NULL_CHECK(array_count); 709 710 BCM_IF_ERROR_RETURN(_bcmx_dest_to_unit_port(failport, &bcm_unit, &bcm_port, 711 BCMX_DEST_CONVERT_DEFAULT)); 712 713 return bcm_trunk_failover_get(bcm_unit, tid, failport, 714 psc, flags, array_size, 715 fail_to_array, array_count); 716 } 717 718 /* 719 * Function: 720 * bcmx_trunk_member_add 721 * Purpose: 722 * Add a member to a trunk group. 723 * Parameters: 724 * tid - Trunk id 725 * member - Pointer to a trunk member structure. 726 * Returns: 727 * BCM_E_XXX 728 */ 729 int 730 bcmx_trunk_member_add(bcm_trunk_t tid, bcmx_trunk_member_t *member) 731 { 732 int bcm_unit; 733 bcm_port_t bcm_port; 734 735 BCMX_TRUNK_INIT_CHECK; 736 737 BCMX_PARAM_NULL_CHECK(member); 738 739 BCM_IF_ERROR_RETURN(_bcmx_dest_to_unit_port(member->gport, 740 &bcm_unit, &bcm_port, 741 BCMX_DEST_CONVERT_DEFAULT)); 742 743 return bcm_trunk_member_add(bcm_unit, tid, 744 BCMX_TRUNK_MEMBER_T_PTR_TO_BCM(member)); 745 } 746 747 /* 748 * Function: 749 * bcmx_trunk_member_delete 750 * Purpose: 751 * Remove a member from a trunk group. 752 * Parameters: 753 * tid - Trunk id 754 * member - Pointer to a trunk member structure. 755 * Returns: 756 * BCM_E_XXX 757 */ 758 int 759 bcmx_trunk_member_delete(bcm_trunk_t tid, bcmx_trunk_member_t *member) 760 { 761 int bcm_unit; 762 bcm_port_t bcm_port; 763 764 BCMX_TRUNK_INIT_CHECK; 765 766 BCMX_PARAM_NULL_CHECK(member); 767 768 BCM_IF_ERROR_RETURN(_bcmx_dest_to_unit_port(member->gport, 769 &bcm_unit, &bcm_port, 770 BCMX_DEST_CONVERT_DEFAULT)); 771 772 return bcm_trunk_member_delete(bcm_unit, tid, 773 BCMX_TRUNK_MEMBER_T_PTR_TO_BCM(member)); 774 } 775 776 /* 777 * Function: 778 * bcmx_trunk_member_delete_all 779 * Purpose: 780 * Remove all members of a trunk group. 781 * Parameters: 782 * tid - Trunk id 783 * Returns: 784 * BCM_E_XXX 785 */ 786 int 787 bcmx_trunk_member_delete_all(bcm_trunk_t tid) 788 { 789 int rv = BCM_E_UNAVAIL, tmp_rv; 790 int i, bcm_unit; 791 792 BCMX_TRUNK_INIT_CHECK; 793 794 BCMX_UNIT_ITER(bcm_unit, i) { 795 tmp_rv = bcm_trunk_member_delete_all(bcm_unit, tid); 796 BCM_IF_ERROR_RETURN 797 (BCMX_TRUNK_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 798 } 799 800 return rv; 801 } 802 803 /* 804 * Function: 805 * bcmx_trunk_member_set 806 * Purpose: 807 * Assign a set of members to a trunk group. 808 * Parameters: 809 * tid - Trunk id 810 * member_count - Number of trunk members in member_array. 811 * member_array - Array of trunk member structures. 812 * Returns: 813 * BCM_E_XXX 814 * Notes: 815 * Assumes all ports are in the same device (pick first one). 816 * BCM will report an error if a port is not local to designated device. 817 */ 818 int 819 bcmx_trunk_member_set(bcm_trunk_t tid, int member_count, 820 bcmx_trunk_member_t *member_array) 821 { 822 int bcm_unit; 823 bcm_port_t bcm_port; 824 825 BCMX_TRUNK_INIT_CHECK; 826 827 BCMX_PARAM_NULL_CHECK(member_array); 828 829 BCM_IF_ERROR_RETURN(_bcmx_dest_to_unit_port(member_array[0].gport, 830 &bcm_unit, &bcm_port, 831 BCMX_DEST_CONVERT_DEFAULT)); 832 /* bcm_trunk_member_set is deprecated. 833 * 834 * return bcm_trunk_member_set(bcm_unit, tid, member_count, 835 * BCMX_TRUNK_MEMBER_T_PTR_TO_BCM(member_array)); 836 */ 837 return BCM_E_UNAVAIL; 838 } 839 840 /* 841 * Function: 842 * bcmx_trunk_member_get 843 * Purpose: 844 * Retrieve members of a trunk group. If member_max is 0, 845 * the number of member ports in the given trunk group 846 * is returned in member_count. 847 * Parameters: 848 * tid - Trunk id 849 * member_max - Size of member_array 850 * member_array - (OUT) Array of trunk member structures. 851 * member_count - (OUT) Number of trunk members returned. 852 * Returns: 853 * BCM_E_XXX 854 */ 855 int 856 bcmx_trunk_member_get(bcm_trunk_t tid, int member_max, 857 bcmx_trunk_member_t *member_array, int *member_count) 858 { 859 BCMX_TRUNK_INIT_CHECK; 860 861 BCMX_PARAM_ARRAY_NULL_CHECK(member_max, member_array); 862 BCMX_PARAM_NULL_CHECK(member_count); 863 864 /* bcm_trunk_member_get is deprecated. 865 * 866 * BCMX_UNIT_ITER(bcm_unit, i) { 867 * rv = bcm_trunk_member_get(bcm_unit, tid, member_max, 868 * BCMX_TRUNK_MEMBER_T_PTR_TO_BCM(member_array), 869 * member_count); 870 * if (BCMX_TRUNK_GET_IS_VALID(bcm_unit, rv)) { 871 * return rv; 872 * } 873 * } 874 */ 875 876 return BCM_E_UNAVAIL; 877 } 878