multicast.c (21524B)
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/multicast.c 8 * Purpose: BCMX Multicast APIs 9 */ 10 11 #include <shared/alloc.h> 12 13 #include <bcm/types.h> 14 15 #include <bcmx/lport.h> 16 #include <bcmx/multicast.h> 17 18 #include "bcmx_int.h" 19 20 #define BCMX_MULTICAST_INIT_CHECK BCMX_READY_CHECK 21 22 #define BCMX_MULTICAST_ERROR_CHECK(_unit, _check, _rv) \ 23 BCMX_ERROR_CHECK(_unit, _check, _rv) 24 25 #define BCMX_MULTICAST_SET_ERROR_CHECK(_unit, _check, _rv) \ 26 BCMX_SET_ERROR_CHECK(_unit, _check, _rv) 27 28 #define BCMX_MULTICAST_DELETE_ERROR_CHECK(_unit, _check, _rv) \ 29 BCMX_DELETE_ERROR_CHECK(_unit, _check, _rv) 30 31 #define BCMX_MULTICAST_GET_IS_VALID(_unit, _rv) \ 32 BCMX_ERROR_IS_VALID(_unit, _rv) 33 34 35 /* 36 * Function: 37 * bcmx_multicast_init 38 */ 39 int 40 bcmx_multicast_init(void) 41 { 42 int rv = BCM_E_UNAVAIL, tmp_rv; 43 int i, bcm_unit; 44 45 BCMX_MULTICAST_INIT_CHECK; 46 47 BCMX_UNIT_ITER(bcm_unit, i) { 48 tmp_rv = bcm_multicast_init(bcm_unit); 49 BCM_IF_ERROR_RETURN(BCMX_MULTICAST_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 50 } 51 52 return rv; 53 } 54 55 /* 56 * Function: 57 * bcmx_multicast_detach 58 */ 59 int 60 bcmx_multicast_detach(void) 61 { 62 int rv = BCM_E_UNAVAIL, tmp_rv; 63 int i, bcm_unit; 64 65 BCMX_MULTICAST_INIT_CHECK; 66 67 BCMX_UNIT_ITER(bcm_unit, i) { 68 tmp_rv = bcm_multicast_detach(bcm_unit); 69 BCM_IF_ERROR_RETURN(BCMX_MULTICAST_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 70 } 71 72 return rv; 73 } 74 75 /* 76 * Function: 77 * bcmx_multicast_create 78 * Notes: 79 * If group ID is not specified, the ID returned 80 * from the first successful 'create' is used for the remaining 81 * units. 82 */ 83 int 84 bcmx_multicast_create(uint32 flags, bcm_multicast_t *group) 85 { 86 int rv = BCM_E_UNAVAIL, tmp_rv; 87 int i, bcm_unit; 88 89 BCMX_MULTICAST_INIT_CHECK; 90 91 BCMX_PARAM_NULL_CHECK(group); 92 93 BCMX_UNIT_ITER(bcm_unit, i) { 94 95 tmp_rv = bcm_multicast_create(bcm_unit, flags, group); 96 BCM_IF_ERROR_RETURN 97 (BCMX_MULTICAST_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 98 99 /* 100 * Use the ID from first successful 'create' if policer ID 101 * is not specified. 102 */ 103 if (!(flags & BCM_MULTICAST_WITH_ID)) { 104 if (BCM_SUCCESS(tmp_rv)) { 105 flags |= BCM_MULTICAST_WITH_ID; 106 } 107 } 108 } 109 110 return rv; 111 } 112 113 /* 114 * Function: 115 * bcmx_multicast_destroy 116 */ 117 int 118 bcmx_multicast_destroy(bcm_multicast_t group) 119 { 120 int rv = BCM_E_UNAVAIL, tmp_rv; 121 int i, bcm_unit; 122 123 BCMX_MULTICAST_INIT_CHECK; 124 125 BCMX_UNIT_ITER(bcm_unit, i) { 126 tmp_rv = bcm_multicast_destroy(bcm_unit, group); 127 BCM_IF_ERROR_RETURN 128 (BCMX_MULTICAST_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 129 } 130 131 return rv; 132 } 133 134 /* 135 * Function: 136 * bcmx_multicast_group_get 137 * Purpose: 138 * Retrieve the flags associated with a multicast group. 139 * Parameters: 140 * group - (IN) Multicast group ID 141 * flags - (OUT) BCM_MULTICAST_* 142 * Returns: 143 * BCM_E_xxx 144 */ 145 int 146 bcmx_multicast_group_get(bcm_multicast_t group, uint32 *flags) 147 { 148 int rv; 149 int i, bcm_unit; 150 151 BCMX_MULTICAST_INIT_CHECK; 152 153 BCMX_PARAM_NULL_CHECK(flags); 154 155 BCMX_UNIT_ITER(bcm_unit, i) { 156 rv = bcm_multicast_group_get(bcm_unit, group, flags); 157 if (BCMX_MULTICAST_GET_IS_VALID(bcm_unit, rv)) { 158 return rv; 159 } 160 } 161 162 return BCM_E_UNAVAIL; 163 } 164 165 /* 166 * Function: 167 * bcmx_multicast_l3_encap_get 168 * Notes: 169 * Gport 'port' is a physical local port. 170 */ 171 int 172 bcmx_multicast_l3_encap_get(bcm_multicast_t group, 173 bcm_gport_t port, bcm_if_t intf, 174 bcm_if_t *encap_id) 175 { 176 int bcm_unit; 177 bcm_port_t bcm_port; 178 179 BCMX_MULTICAST_INIT_CHECK; 180 181 BCMX_PARAM_NULL_CHECK(encap_id); 182 183 BCM_IF_ERROR_RETURN 184 (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port, 185 BCMX_DEST_CONVERT_DEFAULT)); 186 187 return bcm_multicast_l3_encap_get(bcm_unit, group, port, intf, encap_id); 188 } 189 190 /* 191 * Function: 192 * bcmx_multicast_l2_encap_get 193 * Notes: 194 * Gport 'port' is a physical local port. 195 */ 196 int 197 bcmx_multicast_l2_encap_get(bcm_multicast_t group, 198 bcm_gport_t port, bcm_vlan_t vlan, 199 bcm_if_t *encap_id) 200 { 201 int bcm_unit; 202 bcm_port_t bcm_port; 203 204 BCMX_MULTICAST_INIT_CHECK; 205 206 BCMX_PARAM_NULL_CHECK(encap_id); 207 208 BCM_IF_ERROR_RETURN 209 (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port, 210 BCMX_DEST_CONVERT_DEFAULT)); 211 212 return bcm_multicast_l2_encap_get(bcm_unit, group, port, vlan, encap_id); 213 } 214 215 /* 216 * Function: 217 * bcmx_multicast_vpls_encap_get 218 * Notes: 219 * Gport 'port' is a physical local port. 220 */ 221 int 222 bcmx_multicast_vpls_encap_get(bcm_multicast_t group, 223 bcm_gport_t port, bcm_gport_t mpls_port_id, 224 bcm_if_t *encap_id) 225 { 226 int bcm_unit; 227 bcm_port_t bcm_port; 228 229 BCMX_MULTICAST_INIT_CHECK; 230 231 BCMX_PARAM_NULL_CHECK(encap_id); 232 233 BCM_IF_ERROR_RETURN 234 (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port, 235 BCMX_DEST_CONVERT_DEFAULT)); 236 237 return bcm_multicast_vpls_encap_get(bcm_unit, group, 238 port, mpls_port_id, encap_id); 239 } 240 241 /* 242 * Function: 243 * bcmx_multicast_trill_encap_get 244 * Notes: 245 * Gport 'port' is a physical local port. 246 */ 247 int 248 bcmx_multicast_trill_encap_get(bcm_multicast_t group, 249 bcm_gport_t port, bcm_if_t intf, 250 bcm_if_t *encap_id) 251 { 252 int bcm_unit; 253 bcm_port_t bcm_port; 254 255 BCMX_MULTICAST_INIT_CHECK; 256 257 BCMX_PARAM_NULL_CHECK(encap_id); 258 259 BCM_IF_ERROR_RETURN 260 (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port, 261 BCMX_DEST_CONVERT_DEFAULT)); 262 263 return bcm_multicast_trill_encap_get(bcm_unit, group, 264 port, intf, encap_id); 265 } 266 267 /* 268 * Function: 269 * bcmx_multicast_subport_encap_get 270 * Notes: 271 * Gport 'port' is a physical local port. 272 */ 273 int 274 bcmx_multicast_subport_encap_get(bcm_multicast_t group, 275 bcm_gport_t port, bcm_gport_t subport, 276 bcm_if_t *encap_id) 277 { 278 int bcm_unit; 279 bcm_port_t bcm_port; 280 281 BCMX_MULTICAST_INIT_CHECK; 282 283 BCMX_PARAM_NULL_CHECK(encap_id); 284 285 BCM_IF_ERROR_RETURN 286 (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port, 287 BCMX_DEST_CONVERT_DEFAULT)); 288 289 return bcm_multicast_subport_encap_get(bcm_unit, group, 290 port, subport, encap_id); 291 } 292 293 /* 294 * Function: 295 * bcmx_multicast_mim_encap_get 296 * Notes: 297 * Gport 'port' can be a physical local port or a virtual port. 298 * If 'port' is a physical port, apply to device where port resides. 299 * If 'port' is a virtual port, apply to all devices. 300 */ 301 int 302 bcmx_multicast_mim_encap_get(bcm_multicast_t group, 303 bcm_gport_t port, bcm_gport_t mim_port_id, 304 bcm_if_t *encap_id) 305 { 306 int rv; 307 int i; 308 int bcm_unit; 309 bcm_port_t bcm_port; 310 311 BCMX_MULTICAST_INIT_CHECK; 312 313 BCMX_PARAM_NULL_CHECK(encap_id); 314 315 BCMX_LPORT_CHECK(port); 316 317 /* Physical port */ 318 if (BCMX_LPORT_IS_PHYSICAL(port)) { 319 BCM_IF_ERROR_RETURN 320 (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port, 321 BCMX_DEST_CONVERT_DEFAULT)); 322 return bcm_multicast_mim_encap_get(bcm_unit, group, 323 port, mim_port_id, encap_id); 324 } 325 326 /* Virtual port */ 327 BCMX_UNIT_ITER(bcm_unit, i) { 328 rv = bcm_multicast_mim_encap_get(bcm_unit, group, 329 port, mim_port_id, encap_id); 330 if (BCMX_MULTICAST_GET_IS_VALID(bcm_unit, rv)) { 331 return rv; 332 } 333 } 334 335 return BCM_E_UNAVAIL; 336 } 337 338 /* 339 * Function: 340 * bcmx_multicast_wlan_encap_get 341 * Notes: 342 * Gport 'port' can be a physical local port or a virtual port. 343 * If 'port' is a physical port, apply to device where port resides. 344 * If 'port' is a virtual port, apply to all devices. 345 */ 346 int 347 bcmx_multicast_wlan_encap_get(bcm_multicast_t group, 348 bcm_gport_t port, bcm_gport_t wlan_port_id, 349 bcm_if_t *encap_id) 350 { 351 int rv; 352 int i, bcm_unit; 353 bcm_port_t bcm_port; 354 355 BCMX_MULTICAST_INIT_CHECK; 356 357 BCMX_PARAM_NULL_CHECK(encap_id); 358 359 BCMX_LPORT_CHECK(port); 360 361 /* Physical port */ 362 if (BCMX_LPORT_IS_PHYSICAL(port)) { 363 BCM_IF_ERROR_RETURN 364 (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port, 365 BCMX_DEST_CONVERT_DEFAULT)); 366 return bcm_multicast_wlan_encap_get(bcm_unit, group, 367 port, wlan_port_id, encap_id); 368 } 369 370 /* Virtual port */ 371 BCMX_UNIT_ITER(bcm_unit, i) { 372 rv = bcm_multicast_wlan_encap_get(bcm_unit, group, 373 port, wlan_port_id, encap_id); 374 if (BCMX_MULTICAST_GET_IS_VALID(bcm_unit, rv)) { 375 return rv; 376 } 377 } 378 379 return BCM_E_UNAVAIL; 380 } 381 382 /* 383 * Function: 384 * bcmx_multicast_vlan_encap_get 385 * Notes: 386 * Gport 'port' can be a physical local port or a virtual port. 387 * If 'port' is a physical port, apply to device where port resides. 388 * If 'port' is a virtual port, apply to all devices. 389 */ 390 int 391 bcmx_multicast_vlan_encap_get(bcm_multicast_t group, 392 bcm_gport_t port, bcm_gport_t vlan_port_id, 393 bcm_if_t *encap_id) 394 { 395 int rv; 396 int i, bcm_unit; 397 bcm_port_t bcm_port; 398 399 BCMX_MULTICAST_INIT_CHECK; 400 401 BCMX_PARAM_NULL_CHECK(encap_id); 402 403 BCMX_LPORT_CHECK(port); 404 405 /* Physical port */ 406 if (BCMX_LPORT_IS_PHYSICAL(port)) { 407 BCM_IF_ERROR_RETURN 408 (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port, 409 BCMX_DEST_CONVERT_DEFAULT)); 410 return bcm_multicast_vlan_encap_get(bcm_unit, group, 411 port, vlan_port_id, encap_id); 412 } 413 414 /* Virtual port */ 415 BCMX_UNIT_ITER(bcm_unit, i) { 416 rv = bcm_multicast_vlan_encap_get(bcm_unit, group, 417 port, vlan_port_id, encap_id); 418 if (BCMX_MULTICAST_GET_IS_VALID(bcm_unit, rv)) { 419 return rv; 420 } 421 } 422 423 return BCM_E_UNAVAIL; 424 } 425 426 /* 427 * Function: 428 * bcmx_multicast_niv_encap_get 429 * Notes: 430 * Gport 'port' can be a physical local port or a virtual port. 431 * If 'port' is a physical port, apply to device where port resides. 432 * If 'port' is a virtual port, apply to all devices. 433 */ 434 int 435 bcmx_multicast_niv_encap_get(bcm_multicast_t group, bcm_gport_t port, 436 bcm_gport_t niv_port_id, bcm_if_t *encap_id) 437 { 438 int rv; 439 int i, bcm_unit; 440 bcm_port_t bcm_port; 441 442 BCMX_MULTICAST_INIT_CHECK; 443 444 BCMX_PARAM_NULL_CHECK(encap_id); 445 446 BCMX_LPORT_CHECK(port); 447 448 /* Physical port */ 449 if (BCMX_LPORT_IS_PHYSICAL(port)) { 450 BCM_IF_ERROR_RETURN 451 (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port, 452 BCMX_DEST_CONVERT_DEFAULT)); 453 return bcm_multicast_niv_encap_get(bcm_unit, group, 454 port, niv_port_id, encap_id); 455 } 456 457 /* Virtual port */ 458 BCMX_UNIT_ITER(bcm_unit, i) { 459 rv = bcm_multicast_niv_encap_get(bcm_unit, group, 460 port, niv_port_id, encap_id); 461 if (BCMX_MULTICAST_GET_IS_VALID(bcm_unit, rv)) { 462 return rv; 463 } 464 } 465 466 return BCM_E_UNAVAIL; 467 } 468 469 470 /* 471 * Function: 472 * bcmx_multicast_egress_add 473 * Notes: 474 * Gport 'port' can be a physical local port or a virtual port. 475 * If 'port' is a physical port, apply to device where port resides. 476 * If 'port' is a virtual port, apply to all devices. 477 */ 478 int 479 bcmx_multicast_egress_add(bcm_multicast_t group, 480 bcm_gport_t port, bcm_if_t encap_id) 481 { 482 int rv = BCM_E_UNAVAIL, tmp_rv; 483 int i; 484 int bcm_unit; 485 bcm_port_t bcm_port; 486 487 BCMX_MULTICAST_INIT_CHECK; 488 489 BCMX_LPORT_CHECK(port); 490 491 /* Physical port */ 492 if (BCMX_LPORT_IS_PHYSICAL(port)) { 493 BCM_IF_ERROR_RETURN 494 (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port, 495 BCMX_DEST_CONVERT_DEFAULT)); 496 return bcm_multicast_egress_add(bcm_unit, group, port, encap_id); 497 } 498 499 /* Virtual port */ 500 BCMX_UNIT_ITER(bcm_unit, i) { 501 tmp_rv = bcm_multicast_egress_add(bcm_unit, group, port, encap_id); 502 BCM_IF_ERROR_RETURN 503 (BCMX_MULTICAST_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 504 } 505 506 return rv; 507 } 508 509 /* 510 * Function: 511 * bcmx_multicast_egress_delete 512 * Notes: 513 * Gport 'port' can be a physical local port or a virtual port. 514 * If 'port' is a physical port, apply to device where port resides. 515 * If 'port' is a virtual port, apply to all devices. 516 */ 517 int 518 bcmx_multicast_egress_delete(bcm_multicast_t group, 519 bcm_gport_t port, bcm_if_t encap_id) 520 { 521 int rv = BCM_E_UNAVAIL, tmp_rv; 522 int i; 523 int bcm_unit; 524 bcm_port_t bcm_port; 525 526 BCMX_MULTICAST_INIT_CHECK; 527 528 BCMX_LPORT_CHECK(port); 529 530 /* Physical port */ 531 if (BCMX_LPORT_IS_PHYSICAL(port)) { 532 BCM_IF_ERROR_RETURN 533 (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port, 534 BCMX_DEST_CONVERT_DEFAULT)); 535 536 return bcm_multicast_egress_delete(bcm_unit, group, port, encap_id); 537 } 538 539 /* Virtual port */ 540 BCMX_UNIT_ITER(bcm_unit, i) { 541 tmp_rv = bcm_multicast_egress_delete(bcm_unit, group, port, encap_id); 542 BCM_IF_ERROR_RETURN 543 (BCMX_MULTICAST_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 544 } 545 546 return rv; 547 } 548 549 /* 550 * Function: 551 * bcmx_multicast_egress_delete_all 552 */ 553 int 554 bcmx_multicast_egress_delete_all(bcm_multicast_t group) 555 { 556 int rv = BCM_E_UNAVAIL, tmp_rv; 557 int i, bcm_unit; 558 559 BCMX_MULTICAST_INIT_CHECK; 560 561 BCMX_UNIT_ITER(bcm_unit, i) { 562 tmp_rv = bcm_multicast_egress_delete_all(bcm_unit, group); 563 BCM_IF_ERROR_RETURN 564 (BCMX_MULTICAST_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 565 } 566 567 return rv; 568 } 569 570 /* 571 * Function: 572 * bcmx_multicast_egress_set 573 * Notes: 574 * Each gport 'port' in array is a physical local port. 575 */ 576 int 577 bcmx_multicast_egress_set(bcm_multicast_t group, int port_count, 578 bcm_gport_t *port_array, bcm_if_t *encap_id_array) 579 { 580 int rv = BCM_E_UNAVAIL; 581 int tmp_rv; 582 int i, bcm_unit; 583 int j, unit; 584 bcm_port_t unit_port; 585 int unit_port_count; 586 bcm_gport_t *unit_port_array; 587 bcm_if_t *unit_encap_id_array; 588 589 BCMX_MULTICAST_INIT_CHECK; 590 591 BCMX_PARAM_ARRAY_NULL_CHECK(port_count, port_array); 592 BCMX_PARAM_ARRAY_NULL_CHECK(port_count, encap_id_array); 593 594 if ((unit_port_array = sal_alloc(port_count * sizeof(*port_array), 595 "bcmx_multicast_egress_set")) == NULL) { 596 return BCM_E_MEMORY; 597 } 598 599 if ((unit_encap_id_array = sal_alloc(port_count * sizeof(*encap_id_array), 600 "bcmx_multicast_egress_set")) == NULL) { 601 sal_free(unit_port_array); 602 return BCM_E_MEMORY; 603 } 604 605 /* Need to gather all ports in a unit, then do a 'set' */ 606 BCMX_UNIT_ITER(bcm_unit, i) { 607 unit_port_count = 0; 608 609 /* Get all ports that belong to a unit */ 610 for (j = 0; j < port_count; j++) { 611 if (BCM_FAILURE 612 (_bcmx_dest_to_unit_port(port_array[j], 613 &unit, &unit_port, 614 BCMX_DEST_CONVERT_DEFAULT))) { 615 continue; 616 } 617 if (unit != bcm_unit) { 618 continue; 619 } 620 621 unit_port_array[unit_port_count] = port_array[j]; 622 unit_encap_id_array[unit_port_count] = encap_id_array[j]; 623 unit_port_count++; 624 } 625 626 if (unit_port_count == 0) { 627 continue; 628 } 629 630 tmp_rv = bcm_multicast_egress_set(bcm_unit, group, unit_port_count, 631 unit_port_array, unit_encap_id_array); 632 633 if (BCM_FAILURE 634 (BCMX_MULTICAST_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv))) { 635 break; 636 } 637 } 638 639 sal_free(unit_port_array); 640 sal_free(unit_encap_id_array); 641 642 return rv; 643 } 644 645 /* 646 * Function: 647 * bcmx_multicast_egress_get 648 * Notes: 649 * Each gport 'port' is a physical local port. 650 */ 651 int 652 bcmx_multicast_egress_get(bcm_multicast_t group, int port_max, 653 bcm_gport_t *port_array, bcm_if_t *encap_id_array, 654 int *port_count) 655 { 656 int rv = BCM_E_UNAVAIL; 657 int tmp_rv; 658 int i, bcm_unit; 659 int port_max_left; 660 int unit_port_count; 661 bcm_gport_t *unit_port_array; 662 bcm_if_t *unit_encap_id_array; 663 664 BCMX_MULTICAST_INIT_CHECK; 665 666 BCMX_PARAM_ARRAY_NULL_CHECK(port_max, port_array); 667 BCMX_PARAM_ARRAY_NULL_CHECK(port_max, encap_id_array); 668 BCMX_PARAM_NULL_CHECK(port_count); 669 670 *port_count = 0; 671 port_max_left = port_max; 672 673 /* Need to gather egress ports from all units */ 674 BCMX_UNIT_ITER(bcm_unit, i) { 675 676 if (port_max_left <= 0) { 677 break; 678 } 679 680 unit_port_count = 0; 681 unit_port_array = &port_array[*port_count]; 682 unit_encap_id_array = &encap_id_array[*port_count]; 683 684 tmp_rv = bcm_multicast_egress_get(bcm_unit, group, port_max_left, 685 unit_port_array, unit_encap_id_array, 686 &unit_port_count); 687 688 if (BCMX_MULTICAST_GET_IS_VALID(bcm_unit, tmp_rv)) { 689 /* 690 * Ignore BCM_E_NOT_FOUND since objects are physical ports 691 * and are added for specific unit. Exit on other failure. 692 */ 693 if (tmp_rv == BCM_E_NOT_FOUND) { 694 if (rv == BCM_E_UNAVAIL) { 695 rv = tmp_rv; 696 } 697 continue; 698 } 699 rv = tmp_rv; 700 if (BCM_FAILURE(tmp_rv)) { 701 break; 702 } 703 *port_count += unit_port_count; 704 port_max_left -= unit_port_count; 705 } 706 } 707 708 return rv; 709 } 710 711 /* 712 * Function: 713 * bcmx_multicast_repl_set 714 * Notes: 715 * Each gport 'port' is a physical local port. 716 */ 717 int 718 bcmx_multicast_repl_set(int index, 719 bcmx_lport_t port, 720 bcm_vlan_vector_t vlan_vec) 721 { 722 int bcm_unit; 723 bcm_port_t bcm_port; 724 725 BCMX_MULTICAST_INIT_CHECK; 726 727 BCM_IF_ERROR_RETURN(_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port, 728 BCMX_DEST_CONVERT_DEFAULT)); 729 730 return bcm_multicast_repl_set(bcm_unit, index, bcm_port, vlan_vec); 731 } 732 733 /* 734 * Function: 735 * bcmx_multicast_repl_get 736 * Notes: 737 * Each gport 'port' is a physical local port. 738 */ 739 int 740 bcmx_multicast_repl_get(int index, 741 bcmx_lport_t port, 742 bcm_vlan_vector_t vlan_vec) 743 { 744 int bcm_unit; 745 bcm_port_t bcm_port; 746 747 BCMX_MULTICAST_INIT_CHECK; 748 749 BCM_IF_ERROR_RETURN(_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port, 750 BCMX_DEST_CONVERT_DEFAULT)); 751 752 return bcm_multicast_repl_get(bcm_unit, index, bcm_port, vlan_vec); 753 } 754 755 /* 756 * Function: 757 * bcmx_multicast_control_set 758 * Purpose: 759 * Set multicast group control. 760 * Parameters: 761 * group - (IN) Multicast group ID. 762 * type - (IN) Multicast group control type. 763 * arg - (IN) Multicast group control argument. 764 * Returns: 765 * BCM_E_XXX 766 */ 767 int 768 bcmx_multicast_control_set(bcm_multicast_t group, 769 bcm_multicast_control_t type, int arg) 770 { 771 int rv = BCM_E_UNAVAIL, tmp_rv; 772 int i, bcm_unit; 773 774 BCMX_MULTICAST_INIT_CHECK; 775 776 BCMX_UNIT_ITER(bcm_unit, i) { 777 tmp_rv = bcm_multicast_control_set(bcm_unit, group, type, arg); 778 BCM_IF_ERROR_RETURN 779 (BCMX_MULTICAST_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 780 } 781 782 return rv; 783 } 784 785 /* 786 * Function: 787 * bcmx_multicast_control_get 788 * Purpose: 789 * Get multicast group control. 790 * Parameters: 791 * group - (IN) Multicast group ID. 792 * type - (IN) Multicast group control type. 793 * arg - (OUT) Multicast group control argument. 794 * Returns: 795 * BCM_E_XXX 796 */ 797 int 798 bcmx_multicast_control_get(bcm_multicast_t group, 799 bcm_multicast_control_t type, int *arg) 800 { 801 int rv; 802 int i, bcm_unit; 803 804 BCMX_MULTICAST_INIT_CHECK; 805 806 BCMX_PARAM_NULL_CHECK(arg); 807 808 BCMX_UNIT_ITER(bcm_unit, i) { 809 rv = bcm_multicast_control_get(bcm_unit, group, type, arg); 810 if (BCMX_MULTICAST_GET_IS_VALID(bcm_unit, rv)) { 811 return rv; 812 } 813 } 814 815 return BCM_E_UNAVAIL; 816 }