openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

vlan.c (101779B)


      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:        src/bcmx/vlan.c
      8  * Purpose:     BCMX Virtual LAN (VLAN) APIs
      9  */
     10 
     11 #include <shared/alloc.h>
     12 
     13 #include <bcm/types.h>
     14 
     15 #include <bcmx/vlan.h>
     16 #include <bcmx/lport.h>
     17 #include <bcmx/bcmx.h>
     18 #include <bcmx/lplist.h>
     19 
     20 #include "bcmx_int.h"
     21 
     22 #define BCMX_VLAN_INIT_CHECK    BCMX_READY_CHECK
     23 
     24 #define BCMX_VLAN_SET_ERROR_CHECK(_unit, _check, _rv)    \
     25     BCMX_SET_ERROR_CHECK(_unit, _check, _rv)
     26 
     27 #define BCMX_VLAN_DELETE_ERROR_CHECK(_unit, _check, _rv)    \
     28     BCMX_DELETE_ERROR_CHECK(_unit, _check, _rv)
     29 
     30 #define BCMX_VLAN_GET_IS_VALID(_unit, _rv)    \
     31     BCMX_ERROR_IS_VALID(_unit, _rv)
     32 
     33 #define BCMX_VLAN_ERROR_IS_VALID(_unit, _rv)    \
     34     BCMX_ERROR_IS_VALID(_unit, _rv)
     35 
     36 
     37 #define BCMX_VLAN_PORT_T_PTR_TO_BCM(_vlan_port)   \
     38     ((bcm_vlan_port_t *)(_vlan_port))
     39 
     40 
     41 /*
     42  * Function:
     43  *     bcmx_vlan_port_t_init
     44  */
     45 void
     46 bcmx_vlan_port_t_init(bcmx_vlan_port_t *vlan_port)
     47 {
     48     if (vlan_port != NULL) {
     49         bcm_vlan_port_t_init
     50             (BCMX_VLAN_PORT_T_PTR_TO_BCM(vlan_port));
     51     }
     52 }
     53 
     54 
     55 int 
     56 bcmx_vlan_create(bcm_vlan_t vid)
     57 {
     58     int rv = BCM_E_UNAVAIL, tmp_rv;
     59     int i, bcm_unit;
     60 
     61     BCMX_VLAN_INIT_CHECK;
     62 
     63     BCMX_UNIT_ITER(bcm_unit, i) {
     64         tmp_rv = bcm_vlan_create(bcm_unit, vid);
     65         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
     66     }
     67 
     68     return rv;
     69 }
     70 
     71 
     72 int 
     73 bcmx_vlan_destroy(bcm_vlan_t vid)
     74 {
     75     int rv = BCM_E_UNAVAIL, tmp_rv;
     76     int i, bcm_unit;
     77 
     78     BCMX_VLAN_INIT_CHECK;
     79 
     80     BCMX_UNIT_ITER(bcm_unit, i) {
     81         tmp_rv = bcm_vlan_destroy(bcm_unit, vid);
     82         BCM_IF_ERROR_RETURN
     83             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
     84     }
     85 
     86     return rv;
     87 }
     88 
     89 
     90 int
     91 bcmx_vlan_destroy_all(void)
     92 {
     93     int rv = BCM_E_UNAVAIL, tmp_rv;
     94     int i, bcm_unit;
     95 
     96     BCMX_VLAN_INIT_CHECK;
     97 
     98     BCMX_UNIT_ITER(bcm_unit, i) {
     99         tmp_rv = bcm_vlan_destroy_all(bcm_unit);
    100         BCM_IF_ERROR_RETURN
    101             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    102     }
    103 
    104     return rv;
    105 }
    106 
    107 
    108 /*
    109  * Function:
    110  *      bcmx_vlan_port_add
    111  * Notes:
    112  *      Currently assumes stack ports are added by BCM on vlan create.
    113  */
    114 
    115 int
    116 bcmx_vlan_port_add(bcm_vlan_t vid, 
    117                    bcmx_lplist_t lplist,
    118                    bcmx_lplist_t ut_lplist)
    119 {
    120     int rv = BCM_E_UNAVAIL, tmp_rv;
    121     bcm_pbmp_t pbmp, upbmp;
    122     int bcm_unit;
    123     int i;
    124 
    125     BCMX_VLAN_INIT_CHECK;
    126 
    127     BCMX_UNIT_ITER(bcm_unit, i) {
    128         BCMX_LPLIST_TO_PBMP(lplist, bcm_unit, pbmp);
    129         BCMX_LPLIST_TO_PBMP(ut_lplist, bcm_unit, upbmp);
    130         if (BCM_PBMP_NOT_NULL(pbmp)) {
    131             tmp_rv = bcm_vlan_port_add(bcm_unit, vid, pbmp, upbmp);
    132             BCM_IF_ERROR_RETURN
    133                 (BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    134         }
    135     }
    136 
    137     return rv;
    138 }
    139 
    140 
    141 int
    142 bcmx_vlan_port_remove(bcm_vlan_t vid, bcmx_lplist_t lplist)
    143 {
    144     int rv = BCM_E_UNAVAIL, tmp_rv;
    145     bcm_pbmp_t pbmp;
    146     int bcm_unit;
    147     int i;
    148 
    149     BCMX_VLAN_INIT_CHECK;
    150 
    151     BCMX_UNIT_ITER(bcm_unit, i) {
    152         BCMX_LPLIST_TO_PBMP(lplist, bcm_unit, pbmp);
    153         if (BCM_PBMP_NOT_NULL(pbmp)) {
    154             tmp_rv = bcm_vlan_port_remove(bcm_unit, vid, pbmp);
    155             BCM_IF_ERROR_RETURN
    156                 (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    157         }
    158     }
    159 
    160     return rv;
    161 }
    162 
    163 
    164 int
    165 bcmx_vlan_port_get(bcm_vlan_t vid,
    166                    bcmx_lplist_t *lplist,
    167                    bcmx_lplist_t *ut_lplist)
    168 {
    169     int rv = BCM_E_UNAVAIL, tmp_rv;
    170     bcm_pbmp_t pbmp, upbmp;
    171     int bcm_unit;
    172     int i;
    173 
    174     BCMX_VLAN_INIT_CHECK;
    175 
    176     BCMX_PARAM_NULL_CHECK(lplist);
    177     BCMX_PARAM_NULL_CHECK(ut_lplist);
    178     
    179     bcmx_lplist_clear(lplist);
    180     bcmx_lplist_clear(ut_lplist);
    181     BCMX_UNIT_ITER(bcm_unit, i) {
    182         tmp_rv = bcm_vlan_port_get(bcm_unit, vid, &pbmp, &upbmp);
    183         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, tmp_rv)) {
    184             rv = tmp_rv;
    185             if (BCM_FAILURE(tmp_rv)) {
    186                 break;
    187             }
    188 
    189             rv = BCMX_LPLIST_PBMP_ADD(lplist, bcm_unit, pbmp);
    190             rv = BCMX_LPLIST_PBMP_ADD(ut_lplist, bcm_unit, upbmp);
    191         }
    192     }
    193 
    194     return rv;
    195 }
    196 
    197 
    198 int
    199 bcmx_vlan_default_get(bcm_vlan_t *vid_ptr)
    200 {
    201     int rv;
    202     int i, bcm_unit;
    203 
    204     BCMX_VLAN_INIT_CHECK;
    205 
    206     BCMX_PARAM_NULL_CHECK(vid_ptr);
    207 
    208     BCMX_UNIT_ITER(bcm_unit, i) {
    209         rv = bcm_vlan_default_get(bcm_unit, vid_ptr);
    210         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, rv)) {
    211             return rv;
    212         }
    213     }
    214 
    215     return BCM_E_UNAVAIL;
    216 }
    217 
    218 
    219 int
    220 bcmx_vlan_default_set(bcm_vlan_t vid)
    221 {
    222     int rv = BCM_E_UNAVAIL, tmp_rv;
    223     int i, bcm_unit;
    224 
    225     BCMX_VLAN_INIT_CHECK;
    226 
    227     BCMX_UNIT_ITER(bcm_unit, i) {
    228         tmp_rv = bcm_vlan_default_set(bcm_unit, vid);
    229         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    230     }
    231 
    232     return rv;
    233 }
    234 
    235 
    236 int
    237 bcmx_vlan_stg_get(bcm_vlan_t vid, bcm_stg_t *stg_ptr)
    238 {
    239     int rv;
    240     int i, bcm_unit;
    241 
    242     BCMX_VLAN_INIT_CHECK;
    243 
    244     BCMX_PARAM_NULL_CHECK(stg_ptr);
    245 
    246     BCMX_UNIT_ITER(bcm_unit, i) {
    247         rv = bcm_vlan_stg_get(bcm_unit, vid, stg_ptr);
    248         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, rv)) {
    249             return rv;
    250         }
    251     }
    252 
    253     return BCM_E_UNAVAIL;
    254 }
    255 
    256 
    257 int
    258 bcmx_vlan_stg_set(bcm_vlan_t vid, bcm_stg_t stg)
    259 {
    260     int rv = BCM_E_UNAVAIL, tmp_rv;
    261     int i, bcm_unit;
    262 
    263     BCMX_VLAN_INIT_CHECK;
    264 
    265     BCMX_UNIT_ITER(bcm_unit, i) {
    266         tmp_rv = bcm_vlan_stg_set(bcm_unit, vid, stg);
    267         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    268     }
    269 
    270     return rv;
    271 }
    272 
    273 
    274 int
    275 bcmx_vlan_port_default_action_set(bcmx_lport_t port,
    276                                   bcm_vlan_action_set_t *action)
    277 {
    278     int         bcm_unit;
    279     bcm_port_t  bcm_port;
    280 
    281     BCMX_VLAN_INIT_CHECK;
    282 
    283     BCMX_PARAM_NULL_CHECK(action);
    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_vlan_port_default_action_set(bcm_unit, bcm_port,
    290                                             action);
    291 }
    292 
    293 int
    294 bcmx_vlan_port_default_action_get(bcmx_lport_t port,
    295                                   bcm_vlan_action_set_t *action)
    296 {
    297     int         bcm_unit;
    298     bcm_port_t  bcm_port;
    299 
    300     BCMX_VLAN_INIT_CHECK;
    301 
    302     BCMX_PARAM_NULL_CHECK(action);
    303 
    304     BCM_IF_ERROR_RETURN
    305         (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
    306                                  BCMX_DEST_CONVERT_DEFAULT));
    307 
    308     return bcm_vlan_port_default_action_get(bcm_unit, bcm_port,
    309                                             action);
    310 }
    311 
    312 int
    313 bcmx_vlan_port_default_action_delete(bcmx_lport_t port)
    314 {
    315     int         bcm_unit;
    316     bcm_port_t  bcm_port;
    317 
    318     BCMX_VLAN_INIT_CHECK;
    319 
    320     BCM_IF_ERROR_RETURN
    321         (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
    322                                  BCMX_DEST_CONVERT_DEFAULT));
    323 
    324     return bcm_vlan_port_default_action_delete(bcm_unit, bcm_port);
    325 }
    326 
    327 int
    328 bcmx_vlan_port_egress_default_action_set(bcmx_lport_t port,
    329                                          bcm_vlan_action_set_t *action)
    330 {
    331     int         bcm_unit;
    332     bcm_port_t  bcm_port;
    333 
    334     BCMX_VLAN_INIT_CHECK;
    335 
    336     BCMX_PARAM_NULL_CHECK(action);
    337 
    338     BCM_IF_ERROR_RETURN
    339         (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
    340                                  BCMX_DEST_CONVERT_DEFAULT));
    341 
    342     return bcm_vlan_port_egress_default_action_set(bcm_unit, bcm_port,
    343                                                    action);
    344 }
    345  
    346 int
    347 bcmx_vlan_port_egress_default_action_get(bcmx_lport_t port,
    348                                          bcm_vlan_action_set_t *action)
    349 {
    350     int         bcm_unit;
    351     bcm_port_t  bcm_port;
    352 
    353     BCMX_VLAN_INIT_CHECK;
    354 
    355     BCMX_PARAM_NULL_CHECK(action);
    356 
    357     BCM_IF_ERROR_RETURN
    358         (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
    359                                  BCMX_DEST_CONVERT_DEFAULT));
    360 
    361     return bcm_vlan_port_egress_default_action_get(bcm_unit, bcm_port,
    362                                                    action);
    363 }   
    364 
    365 int
    366 bcmx_vlan_port_egress_default_action_delete(bcmx_lport_t port)
    367 {
    368     int         bcm_unit;
    369     bcm_port_t  bcm_port;
    370 
    371     BCMX_VLAN_INIT_CHECK;
    372 
    373     BCM_IF_ERROR_RETURN
    374         (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
    375                                  BCMX_DEST_CONVERT_DEFAULT));
    376 
    377     return bcm_vlan_port_egress_default_action_delete(bcm_unit, bcm_port);
    378 }
    379 
    380 int
    381 bcmx_vlan_port_protocol_action_add(bcmx_lport_t port,
    382                                    bcm_port_frametype_t frame,
    383                                    bcm_port_ethertype_t ether,
    384                                    bcm_vlan_action_set_t *action)
    385 {
    386     int         bcm_unit;
    387     bcm_port_t  bcm_port;
    388 
    389     BCMX_VLAN_INIT_CHECK;
    390 
    391     BCMX_PARAM_NULL_CHECK(action);
    392 
    393     BCM_IF_ERROR_RETURN
    394         (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
    395                                  BCMX_DEST_CONVERT_DEFAULT));
    396 
    397     return bcm_vlan_port_protocol_action_add(bcm_unit, bcm_port,
    398                                              frame, ether, action);
    399 }
    400 
    401 int
    402 bcmx_vlan_port_protocol_action_get(bcmx_lport_t port, 
    403                                    bcm_port_frametype_t frame, 
    404                                    bcm_port_ethertype_t ether, 
    405                                    bcm_vlan_action_set_t *action)
    406 {
    407     int         bcm_unit;
    408     bcm_port_t  bcm_port;
    409 
    410     BCMX_VLAN_INIT_CHECK;
    411 
    412     BCMX_PARAM_NULL_CHECK(action);
    413 
    414     BCM_IF_ERROR_RETURN
    415         (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
    416                                  BCMX_DEST_CONVERT_DEFAULT));
    417 
    418     return bcm_vlan_port_protocol_action_get(bcm_unit, bcm_port,
    419                                              frame, ether, action);
    420 }
    421 
    422 int
    423 bcmx_vlan_port_protocol_action_delete(bcmx_lport_t port, 
    424                                       bcm_port_frametype_t frame, 
    425                                       bcm_port_ethertype_t ether)
    426 {
    427     int         bcm_unit;
    428     bcm_port_t  bcm_port;
    429 
    430     BCMX_VLAN_INIT_CHECK;
    431 
    432     BCM_IF_ERROR_RETURN
    433         (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
    434                                  BCMX_DEST_CONVERT_DEFAULT));
    435 
    436     return bcm_vlan_port_protocol_action_delete(bcm_unit, bcm_port,
    437                                                 frame, ether);
    438 }
    439 
    440 int
    441 bcmx_vlan_port_protocol_action_delete_all(bcmx_lport_t port)
    442 {
    443     int         bcm_unit;
    444     bcm_port_t  bcm_port;
    445 
    446     BCMX_VLAN_INIT_CHECK;
    447 
    448     BCM_IF_ERROR_RETURN
    449         (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
    450                                  BCMX_DEST_CONVERT_DEFAULT));
    451 
    452     return bcm_vlan_port_protocol_action_delete_all(bcm_unit, bcm_port);
    453 }
    454 
    455 
    456 int
    457 bcmx_vlan_mac_add(bcm_mac_t mac, bcm_vlan_t vid, int prio)
    458 {
    459     int rv = BCM_E_UNAVAIL, tmp_rv;
    460     int i, bcm_unit;
    461 
    462     BCMX_VLAN_INIT_CHECK;
    463 
    464     BCMX_UNIT_ITER(bcm_unit, i) {
    465         tmp_rv = bcm_vlan_mac_add(bcm_unit, mac, vid, prio);
    466         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    467     }
    468 
    469     return rv;
    470 }
    471 
    472 
    473 int
    474 bcmx_vlan_mac_delete(bcm_mac_t mac)
    475 {
    476     int rv = BCM_E_UNAVAIL, tmp_rv;
    477     int i, bcm_unit;
    478 
    479     BCMX_VLAN_INIT_CHECK;
    480 
    481     BCMX_UNIT_ITER(bcm_unit, i) {
    482         tmp_rv = bcm_vlan_mac_delete(bcm_unit, mac);
    483         BCM_IF_ERROR_RETURN
    484             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    485     }
    486 
    487     return rv;
    488 }
    489 
    490 
    491 int
    492 bcmx_vlan_mac_delete_all(void)
    493 {
    494     int rv = BCM_E_UNAVAIL, tmp_rv;
    495     int i, bcm_unit;
    496 
    497     BCMX_VLAN_INIT_CHECK;
    498 
    499     BCMX_UNIT_ITER(bcm_unit, i) {
    500         tmp_rv = bcm_vlan_mac_delete_all(bcm_unit);
    501         BCM_IF_ERROR_RETURN
    502             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    503     }
    504 
    505     return rv;
    506 }
    507 
    508 
    509 int bcmx_vlan_mac_action_add(bcm_mac_t mac,
    510                              bcm_vlan_action_set_t *action)
    511 {
    512     int rv = BCM_E_UNAVAIL, tmp_rv;
    513     int i, bcm_unit;
    514 
    515     BCMX_VLAN_INIT_CHECK;
    516 
    517     BCMX_PARAM_NULL_CHECK(action);
    518 
    519     BCMX_UNIT_ITER(bcm_unit, i) {
    520         tmp_rv = bcm_vlan_mac_action_add(bcm_unit, mac, action);
    521         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    522     }
    523 
    524     return rv;
    525 }
    526 
    527 
    528 int
    529 bcmx_vlan_mac_action_delete(bcm_mac_t mac)
    530 {
    531     int rv = BCM_E_UNAVAIL, tmp_rv;
    532     int i, bcm_unit;
    533 
    534     BCMX_VLAN_INIT_CHECK;
    535 
    536     BCMX_UNIT_ITER(bcm_unit, i) {
    537         tmp_rv = bcm_vlan_mac_action_delete(bcm_unit, mac);
    538         BCM_IF_ERROR_RETURN
    539             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    540     }
    541 
    542     return rv;
    543 }
    544 
    545 
    546 int
    547 bcmx_vlan_mac_action_delete_all(void)
    548 {
    549     int rv = BCM_E_UNAVAIL, tmp_rv;
    550     int i, bcm_unit;
    551 
    552     BCMX_VLAN_INIT_CHECK;
    553 
    554     BCMX_UNIT_ITER(bcm_unit, i) {
    555         tmp_rv = bcm_vlan_mac_action_delete_all(bcm_unit);
    556         BCM_IF_ERROR_RETURN
    557             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    558     }
    559 
    560     return rv;
    561 }
    562 
    563 
    564 int
    565 bcmx_vlan_mac_action_get(bcm_mac_t mac, 
    566                          bcm_vlan_action_set_t *action)
    567 {
    568     int rv;
    569     int i, bcm_unit;
    570 
    571     BCMX_VLAN_INIT_CHECK;
    572 
    573     BCMX_PARAM_NULL_CHECK(action);
    574 
    575     BCMX_UNIT_ITER(bcm_unit, i) {
    576         rv = bcm_vlan_mac_action_get(bcm_unit, mac, action);
    577         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, rv)) {
    578             return rv;
    579         }
    580     }
    581 
    582     return BCM_E_UNAVAIL;
    583 }
    584 
    585 
    586 int
    587 bcmx_vlan_translate_add(bcmx_lport_t port,
    588                         bcm_vlan_t old_vid,
    589                         bcm_vlan_t new_vid,
    590                         int prio)
    591 {
    592     int         rv = BCM_E_UNAVAIL, tmp_rv;
    593     int         i, bcm_unit;
    594     bcm_port_t  bcm_port;
    595 
    596     BCMX_VLAN_INIT_CHECK;
    597 
    598     BCMX_LPORT_CHECK(port);
    599 
    600     /* Physical port */
    601     if (BCMX_LPORT_IS_PHYSICAL(port)) {
    602         BCM_IF_ERROR_RETURN
    603             (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
    604                                      BCMX_DEST_CONVERT_DEFAULT));
    605         return bcm_vlan_translate_add(bcm_unit, bcm_port,
    606                                       old_vid, new_vid, prio);
    607     }
    608 
    609     /* Virtual port */
    610     BCMX_UNIT_ITER(bcm_unit, i) {
    611         tmp_rv = bcm_vlan_translate_add(bcm_unit, port,
    612                                         old_vid, new_vid, prio);
    613         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    614     }
    615 
    616     return rv;
    617 }
    618 
    619 int
    620 bcmx_vlan_translate_delete(bcmx_lport_t port, bcm_vlan_t old_vid)
    621 {
    622     int         rv = BCM_E_UNAVAIL, tmp_rv;
    623     int         i, bcm_unit;
    624     bcm_port_t  bcm_port;
    625 
    626     BCMX_VLAN_INIT_CHECK;
    627 
    628     BCMX_LPORT_CHECK(port);
    629 
    630     /* Physical port */
    631     if (BCMX_LPORT_IS_PHYSICAL(port)) {
    632         BCM_IF_ERROR_RETURN
    633             (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
    634                                      BCMX_DEST_CONVERT_DEFAULT));
    635         return bcm_vlan_translate_delete(bcm_unit, bcm_port, old_vid);
    636     }
    637 
    638     /* Virtual port */
    639     BCMX_UNIT_ITER(bcm_unit, i) {
    640         tmp_rv = bcm_vlan_translate_delete(bcm_unit, port, old_vid);
    641         BCM_IF_ERROR_RETURN
    642             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    643     }
    644 
    645     return rv;
    646 }
    647 
    648 int
    649 bcmx_vlan_translate_delete_all(void)
    650 {
    651     int rv = BCM_E_UNAVAIL, tmp_rv;
    652     int i, bcm_unit;
    653 
    654     BCMX_VLAN_INIT_CHECK;
    655 
    656     BCMX_UNIT_ITER(bcm_unit, i) {
    657         tmp_rv = bcm_vlan_translate_delete_all(bcm_unit);
    658         BCM_IF_ERROR_RETURN
    659             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    660     }
    661 
    662     return rv;
    663 }
    664 
    665 int
    666 bcmx_vlan_translate_get(bcmx_lport_t port, bcm_vlan_t old_vid,
    667                         bcm_vlan_t *new_vid, int *prio)
    668 {
    669     int         rv;
    670     int         i, bcm_unit;
    671     bcm_port_t  bcm_port;
    672 
    673     BCMX_VLAN_INIT_CHECK;
    674 
    675     BCMX_PARAM_NULL_CHECK(new_vid);
    676     BCMX_PARAM_NULL_CHECK(prio);
    677     
    678     BCMX_LPORT_CHECK(port);
    679 
    680     /* Physical port */
    681     if (BCMX_LPORT_IS_PHYSICAL(port)) {
    682         BCM_IF_ERROR_RETURN
    683             (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
    684                                      BCMX_DEST_CONVERT_DEFAULT));
    685         return bcm_vlan_translate_get(bcm_unit, bcm_port,
    686                                       old_vid, new_vid, prio);
    687     }
    688 
    689     /* Virtual port */
    690     BCMX_UNIT_ITER(bcm_unit, i) {
    691         rv = bcm_vlan_translate_get(bcm_unit, port, old_vid, new_vid, prio);
    692         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, rv)) {
    693             return rv;
    694         }
    695     }
    696 
    697     return BCM_E_UNAVAIL;
    698 }
    699 
    700 int
    701 bcmx_vlan_translate_action_add(bcm_gport_t port, 
    702                                bcm_vlan_translate_key_t key_type, 
    703                                bcm_vlan_t outer_vlan, bcm_vlan_t inner_vlan, 
    704                                bcm_vlan_action_set_t *action)
    705 {
    706     int         rv = BCM_E_UNAVAIL, tmp_rv;
    707     int         i, bcm_unit;
    708     bcm_port_t  bcm_port;
    709 
    710     BCMX_VLAN_INIT_CHECK;
    711 
    712     BCMX_PARAM_NULL_CHECK(action);
    713 
    714     BCMX_LPORT_CHECK(port);
    715 
    716     /* Physical port */
    717     if (BCMX_LPORT_IS_PHYSICAL(port)) {
    718         BCM_IF_ERROR_RETURN
    719             (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
    720                                      BCMX_DEST_CONVERT_DEFAULT));
    721         return bcm_vlan_translate_action_add(bcm_unit, port,
    722                                              key_type, outer_vlan, inner_vlan,
    723                                              action);
    724     }
    725 
    726     /* Virtual port */
    727     BCMX_UNIT_ITER(bcm_unit, i) {
    728         tmp_rv = bcm_vlan_translate_action_add(bcm_unit, port,
    729                                                key_type, outer_vlan,
    730                                                inner_vlan, action);
    731         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    732     }
    733 
    734     return rv;
    735 }
    736 
    737 int
    738 bcmx_vlan_translate_action_delete(bcm_gport_t port,
    739                                   bcm_vlan_translate_key_t key_type,
    740                                   bcm_vlan_t outer_vlan, bcm_vlan_t inner_vlan)
    741 {
    742     int         rv = BCM_E_UNAVAIL, tmp_rv;
    743     int         i, bcm_unit;
    744     bcm_port_t  bcm_port;
    745 
    746     BCMX_VLAN_INIT_CHECK;
    747 
    748     BCMX_LPORT_CHECK(port);
    749 
    750     /* Physical port */
    751     if (BCMX_LPORT_IS_PHYSICAL(port)) {
    752         BCM_IF_ERROR_RETURN
    753             (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
    754                                      BCMX_DEST_CONVERT_DEFAULT));
    755         return bcm_vlan_translate_action_delete(bcm_unit, port,
    756                                                 key_type, outer_vlan,
    757                                                 inner_vlan);
    758     }
    759 
    760     /* Virtual port */
    761     BCMX_UNIT_ITER(bcm_unit, i) {
    762         tmp_rv = bcm_vlan_translate_action_delete(bcm_unit, port,
    763                                                   key_type, outer_vlan,
    764                                                   inner_vlan);
    765         BCM_IF_ERROR_RETURN
    766             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    767     }
    768 
    769     return rv;
    770 }
    771 
    772 int
    773 bcmx_vlan_translate_action_get(bcm_gport_t port, 
    774                                bcm_vlan_translate_key_t key_type, 
    775                                bcm_vlan_t outer_vlan, bcm_vlan_t inner_vlan, 
    776                                bcm_vlan_action_set_t *action)
    777 {
    778     int         rv;
    779     int         i, bcm_unit;
    780     bcm_port_t  bcm_port;
    781 
    782     BCMX_VLAN_INIT_CHECK;
    783 
    784     BCMX_PARAM_NULL_CHECK(action);
    785 
    786     BCMX_LPORT_CHECK(port);
    787 
    788     /* Physical port */
    789     if (BCMX_LPORT_IS_PHYSICAL(port)) {
    790         BCM_IF_ERROR_RETURN
    791             (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
    792                                      BCMX_DEST_CONVERT_DEFAULT));
    793         return bcm_vlan_translate_action_get(bcm_unit, port, key_type,
    794                                              outer_vlan, inner_vlan,
    795                                              action);
    796     }
    797 
    798     /* Virtual port */
    799     BCMX_UNIT_ITER(bcm_unit, i) {
    800         rv = bcm_vlan_translate_action_get(bcm_unit, port, key_type,
    801                                            outer_vlan, inner_vlan,
    802                                            action);
    803         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, rv)) {
    804             return rv;
    805         }
    806     }
    807 
    808     return BCM_E_UNAVAIL;
    809 }
    810 
    811 
    812 int
    813 bcmx_vlan_translate_egress_add(bcmx_lport_t port,
    814                                bcm_vlan_t old_vid,
    815                                bcm_vlan_t new_vid,
    816                                int prio)
    817 {
    818     int         bcm_unit;
    819     bcm_port_t  bcm_port;
    820 
    821     BCMX_VLAN_INIT_CHECK;
    822 
    823     BCM_IF_ERROR_RETURN
    824         (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
    825                                  BCMX_DEST_CONVERT_DEFAULT));
    826 
    827     return bcm_vlan_translate_egress_add(bcm_unit, bcm_port,
    828                                          old_vid, new_vid, prio);
    829 }
    830 
    831 int
    832 bcmx_vlan_translate_egress_delete(bcmx_lport_t port, bcm_vlan_t old_vid)
    833 {
    834     int         bcm_unit;
    835     bcm_port_t  bcm_port;
    836 
    837     BCMX_VLAN_INIT_CHECK;
    838 
    839     BCM_IF_ERROR_RETURN
    840         (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
    841                                  BCMX_DEST_CONVERT_DEFAULT));
    842 
    843     return bcm_vlan_translate_egress_delete(bcm_unit, bcm_port,
    844                                             old_vid);
    845 }
    846 
    847 int
    848 bcmx_vlan_translate_egress_delete_all(void)
    849 {
    850     int rv = BCM_E_UNAVAIL, tmp_rv;
    851     int i, bcm_unit;
    852 
    853     BCMX_VLAN_INIT_CHECK;
    854 
    855     BCMX_UNIT_ITER(bcm_unit, i) {
    856         tmp_rv = bcm_vlan_translate_egress_delete_all(bcm_unit);
    857         BCM_IF_ERROR_RETURN
    858             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    859     }
    860 
    861     return rv;
    862 }
    863 
    864 int
    865 bcmx_vlan_translate_egress_get(bcmx_lport_t port, bcm_vlan_t old_vid, 
    866                                bcm_vlan_t *new_vid, int *prio)
    867 {
    868     int         bcm_unit;
    869     bcm_port_t  bcm_port;
    870 
    871     BCMX_VLAN_INIT_CHECK;
    872 
    873     BCMX_PARAM_NULL_CHECK(new_vid);
    874     BCMX_PARAM_NULL_CHECK(prio);
    875     
    876     BCM_IF_ERROR_RETURN
    877         (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
    878                                  BCMX_DEST_CONVERT_DEFAULT));
    879 
    880     return bcm_vlan_translate_egress_get(bcm_unit, bcm_port, old_vid,
    881                                          new_vid, prio);
    882 }
    883 
    884 
    885 int
    886 bcmx_vlan_translate_egress_action_add(int port_class,
    887                                       bcm_vlan_t outer_vlan,
    888                                       bcm_vlan_t inner_vlan,
    889                                       bcm_vlan_action_set_t *action)
    890 {
    891     int rv = BCM_E_UNAVAIL, tmp_rv;
    892     int i, bcm_unit;
    893 
    894     BCMX_VLAN_INIT_CHECK;
    895 
    896     BCMX_PARAM_NULL_CHECK(action);
    897 
    898     BCMX_UNIT_ITER(bcm_unit, i) {
    899         tmp_rv = bcm_vlan_translate_egress_action_add(bcm_unit, port_class,
    900                                                       outer_vlan, inner_vlan,
    901                                                       action);
    902         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    903     }
    904 
    905     return rv;
    906 }
    907 
    908 int
    909 bcmx_vlan_translate_egress_action_delete(int port_class,
    910                                          bcm_vlan_t outer_vlan,
    911                                          bcm_vlan_t inner_vlan)
    912 {
    913     int rv = BCM_E_UNAVAIL, tmp_rv;
    914     int i, bcm_unit;
    915 
    916     BCMX_VLAN_INIT_CHECK;
    917 
    918     BCMX_UNIT_ITER(bcm_unit, i) {
    919         tmp_rv = bcm_vlan_translate_egress_action_delete(bcm_unit, port_class,
    920                                                          outer_vlan, inner_vlan);
    921         BCM_IF_ERROR_RETURN
    922             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    923     }
    924 
    925     return rv;
    926 }
    927 
    928 int
    929 bcmx_vlan_translate_egress_action_get(int port_class, 
    930                                       bcm_vlan_t outer_vlan, 
    931                                       bcm_vlan_t inner_vlan, 
    932                                       bcm_vlan_action_set_t *action)
    933 {
    934     int rv;
    935     int i, bcm_unit;
    936 
    937     BCMX_VLAN_INIT_CHECK;
    938 
    939     BCMX_PARAM_NULL_CHECK(action);
    940 
    941     BCMX_UNIT_ITER(bcm_unit, i) {
    942         rv = bcm_vlan_translate_egress_action_get(bcm_unit, port_class,
    943                                                   outer_vlan, inner_vlan,
    944                                                   action);
    945         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, rv)) {
    946             return rv;
    947         }
    948     }
    949 
    950     return BCM_E_UNAVAIL;
    951 }
    952 
    953 
    954 int
    955 bcmx_vlan_dtag_add(bcmx_lport_t port,
    956                    bcm_vlan_t old_vid,
    957                    bcm_vlan_t new_vid,
    958                    int prio)
    959 {
    960     int         rv = BCM_E_UNAVAIL, tmp_rv;
    961     int         i, bcm_unit;
    962     bcm_port_t  bcm_port;
    963 
    964     BCMX_VLAN_INIT_CHECK;
    965 
    966     BCMX_LPORT_CHECK(port);
    967 
    968     /* Physical port */
    969     if (BCMX_LPORT_IS_PHYSICAL(port)) {
    970         BCM_IF_ERROR_RETURN
    971             (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
    972                                      BCMX_DEST_CONVERT_DEFAULT));
    973         return bcm_vlan_dtag_add(bcm_unit, bcm_port, old_vid, new_vid, prio);
    974     }
    975 
    976     /* Virtual port */
    977     BCMX_UNIT_ITER(bcm_unit, i) {
    978         tmp_rv = bcm_vlan_dtag_add(bcm_unit, port, old_vid, new_vid, prio);
    979         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    980     }
    981 
    982     return rv;
    983 }
    984 
    985 int
    986 bcmx_vlan_dtag_delete(bcmx_lport_t port, bcm_vlan_t old_vid)
    987 {
    988     int         rv = BCM_E_UNAVAIL, tmp_rv;
    989     int         i, bcm_unit;
    990     bcm_port_t  bcm_port;
    991 
    992     BCMX_VLAN_INIT_CHECK;
    993 
    994     BCMX_LPORT_CHECK(port);
    995 
    996     /* Physical port */
    997     if (BCMX_LPORT_IS_PHYSICAL(port)) {
    998         BCM_IF_ERROR_RETURN
    999             (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   1000                                      BCMX_DEST_CONVERT_DEFAULT));
   1001         return bcm_vlan_dtag_delete(bcm_unit, bcm_port, old_vid);
   1002     }
   1003 
   1004     /* Virtual port */
   1005     BCMX_UNIT_ITER(bcm_unit, i) {
   1006         tmp_rv = bcm_vlan_dtag_delete(bcm_unit, port, old_vid);
   1007         BCM_IF_ERROR_RETURN
   1008             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1009     }
   1010 
   1011     return rv;
   1012 }
   1013 
   1014 int
   1015 bcmx_vlan_dtag_delete_all(void)
   1016 {
   1017     int rv = BCM_E_UNAVAIL, tmp_rv;
   1018     int i, bcm_unit;
   1019 
   1020     BCMX_VLAN_INIT_CHECK;
   1021 
   1022     BCMX_UNIT_ITER(bcm_unit, i) {
   1023         tmp_rv = bcm_vlan_dtag_delete_all(bcm_unit);
   1024         BCM_IF_ERROR_RETURN
   1025             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1026     }
   1027 
   1028     return rv;
   1029 }
   1030 
   1031 int
   1032 bcmx_vlan_dtag_get(bcmx_lport_t port, bcm_vlan_t old_vid, 
   1033                    bcm_vlan_t *new_vid, int *prio)
   1034 {
   1035     int         rv;
   1036     int         i, bcm_unit;
   1037     bcm_port_t  bcm_port;
   1038 
   1039     BCMX_VLAN_INIT_CHECK;
   1040 
   1041     BCMX_PARAM_NULL_CHECK(new_vid);
   1042     BCMX_PARAM_NULL_CHECK(prio);
   1043     
   1044     BCMX_LPORT_CHECK(port);
   1045 
   1046     /* Physical port */
   1047     if (BCMX_LPORT_IS_PHYSICAL(port)) {
   1048         BCM_IF_ERROR_RETURN
   1049             (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   1050                                      BCMX_DEST_CONVERT_DEFAULT));
   1051         return bcm_vlan_dtag_get(bcm_unit, bcm_port, old_vid, new_vid, prio);
   1052     }
   1053     
   1054     /* Virtual port */
   1055     BCMX_UNIT_ITER(bcm_unit, i) {
   1056         rv = bcm_vlan_dtag_get(bcm_unit, port, old_vid, new_vid, prio);
   1057         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, rv)) {
   1058             return rv;
   1059         }
   1060     }
   1061 
   1062     return BCM_E_UNAVAIL;
   1063 }
   1064 
   1065 
   1066 int
   1067 bcmx_vlan_translate_range_add(bcmx_lport_t port,
   1068                               bcm_vlan_t old_vid_low, bcm_vlan_t old_vid_high,
   1069                               bcm_vlan_t new_vid, int int_prio)
   1070 {
   1071     int         rv = BCM_E_UNAVAIL, tmp_rv;
   1072     int         i, bcm_unit;
   1073     bcm_port_t  bcm_port;
   1074 
   1075     BCMX_VLAN_INIT_CHECK;
   1076 
   1077     BCMX_LPORT_CHECK(port);
   1078 
   1079     /* Physical port */
   1080     if (BCMX_LPORT_IS_PHYSICAL(port)) {
   1081         BCM_IF_ERROR_RETURN
   1082             (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   1083                                      BCMX_DEST_CONVERT_DEFAULT));
   1084         return bcm_vlan_translate_range_add(bcm_unit, bcm_port,
   1085                                             old_vid_low, old_vid_high,
   1086                                             new_vid, int_prio);
   1087     }
   1088 
   1089     /* Virtual port */
   1090     BCMX_UNIT_ITER(bcm_unit, i) {
   1091         tmp_rv = bcm_vlan_translate_range_add(bcm_unit, port,
   1092                                               old_vid_low, old_vid_high,
   1093                                               new_vid, int_prio);
   1094         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1095     }
   1096 
   1097     return rv;
   1098 }
   1099 
   1100 int
   1101 bcmx_vlan_translate_range_delete(bcmx_lport_t port,
   1102                                  bcm_vlan_t old_vid_low,
   1103                                  bcm_vlan_t old_vid_high)
   1104 {
   1105     int         rv = BCM_E_UNAVAIL, tmp_rv;
   1106     int         i, bcm_unit;
   1107     bcm_port_t  bcm_port;
   1108 
   1109     BCMX_VLAN_INIT_CHECK;
   1110 
   1111     BCMX_LPORT_CHECK(port);
   1112 
   1113     /* Physical port */
   1114     if (BCMX_LPORT_IS_PHYSICAL(port)) {
   1115         BCM_IF_ERROR_RETURN
   1116             (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   1117                                      BCMX_DEST_CONVERT_DEFAULT));
   1118         return bcm_vlan_translate_range_delete(bcm_unit, bcm_port,
   1119                                                old_vid_low, old_vid_high);
   1120     }
   1121 
   1122     /* Virtual port */
   1123     BCMX_UNIT_ITER(bcm_unit, i) {
   1124         tmp_rv = bcm_vlan_translate_range_delete(bcm_unit, port,
   1125                                                  old_vid_low, old_vid_high);
   1126         BCM_IF_ERROR_RETURN
   1127             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1128     }
   1129 
   1130     return rv;
   1131 }
   1132 
   1133 int
   1134 bcmx_vlan_translate_range_delete_all(void)
   1135 {
   1136     int rv = BCM_E_UNAVAIL, tmp_rv;
   1137     int i, bcm_unit;
   1138 
   1139     BCMX_VLAN_INIT_CHECK;
   1140 
   1141     BCMX_UNIT_ITER(bcm_unit, i) {
   1142         tmp_rv = bcm_vlan_translate_range_delete_all(bcm_unit);
   1143         BCM_IF_ERROR_RETURN
   1144             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1145     }
   1146 
   1147     return rv;
   1148 }
   1149 
   1150 int
   1151 bcmx_vlan_translate_range_get(bcmx_lport_t port, 
   1152                               bcm_vlan_t old_vid_low, bcm_vlan_t old_vid_high, 
   1153                               bcm_vlan_t *new_vid, int *int_prio)
   1154 {
   1155     int         rv;
   1156     int         i, bcm_unit;
   1157     bcm_port_t  bcm_port;
   1158 
   1159     BCMX_VLAN_INIT_CHECK;
   1160 
   1161     BCMX_PARAM_NULL_CHECK(new_vid);
   1162     BCMX_PARAM_NULL_CHECK(int_prio);
   1163     
   1164     BCMX_LPORT_CHECK(port);
   1165 
   1166     /* Physical port */
   1167     if (BCMX_LPORT_IS_PHYSICAL(port)) {
   1168         BCM_IF_ERROR_RETURN
   1169             (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   1170                                      BCMX_DEST_CONVERT_DEFAULT));
   1171         return bcm_vlan_translate_range_get(bcm_unit, bcm_port,
   1172                                             old_vid_low, old_vid_high,
   1173                                             new_vid, int_prio);
   1174     }
   1175 
   1176     /* Virtual port */
   1177     BCMX_UNIT_ITER(bcm_unit, i) {
   1178         rv = bcm_vlan_translate_range_get(bcm_unit, port,
   1179                                           old_vid_low, old_vid_high,
   1180                                           new_vid, int_prio);
   1181         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, rv)) {
   1182             return rv;
   1183         }
   1184     }
   1185 
   1186     return BCM_E_UNAVAIL;
   1187 }
   1188 
   1189 
   1190 int
   1191 bcmx_vlan_dtag_range_add(bcmx_lport_t port,
   1192                          bcm_vlan_t old_vid_low, bcm_vlan_t old_vid_high,
   1193                          bcm_vlan_t new_vid, int int_prio)
   1194 {
   1195     int         rv = BCM_E_UNAVAIL, tmp_rv;
   1196     int         i, bcm_unit;
   1197     bcm_port_t  bcm_port;
   1198 
   1199     BCMX_VLAN_INIT_CHECK;
   1200 
   1201     BCMX_LPORT_CHECK(port);
   1202 
   1203     /* Physical port */
   1204     if (BCMX_LPORT_IS_PHYSICAL(port)) {
   1205         BCM_IF_ERROR_RETURN
   1206             (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   1207                                      BCMX_DEST_CONVERT_DEFAULT));
   1208         return bcm_vlan_dtag_range_add(bcm_unit, bcm_port,
   1209                                        old_vid_low, old_vid_high,
   1210                                        new_vid, int_prio);
   1211     }
   1212 
   1213     /* Virtual port */
   1214     BCMX_UNIT_ITER(bcm_unit, i) {
   1215         tmp_rv = bcm_vlan_dtag_range_add(bcm_unit, port,
   1216                                          old_vid_low, old_vid_high,
   1217                                          new_vid, int_prio);
   1218         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1219     }
   1220 
   1221     return rv;
   1222 }
   1223 
   1224 int
   1225 bcmx_vlan_dtag_range_delete(bcmx_lport_t port, 
   1226                             bcm_vlan_t old_vid_low,
   1227                             bcm_vlan_t old_vid_high)
   1228 {
   1229     int         rv = BCM_E_UNAVAIL, tmp_rv;
   1230     int         i, bcm_unit;
   1231     bcm_port_t  bcm_port;
   1232 
   1233     BCMX_VLAN_INIT_CHECK;
   1234 
   1235     BCMX_LPORT_CHECK(port);
   1236 
   1237     /* Physical port */
   1238     if (BCMX_LPORT_IS_PHYSICAL(port)) {
   1239         BCM_IF_ERROR_RETURN
   1240             (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   1241                                      BCMX_DEST_CONVERT_DEFAULT));
   1242         return bcm_vlan_dtag_range_delete(bcm_unit, bcm_port,
   1243                                           old_vid_low, old_vid_high);
   1244     }
   1245 
   1246     /* Virtual port */
   1247     BCMX_UNIT_ITER(bcm_unit, i) {
   1248         tmp_rv = bcm_vlan_dtag_range_delete(bcm_unit, port,
   1249                                             old_vid_low, old_vid_high);
   1250         BCM_IF_ERROR_RETURN
   1251             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1252     }
   1253 
   1254     return rv;
   1255 }
   1256 
   1257 int
   1258 bcmx_vlan_dtag_range_delete_all(void)
   1259 {
   1260     int rv = BCM_E_UNAVAIL, tmp_rv;
   1261     int i, bcm_unit;
   1262 
   1263     BCMX_VLAN_INIT_CHECK;
   1264 
   1265     BCMX_UNIT_ITER(bcm_unit, i) {
   1266         tmp_rv = bcm_vlan_dtag_range_delete_all(bcm_unit);
   1267         BCM_IF_ERROR_RETURN
   1268             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1269     }
   1270 
   1271     return rv;
   1272 }
   1273 
   1274 int
   1275 bcmx_vlan_dtag_range_get(bcmx_lport_t port,
   1276                          bcm_vlan_t old_vid_low, bcm_vlan_t old_vid_high, 
   1277                          bcm_vlan_t *new_vid, int *prio)
   1278 {
   1279     int         rv;
   1280     int         i, bcm_unit;
   1281     bcm_port_t  bcm_port;
   1282 
   1283     BCMX_VLAN_INIT_CHECK;
   1284 
   1285     BCMX_PARAM_NULL_CHECK(new_vid);
   1286     BCMX_PARAM_NULL_CHECK(prio);
   1287     
   1288     BCMX_LPORT_CHECK(port);
   1289 
   1290     /* Physical port */
   1291     if (BCMX_LPORT_IS_PHYSICAL(port)) {
   1292         BCM_IF_ERROR_RETURN
   1293             (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   1294                                      BCMX_DEST_CONVERT_DEFAULT));
   1295         return bcm_vlan_dtag_range_get(bcm_unit, bcm_port,
   1296                                        old_vid_low, old_vid_high,
   1297                                        new_vid, prio);
   1298     }
   1299 
   1300     /* Virtual port */
   1301     BCMX_UNIT_ITER(bcm_unit, i) {
   1302         rv = bcm_vlan_dtag_range_get(bcm_unit, port,
   1303                                      old_vid_low, old_vid_high,
   1304                                      new_vid, prio);
   1305         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, rv)) {
   1306             return rv;
   1307         }
   1308     }
   1309 
   1310     return BCM_E_UNAVAIL;
   1311 }
   1312 
   1313 
   1314 int
   1315 bcmx_vlan_translate_action_range_add(bcm_gport_t port,
   1316                                      bcm_vlan_t outer_vlan_low, 
   1317                                      bcm_vlan_t outer_vlan_high, 
   1318                                      bcm_vlan_t inner_vlan_low, 
   1319                                      bcm_vlan_t inner_vlan_high, 
   1320                                      bcm_vlan_action_set_t *action)
   1321 {
   1322     int         rv = BCM_E_UNAVAIL, tmp_rv;
   1323     int         i, bcm_unit;
   1324     bcm_port_t  bcm_port;
   1325 
   1326     BCMX_VLAN_INIT_CHECK;
   1327 
   1328     BCMX_PARAM_NULL_CHECK(action);
   1329 
   1330     BCMX_LPORT_CHECK(port);
   1331 
   1332     /* Physical port */
   1333     if (BCMX_LPORT_IS_PHYSICAL(port)) {
   1334         BCM_IF_ERROR_RETURN
   1335             (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   1336                                      BCMX_DEST_CONVERT_DEFAULT));
   1337         return bcm_vlan_translate_action_range_add(bcm_unit, port,
   1338                                                    outer_vlan_low,
   1339                                                    outer_vlan_high,
   1340                                                    inner_vlan_low, 
   1341                                                    inner_vlan_high, 
   1342                                                    action);
   1343     }
   1344 
   1345     /* Virtual port */
   1346     BCMX_UNIT_ITER(bcm_unit, i) {
   1347         tmp_rv = bcm_vlan_translate_action_range_add(bcm_unit, port,
   1348                                                      outer_vlan_low,
   1349                                                      outer_vlan_high,
   1350                                                      inner_vlan_low, 
   1351                                                      inner_vlan_high, 
   1352                                                      action);
   1353         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1354     }
   1355 
   1356     return rv;
   1357 }
   1358 
   1359 int
   1360 bcmx_vlan_translate_action_range_delete(bcm_gport_t port,
   1361                                         bcm_vlan_t outer_vlan_low, 
   1362                                         bcm_vlan_t outer_vlan_high, 
   1363                                         bcm_vlan_t inner_vlan_low, 
   1364                                         bcm_vlan_t inner_vlan_high)
   1365 {
   1366     int         rv = BCM_E_UNAVAIL, tmp_rv;
   1367     int         i, bcm_unit;
   1368     bcm_port_t  bcm_port;
   1369 
   1370     BCMX_VLAN_INIT_CHECK;
   1371 
   1372     BCMX_LPORT_CHECK(port);
   1373 
   1374     /* Physical port */
   1375     if (BCMX_LPORT_IS_PHYSICAL(port)) {
   1376         BCM_IF_ERROR_RETURN
   1377             (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   1378                                      BCMX_DEST_CONVERT_DEFAULT));
   1379         return bcm_vlan_translate_action_range_delete(bcm_unit, port,
   1380                                                       outer_vlan_low,
   1381                                                       outer_vlan_high,
   1382                                                       inner_vlan_low, 
   1383                                                       inner_vlan_high);
   1384     }
   1385 
   1386     /* Virtual port */
   1387     BCMX_UNIT_ITER(bcm_unit, i) {
   1388         tmp_rv = bcm_vlan_translate_action_range_delete(bcm_unit, port,
   1389                                                         outer_vlan_low,
   1390                                                         outer_vlan_high,
   1391                                                         inner_vlan_low, 
   1392                                                         inner_vlan_high);
   1393         BCM_IF_ERROR_RETURN
   1394             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1395     }
   1396 
   1397     return rv;
   1398 }
   1399 
   1400 int
   1401 bcmx_vlan_translate_action_range_delete_all(void)
   1402 {
   1403     int rv = BCM_E_UNAVAIL, tmp_rv;
   1404     int i, bcm_unit;
   1405 
   1406     BCMX_VLAN_INIT_CHECK;
   1407 
   1408     BCMX_UNIT_ITER(bcm_unit, i) {
   1409         tmp_rv = bcm_vlan_translate_action_range_delete_all(bcm_unit);
   1410         BCM_IF_ERROR_RETURN
   1411             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1412     }
   1413 
   1414     return rv;
   1415 }
   1416 
   1417 int
   1418 bcmx_vlan_translate_action_range_get(bcm_gport_t port, 
   1419                                      bcm_vlan_t outer_vlan_low, 
   1420                                      bcm_vlan_t outer_vlan_high, 
   1421                                      bcm_vlan_t inner_vlan_low, 
   1422                                      bcm_vlan_t inner_vlan_high, 
   1423                                      bcm_vlan_action_set_t *action)
   1424 {
   1425     int         rv;
   1426     int         i, bcm_unit;
   1427     bcm_port_t  bcm_port;
   1428 
   1429     BCMX_VLAN_INIT_CHECK;
   1430 
   1431     BCMX_PARAM_NULL_CHECK(action);
   1432 
   1433     BCMX_LPORT_CHECK(port);
   1434 
   1435     /* Physical port */
   1436     if (BCMX_LPORT_IS_PHYSICAL(port)) {
   1437         BCM_IF_ERROR_RETURN
   1438             (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   1439                                      BCMX_DEST_CONVERT_DEFAULT));
   1440         return bcm_vlan_translate_action_range_get(bcm_unit, port,
   1441                                                    outer_vlan_low,
   1442                                                    outer_vlan_high,
   1443                                                    inner_vlan_low,
   1444                                                    inner_vlan_high,
   1445                                                    action);
   1446     }
   1447 
   1448     /* Virtual port */
   1449     BCMX_UNIT_ITER(bcm_unit, i) {
   1450         rv =  bcm_vlan_translate_action_range_get(bcm_unit, port,
   1451                                                   outer_vlan_low,
   1452                                                   outer_vlan_high,
   1453                                                   inner_vlan_low,
   1454                                                   inner_vlan_high,
   1455                                                   action);
   1456         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, rv)) {
   1457             return rv;
   1458         }
   1459     }
   1460 
   1461     return BCM_E_UNAVAIL;
   1462 }
   1463 
   1464 
   1465 int
   1466 bcmx_vlan_ip_add(bcm_vlan_ip_t *vlan_ip)
   1467 {
   1468     int rv = BCM_E_UNAVAIL, tmp_rv;
   1469     int i, bcm_unit;
   1470 
   1471     BCMX_VLAN_INIT_CHECK;
   1472 
   1473     BCMX_PARAM_NULL_CHECK(vlan_ip);
   1474 
   1475     BCMX_UNIT_ITER(bcm_unit, i) {
   1476         tmp_rv = bcm_vlan_ip_add(bcm_unit, vlan_ip);
   1477         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1478     }
   1479 
   1480     return rv;
   1481 }
   1482 
   1483 
   1484 int
   1485 bcmx_vlan_ip_delete(bcm_vlan_ip_t *vlan_ip)
   1486 {
   1487     int rv = BCM_E_UNAVAIL, tmp_rv;
   1488     int i, bcm_unit;
   1489 
   1490     BCMX_VLAN_INIT_CHECK;
   1491 
   1492     BCMX_PARAM_NULL_CHECK(vlan_ip);
   1493 
   1494     BCMX_UNIT_ITER(bcm_unit, i) {
   1495         tmp_rv = bcm_vlan_ip_delete(bcm_unit, vlan_ip);
   1496         BCM_IF_ERROR_RETURN
   1497             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1498     }
   1499 
   1500     return rv;
   1501 }
   1502 
   1503 
   1504 int
   1505 bcmx_vlan_ip_delete_all(void)
   1506 {
   1507     int rv = BCM_E_UNAVAIL, tmp_rv;
   1508     int i, bcm_unit;
   1509 
   1510     BCMX_VLAN_INIT_CHECK;
   1511 
   1512     BCMX_UNIT_ITER(bcm_unit, i) {
   1513         tmp_rv = bcm_vlan_ip_delete_all(bcm_unit);
   1514         BCM_IF_ERROR_RETURN
   1515             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1516     }
   1517 
   1518     return rv;
   1519 }
   1520 
   1521 
   1522 int
   1523 bcmx_vlan_ip_action_add(bcm_vlan_ip_t *vlan_ip,
   1524                         bcm_vlan_action_set_t *action)
   1525 {
   1526     int rv = BCM_E_UNAVAIL, tmp_rv;
   1527     int i, bcm_unit;
   1528 
   1529     BCMX_VLAN_INIT_CHECK;
   1530 
   1531     BCMX_PARAM_NULL_CHECK(vlan_ip);
   1532     BCMX_PARAM_NULL_CHECK(action);
   1533 
   1534     BCMX_UNIT_ITER(bcm_unit, i) {
   1535         tmp_rv = bcm_vlan_ip_action_add(bcm_unit, vlan_ip, action);
   1536         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1537     }
   1538 
   1539     return rv;
   1540 
   1541 }
   1542 
   1543 int
   1544 bcmx_vlan_ip_action_get(bcm_vlan_ip_t *vlan_ip,
   1545                         bcm_vlan_action_set_t *action)
   1546 {
   1547     int  rv;
   1548     int  i, bcm_unit;
   1549 
   1550     BCMX_VLAN_INIT_CHECK;
   1551 
   1552     BCMX_PARAM_NULL_CHECK(vlan_ip);
   1553     BCMX_PARAM_NULL_CHECK(action);
   1554 
   1555     BCMX_UNIT_ITER(bcm_unit, i) {
   1556         rv = bcm_vlan_ip_action_get(bcm_unit, vlan_ip, action);
   1557         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, rv)) {
   1558             return rv;
   1559         }
   1560     }
   1561 
   1562     return BCM_E_UNAVAIL;
   1563 }
   1564 
   1565 int
   1566 bcmx_vlan_ip_action_delete(bcm_vlan_ip_t *vlan_ip)
   1567 {
   1568     int  rv = BCM_E_UNAVAIL, tmp_rv;
   1569     int  i, bcm_unit;
   1570 
   1571     BCMX_VLAN_INIT_CHECK;
   1572 
   1573     BCMX_PARAM_NULL_CHECK(vlan_ip);
   1574 
   1575     BCMX_UNIT_ITER(bcm_unit, i) {
   1576         tmp_rv = bcm_vlan_ip_action_delete(bcm_unit, vlan_ip);
   1577         BCM_IF_ERROR_RETURN
   1578             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1579     }
   1580 
   1581     return rv;
   1582 
   1583 }
   1584 
   1585 int
   1586 bcmx_vlan_ip_action_delete_all(void)
   1587 {
   1588     int  rv = BCM_E_UNAVAIL, tmp_rv;
   1589     int  i, bcm_unit;
   1590 
   1591     BCMX_VLAN_INIT_CHECK;
   1592 
   1593     BCMX_UNIT_ITER(bcm_unit, i) {
   1594         tmp_rv = bcm_vlan_ip_action_delete_all(bcm_unit);
   1595         BCM_IF_ERROR_RETURN
   1596             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1597     }
   1598 
   1599     return rv;
   1600 }
   1601 
   1602 int
   1603 bcmx_vlan_control_set(bcm_vlan_control_t type, int arg)
   1604 {
   1605     int rv = BCM_E_UNAVAIL, tmp_rv;
   1606     int i, bcm_unit;
   1607 
   1608     BCMX_VLAN_INIT_CHECK;
   1609 
   1610     BCMX_UNIT_ITER(bcm_unit, i) {
   1611         tmp_rv = bcm_vlan_control_set(bcm_unit, type, arg);
   1612         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1613     }
   1614 
   1615     return rv;
   1616 }
   1617 
   1618 
   1619 int
   1620 bcmx_vlan_control_get(bcm_vlan_control_t type, int *arg)
   1621 {
   1622     int rv;
   1623     int i, bcm_unit;
   1624 
   1625     BCMX_VLAN_INIT_CHECK;
   1626 
   1627     BCMX_PARAM_NULL_CHECK(arg);
   1628 
   1629     BCMX_UNIT_ITER(bcm_unit, i) {
   1630         rv = bcm_vlan_control_get(bcm_unit, type, arg);
   1631         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, rv)) {
   1632             return rv;
   1633         }
   1634     }
   1635 
   1636     return BCM_E_UNAVAIL;
   1637 }
   1638 
   1639 
   1640 /*
   1641  * Function:
   1642  *      bcmx_vlan_control_port_set
   1643  * Notes:
   1644  *      Exposing the ability of the BCM API to set all Ethernet ports
   1645  *      the BCMX layer provides an special value defined for this purpose:
   1646  *          BCMX_LPORT_ETHER_ALL  --> All Ethernet ports (FE, GE, XE)
   1647  */
   1648 
   1649 int
   1650 bcmx_vlan_control_port_set(bcmx_lport_t port, 
   1651                            bcm_vlan_control_port_t type,
   1652                            int arg)
   1653 {
   1654     int rv = BCM_E_UNAVAIL, tmp_rv;
   1655     int i, bcm_unit;
   1656     int bcm_port_all = -1; /* This value indicates all ether ports in BCM */
   1657 
   1658     BCMX_VLAN_INIT_CHECK;
   1659 
   1660     if (port == BCMX_LPORT_ETHER_ALL) {
   1661         BCMX_UNIT_ITER(bcm_unit, i) {
   1662             tmp_rv = bcm_vlan_control_port_set(bcm_unit, bcm_port_all, 
   1663                                                type, arg);
   1664             BCM_IF_ERROR_RETURN
   1665                 (BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1666         }
   1667     } else {
   1668         int         bcm_unit;
   1669         bcm_port_t  bcm_port;
   1670 
   1671         BCM_IF_ERROR_RETURN
   1672             (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   1673                                      BCMX_DEST_CONVERT_DEFAULT));
   1674 
   1675         return bcm_vlan_control_port_set(bcm_unit, bcm_port,
   1676                                          type, arg);
   1677     }
   1678 
   1679     return rv;
   1680 }
   1681 
   1682 
   1683 int
   1684 bcmx_vlan_control_port_get(bcmx_lport_t port,
   1685                            bcm_vlan_control_port_t type,
   1686                            int *arg)
   1687 {
   1688     int         bcm_unit;
   1689     bcm_port_t  bcm_port;
   1690 
   1691     BCMX_VLAN_INIT_CHECK;
   1692 
   1693     BCMX_PARAM_NULL_CHECK(arg);
   1694 
   1695     BCM_IF_ERROR_RETURN
   1696         (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   1697                                  BCMX_DEST_CONVERT_DEFAULT));
   1698 
   1699     return bcm_vlan_control_port_get(bcm_unit, bcm_port,
   1700                                      type, arg);
   1701 }
   1702 
   1703 
   1704 int
   1705 bcmx_vlan_mcast_flood_set(bcm_vlan_t vlan,
   1706                           bcm_vlan_mcast_flood_t mode)
   1707 {
   1708     int rv = BCM_E_UNAVAIL, tmp_rv;
   1709     int i, bcm_unit;
   1710 
   1711     BCMX_VLAN_INIT_CHECK;
   1712 
   1713     BCMX_UNIT_ITER(bcm_unit, i) {
   1714         tmp_rv = bcm_vlan_mcast_flood_set(bcm_unit, vlan, mode);
   1715         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1716     }
   1717 
   1718     return rv;
   1719 }
   1720 
   1721 int
   1722 bcmx_vlan_mcast_flood_get(bcm_vlan_t vlan,
   1723                           bcm_vlan_mcast_flood_t *mode)
   1724 {
   1725     int rv;
   1726     int i, bcm_unit;
   1727 
   1728     BCMX_VLAN_INIT_CHECK;
   1729 
   1730     BCMX_PARAM_NULL_CHECK(mode);
   1731 
   1732     BCMX_UNIT_ITER(bcm_unit, i) {
   1733         rv = bcm_vlan_mcast_flood_get(bcm_unit, vlan, mode);
   1734         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, rv)) {
   1735             return rv;
   1736         }
   1737     }
   1738 
   1739     return BCM_E_UNAVAIL;
   1740 }
   1741 
   1742 /*
   1743  * Function:
   1744  *      bcmx_vlan_control_vlan_set
   1745  */
   1746 int 
   1747 bcmx_vlan_control_vlan_set(bcm_vlan_t vlan,
   1748                            bcm_vlan_control_vlan_t control) 
   1749 {
   1750     int rv = BCM_E_UNAVAIL, tmp_rv;
   1751     int i, bcm_unit;
   1752 
   1753     BCMX_VLAN_INIT_CHECK;
   1754 
   1755     BCMX_UNIT_ITER(bcm_unit, i) {
   1756         tmp_rv = bcm_vlan_control_vlan_set(bcm_unit, vlan, control);
   1757         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1758     }
   1759 
   1760     return rv;
   1761 }
   1762 
   1763 /*
   1764  * Function:
   1765  *      bcmx_vlan_control_vlan_get
   1766  */
   1767 int
   1768 bcmx_vlan_control_vlan_get(bcm_vlan_t vlan,
   1769                            bcm_vlan_control_vlan_t *control) 
   1770 {
   1771     int rv;
   1772     int i, bcm_unit;
   1773 
   1774     BCMX_VLAN_INIT_CHECK;
   1775 
   1776     BCMX_PARAM_NULL_CHECK(control);
   1777 
   1778     BCMX_UNIT_ITER(bcm_unit, i) {
   1779         rv = bcm_vlan_control_vlan_get(bcm_unit, vlan, control);
   1780         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, rv)) {
   1781             return rv;
   1782         }
   1783     }
   1784 
   1785     return BCM_E_UNAVAIL;
   1786 }
   1787 
   1788 /*
   1789  * Function:
   1790  *      bcmx_vlan_vector_flags_set
   1791  */
   1792 int
   1793 bcmx_vlan_vector_flags_set(bcm_vlan_vector_t vlan_vector,
   1794                            uint32 flags_mask, uint32 flags_value)
   1795 {
   1796     int rv = BCM_E_UNAVAIL, tmp_rv;
   1797     int i, bcm_unit;
   1798 
   1799     BCMX_VLAN_INIT_CHECK;
   1800 
   1801     BCMX_UNIT_ITER(bcm_unit, i) {
   1802         tmp_rv = bcm_vlan_vector_flags_set(bcm_unit, vlan_vector,
   1803                                            flags_mask, flags_value);
   1804         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1805     }
   1806 
   1807     return rv;
   1808 }
   1809 
   1810 /*
   1811  * Function:
   1812  *      bcmx_vlan_cross_connect_add
   1813  */
   1814 int
   1815 bcmx_vlan_cross_connect_add(bcm_vlan_t outer_vlan, bcm_vlan_t inner_vlan, 
   1816                             bcm_gport_t port_1, bcm_gport_t port_2)
   1817 {
   1818     int rv = BCM_E_UNAVAIL, tmp_rv;
   1819     int i, bcm_unit;
   1820 
   1821     BCMX_VLAN_INIT_CHECK;
   1822 
   1823     BCMX_UNIT_ITER(bcm_unit, i) {
   1824         tmp_rv = bcm_vlan_cross_connect_add(bcm_unit,
   1825                                             outer_vlan, inner_vlan,
   1826                                             port_1, port_2);
   1827         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1828     }
   1829 
   1830     return rv;
   1831 }
   1832 
   1833 /*
   1834  * Function:
   1835  *      bcmx_vlan_cross_connect_delete
   1836  */
   1837 int bcmx_vlan_cross_connect_delete(bcm_vlan_t outer_vlan, 
   1838                                    bcm_vlan_t inner_vlan)
   1839 {
   1840     int rv = BCM_E_UNAVAIL, tmp_rv;
   1841     int i, bcm_unit;
   1842 
   1843     BCMX_VLAN_INIT_CHECK;
   1844 
   1845     BCMX_UNIT_ITER(bcm_unit, i) {
   1846         tmp_rv = bcm_vlan_cross_connect_delete(bcm_unit,
   1847                                                outer_vlan, inner_vlan);
   1848         BCM_IF_ERROR_RETURN
   1849             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1850     }
   1851 
   1852     return rv;
   1853 }
   1854 
   1855 /*
   1856  * Function:
   1857  *      bcmx_vlan_cross_connect_delete_all
   1858  */
   1859 int
   1860 bcmx_vlan_cross_connect_delete_all(void)
   1861 {
   1862     int rv = BCM_E_UNAVAIL, tmp_rv;
   1863     int i, bcm_unit;
   1864 
   1865     BCMX_VLAN_INIT_CHECK;
   1866 
   1867     BCMX_UNIT_ITER(bcm_unit, i) {
   1868         tmp_rv = bcm_vlan_cross_connect_delete_all(bcm_unit);
   1869         BCM_IF_ERROR_RETURN
   1870             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1871     }
   1872 
   1873     return rv;
   1874 }
   1875 
   1876 void
   1877 bcmx_vlan_block_t_init(bcmx_vlan_block_t *data)
   1878 {
   1879     bcmx_lplist_t_init(&data->known_multicast);
   1880     bcmx_lplist_t_init(&data->unknown_multicast);
   1881     bcmx_lplist_t_init(&data->unknown_unicast);
   1882     bcmx_lplist_t_init(&data->broadcast);
   1883 }
   1884 
   1885 int
   1886 bcmx_vlan_block_get(bcm_vlan_t vlan, bcmx_vlan_block_t *vlan_block)
   1887 {
   1888     int rv = BCM_E_UNAVAIL, tmp_rv;
   1889     int i, bcm_unit;
   1890     bcm_vlan_block_t bcm_vlb;
   1891 
   1892     BCMX_VLAN_INIT_CHECK;
   1893 
   1894     BCMX_PARAM_NULL_CHECK(vlan_block);
   1895 
   1896     bcmx_vlan_block_t_init(vlan_block);
   1897     BCMX_UNIT_ITER(bcm_unit, i) {
   1898         bcm_vlan_block_t_init(&bcm_vlb);
   1899         tmp_rv = bcm_vlan_block_get(bcm_unit, vlan, &bcm_vlb);
   1900 
   1901         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, tmp_rv)) {
   1902             rv = tmp_rv;
   1903             if (BCM_FAILURE(tmp_rv)) {
   1904                 break;
   1905             }
   1906 
   1907             BCM_IF_ERROR_RETURN
   1908                 (bcmx_lplist_pbmp_add(&vlan_block->known_multicast,
   1909                                       bcm_unit, &bcm_vlb.known_multicast));
   1910             BCM_IF_ERROR_RETURN
   1911                 (bcmx_lplist_pbmp_add(&vlan_block->unknown_multicast,
   1912                                       bcm_unit, &bcm_vlb.unknown_multicast));
   1913             BCM_IF_ERROR_RETURN
   1914                 (bcmx_lplist_pbmp_add(&vlan_block->unknown_unicast,
   1915                                       bcm_unit, &bcm_vlb.unknown_unicast));
   1916             BCM_IF_ERROR_RETURN
   1917                 (bcmx_lplist_pbmp_add(&vlan_block->broadcast,
   1918                                       bcm_unit, &bcm_vlb.broadcast));
   1919         }
   1920     }
   1921 
   1922     return rv;
   1923 }
   1924 
   1925 int
   1926 bcmx_vlan_block_set(bcm_vlan_t vlan, bcmx_vlan_block_t *vlan_block)
   1927 {
   1928     int rv = BCM_E_UNAVAIL, tmp_rv;
   1929     int i, bcm_unit;
   1930     bcm_vlan_block_t bcm_vlb;
   1931 
   1932     BCMX_VLAN_INIT_CHECK;
   1933 
   1934     BCMX_PARAM_NULL_CHECK(vlan_block);
   1935 
   1936     BCMX_UNIT_ITER(bcm_unit, i) {
   1937         bcm_vlan_block_t_init(&bcm_vlb);
   1938         BCMX_LPLIST_TO_PBMP(vlan_block->known_multicast,
   1939                             bcm_unit, bcm_vlb.known_multicast);
   1940         BCMX_LPLIST_TO_PBMP(vlan_block->unknown_multicast,
   1941                             bcm_unit, bcm_vlb.unknown_multicast);
   1942         BCMX_LPLIST_TO_PBMP(vlan_block->unknown_unicast,
   1943                             bcm_unit, bcm_vlb.unknown_unicast);
   1944         BCMX_LPLIST_TO_PBMP(vlan_block->broadcast,
   1945                             bcm_unit, bcm_vlb.broadcast);
   1946         tmp_rv = bcm_vlan_block_set(bcm_unit, vlan, &bcm_vlb);
   1947         BCM_IF_ERROR_RETURN
   1948             (BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1949     }
   1950     
   1951     return rv;
   1952 }
   1953 
   1954 /*
   1955  * Function:
   1956  *      bcmx_vlan_stat_enable_set
   1957  * Purpose:
   1958  *      Enable/disable collection of statistics on the indicated VLAN.
   1959  * Parameters:
   1960  *      vlan   - VLAN Id
   1961  *      enable - Non-zero to enable counter collection, zero to disable
   1962  * Returns:
   1963  *      BCM_E_XXX
   1964  * Notes:
   1965  */
   1966 int
   1967 bcmx_vlan_stat_enable_set(bcm_vlan_t vlan, int enable)
   1968 {
   1969     int  rv = BCM_E_UNAVAIL, tmp_rv;
   1970     int  i, bcm_unit;
   1971 
   1972     BCMX_VLAN_INIT_CHECK;
   1973 
   1974     BCMX_UNIT_ITER(bcm_unit, i) {
   1975         tmp_rv = bcm_vlan_stat_enable_set(bcm_unit, vlan, enable);
   1976         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   1977     }
   1978 
   1979     return rv;
   1980 }
   1981 
   1982 /*
   1983  * Function:
   1984  *      bcmx_vlan_stat_multi_get
   1985  * Purpose:
   1986  *      Get 64-bit counter value for multiple VLAN statistic types.
   1987  * Parameters:
   1988  *      vlan      - VLAN Id
   1989  *      cos       - COS or priority
   1990  *      nstat     - Number of elements in stat array
   1991  *      stat_arr  - Collected statistics descriptors array
   1992  *      value_arr - (OUT) Collected counters values
   1993  * Returns:
   1994  *      BCM_E_XXX
   1995  * Notes:
   1996  */
   1997 int
   1998 bcmx_vlan_stat_multi_get(bcm_vlan_t vlan, bcm_cos_t cos, int nstat, 
   1999                          bcm_vlan_stat_t *stat_arr, uint64 *value_arr)
   2000 {
   2001     int     rv = BCM_E_UNAVAIL, tmp_rv;
   2002     int     i, bcm_unit;
   2003     uint64  *tmp_val;
   2004 
   2005     BCMX_VLAN_INIT_CHECK;
   2006 
   2007     BCMX_PARAM_ARRAY_NULL_CHECK(nstat, stat_arr);
   2008     BCMX_PARAM_ARRAY_NULL_CHECK(nstat, value_arr);
   2009 
   2010     tmp_val = sal_alloc(sizeof(uint64) * nstat, "bcmx vlan stat");
   2011     if (tmp_val == NULL) {
   2012         return BCM_E_MEMORY;
   2013     }
   2014 
   2015     for (i = 0; i < nstat; i++) {
   2016         COMPILER_64_ZERO(value_arr[i]);
   2017     }
   2018     BCMX_UNIT_ITER(bcm_unit, i) {
   2019         tmp_rv = bcm_vlan_stat_multi_get(bcm_unit, vlan, cos, nstat,
   2020                                          stat_arr, tmp_val);
   2021         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, tmp_rv)) {
   2022             rv = tmp_rv;
   2023             if (BCM_SUCCESS(tmp_rv)) {
   2024                 for (i = 0; i < nstat; i++) {
   2025                     COMPILER_64_ADD_64(value_arr[i], tmp_val[i]);
   2026                 }
   2027             } else {
   2028                 break;
   2029             }
   2030         }
   2031     }
   2032 
   2033     sal_free(tmp_val);
   2034 
   2035     return rv;
   2036 }
   2037 
   2038 /*
   2039  * Function:
   2040  *      bcmx_vlan_stat_multi_get32
   2041  * Purpose:
   2042  *      Get lower 32-bit counter value for multiple VLAN statistic types.
   2043  * Parameters:
   2044  *      vlan      - VLAN Id
   2045  *      cos       - COS or priority
   2046  *      nstat     - Number of elements in stat array
   2047  *      stat_arr  - Collected statistics descriptors array
   2048  *      value_arr - (OUT) Collected counters values
   2049  * Returns:
   2050  *      BCM_E_XXX
   2051  * Notes:
   2052  */
   2053 int
   2054 bcmx_vlan_stat_multi_get32(bcm_vlan_t vlan, bcm_cos_t cos, int nstat,
   2055                            bcm_vlan_stat_t *stat_arr, uint32 *value_arr)
   2056 {
   2057     int     rv = BCM_E_UNAVAIL, tmp_rv;
   2058     int     i, bcm_unit;
   2059     uint32  *tmp_val;
   2060 
   2061     BCMX_VLAN_INIT_CHECK;
   2062 
   2063     BCMX_PARAM_ARRAY_NULL_CHECK(nstat, stat_arr);
   2064     BCMX_PARAM_ARRAY_NULL_CHECK(nstat, value_arr);
   2065 
   2066     tmp_val = sal_alloc(sizeof(uint32) * nstat, "bcmx vlan stat");
   2067     if (tmp_val == NULL) {
   2068         return BCM_E_MEMORY;
   2069     }
   2070 
   2071     for (i = 0; i < nstat; i++) {
   2072         value_arr[i] = 0;
   2073     }
   2074     BCMX_UNIT_ITER(bcm_unit, i) {
   2075         tmp_rv = bcm_vlan_stat_multi_get32(bcm_unit, vlan, cos, nstat,
   2076                                            stat_arr, tmp_val);
   2077         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, tmp_rv)) {
   2078             rv = tmp_rv;
   2079             if (BCM_SUCCESS(tmp_rv)) {
   2080                 for (i = 0; i < nstat; i++) {
   2081                     value_arr[i] += tmp_val[i];
   2082                 }
   2083             } else {
   2084                 break;
   2085             }
   2086         }
   2087     }
   2088 
   2089     sal_free(tmp_val);
   2090 
   2091     return rv;
   2092 }
   2093 
   2094 /*
   2095  * Function:
   2096  *      bcmx_vlan_stat_multi_set
   2097  * Purpose:
   2098  *      Set 64-bit counter value for multiple VLAN statistic types.
   2099  * Parameters:
   2100  *      vlan      - VLAN Id
   2101  *      cos       - COS or priority
   2102  *      nstat     - Number of elements in stat array
   2103  *      stat_arr  - New statistics descriptors array
   2104  *      value_arr - New counters values
   2105  * Returns:
   2106  *      BCM_E_XXX
   2107  * Notes:
   2108  */
   2109 int
   2110 bcmx_vlan_stat_multi_set(bcm_vlan_t vlan, bcm_cos_t cos, int nstat, 
   2111                          bcm_vlan_stat_t *stat_arr, uint64 *value_arr)
   2112 {
   2113     int  rv = BCM_E_UNAVAIL, tmp_rv;
   2114     int  i, bcm_unit;
   2115 
   2116     BCMX_VLAN_INIT_CHECK;
   2117 
   2118     BCMX_PARAM_ARRAY_NULL_CHECK(nstat, stat_arr);
   2119     BCMX_PARAM_ARRAY_NULL_CHECK(nstat, value_arr);
   2120 
   2121     BCMX_UNIT_ITER(bcm_unit, i) {
   2122         tmp_rv = bcm_vlan_stat_multi_set(bcm_unit, vlan, cos, nstat,
   2123                                          stat_arr, value_arr);
   2124         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   2125     }
   2126 
   2127     return rv;
   2128 }
   2129 
   2130 /*
   2131  * Function:
   2132  *      bcmx_vlan_stat_multi_set32
   2133  * Purpose:
   2134  *      Set lower 32-bit counter value for multiple VLAN statistic types.
   2135  * Parameters:
   2136  *      vlan      - VLAN Id
   2137  *      cos       - COS or priority
   2138  *      nstat     - Number of elements in stat array
   2139  *      stat_arr  - New statistics descriptors array
   2140  *      value_arr - New counters values
   2141  * Returns:
   2142  *      BCM_E_XXX
   2143  * Notes:
   2144  */
   2145 int
   2146 bcmx_vlan_stat_multi_set32(bcm_vlan_t vlan, bcm_cos_t cos, int nstat, 
   2147                            bcm_vlan_stat_t *stat_arr, uint32 *value_arr)
   2148 {
   2149     int  rv = BCM_E_UNAVAIL, tmp_rv;
   2150     int  i, bcm_unit;
   2151 
   2152     BCMX_VLAN_INIT_CHECK;
   2153 
   2154     BCMX_PARAM_ARRAY_NULL_CHECK(nstat, stat_arr);
   2155     BCMX_PARAM_ARRAY_NULL_CHECK(nstat, value_arr);
   2156 
   2157     BCMX_UNIT_ITER(bcm_unit, i) {
   2158         tmp_rv = bcm_vlan_stat_multi_set32(bcm_unit, vlan, cos, nstat,
   2159                                            stat_arr, value_arr);
   2160         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   2161     }
   2162 
   2163     return rv;
   2164 }
   2165 
   2166 /*
   2167  * Function:
   2168  *      bcmx_vlan_translate_stat_enable_set
   2169  * Purpose:
   2170  *      Enable/disable collection of statistics on the indicated
   2171  *      ingress VLAN translation.
   2172  * Parameters:
   2173  *      port       - Generic port, physical (lport) or virtual port
   2174  *      key_type   - Key Type : bcmVlanTranslateKey*
   2175  *      outer_vlan - Packet outer VLAN ID
   2176  *      inner_vlan - Packet inner VLAN ID
   2177  *      enable     - Non-zero to enable counter collection, zero to disable.
   2178  * Returns:
   2179  *      BCM_E_XXX
   2180  */
   2181 int
   2182 bcmx_vlan_translate_stat_enable_set(bcm_gport_t port, 
   2183                                     bcm_vlan_translate_key_t key_type, 
   2184                                     bcm_vlan_t outer_vlan,
   2185                                     bcm_vlan_t inner_vlan, 
   2186                                     int enable)
   2187 {
   2188     int         rv = BCM_E_UNAVAIL, tmp_rv;
   2189     int         bcm_unit;
   2190     bcm_port_t  bcm_port;
   2191     int         i;
   2192 
   2193     BCMX_VLAN_INIT_CHECK;
   2194 
   2195     if (!BCM_GPORT_IS_SET(port)) {
   2196         return BCM_E_PORT;
   2197     }
   2198 
   2199     /* Physical port, apply to unit where port resides */
   2200     if (BCM_SUCCESS(_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   2201                                             BCMX_DEST_CONVERT_DEFAULT))) {
   2202         return bcm_vlan_translate_stat_enable_set(bcm_unit, port, key_type,
   2203                                                   outer_vlan, inner_vlan,
   2204                                                   enable);
   2205     }
   2206 
   2207     /* Virtual port, enable/disable stat in all units */
   2208     BCMX_UNIT_ITER(bcm_unit, i) {
   2209         tmp_rv = bcm_vlan_translate_stat_enable_set(bcm_unit, port, key_type,
   2210                                                     outer_vlan, inner_vlan,
   2211                                                     enable);
   2212         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   2213     }
   2214 
   2215     return rv;
   2216 }
   2217 
   2218 /*
   2219  * Function:
   2220  *      bcmx_vlan_translate_stat_get/get32
   2221  * Purpose:
   2222  *      Extract ingress VLAN translation statistics from the chip.
   2223  * Parameters:
   2224  *      port       - Generic port, physical (lport) or virtual port
   2225  *      key_type   - Key Type : bcmVlanTranslateKey*
   2226  *      outer_vlan - Packet outer VLAN ID
   2227  *      inner_vlan - Packet inner VLAN ID
   2228  *      stat       - Type of the counter to retrieve.
   2229  *      val        - (OUT) Pointer to a counter value.
   2230  * Returns:
   2231  *      BCM_E_XXX
   2232  */
   2233 int
   2234 bcmx_vlan_translate_stat_get(bcm_gport_t port,
   2235                              bcm_vlan_translate_key_t key_type, 
   2236                              bcm_vlan_t outer_vlan, bcm_vlan_t inner_vlan, 
   2237                              bcm_vlan_stat_t stat, uint64 *val)
   2238 {
   2239     int         rv = BCM_E_UNAVAIL, tmp_rv;
   2240     int         bcm_unit;
   2241     bcm_port_t  bcm_port;
   2242     uint64      tmp_val;
   2243     int         i;
   2244 
   2245     BCMX_VLAN_INIT_CHECK;
   2246 
   2247     if (!BCM_GPORT_IS_SET(port)) {
   2248         return BCM_E_PORT;
   2249     }
   2250     BCMX_PARAM_NULL_CHECK(val);
   2251 
   2252     /* Physical port, get stat from unit where port resides */
   2253     if (BCM_SUCCESS(_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   2254                                             BCMX_DEST_CONVERT_DEFAULT))) {
   2255         return bcm_vlan_translate_stat_get(bcm_unit, port, key_type,
   2256                                            outer_vlan, inner_vlan, stat, val);
   2257     }
   2258 
   2259     /* Virtual port, gather stats from all units */
   2260     COMPILER_64_ZERO(*val);
   2261     BCMX_UNIT_ITER(bcm_unit, i) {
   2262         tmp_rv = bcm_vlan_translate_stat_get(bcm_unit, port, key_type,
   2263                                              outer_vlan, inner_vlan, stat,
   2264                                              &tmp_val);
   2265         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, tmp_rv)) {
   2266             rv = tmp_rv;
   2267             if (BCM_SUCCESS(tmp_rv)) {
   2268                 COMPILER_64_ADD_64(*val, tmp_val);
   2269             } else {
   2270                 break;
   2271             }
   2272         }
   2273     }
   2274 
   2275     return rv;
   2276 }
   2277 
   2278 int
   2279 bcmx_vlan_translate_stat_get32(bcm_gport_t port, 
   2280                                bcm_vlan_translate_key_t key_type, 
   2281                                bcm_vlan_t outer_vlan, bcm_vlan_t inner_vlan, 
   2282                                bcm_vlan_stat_t stat, uint32 *val)
   2283 {
   2284     int         rv = BCM_E_UNAVAIL, tmp_rv;
   2285     int         bcm_unit;
   2286     bcm_port_t  bcm_port;
   2287     uint32      tmp_val;
   2288     int         i;
   2289 
   2290     BCMX_VLAN_INIT_CHECK;
   2291 
   2292     if (!BCM_GPORT_IS_SET(port)) {
   2293         return BCM_E_PORT;
   2294     }
   2295     BCMX_PARAM_NULL_CHECK(val);
   2296 
   2297     /* Physical port, get stat from unit where port resides */
   2298     if (BCM_SUCCESS(_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   2299                                             BCMX_DEST_CONVERT_DEFAULT))) {
   2300         return bcm_vlan_translate_stat_get32(bcm_unit, port, key_type,
   2301                                              outer_vlan, inner_vlan, stat, val);
   2302     }
   2303 
   2304     /* Virtual port, gather stats from all units */
   2305     *val = 0;
   2306     BCMX_UNIT_ITER(bcm_unit, i) {
   2307         tmp_rv = bcm_vlan_translate_stat_get32(bcm_unit, port, key_type,
   2308                                                outer_vlan, inner_vlan, stat,
   2309                                                &tmp_val);
   2310         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, tmp_rv)) {
   2311             rv = tmp_rv;
   2312             if (BCM_SUCCESS(tmp_rv)) {
   2313                 *val += tmp_val;
   2314             } else {
   2315                 break;
   2316             }
   2317         }
   2318     }
   2319 
   2320     return rv;
   2321 }
   2322 
   2323 /*
   2324  * Function:
   2325  *      bcmx_vlan_translate_stat_set/set32
   2326  * Purpose:
   2327  *      Set the specified statistic to the indicated value for the
   2328  *      specified ingress VLAN translation.
   2329  * Parameters:
   2330  *      port       - Generic port, physical (lport) or virtual port
   2331  *      key_type   - Key Type : bcmVlanTranslateKey*
   2332  *      outer_vlan - Packet outer VLAN ID
   2333  *      inner_vlan - Packet inner VLAN ID
   2334  *      stat       - Type of the counter to retrieve.
   2335  *      val        - New counter value
   2336  * Returns:
   2337  *      BCM_E_XXX
   2338  */
   2339 int
   2340 bcmx_vlan_translate_stat_set(bcm_gport_t port, 
   2341                              bcm_vlan_translate_key_t key_type, 
   2342                              bcm_vlan_t outer_vlan, bcm_vlan_t inner_vlan, 
   2343                              bcm_vlan_stat_t stat, uint64 val)
   2344 {
   2345     int         rv = BCM_E_UNAVAIL, tmp_rv;
   2346     int         bcm_unit;
   2347     bcm_port_t  bcm_port;
   2348     int         i;
   2349 
   2350     BCMX_VLAN_INIT_CHECK;
   2351 
   2352     if (!BCM_GPORT_IS_SET(port)) {
   2353         return BCM_E_PORT;
   2354     }
   2355 
   2356     /* Physical port, set stat in unit where port resides */
   2357     if (BCM_SUCCESS(_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   2358                                             BCMX_DEST_CONVERT_DEFAULT))) {
   2359         return bcm_vlan_translate_stat_set(bcm_unit, port, key_type,
   2360                                            outer_vlan, inner_vlan, stat, val);
   2361     }
   2362 
   2363     /* Virtual port, set stat in all units */
   2364     BCMX_UNIT_ITER(bcm_unit, i) {
   2365         tmp_rv = bcm_vlan_translate_stat_set(bcm_unit, port, key_type,
   2366                                              outer_vlan, inner_vlan, stat,
   2367                                              val);
   2368         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   2369     }
   2370 
   2371     return rv;
   2372 }
   2373 
   2374 int
   2375 bcmx_vlan_translate_stat_set32(bcm_gport_t port, 
   2376                                bcm_vlan_translate_key_t key_type, 
   2377                                bcm_vlan_t outer_vlan, bcm_vlan_t inner_vlan, 
   2378                                bcm_vlan_stat_t stat, uint32 val)
   2379 {
   2380     int         rv = BCM_E_UNAVAIL, tmp_rv;
   2381     int         bcm_unit;
   2382     bcm_port_t  bcm_port;
   2383     int         i;
   2384 
   2385     BCMX_VLAN_INIT_CHECK;
   2386 
   2387     if (!BCM_GPORT_IS_SET(port)) {
   2388         return BCM_E_PORT;
   2389     }
   2390 
   2391     /* Physical port, set stat in unit where port resides */
   2392     if (BCM_SUCCESS(_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   2393                                             BCMX_DEST_CONVERT_DEFAULT))) {
   2394         return bcm_vlan_translate_stat_set32(bcm_unit, port, key_type,
   2395                                              outer_vlan, inner_vlan, stat,
   2396                                              val);
   2397     }
   2398 
   2399     /* Virtual port, set stat in all units */
   2400     BCMX_UNIT_ITER(bcm_unit, i) {
   2401         tmp_rv =  bcm_vlan_translate_stat_set32(bcm_unit, port, key_type,
   2402                                                 outer_vlan, inner_vlan, stat,
   2403                                                 val);
   2404         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   2405     }
   2406 
   2407     return rv;
   2408 }
   2409 
   2410 /*
   2411  * Function:
   2412  *      bcmx_vlan_translate_stat_multi_get/get32
   2413  * Purpose:
   2414  *      Get 64-bit/32-bit counter values for multiple ingress VLAN translation
   2415  *      statistic types.
   2416  * Parameters:
   2417  *      port       - Generic port, physical (lport) or virtual port
   2418  *      key_type   - Key Type : bcmVlanTranslateKey*
   2419  *      outer_vlan - Packet outer VLAN ID
   2420  *      inner_vlan - Packet inner VLAN ID
   2421  *      nstat      - Number of elements in stat array
   2422  *      stat_arr   - Collected statistics descriptors array
   2423  *      value_arr  - (OUT) Collected counters values
   2424  * Returns:
   2425  *      BCM_E_xxx
   2426  */
   2427 int
   2428 bcmx_vlan_translate_stat_multi_get(bcm_gport_t port, 
   2429                                    bcm_vlan_translate_key_t key_type, 
   2430                                    bcm_vlan_t outer_vlan,
   2431                                    bcm_vlan_t inner_vlan,
   2432                                    int nstat, bcm_vlan_stat_t *stat_arr, 
   2433                                    uint64 *value_arr)
   2434 {
   2435     int         rv = BCM_E_UNAVAIL, tmp_rv;
   2436     int         bcm_unit;
   2437     bcm_port_t  bcm_port;
   2438     uint64      *tmp_val;
   2439     int         i;
   2440 
   2441     BCMX_VLAN_INIT_CHECK;
   2442 
   2443     if (!BCM_GPORT_IS_SET(port)) {
   2444         return BCM_E_PORT;
   2445     }
   2446     BCMX_PARAM_ARRAY_NULL_CHECK(nstat, stat_arr);
   2447     BCMX_PARAM_ARRAY_NULL_CHECK(nstat, value_arr);
   2448 
   2449     /* Physical port, get stat from unit where port resides */
   2450     if (BCM_SUCCESS(_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   2451                                             BCMX_DEST_CONVERT_DEFAULT))) {
   2452         return bcm_vlan_translate_stat_multi_get(bcm_unit, port, key_type,
   2453                                                  outer_vlan, inner_vlan,
   2454                                                  nstat, stat_arr, value_arr);
   2455     }
   2456 
   2457     /* Virtual port, gather stats from all units */
   2458     tmp_val = sal_alloc(sizeof(uint64) * nstat, "bcmx vlan translate stat");
   2459     if (tmp_val == NULL) {
   2460         return BCM_E_MEMORY;
   2461     }
   2462 
   2463     for (i = 0; i < nstat; i++) {
   2464         COMPILER_64_ZERO(value_arr[i]);
   2465     }
   2466     BCMX_UNIT_ITER(bcm_unit, i) {
   2467         tmp_rv = bcm_vlan_translate_stat_multi_get(bcm_unit, port, key_type,
   2468                                                    outer_vlan, inner_vlan,
   2469                                                    nstat, stat_arr, tmp_val);
   2470         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, tmp_rv)) {
   2471             rv = tmp_rv;
   2472             if (BCM_SUCCESS(tmp_rv)) {
   2473                 for (i = 0; i < nstat; i++) {
   2474                     COMPILER_64_ADD_64(value_arr[i], tmp_val[i]);
   2475                 }
   2476             } else {
   2477                 break;
   2478             }
   2479         }
   2480     }
   2481 
   2482     sal_free(tmp_val);
   2483 
   2484     return rv;
   2485 }
   2486 
   2487 int
   2488 bcmx_vlan_translate_stat_multi_get32(bcm_gport_t port, 
   2489                                      bcm_vlan_translate_key_t key_type, 
   2490                                      bcm_vlan_t outer_vlan,
   2491                                      bcm_vlan_t inner_vlan,
   2492                                      int nstat, bcm_vlan_stat_t *stat_arr, 
   2493                                      uint32 *value_arr)
   2494 {
   2495     int         rv = BCM_E_UNAVAIL, tmp_rv;
   2496     int         bcm_unit;
   2497     bcm_port_t  bcm_port;
   2498     uint32      *tmp_val;
   2499     int         i;
   2500 
   2501     BCMX_VLAN_INIT_CHECK;
   2502 
   2503     if (!BCM_GPORT_IS_SET(port)) {
   2504         return BCM_E_PORT;
   2505     }
   2506     BCMX_PARAM_NULL_CHECK(stat_arr);
   2507     BCMX_PARAM_NULL_CHECK(value_arr);
   2508 
   2509     /* Physical port, get stat from unit where port resides */
   2510     if (BCM_SUCCESS(_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   2511                                             BCMX_DEST_CONVERT_DEFAULT))) {
   2512         return bcm_vlan_translate_stat_multi_get32(bcm_unit, port, key_type,
   2513                                                    outer_vlan, inner_vlan,
   2514                                                    nstat, stat_arr, value_arr);
   2515     }
   2516 
   2517     /* Virtual port, gather stats from all units */
   2518     tmp_val = sal_alloc(sizeof(uint32) * nstat, "bcmx vlan translate stat");
   2519     if (tmp_val == NULL) {
   2520         return BCM_E_MEMORY;
   2521     }
   2522 
   2523     for (i = 0; i < nstat; i++) {
   2524         value_arr[i] = 0;
   2525     }
   2526     BCMX_UNIT_ITER(bcm_unit, i) {
   2527         tmp_rv = bcm_vlan_translate_stat_multi_get32(bcm_unit, port, key_type,
   2528                                                      outer_vlan, inner_vlan,
   2529                                                      nstat, stat_arr,
   2530                                                      tmp_val);
   2531         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, tmp_rv)) {
   2532             rv = tmp_rv;
   2533             if (BCM_SUCCESS(tmp_rv)) {
   2534                 for (i = 0; i < nstat; i++) {
   2535                     value_arr[i] += tmp_val[i];
   2536                 }
   2537             } else {
   2538                 break;
   2539             }
   2540         }
   2541     }
   2542 
   2543     sal_free(tmp_val);
   2544 
   2545     return rv;
   2546 }
   2547 
   2548 /*
   2549  * Function:
   2550  *      bcmx_vlan_translate_stat_multi_set/set32
   2551  * Purpose:
   2552  *      Set 64-bit/32-bit counter value for multiple ingress VLAN translation
   2553  *      statistic types.
   2554  * Parameters:
   2555  *      port       - Generic port, physical (lport) or virtual port
   2556  *      key_type   - Key Type : bcmVlanTranslateKey*
   2557  *      outer_vlan - Packet outer VLAN ID
   2558  *      inner_vlan - Packet inner VLAN ID
   2559  *      nstat      - Number of elements in stat array
   2560  *      stat_arr   - New statistics descriptors array
   2561  *      value_arr  - New counters values
   2562  * Returns:
   2563  *      BCM_E_xxx
   2564  */
   2565 int
   2566 bcmx_vlan_translate_stat_multi_set(bcm_gport_t port, 
   2567                                    bcm_vlan_translate_key_t key_type, 
   2568                                    bcm_vlan_t outer_vlan, 
   2569                                    bcm_vlan_t inner_vlan, 
   2570                                    int nstat, bcm_vlan_stat_t *stat_arr, 
   2571                                    uint64 *value_arr)
   2572 {
   2573     int         rv = BCM_E_UNAVAIL, tmp_rv;
   2574     int         bcm_unit;
   2575     bcm_port_t  bcm_port;
   2576     int         i;
   2577 
   2578     BCMX_VLAN_INIT_CHECK;
   2579 
   2580     if (!BCM_GPORT_IS_SET(port)) {
   2581         return BCM_E_PORT;
   2582     }
   2583     BCMX_PARAM_NULL_CHECK(stat_arr);
   2584     BCMX_PARAM_NULL_CHECK(value_arr);
   2585 
   2586     /* Physical port, set stat in unit where port resides */
   2587     if (BCM_SUCCESS(_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   2588                                             BCMX_DEST_CONVERT_DEFAULT))) {
   2589         return bcm_vlan_translate_stat_multi_set(bcm_unit, port, key_type,
   2590                                                  outer_vlan, inner_vlan,
   2591                                                  nstat, stat_arr, value_arr);
   2592     }
   2593 
   2594     /* Virtual port, set stat in all units */
   2595     BCMX_UNIT_ITER(bcm_unit, i) {
   2596         tmp_rv = bcm_vlan_translate_stat_multi_set(bcm_unit, port, key_type,
   2597                                                    outer_vlan, inner_vlan,
   2598                                                    nstat, stat_arr, value_arr);
   2599         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   2600     }
   2601 
   2602     return rv;
   2603 }
   2604 
   2605 int
   2606 bcmx_vlan_translate_stat_multi_set32(bcm_gport_t port, 
   2607                                      bcm_vlan_translate_key_t key_type, 
   2608                                      bcm_vlan_t outer_vlan, 
   2609                                      bcm_vlan_t inner_vlan, 
   2610                                      int nstat, bcm_vlan_stat_t *stat_arr, 
   2611                                      uint32 *value_arr)
   2612 {
   2613     int         rv = BCM_E_UNAVAIL, tmp_rv;
   2614     int         bcm_unit;
   2615     bcm_port_t  bcm_port;
   2616     int         i;
   2617 
   2618     BCMX_VLAN_INIT_CHECK;
   2619 
   2620     if (!BCM_GPORT_IS_SET(port)) {
   2621         return BCM_E_PORT;
   2622     }
   2623     BCMX_PARAM_NULL_CHECK(stat_arr);
   2624     BCMX_PARAM_NULL_CHECK(value_arr);
   2625 
   2626     /* Physical port, set stat in unit where port resides */
   2627     if (BCM_SUCCESS(_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   2628                                             BCMX_DEST_CONVERT_DEFAULT))) {
   2629         return bcm_vlan_translate_stat_multi_set32(bcm_unit, port, key_type,
   2630                                                    outer_vlan, inner_vlan,
   2631                                                    nstat, stat_arr, value_arr);
   2632     }
   2633 
   2634     /* Virtual port, set stat in all units */
   2635     BCMX_UNIT_ITER(bcm_unit, i) {
   2636         tmp_rv = bcm_vlan_translate_stat_multi_set32(bcm_unit, port, key_type,
   2637                                                      outer_vlan, inner_vlan,
   2638                                                      nstat, stat_arr,
   2639                                                      value_arr);
   2640         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   2641     }
   2642 
   2643     return rv;
   2644 }
   2645 
   2646 /*
   2647  * Function:
   2648  *      bcmx_vlan_translate_egress_stat_enable_set
   2649  * Purpose:
   2650  *      Enable/disable collection of statistics on the indicated
   2651  *      egress VLAN translation.
   2652  * Parameters:
   2653  *      port_class - Group ID of ingress port
   2654  *      outer_vlan - Packet outer VLAN ID
   2655  *      inner_vlan - Packet inner VLAN ID
   2656  *      enable     - Non-zero to enable counter collection, zero to disable
   2657  * Returns:
   2658  *      BCM_E_xxx
   2659  */
   2660 int
   2661 bcmx_vlan_translate_egress_stat_enable_set(int port_class, 
   2662                                            bcm_vlan_t outer_vlan, 
   2663                                            bcm_vlan_t inner_vlan, 
   2664                                            int enable)
   2665 {
   2666     int  rv = BCM_E_UNAVAIL, tmp_rv;
   2667     int  bcm_unit;
   2668     int  i;
   2669 
   2670     BCMX_VLAN_INIT_CHECK;
   2671 
   2672     /* 'port_class' is a global ID */
   2673     BCMX_UNIT_ITER(bcm_unit, i) {
   2674         tmp_rv = bcm_vlan_translate_egress_stat_enable_set(bcm_unit, port_class,
   2675                                                            outer_vlan,
   2676                                                            inner_vlan,
   2677                                                            enable);
   2678         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   2679     }
   2680 
   2681     return rv;
   2682 }
   2683 
   2684 /*
   2685  * Function:
   2686  *      bcmx_vlan_translate_egress_stat_get/get32
   2687  * Purpose:
   2688  *      Extract egress VLAN translation statistics from the chip.
   2689  * Parameters:
   2690  *      port_class - Group ID of ingress port
   2691  *      outer_vlan - Packet outer VLAN ID
   2692  *      inner_vlan - Packet inner VLAN ID
   2693  *      stat       - Type of the counter to retrieve
   2694  *      val        - (OUT) Pointer to a counter value
   2695  * Returns:
   2696  *      BCM_E_xxx
   2697  */
   2698 int
   2699 bcmx_vlan_translate_egress_stat_get(int port_class, 
   2700                                     bcm_vlan_t outer_vlan, 
   2701                                     bcm_vlan_t inner_vlan, 
   2702                                     bcm_vlan_stat_t stat, uint64 *val)
   2703 {
   2704     int     rv = BCM_E_UNAVAIL, tmp_rv;
   2705     int     bcm_unit;
   2706     uint64  tmp_val;
   2707     int     i;
   2708 
   2709     BCMX_VLAN_INIT_CHECK;
   2710 
   2711     BCMX_PARAM_NULL_CHECK(val);
   2712 
   2713     /* 'port_class' is a global ID */
   2714     COMPILER_64_ZERO(*val);
   2715     BCMX_UNIT_ITER(bcm_unit, i) {
   2716         tmp_rv = bcm_vlan_translate_egress_stat_get(bcm_unit, port_class,
   2717                                                     outer_vlan, inner_vlan,
   2718                                                     stat, &tmp_val);
   2719         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, tmp_rv)) {
   2720             rv = tmp_rv;
   2721             if (BCM_SUCCESS(tmp_rv)) {
   2722                 COMPILER_64_ADD_64(*val, tmp_val);
   2723             } else {
   2724                 break;
   2725             }
   2726         }
   2727     }
   2728 
   2729     return rv;
   2730 }
   2731 
   2732 int
   2733 bcmx_vlan_translate_egress_stat_get32(int port_class, 
   2734                                       bcm_vlan_t outer_vlan, 
   2735                                       bcm_vlan_t inner_vlan, 
   2736                                       bcm_vlan_stat_t stat, uint32 *val)
   2737 {
   2738     int     rv = BCM_E_UNAVAIL, tmp_rv;
   2739     int     bcm_unit;
   2740     uint32  tmp_val;
   2741     int     i;
   2742 
   2743     BCMX_VLAN_INIT_CHECK;
   2744 
   2745     BCMX_PARAM_NULL_CHECK(val);
   2746 
   2747     /* 'port_class' is a global ID */
   2748     *val = 0;
   2749     BCMX_UNIT_ITER(bcm_unit, i) {
   2750         tmp_rv = bcm_vlan_translate_egress_stat_get32(bcm_unit, port_class,
   2751                                                       outer_vlan, inner_vlan,
   2752                                                       stat, &tmp_val);
   2753         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, tmp_rv)) {
   2754             rv = tmp_rv;
   2755             if (BCM_SUCCESS(tmp_rv)) {
   2756                 *val += tmp_val;
   2757             } else {
   2758                 break;
   2759             }
   2760         }
   2761     }
   2762 
   2763     return rv;
   2764 }
   2765 
   2766 /*
   2767  * Function:
   2768  *      bcmx_vlan_translate_egress_stat_set/set32
   2769  * Purpose:
   2770  *      Set the specified statistic to the indicated value for the
   2771  *      specified egress VLAN translation.
   2772  * Parameters:
   2773  *      port_class - Group ID of ingress port
   2774  *      outer_vlan - Packet outer VLAN ID
   2775  *      inner_vlan - Packet inner VLAN ID
   2776  *      stat       - Type of the counter to set
   2777  *      val        - New counter value
   2778  * Returns:
   2779  *      BCM_E_xxx
   2780  */
   2781 int
   2782 bcmx_vlan_translate_egress_stat_set(int port_class, 
   2783                                     bcm_vlan_t outer_vlan, 
   2784                                     bcm_vlan_t inner_vlan, 
   2785                                     bcm_vlan_stat_t stat, uint64 val)
   2786 {
   2787     int  rv = BCM_E_UNAVAIL, tmp_rv;
   2788     int  bcm_unit;
   2789     int  i;
   2790 
   2791     BCMX_VLAN_INIT_CHECK;
   2792 
   2793     /* 'port_class' is a global ID */
   2794     BCMX_UNIT_ITER(bcm_unit, i) {
   2795         tmp_rv = bcm_vlan_translate_egress_stat_set(bcm_unit, port_class,
   2796                                                     outer_vlan, inner_vlan,
   2797                                                     stat, val);
   2798         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   2799     }
   2800 
   2801     return rv;
   2802 }
   2803 
   2804 int
   2805 bcmx_vlan_translate_egress_stat_set32(int port_class, 
   2806                                       bcm_vlan_t outer_vlan, 
   2807                                       bcm_vlan_t inner_vlan, 
   2808                                       bcm_vlan_stat_t stat, uint32 val)
   2809 {
   2810     int  rv = BCM_E_UNAVAIL, tmp_rv;
   2811     int  bcm_unit;
   2812     int  i;
   2813 
   2814     BCMX_VLAN_INIT_CHECK;
   2815 
   2816     /* 'port_class' is a global ID */
   2817     BCMX_UNIT_ITER(bcm_unit, i) {
   2818         tmp_rv =  bcm_vlan_translate_egress_stat_set32(bcm_unit, port_class,
   2819                                                        outer_vlan, inner_vlan,
   2820                                                        stat, val);
   2821         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   2822     }
   2823 
   2824     return rv;
   2825 }
   2826 
   2827 /*
   2828  * Function:
   2829  *      bcmx_vlan_translate_egress_stat_multi_get/get32
   2830  * Purpose:
   2831  *      Get 64-bit/32-bit counter value for multiple egress VLAN translation
   2832  *      statistic types.
   2833  * Parameters:
   2834  *      port_class - Group ID of ingress port
   2835  *      outer_vlan - Packet outer VLAN ID
   2836  *      inner_vlan - Packet inner VLAN ID
   2837  *      nstat      - Number of elements in stat array
   2838  *      stat_arr   - Collected statistics descriptors array
   2839  *      value_arr  - (OUT) Collected counters values
   2840  * Returns:
   2841  *      BCM_E_xxx
   2842  */
   2843 int
   2844 bcmx_vlan_translate_egress_stat_multi_get(int port_class, 
   2845                                           bcm_vlan_t outer_vlan, 
   2846                                           bcm_vlan_t inner_vlan, 
   2847                                           int nstat, bcm_vlan_stat_t *stat_arr, 
   2848                                           uint64 *value_arr)
   2849 {
   2850     int     rv = BCM_E_UNAVAIL, tmp_rv;
   2851     int     bcm_unit;
   2852     uint64  *tmp_val;
   2853     int     i;
   2854 
   2855     BCMX_VLAN_INIT_CHECK;
   2856 
   2857     BCMX_PARAM_ARRAY_NULL_CHECK(nstat, stat_arr);
   2858     BCMX_PARAM_ARRAY_NULL_CHECK(nstat, value_arr);
   2859 
   2860     tmp_val = sal_alloc(sizeof(uint64) * nstat,
   2861                         "bcmx vlan translate egress stat");
   2862     if (tmp_val == NULL) {
   2863         return BCM_E_MEMORY;
   2864     }
   2865 
   2866     for (i = 0; i < nstat; i++) {
   2867         COMPILER_64_ZERO(value_arr[i]);
   2868     }
   2869 
   2870     /* 'port_class' is a global ID */
   2871     BCMX_UNIT_ITER(bcm_unit, i) {
   2872         tmp_rv = bcm_vlan_translate_egress_stat_multi_get(bcm_unit, port_class,
   2873                                                           outer_vlan,
   2874                                                           inner_vlan,
   2875                                                           nstat, stat_arr,
   2876                                                           tmp_val);
   2877         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, tmp_rv)) {
   2878             rv = tmp_rv;
   2879             if (BCM_SUCCESS(tmp_rv)) {
   2880                 for (i = 0; i < nstat; i++) {
   2881                     COMPILER_64_ADD_64(value_arr[i], tmp_val[i]);
   2882                 }
   2883             } else {
   2884                 break;
   2885             }
   2886         }
   2887     }
   2888 
   2889     sal_free(tmp_val);
   2890 
   2891     return rv;
   2892 }
   2893 
   2894 int
   2895 bcmx_vlan_translate_egress_stat_multi_get32(int port_class, 
   2896                                             bcm_vlan_t outer_vlan, 
   2897                                             bcm_vlan_t inner_vlan, 
   2898                                             int nstat, 
   2899                                             bcm_vlan_stat_t *stat_arr, 
   2900                                             uint32 *value_arr)
   2901 {
   2902     int     rv = BCM_E_UNAVAIL, tmp_rv;
   2903     int     bcm_unit;
   2904     uint32  *tmp_val;
   2905     int     i;
   2906 
   2907     BCMX_VLAN_INIT_CHECK;
   2908 
   2909     BCMX_PARAM_NULL_CHECK(stat_arr);
   2910     BCMX_PARAM_NULL_CHECK(value_arr);
   2911 
   2912     tmp_val = sal_alloc(sizeof(uint32) * nstat,
   2913                         "bcmx vlan translate egress stat");
   2914     if (tmp_val == NULL) {
   2915         return BCM_E_MEMORY;
   2916     }
   2917 
   2918     for (i = 0; i < nstat; i++) {
   2919         value_arr[i] = 0;
   2920     }
   2921 
   2922     /* 'port_class' is a global ID */
   2923     BCMX_UNIT_ITER(bcm_unit, i) {
   2924         tmp_rv = bcm_vlan_translate_egress_stat_multi_get32(bcm_unit,
   2925                                                             port_class,
   2926                                                             outer_vlan,
   2927                                                             inner_vlan,
   2928                                                             nstat, stat_arr,
   2929                                                             tmp_val);
   2930         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, tmp_rv)) {
   2931             rv = tmp_rv;
   2932             if (BCM_SUCCESS(tmp_rv)) {
   2933                 for (i = 0; i < nstat; i++) {
   2934                     value_arr[i] += tmp_val[i];
   2935                 }
   2936             } else {
   2937                 break;
   2938             }
   2939         }
   2940     }
   2941 
   2942     sal_free(tmp_val);
   2943 
   2944     return rv;
   2945 }
   2946 
   2947 /*
   2948  * Function:
   2949  *      bcmx_vlan_translate_egress_stat_multi_set/set32
   2950  * Purpose:
   2951  *      Set 64-bit/32-bit counter value for multiple egress VLAN translation
   2952  *      statistic types.
   2953  * Parameters:
   2954  *      port_class - Group ID of ingress port
   2955  *      outer_vlan - Packet outer VLAN ID
   2956  *      inner_vlan - Packet inner VLAN ID
   2957  *      nstat      - Number of elements in stat array
   2958  *      stat_arr   - New statistics descriptors array
   2959  *      value_arr  - New counters values
   2960  * Returns:
   2961  *      BCM_E_xxx
   2962  */
   2963 int
   2964 bcmx_vlan_translate_egress_stat_multi_set(int port_class, 
   2965                                           bcm_vlan_t outer_vlan, 
   2966                                           bcm_vlan_t inner_vlan, 
   2967                                           int nstat, 
   2968                                           bcm_vlan_stat_t *stat_arr, 
   2969                                           uint64 *value_arr)
   2970 {
   2971     int  rv = BCM_E_UNAVAIL, tmp_rv;
   2972     int  bcm_unit;
   2973     int  i;
   2974 
   2975     BCMX_VLAN_INIT_CHECK;
   2976 
   2977     BCMX_PARAM_NULL_CHECK(stat_arr);
   2978     BCMX_PARAM_NULL_CHECK(value_arr);
   2979 
   2980     /* 'port_class' is a global ID */
   2981     BCMX_UNIT_ITER(bcm_unit, i) {
   2982         tmp_rv = bcm_vlan_translate_egress_stat_multi_set(bcm_unit, port_class,
   2983                                                           outer_vlan,
   2984                                                           inner_vlan,
   2985                                                           nstat, stat_arr,
   2986                                                           value_arr);
   2987         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   2988     }
   2989 
   2990     return rv;
   2991 }
   2992 
   2993 int
   2994 bcmx_vlan_translate_egress_stat_multi_set32(int port_class, 
   2995                                             bcm_vlan_t outer_vlan, 
   2996                                             bcm_vlan_t inner_vlan, 
   2997                                             int nstat, 
   2998                                             bcm_vlan_stat_t *stat_arr, 
   2999                                             uint32 *value_arr)
   3000 {
   3001     int  rv = BCM_E_UNAVAIL, tmp_rv;
   3002     int  bcm_unit;
   3003     int  i;
   3004 
   3005     BCMX_VLAN_INIT_CHECK;
   3006 
   3007     BCMX_PARAM_NULL_CHECK(stat_arr);
   3008     BCMX_PARAM_NULL_CHECK(value_arr);
   3009 
   3010     /* 'port_class' is a global ID */
   3011     BCMX_UNIT_ITER(bcm_unit, i) {
   3012         tmp_rv = bcm_vlan_translate_egress_stat_multi_set32(bcm_unit,
   3013                                                             port_class,
   3014                                                             outer_vlan,
   3015                                                             inner_vlan,
   3016                                                             nstat, stat_arr,
   3017                                                             value_arr);
   3018         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   3019     }
   3020 
   3021     return rv;
   3022 }
   3023 
   3024 
   3025 /*
   3026  * Function:
   3027  *      bcmx_vlan_queue_map_create
   3028  * Purpose:
   3029  *      Create a VLAN queue map entry.
   3030  * Parameters:
   3031  *      flags - Control flags
   3032  *      qmid  - (IN/OUT) Queue map identifier
   3033  * Returns:
   3034  *      BCM_E_XXX
   3035  * Notes:
   3036  */
   3037 int
   3038 bcmx_vlan_queue_map_create(uint32 flags, int *qmid)
   3039 {
   3040     int  rv = BCM_E_UNAVAIL, tmp_rv;
   3041     int  i, bcm_unit;
   3042 
   3043     BCMX_VLAN_INIT_CHECK;
   3044 
   3045     BCMX_PARAM_NULL_CHECK(qmid);
   3046 
   3047     BCMX_UNIT_ITER(bcm_unit, i) {
   3048 
   3049         tmp_rv = bcm_vlan_queue_map_create(bcm_unit, flags, qmid);
   3050         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   3051 
   3052         /*
   3053          * Use the ID from first successful 'create' if group ID
   3054          * is not specified.
   3055          */
   3056         if (!(flags & BCM_VLAN_QUEUE_MAP_WITH_ID)) {
   3057             if (BCM_SUCCESS(tmp_rv)) {
   3058                 flags |= BCM_VLAN_QUEUE_MAP_WITH_ID;
   3059             }
   3060         }
   3061     }
   3062 
   3063     return rv;
   3064 }
   3065 
   3066 /*
   3067  * Function:
   3068  *      bcmx_vlan_queue_map_destroy
   3069  * Purpose:
   3070  *      Delete a VLAN queue map entry.
   3071  * Parameters:
   3072  *      qmid  - Queue map identifier
   3073  * Returns:
   3074  *      BCM_E_XXX
   3075  * Notes:
   3076  */
   3077 int
   3078 bcmx_vlan_queue_map_destroy(int qmid)
   3079 {
   3080     int  rv = BCM_E_UNAVAIL, tmp_rv;
   3081     int  i, bcm_unit;
   3082 
   3083     BCMX_VLAN_INIT_CHECK;
   3084 
   3085     BCMX_UNIT_ITER(bcm_unit, i) {
   3086         tmp_rv = bcm_vlan_queue_map_destroy(bcm_unit, qmid);
   3087         BCM_IF_ERROR_RETURN
   3088             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   3089     }
   3090 
   3091     return rv;
   3092 }
   3093 
   3094 /*
   3095  * Function:
   3096  *      bcmx_vlan_queue_map_destroy_all
   3097  * Purpose:
   3098  *      Delete all VLAN queue map entries.
   3099  * Parameters:
   3100  *      None
   3101  * Returns:
   3102  *      BCM_E_XXX
   3103  * Notes:
   3104  */
   3105 int
   3106 bcmx_vlan_queue_map_destroy_all(void)
   3107 {
   3108     int  rv = BCM_E_UNAVAIL, tmp_rv;
   3109     int  i, bcm_unit;
   3110 
   3111     BCMX_VLAN_INIT_CHECK;
   3112 
   3113     BCMX_UNIT_ITER(bcm_unit, i) {
   3114         tmp_rv = bcm_vlan_queue_map_destroy_all(bcm_unit);
   3115         BCM_IF_ERROR_RETURN
   3116             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   3117     }
   3118 
   3119     return rv;
   3120 }
   3121 
   3122 /*
   3123  * Function:
   3124  *      bcmx_vlan_queue_map_set
   3125  * Purpose:
   3126  *      Set packet queue and color for a VLAN queue map entry.
   3127  * Parameters:
   3128  *      qmid    - Queue map identifier
   3129  *      pkt_pri - Packet priority
   3130  *      cfi     - Packet CFI value
   3131  *      queue   - Assigned COS queue number
   3132  *      color   - Assigned color value
   3133  * Returns:
   3134  *      BCM_E_XXX
   3135  * Notes:
   3136  */
   3137 int
   3138 bcmx_vlan_queue_map_set(int qmid, int pkt_pri, int cfi,
   3139                         int queue, int color)
   3140 {
   3141     int  rv = BCM_E_UNAVAIL, tmp_rv;
   3142     int  i, bcm_unit;
   3143 
   3144     BCMX_VLAN_INIT_CHECK;
   3145 
   3146     BCMX_UNIT_ITER(bcm_unit, i) {
   3147         tmp_rv = bcm_vlan_queue_map_set(bcm_unit, qmid, pkt_pri, cfi,
   3148                                         queue, color);
   3149         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   3150     }
   3151 
   3152     return rv;
   3153 }
   3154 
   3155 /*
   3156  * Function:
   3157  *      bcmx_vlan_queue_map_get
   3158  * Purpose:
   3159  *      Get packet queue and color for a VLAN queue map entry.
   3160  * Parameters:
   3161  *      qmid    - Queue map identifier
   3162  *      pkt_pri - Packet priority
   3163  *      cfi     - Packet CFI value
   3164  *      queue   - (OUT) Assigned COS queue number
   3165  *      color   - (OUT) Assigned color value
   3166  * Returns:
   3167  *      BCM_E_XXX
   3168  * Notes:
   3169  */
   3170 int
   3171 bcmx_vlan_queue_map_get(int qmid, int pkt_pri, int cfi, 
   3172                         int *queue, int *color)
   3173 {
   3174     int  rv;
   3175     int  i;
   3176     int  bcm_unit;
   3177 
   3178     BCMX_VLAN_INIT_CHECK;
   3179 
   3180     BCMX_PARAM_NULL_CHECK(queue);
   3181     BCMX_PARAM_NULL_CHECK(color);
   3182 
   3183     BCMX_UNIT_ITER(bcm_unit, i) {
   3184         rv = bcm_vlan_queue_map_get(bcm_unit, qmid, pkt_pri, cfi,
   3185                                     queue, color);
   3186         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, rv)) {
   3187             return rv;
   3188         }
   3189     }
   3190 
   3191     return BCM_E_UNAVAIL;
   3192 }
   3193 
   3194 /*
   3195  * Function:
   3196  *      bcmx_vlan_queue_map_attach
   3197  * Purpose:
   3198  *      Attach a queue map object to a VLAN or VFI.
   3199  * Parameters:
   3200  *      vlan  - VLAN identifier
   3201  *      qmid  - Queue map identifier
   3202  * Returns:
   3203  *      BCM_E_XXX
   3204  * Notes:
   3205  */
   3206 int
   3207 bcmx_vlan_queue_map_attach(bcm_vlan_t vlan, int qmid)
   3208 {
   3209     int  rv = BCM_E_UNAVAIL, tmp_rv;
   3210     int  i, bcm_unit;
   3211 
   3212     BCMX_VLAN_INIT_CHECK;
   3213 
   3214     BCMX_UNIT_ITER(bcm_unit, i) {
   3215         tmp_rv = bcm_vlan_queue_map_attach(bcm_unit, vlan, qmid);
   3216         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   3217     }
   3218 
   3219     return rv;
   3220 }
   3221 
   3222 /*
   3223  * Function:
   3224  *      bcmx_vlan_queue_map_attach_get
   3225  * Purpose:
   3226  *      Get attached queue map object for given VLAN or VFI.
   3227  * Parameters:
   3228  *      vlan  - VLAN identifier
   3229  *      qmid  - (OUT) Queue map identifier
   3230  * Returns:
   3231  *      BCM_E_XXX
   3232  * Notes:
   3233  */
   3234 int
   3235 bcmx_vlan_queue_map_attach_get(bcm_vlan_t vlan, int *qmid)
   3236 {
   3237     int  rv;
   3238     int  i;
   3239     int  bcm_unit;
   3240 
   3241     BCMX_VLAN_INIT_CHECK;
   3242 
   3243     BCMX_PARAM_NULL_CHECK(qmid);
   3244 
   3245     BCMX_UNIT_ITER(bcm_unit, i) {
   3246         rv = bcm_vlan_queue_map_attach_get(bcm_unit, vlan, qmid);
   3247         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, rv)) {
   3248             return rv;
   3249         }
   3250     }
   3251 
   3252     return BCM_E_UNAVAIL;
   3253 }
   3254 
   3255 /*
   3256  * Function:
   3257  *      bcmx_vlan_queue_map_detach
   3258  * Purpose:
   3259  *      Dettached queue map object for given VLAN or VFI.
   3260  * Parameters:
   3261  *      vlan  - VLAN identifier
   3262  * Returns:
   3263  *      BCM_E_XXX
   3264  * Notes:
   3265  */
   3266 int
   3267 bcmx_vlan_queue_map_detach(bcm_vlan_t vlan)
   3268 {
   3269     int  rv = BCM_E_UNAVAIL, tmp_rv;
   3270     int  i, bcm_unit;
   3271 
   3272     BCMX_VLAN_INIT_CHECK;
   3273 
   3274     BCMX_UNIT_ITER(bcm_unit, i) {
   3275         tmp_rv = bcm_vlan_queue_map_detach(bcm_unit, vlan);
   3276         BCM_IF_ERROR_RETURN
   3277             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   3278     }
   3279 
   3280     return rv;
   3281 }
   3282     
   3283 /*
   3284  * Function:
   3285  *      bcmx_vlan_queue_map_detach_all
   3286  * Purpose:
   3287  *      Dettached queue map objects from all VLAN or VFI.
   3288  * Parameters:
   3289  *      None
   3290  * Returns:
   3291  *      BCM_E_XXX
   3292  * Notes:
   3293  */
   3294 int
   3295 bcmx_vlan_queue_map_detach_all(void)
   3296 {
   3297     int  rv = BCM_E_UNAVAIL, tmp_rv;
   3298     int  i, bcm_unit;
   3299 
   3300     BCMX_VLAN_INIT_CHECK;
   3301 
   3302     BCMX_UNIT_ITER(bcm_unit, i) {
   3303         tmp_rv = bcm_vlan_queue_map_detach_all(bcm_unit);
   3304         BCM_IF_ERROR_RETURN
   3305             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   3306     }
   3307 
   3308     return rv;
   3309 }
   3310 
   3311 
   3312 /*
   3313  * Function:
   3314  *      bcmx_vlan_gport_add
   3315  * Purpose:
   3316  *      Add a gport (virtual or physical port) to the specified VLAN.
   3317  * Parameters:
   3318  *      vlan        - VLAN ID to add port to as a member
   3319  *      port        - Gport ID
   3320  *      flags       - BCM_VLAN_PORT_XXX
   3321  * Returns:
   3322  *      BCM_E_XXX
   3323  * Notes:
   3324  */
   3325 int
   3326 bcmx_vlan_gport_add(bcm_vlan_t vlan, bcm_gport_t port, int flags)
   3327 {
   3328     int          rv = BCM_E_UNAVAIL, tmp_rv;
   3329     int          i, bcm_unit;
   3330     bcm_port_t   bcm_port;
   3331 
   3332     BCMX_VLAN_INIT_CHECK;
   3333 
   3334     /*
   3335      * If gport is:
   3336      *    - physical port, apply to unit where port resides
   3337      *    - trunk, apply to first unit
   3338      *    - otherwise, apply to all units
   3339      */
   3340     if (BCM_SUCCESS(_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   3341                                             BCMX_DEST_CONVERT_DEFAULT))) {
   3342         return bcm_vlan_gport_add(bcm_unit, vlan, port, flags);
   3343     }
   3344 
   3345     if (BCM_GPORT_IS_TRUNK(port)) {
   3346         BCMX_UNIT_ITER(bcm_unit, i) {
   3347             tmp_rv = bcm_vlan_gport_add(bcm_unit, vlan, port, flags);
   3348             if (!BCMX_VLAN_ERROR_IS_VALID(bcm_unit, tmp_rv)) {
   3349                 continue;
   3350             }
   3351 
   3352             (void) BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv);
   3353             break;
   3354         }
   3355 
   3356         return rv;
   3357     }
   3358 
   3359     BCMX_UNIT_ITER(bcm_unit, i) {
   3360         tmp_rv = bcm_vlan_gport_add(bcm_unit, vlan, port, flags);
   3361         BCM_IF_ERROR_RETURN(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   3362     }
   3363 
   3364     return rv;
   3365 }
   3366 
   3367 /*
   3368  * Function:
   3369  *      bcmx_vlan_gport_delete
   3370  * Purpose:
   3371  *      Delete a gport (virtual or physical port) from the specified VLAN.
   3372  * Parameters:
   3373  *      vlan - VLAN ID
   3374  *      port - Gport ID
   3375  * Returns:
   3376  *      BCM_E_XXX
   3377  * Notes:
   3378  */
   3379 int
   3380 bcmx_vlan_gport_delete(bcm_vlan_t vlan, bcm_gport_t port)
   3381 {
   3382     int          rv = BCM_E_UNAVAIL, tmp_rv;
   3383     int          i, bcm_unit;
   3384     bcm_port_t   bcm_port;
   3385 
   3386     BCMX_VLAN_INIT_CHECK;
   3387 
   3388     /*
   3389      * If gport is:
   3390      *    - physical port, apply to unit where port resides
   3391      *    - trunk, apply to first unit (skip fabric with unavail error code
   3392      *    - otherwise, apply to all units
   3393      */
   3394     if (BCM_SUCCESS(_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   3395                                             BCMX_DEST_CONVERT_DEFAULT))) {
   3396         return bcm_vlan_gport_delete(bcm_unit, vlan, port);
   3397     }
   3398 
   3399     if (BCM_GPORT_IS_TRUNK(port)) {
   3400         BCMX_UNIT_ITER(bcm_unit, i) {
   3401             tmp_rv = bcm_vlan_gport_delete(bcm_unit, vlan, port);
   3402             if (!BCMX_VLAN_ERROR_IS_VALID(bcm_unit, tmp_rv)) {
   3403                 continue;
   3404             }
   3405 
   3406             (void) BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv);
   3407             break;
   3408         }
   3409 
   3410         return rv;
   3411     }
   3412 
   3413     BCMX_UNIT_ITER(bcm_unit, i) {
   3414         tmp_rv = bcm_vlan_gport_delete(bcm_unit, vlan, port);
   3415         BCM_IF_ERROR_RETURN
   3416             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   3417     }
   3418 
   3419     return rv;
   3420 }
   3421 
   3422 /*
   3423  * Function:
   3424  *      bcmx_vlan_gport_delete_all
   3425  * Purpose:
   3426  *      Delete all gports (virtual and physical port) from the specified VLAN.
   3427  * Parameters:
   3428  *      vlan - VLAN ID
   3429  * Returns:
   3430  *      BCM_E_XXX
   3431  * Notes:
   3432  */
   3433 int
   3434 bcmx_vlan_gport_delete_all(bcm_vlan_t vlan)
   3435 {
   3436     int  rv = BCM_E_UNAVAIL, tmp_rv;
   3437     int  i, bcm_unit;
   3438 
   3439     BCMX_VLAN_INIT_CHECK;
   3440 
   3441     BCMX_UNIT_ITER(bcm_unit, i) {
   3442         tmp_rv = bcm_vlan_gport_delete_all(bcm_unit, vlan);
   3443         BCM_IF_ERROR_RETURN
   3444             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   3445     }
   3446 
   3447     return rv;
   3448 }
   3449 
   3450 /*
   3451  * Function:
   3452  *      bcmx_vlan_gport_get
   3453  * Purpose:
   3454  *      Get control flags for given gport (virtual or physical port)
   3455  *      on the specified VLAN.
   3456  * Parameters:
   3457  *      vlan        - VLAN ID
   3458  *      port        - Gport ID
   3459  *      flags       - (OUT) Control flag BCM_VLAN_PORT_XXX
   3460  * Returns:
   3461  *      BCM_E_XXX
   3462  * Notes:
   3463  */
   3464 int
   3465 bcmx_vlan_gport_get(bcm_vlan_t vlan, bcm_gport_t port, int *flags)
   3466 {
   3467     int          rv;
   3468     int          i, bcm_unit;
   3469     bcm_port_t   bcm_port;
   3470 
   3471     BCMX_VLAN_INIT_CHECK;
   3472 
   3473     BCMX_PARAM_NULL_CHECK(flags);
   3474 
   3475     /*
   3476      * If gport is:
   3477      *    - physical port, get from unit where port resides
   3478      *    - otherwise (including trunk), return from first successful get
   3479      */
   3480     if (BCM_SUCCESS(_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port,
   3481                                             BCMX_DEST_CONVERT_DEFAULT))) {
   3482         return bcm_vlan_gport_get(bcm_unit, vlan, port, flags);
   3483     }
   3484 
   3485     BCMX_UNIT_ITER(bcm_unit, i) {
   3486         rv = bcm_vlan_gport_get(bcm_unit, vlan, port, flags);
   3487         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, rv)) {
   3488             return rv;
   3489         }
   3490     }
   3491 
   3492     return BCM_E_UNAVAIL;
   3493 }
   3494 
   3495 /*
   3496  * Function:
   3497  *      bcmx_vlan_gport_get_all
   3498  * Purpose:
   3499  *      Get all gports (virtual and physical port) for the specified VLAN.
   3500  * Parameters:
   3501  *      vlan        - VLAN ID
   3502  *      array_max   - Maximum number of elements in arrays
   3503  *      gport_array - (OUT) Array of gports
   3504  *      flags_array - (OUT) Array of control flags
   3505  *      array_size  - (OUT) Actual number of returned values in array
   3506  * Returns:
   3507  *      BCM_E_XXX
   3508  * Notes:
   3509  */
   3510 int
   3511 bcmx_vlan_gport_get_all(bcm_vlan_t vlan,
   3512                         int array_max, bcm_gport_t *gport_array, 
   3513                         int *flags_array, int *array_size)
   3514 {
   3515     int          rv = BCM_E_UNAVAIL, tmp_rv;
   3516     int          i, bcm_unit;
   3517     int          count, total_count, array_left;
   3518     bcm_gport_t  *gport_tmp;
   3519     int          *flags_array_tmp;
   3520     int          j, k;    
   3521 
   3522     BCMX_VLAN_INIT_CHECK;
   3523 
   3524     BCMX_PARAM_ARRAY_NULL_CHECK(array_max, gport_array);
   3525     BCMX_PARAM_ARRAY_NULL_CHECK(array_max, flags_array);
   3526     BCMX_PARAM_NULL_CHECK(array_size);
   3527 
   3528     if ((gport_tmp = sal_alloc(sizeof(bcm_gport_t) * array_max,
   3529                                "bcmx vlan gport get")) == NULL) {
   3530         return BCM_E_MEMORY;
   3531     }
   3532     if ((flags_array_tmp = sal_alloc(sizeof(int) * array_max,
   3533                                      "bcmx vlan gport flags get")) == NULL) {
   3534         sal_free(gport_tmp);
   3535         return BCM_E_MEMORY;
   3536     }
   3537 
   3538     /*
   3539      * Collect gports from all units
   3540      */
   3541     *array_size = 0;
   3542     total_count = 0;
   3543     array_left  = array_max;
   3544 
   3545     BCMX_UNIT_ITER(bcm_unit, i) {
   3546         count = 0;
   3547         tmp_rv = bcm_vlan_gport_get_all(bcm_unit, vlan, array_left,
   3548                                         gport_tmp, flags_array_tmp, &count);
   3549         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, tmp_rv)) {
   3550             /*
   3551              * Gports can be in some units but not others (see 'add'),
   3552              * so ignore BCM_E_NOT_FOUND errors.
   3553              */
   3554             if (tmp_rv == BCM_E_NOT_FOUND) {
   3555                 continue;
   3556             }
   3557 
   3558             rv = tmp_rv;
   3559             if (BCM_FAILURE(tmp_rv)) {
   3560                 break;
   3561             }
   3562                                             
   3563             /* Add ports that are not yet in the list */
   3564             for (j = 0; j < count; j++) {
   3565                 for (k = 0; k < total_count; k++) {
   3566                     if (gport_tmp[j] == gport_array[k]) {
   3567                         break;
   3568                     }
   3569                 }
   3570                 if (k == total_count) {
   3571                     gport_array[total_count] = gport_tmp[j];
   3572                     flags_array[total_count] = flags_array_tmp[j];
   3573                     array_left--;
   3574                     total_count++;
   3575                 }
   3576             }
   3577         }
   3578     }
   3579 
   3580     *array_size = total_count;
   3581 
   3582     sal_free(gport_tmp);
   3583     sal_free(flags_array_tmp);
   3584 
   3585     return rv;
   3586 }
   3587 
   3588 /*
   3589  * Function:
   3590  *      bcmx_vlan_port_create
   3591  * Purpose:
   3592  *      Create a VLAN virtual port.
   3593  * Parameters:
   3594  *      vlan_port - (IN/OUT) Pointer to a VLAN virtual port structure. 
   3595  * Returns:
   3596  *      BCM_X_XXX
   3597  */
   3598 int
   3599 bcmx_vlan_port_create(bcmx_vlan_port_t *vlan_port)
   3600 {
   3601     int  rv = BCM_E_UNAVAIL, tmp_rv;
   3602     int  i, bcm_unit;
   3603     uint32  flags_orig;
   3604 
   3605     BCMX_VLAN_INIT_CHECK;
   3606 
   3607     BCMX_PARAM_NULL_CHECK(vlan_port);
   3608 
   3609     /* Store original 'xxx_WITH_ID' flag bit */
   3610     flags_orig = vlan_port->flags & BCM_VLAN_PORT_WITH_ID;
   3611 
   3612     BCMX_UNIT_ITER(bcm_unit, i) {
   3613         tmp_rv = bcm_vlan_port_create(bcm_unit,
   3614                                       BCMX_VLAN_PORT_T_PTR_TO_BCM(vlan_port));
   3615 
   3616         if (BCM_FAILURE(BCMX_VLAN_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv))) {
   3617             break;
   3618         }
   3619 
   3620         /*
   3621          * Use the ID from first successful 'create' if VLAN port ID
   3622          * is not specified.
   3623          */
   3624         if (!(vlan_port->flags & BCM_VLAN_PORT_WITH_ID)) {
   3625             if (BCM_SUCCESS(tmp_rv)) {
   3626                 vlan_port->flags |= BCM_VLAN_PORT_WITH_ID;
   3627             }
   3628         }
   3629     }
   3630 
   3631     /* Restore 'xxx_WITH_ID' flag bit */
   3632     vlan_port->flags &= ~BCM_VLAN_PORT_WITH_ID;
   3633     vlan_port->flags |= flags_orig;
   3634 
   3635     return rv;
   3636 }
   3637 
   3638 /*
   3639  * Function:
   3640  *      bcmx_vlan_port_destroy
   3641  * Purpose:
   3642  *      Destroy a VLAN virtual port.
   3643  * Parameters:
   3644  *      gport - (IN) VLAN virtual port GPORT ID. 
   3645  * Returns:
   3646  *      BCM_X_XXX
   3647  */
   3648 int
   3649 bcmx_vlan_port_destroy(bcm_gport_t gport)
   3650 {
   3651     int  rv = BCM_E_UNAVAIL, tmp_rv;
   3652     int  i, bcm_unit;
   3653 
   3654     BCMX_VLAN_INIT_CHECK;
   3655 
   3656     BCMX_UNIT_ITER(bcm_unit, i) {
   3657         tmp_rv = bcm_vlan_port_destroy(bcm_unit, gport);
   3658         BCM_IF_ERROR_RETURN
   3659             (BCMX_VLAN_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
   3660     }
   3661 
   3662     return rv;
   3663 }
   3664 
   3665 /*
   3666  * Function:
   3667  *      bcmx_vlan_port_find
   3668  * Purpose:
   3669  *      Get VLAN virtual port info.
   3670  * Parameters:
   3671  *      vlan_port - (IN/OUT) Pointer to VLAN virtual port structure. 
   3672  * Returns:
   3673  *      BCM_X_XXX
   3674  */
   3675 int
   3676 bcmx_vlan_port_find(bcmx_vlan_port_t *vlan_port)
   3677 {
   3678     int rv;
   3679     int i, bcm_unit;
   3680 
   3681     BCMX_VLAN_INIT_CHECK;
   3682 
   3683     BCMX_PARAM_NULL_CHECK(vlan_port);
   3684 
   3685     BCMX_UNIT_ITER(bcm_unit, i) {
   3686         rv = bcm_vlan_port_find(bcm_unit,
   3687                                 BCMX_VLAN_PORT_T_PTR_TO_BCM(vlan_port));
   3688         if (BCMX_VLAN_GET_IS_VALID(bcm_unit, rv)) {
   3689             return rv;
   3690         }
   3691     }
   3692 
   3693     return BCM_E_UNAVAIL;
   3694 }