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 (52092B)


      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:    vlan.c
      8  * Purpose: Handle trident2 specific vlan features:
      9  *             Manages VP VLAN membership tables.
     10  */
     11 
     12 #include <soc/defs.h>
     13 #include <sal/core/libc.h>
     14 
     15 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 
     16 
     17 #include <soc/mem.h>
     18 #include <soc/hash.h>
     19 #include <soc/ptable.h>
     20 #include <soc/mcm/memacc.h>
     21 #include <bcm/error.h>
     22 
     23 #include <bcm_int/esw_dispatch.h>
     24 #include <bcm_int/api_xlate_port.h>
     25 
     26 #include <bcm_int/common/multicast.h>
     27 #include <bcm_int/esw/multicast.h>
     28 #include <bcm_int/esw/virtual.h>
     29 #include <bcm_int/esw/vlan.h>
     30 #include <bcm_int/esw/firebolt.h>
     31 #include <bcm_int/esw/trx.h>
     32 #include <bcm_int/esw/triumph2.h>
     33 #include <bcm_int/esw/trident.h>
     34 #include <bcm_int/esw/stack.h>
     35 #include <bcm_int/esw/trunk.h>
     36 #include <bcm_int/esw/ipmc.h>
     37 #include <bcm_int/esw/stg.h>
     38 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
     39 #include <bcm_int/esw/vpn.h>
     40 #endif
     41 /*
     42  * Function:
     43  *      _bcm_td2_flag_to_stp_state
     44  * Purpose:
     45  *      Translate API flags to hardware stp state
     46  *
     47  * Parameters:
     48  *      unit        - (IN)  BCM device number
     49  *      flags       - (IN)  API flags
     50  *      egress      - (IN)  TRUE for egress, FALSE for ingress
     51  * Returns:
     52  *      STP state
     53  */
     54 int
     55 _bcm_td2_flags_to_stp_state(int unit, uint32 flags, int egress)
     56 {
     57     uint32 mask;
     58     int stp_state;
     59 
     60     mask = egress ? BCM_VLAN_GPORT_ADD_EGRESS_STP_MASK : BCM_VLAN_GPORT_ADD_STP_MASK;
     61 
     62     switch (flags & mask) {
     63         case BCM_VLAN_GPORT_ADD_STP_BLOCK:
     64         case BCM_VLAN_GPORT_ADD_EGRESS_STP_BLOCK:
     65             stp_state = 1;
     66             break;
     67         case BCM_VLAN_GPORT_ADD_STP_LEARN:
     68         case BCM_VLAN_GPORT_ADD_EGRESS_STP_LEARN:
     69             stp_state = 2;
     70             break;
     71         case BCM_VLAN_GPORT_ADD_STP_FORWARD:
     72         case BCM_VLAN_GPORT_ADD_EGRESS_STP_FORWARD:
     73             stp_state = 3;
     74             break;
     75         default:
     76             stp_state = 0;
     77             break;
     78     }
     79 
     80     return stp_state;
     81 }
     82 
     83 /*
     84  * Function:
     85  *      _bcm_td2_stp_state_to_flags
     86  * Purpose:
     87  *      Translate hardware stp state to API flags
     88  *
     89  * Parameters:
     90  *      unit        - (IN)  BCM device number
     91  *      stp_state   - (IN)  STP state
     92  *      egress      - (IN)  TRUE for egress, FALSE for ingress
     93  *      flags       - (OUT) API flags
     94  * Returns:
     95  *      corresponding flag value
     96  */
     97 int
     98 _bcm_td2_stp_state_to_flags(int unit, int stp_state, int egress)
     99 {
    100     int flags;
    101 
    102     switch (stp_state) {
    103         case 1:
    104             if (egress) {
    105                 flags = BCM_VLAN_GPORT_ADD_EGRESS_STP_BLOCK;
    106             } else {
    107                 flags = BCM_VLAN_GPORT_ADD_STP_BLOCK;
    108             }
    109             break;
    110         case 2:
    111             if (egress) {
    112                 flags = BCM_VLAN_GPORT_ADD_EGRESS_STP_LEARN;
    113             } else {
    114                 flags = BCM_VLAN_GPORT_ADD_STP_LEARN;
    115             }
    116             break;
    117         case 3:
    118             if (egress) {
    119                 flags = BCM_VLAN_GPORT_ADD_EGRESS_STP_FORWARD;
    120             } else {
    121                 flags = BCM_VLAN_GPORT_ADD_STP_FORWARD;
    122             }
    123             break;
    124         default:
    125             if (egress) {
    126                 flags = BCM_VLAN_GPORT_ADD_EGRESS_STP_DISABLE;
    127             } else {
    128                 flags = BCM_VLAN_GPORT_ADD_STP_DISABLE;
    129             }
    130             break;
    131     }
    132 
    133     return flags;
    134 }
    135 
    136 /*
    137  * Function:
    138  *      bcm_td2_ing_vp_vlan_membership_add
    139  * Purpose:
    140  *      create a ING_VP_VLAN_MEMBERSHIP entry
    141  *      
    142  * Parameters:
    143  *      unit - (IN) BCM device number
    144  *      vp   - (IN) VP number
    145  *      vlan - (IN) VLAN 
    146  * Returns:
    147  *      BCM_E_XXX
    148  */
    149 int
    150 bcm_td2_ing_vp_vlan_membership_add(int unit, int vp, bcm_vlan_t vlan_vfi, 
    151 								   uint32 flags, 
    152                                    _bcm_vp_vlan_mbrship_key_type_e key_type)
    153 {
    154     int rv = BCM_E_NONE;
    155     ing_vp_vlan_membership_entry_t ivvm_ent;
    156     ing_vp_vlan_membership_entry_t ivvm_ent_result;
    157     int index;
    158 
    159     if (!SOC_MEM_IS_VALID(unit, ING_VP_VLAN_MEMBERSHIPm)) {
    160         return BCM_E_UNAVAIL;
    161     }
    162 
    163     sal_memset(&ivvm_ent, 0, sizeof(ivvm_ent));
    164 
    165     /* Setup the appropriate fields based on key_type */
    166     if(key_type == _bcm_vp_vlan_mbrship_vp_vlan_type) {
    167         /* Set key_type if is valid field, it is so TD2+ onwards. The below
    168            sections do not need this check since those key_types are not
    169            valid for earlier devices */
    170         if (soc_feature(unit, soc_feature_key_type_valid_on_vp_vlan_membership)) {
    171             soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 
    172                                                     _bcm_vp_vlan_mbrship_vp_vlan_type);
    173         }
    174         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VPf, vp);
    175         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VLANf, vlan_vfi);
    176     } else if (key_type == _bcm_vp_vlan_mbrship_glp_vlan_type){
    177         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 
    178                                                 _bcm_vp_vlan_mbrship_glp_vlan_type);
    179         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, SGLPf, vp);
    180         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VLANf, vlan_vfi);
    181     } else if (key_type == _bcm_vp_vlan_mbrship_vp_vfi_type) {
    182         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 
    183                                                 _bcm_vp_vlan_mbrship_vp_vfi_type);
    184         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VPf, vp);
    185         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VFIf, vlan_vfi);
    186     } else if (key_type == _bcm_vp_vlan_mbrship_glp_vfi_type) {
    187         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf,
    188                                                 _bcm_vp_vlan_mbrship_glp_vfi_type);
    189         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, SGLPf, vp);
    190         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VFIf, vlan_vfi);
    191     }
    192     
    193     soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, SP_TREEf, 
    194                         _bcm_td2_flags_to_stp_state(unit, flags, FALSE));
    195     soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent,
    196         soc_feature(unit, soc_feature_base_valid) ? BASE_VALIDf : VALIDf, 1);
    197 
    198     rv = soc_mem_search(unit, ING_VP_VLAN_MEMBERSHIPm, MEM_BLOCK_ANY, 
    199                  &index, &ivvm_ent, &ivvm_ent_result, 0);
    200 
    201     if (rv == SOC_E_NONE) {
    202         /* found the entry, update the data field and write back  */
    203         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent_result,
    204                 SP_TREEf, _bcm_td2_flags_to_stp_state(unit, flags, FALSE));
    205         rv = soc_mem_write(unit, ING_VP_VLAN_MEMBERSHIPm,
    206                           MEM_BLOCK_ALL, index, &ivvm_ent_result);
    207         
    208     } else if (rv != SOC_E_NOT_FOUND) {
    209         return rv;  /* error return */
    210     } else {
    211         /* not found, add to the table */ 
    212         rv = soc_mem_insert(unit, ING_VP_VLAN_MEMBERSHIPm, 
    213                        MEM_BLOCK_ALL, &ivvm_ent);
    214     }
    215     return rv;
    216 }
    217 
    218 /*
    219  * Function:
    220  *      bcm_td2_egr_vp_vlan_membership_add
    221  * Purpose:
    222  *      create a EGR_VP_VLAN_MEMBERSHIP entry
    223  *      
    224  * Parameters:
    225  *      unit - (IN) BCM device number
    226  *      vp   - (IN) VP number
    227  *      vlan - (IN) VLAN
    228  *      key_type - (IN) Key type to identify specific entry
    229  * Returns:
    230  *      BCM_E_XXX
    231  */
    232 int
    233 bcm_td2_egr_vp_vlan_membership_add(int unit, int vp, bcm_vlan_t vlan_vfi, uint32 flags, 
    234                                                  _bcm_vp_vlan_mbrship_key_type_e key_type)
    235 {
    236     int rv = BCM_E_NONE;
    237     egr_vp_vlan_membership_entry_t evvm_ent;
    238     egr_vp_vlan_membership_entry_t evvm_ent_result;
    239     int index;
    240 
    241     if (!SOC_MEM_IS_VALID(unit, EGR_VP_VLAN_MEMBERSHIPm)) {
    242         return BCM_E_UNAVAIL;
    243     }
    244 
    245     sal_memset(&evvm_ent, 0, sizeof(evvm_ent));
    246 
    247     /* Setup the appropriate fields based on key_type */
    248     if(key_type == _bcm_vp_vlan_mbrship_vp_vlan_type) {
    249 
    250         /* Set key_type if is valid field, it is so TD2+ onwards. The below
    251            sections do not need this check since those key_types are not
    252            valid for earlier devices */
    253         if (soc_feature(unit, soc_feature_key_type_valid_on_vp_vlan_membership)) {
    254             soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 
    255                                                     _bcm_vp_vlan_mbrship_vp_vlan_type);
    256         }
    257         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VPf, vp);
    258         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VLANf, vlan_vfi);
    259     } else if (key_type == _bcm_vp_vlan_mbrship_glp_vlan_type){
    260         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 
    261                                                 _bcm_vp_vlan_mbrship_glp_vlan_type);
    262         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, DGLPf, vp);
    263         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VLANf, vlan_vfi);
    264     } else if (key_type == _bcm_vp_vlan_mbrship_vp_vfi_type) {
    265         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 
    266                                                 _bcm_vp_vlan_mbrship_vp_vfi_type);
    267         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VPf, vp);
    268         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VFIf, vlan_vfi);
    269     } else if (key_type == _bcm_vp_vlan_mbrship_glp_vfi_type) {
    270         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 
    271                                                 _bcm_vp_vlan_mbrship_glp_vfi_type);
    272         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, DGLPf, vp);
    273         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VFIf, vlan_vfi);
    274     }
    275 
    276     soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent,
    277         soc_feature(unit, soc_feature_base_valid) ? BASE_VALIDf : VALIDf, 1);
    278     soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, SP_TREEf, 
    279                         _bcm_td2_flags_to_stp_state(unit, flags, FALSE));
    280     soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, UNTAGf, 
    281               (flags & BCM_VLAN_PORT_UNTAGGED)? 1:0);
    282 
    283     rv = soc_mem_search(unit, EGR_VP_VLAN_MEMBERSHIPm, MEM_BLOCK_ANY, 
    284                  &index, &evvm_ent, &evvm_ent_result, 0);
    285 
    286     if (rv == SOC_E_NONE) {
    287         /* found the entry, update  */
    288         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent_result,
    289                 SP_TREEf, _bcm_td2_flags_to_stp_state(unit, flags, FALSE));
    290         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, 
    291                &evvm_ent_result, UNTAGf, 
    292               (flags & BCM_VLAN_PORT_UNTAGGED)? 1:0);
    293         rv = soc_mem_write(unit, EGR_VP_VLAN_MEMBERSHIPm,
    294                           MEM_BLOCK_ALL, index, &evvm_ent_result);
    295     } else if (rv != SOC_E_NOT_FOUND) {
    296         return rv;  /* error return */
    297     } else {
    298         /* not found, add to the table */ 
    299         rv = soc_mem_insert(unit, EGR_VP_VLAN_MEMBERSHIPm, 
    300                        MEM_BLOCK_ALL, &evvm_ent);
    301     }
    302     return rv;
    303 }
    304 
    305 /*
    306  * Function:
    307  *      bcm_td2_ing_vp_vlan_membership_delete
    308  * Purpose:
    309  *      delete a ING_VP_VLAN_MEMBERSHIP entry
    310  *      
    311  * Parameters:
    312  *      unit - (IN) BCM device number
    313  *      vp   - (IN) VP number
    314  *      vlan - (IN) VLAN
    315  *      key_type - (IN) Key type to identify specific entry
    316  * Returns:
    317  *      BCM_E_XXX
    318  */
    319 int
    320 bcm_td2_ing_vp_vlan_membership_delete(int unit, int vp, bcm_vlan_t vlan_vfi, 
    321                                       _bcm_vp_vlan_mbrship_key_type_e key_type)
    322 {
    323     int rv = BCM_E_NONE;
    324     ing_vp_vlan_membership_entry_t ivvm_ent;
    325 
    326     sal_memset(&ivvm_ent, 0, sizeof(ivvm_ent));
    327 
    328     /* Setup the appropriate fields based on key_type */
    329     if(key_type == _bcm_vp_vlan_mbrship_vp_vlan_type) {
    330         /* Set key_type if is valid field, it is so TD2+ onwards. The below
    331            sections do not need this check since those key_types are not
    332            valid for earlier devices */
    333         if (soc_feature(unit, soc_feature_key_type_valid_on_vp_vlan_membership)) {
    334             soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 
    335                                                     _bcm_vp_vlan_mbrship_vp_vlan_type);
    336         }
    337         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VPf, vp);
    338         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VLANf, vlan_vfi);
    339     } else if (key_type == _bcm_vp_vlan_mbrship_glp_vlan_type){
    340 		soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 
    341                                                 _bcm_vp_vlan_mbrship_glp_vlan_type);
    342         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, SGLPf, vp);
    343         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VLANf, vlan_vfi);
    344     } else if (key_type == _bcm_vp_vlan_mbrship_vp_vfi_type) {
    345         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 
    346                                                 _bcm_vp_vlan_mbrship_vp_vfi_type);
    347         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VPf, vp);
    348         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VFIf, vlan_vfi);
    349     }  else if (key_type == _bcm_vp_vlan_mbrship_glp_vfi_type) {
    350         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf,
    351                                                 _bcm_vp_vlan_mbrship_glp_vfi_type);
    352         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, SGLPf, vp);
    353         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VFIf, vlan_vfi);
    354     }
    355     soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent,
    356         soc_feature(unit, soc_feature_base_valid) ? BASE_VALIDf : VALIDf, 1);
    357 
    358     rv = soc_mem_delete_return_old(unit, ING_VP_VLAN_MEMBERSHIPm, 
    359                     MEM_BLOCK_ALL, &ivvm_ent, &ivvm_ent);
    360 
    361     return rv;
    362 }
    363 
    364 /*
    365  * Function:
    366  *      bcm_td2_egr_vp_vlan_membership_delete
    367  * Purpose:
    368  *      delete a EGR_VP_VLAN_MEMBERSHIP entry
    369  *
    370  * Parameters:
    371  *      unit - (IN) BCM device number
    372  *      vp   - (IN) VP number
    373  *      vlan - (IN) VLAN
    374  * Returns:
    375  *      BCM_E_XXX
    376  */
    377 int
    378 bcm_td2_egr_vp_vlan_membership_delete(int unit, int vp, bcm_vlan_t vlan_vfi, 
    379                                       _bcm_vp_vlan_mbrship_key_type_e key_type)
    380 {
    381     int rv = BCM_E_NONE;
    382     egr_vp_vlan_membership_entry_t evvm_ent;
    383 
    384     sal_memset(&evvm_ent, 0, sizeof(evvm_ent));
    385 
    386     /* Setup the appropriate fields based on key_type */
    387 	if(key_type == _bcm_vp_vlan_mbrship_vp_vlan_type) {
    388         /* Set key_type if is valid field, it is so TD2+ onwards. The below
    389            sections do not need this check since those key_types are not
    390            valid for earlier devices */
    391         if (soc_feature(unit, soc_feature_key_type_valid_on_vp_vlan_membership)) {
    392             soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 
    393                                                     _bcm_vp_vlan_mbrship_vp_vlan_type);
    394         }
    395         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VPf, vp);
    396         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VLANf, vlan_vfi);
    397     } else if (key_type == _bcm_vp_vlan_mbrship_glp_vlan_type){
    398 		soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 
    399                                                 _bcm_vp_vlan_mbrship_glp_vlan_type);
    400         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, DGLPf, vp);
    401         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VLANf, vlan_vfi);
    402     } else if (key_type == _bcm_vp_vlan_mbrship_vp_vfi_type) {
    403         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 
    404                                                 _bcm_vp_vlan_mbrship_vp_vfi_type);
    405         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VPf, vp);
    406         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VFIf, vlan_vfi);
    407     } else if (key_type == _bcm_vp_vlan_mbrship_glp_vfi_type) {
    408         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 
    409                                                 _bcm_vp_vlan_mbrship_glp_vfi_type);
    410         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, DGLPf, vp);
    411         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VFIf, vlan_vfi);
    412     }
    413 
    414     soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent,
    415         soc_feature(unit, soc_feature_base_valid) ? BASE_VALIDf : VALIDf, 1);
    416 
    417     rv = soc_mem_delete_return_old(unit, EGR_VP_VLAN_MEMBERSHIPm,
    418                     MEM_BLOCK_ALL, &evvm_ent, &evvm_ent);
    419 
    420     return rv;
    421 }
    422 
    423 
    424 /*
    425  * Function:
    426  *      bcm_td2_ing_vp_vlan_membership_get
    427  * Purpose:
    428  *      get the STP state of this ING_VP_VLAN_MEMBERSHIP entry
    429  *      
    430  * Parameters:
    431  *      unit - (IN) BCM device number
    432  *      vp   - (IN) VP number
    433  *      vlan - (IN) VLAN
    434  *      key_type - (IN) Key type to identify specific entry
    435  * Returns:
    436  *      BCM_E_XXX
    437  */
    438 int
    439 bcm_td2_ing_vp_vlan_membership_get(int unit, int vp, bcm_vlan_t vlan_vfi, uint32 *flags,
    440                                    _bcm_vp_vlan_mbrship_key_type_e key_type)
    441 {
    442     ing_vp_vlan_membership_entry_t ivvm_ent;
    443     ing_vp_vlan_membership_entry_t ivvm_ent_result;
    444     int idx;
    445     int sp_state;
    446 
    447     *flags = 0;
    448     sal_memset(&ivvm_ent, 0, sizeof(ivvm_ent));
    449 
    450     /* Setup the appropriate fields based on key_type */
    451     if(key_type == _bcm_vp_vlan_mbrship_vp_vlan_type) {
    452         /* Set key_type if is valid field, it is so TD2+ onwards. The below
    453            sections do not need this check since those key_types are not
    454            valid for earlier devices */
    455         if (soc_feature(unit, soc_feature_key_type_valid_on_vp_vlan_membership)) {
    456             soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 
    457                                                     _bcm_vp_vlan_mbrship_vp_vlan_type);
    458         }
    459         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VPf, vp);
    460         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VLANf, vlan_vfi);
    461     } else if (key_type == _bcm_vp_vlan_mbrship_glp_vlan_type){
    462         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 
    463                                                 _bcm_vp_vlan_mbrship_glp_vlan_type);
    464         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, SGLPf, vp);
    465         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VLANf, vlan_vfi);
    466     } else if (key_type == _bcm_vp_vlan_mbrship_vp_vfi_type) {
    467         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf, 
    468                                                 _bcm_vp_vlan_mbrship_vp_vfi_type);
    469         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VPf, vp);
    470         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VFIf, vlan_vfi);
    471     }  else if (key_type == _bcm_vp_vlan_mbrship_glp_vfi_type) {
    472         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, KEY_TYPEf,
    473                                                 _bcm_vp_vlan_mbrship_glp_vfi_type);
    474         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, SGLPf, vp);
    475         soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VFIf, vlan_vfi);
    476     }
    477     
    478     soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent,
    479         soc_feature(unit, soc_feature_base_valid) ? BASE_VALIDf : VALIDf, 1);
    480 
    481     BCM_IF_ERROR_RETURN(soc_mem_search(unit, ING_VP_VLAN_MEMBERSHIPm, 
    482                          MEM_BLOCK_ALL, &idx,
    483                          &ivvm_ent, &ivvm_ent_result, 0));
    484 
    485     sp_state = soc_ING_VP_VLAN_MEMBERSHIPm_field32_get(unit, &ivvm_ent_result,
    486                                               SP_TREEf);
    487     if (sp_state == PVP_STP_DISABLED) {
    488         *flags = BCM_VLAN_GPORT_ADD_STP_DISABLE;
    489     } else if (sp_state == PVP_STP_LEARNING) {
    490         *flags = BCM_VLAN_GPORT_ADD_STP_LEARN;
    491     } else if (sp_state == PVP_STP_BLOCKING) {
    492         *flags = BCM_VLAN_GPORT_ADD_STP_BLOCK;
    493     } else {
    494         *flags = BCM_VLAN_GPORT_ADD_STP_FORWARD;
    495     }   
    496     
    497     return BCM_E_NONE;
    498 }
    499 
    500 /*
    501  * Function:
    502  *      bcm_td2_egr_vp_vlan_membership_get
    503  * Purpose:
    504  *      get the STP state of this EGR_VP_VLAN_MEMBERSHIP entry
    505  *      
    506  * Parameters:
    507  *      unit - (IN) BCM device number
    508  *      vp   - (IN) VP number
    509  *      vlan - (IN) VLAN
    510  *      key_type - (IN) Key type to identify specific entry
    511  * Returns:
    512  *      BCM_E_XXX
    513  */
    514 int
    515 bcm_td2_egr_vp_vlan_membership_get(int unit, int vp, bcm_vlan_t vlan_vfi, uint32 *flags,
    516                                    _bcm_vp_vlan_mbrship_key_type_e key_type)
    517 {
    518     egr_vp_vlan_membership_entry_t evvm_ent;
    519     egr_vp_vlan_membership_entry_t evvm_ent_result;
    520     int idx;
    521     int sp_state;
    522     int untag;
    523 
    524     *flags = 0;
    525     sal_memset(&evvm_ent, 0, sizeof(evvm_ent));
    526 
    527     /* Setup the appropriate fields based on key_type */
    528     if(key_type == _bcm_vp_vlan_mbrship_vp_vlan_type) {
    529 
    530         /* Set key_type if is valid field, it is so TD2+ onwards. The below
    531            sections do not need this check since those key_types are not
    532            valid for earlier devices */
    533         if (soc_feature(unit, soc_feature_key_type_valid_on_vp_vlan_membership)) {
    534             soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 
    535                                                     _bcm_vp_vlan_mbrship_vp_vlan_type);
    536         }
    537         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VPf, vp);
    538         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VLANf, vlan_vfi);
    539     } else if (key_type == _bcm_vp_vlan_mbrship_glp_vlan_type){
    540         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 
    541                                                 _bcm_vp_vlan_mbrship_glp_vlan_type);
    542         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, DGLPf, vp);
    543         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VLANf, vlan_vfi);
    544     } else if (key_type == _bcm_vp_vlan_mbrship_vp_vfi_type) {
    545         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 
    546                                                 _bcm_vp_vlan_mbrship_vp_vfi_type);
    547         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VPf, vp);
    548         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VFIf, vlan_vfi);
    549     } else if (key_type == _bcm_vp_vlan_mbrship_glp_vfi_type) {
    550         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, KEY_TYPEf, 
    551                                                 _bcm_vp_vlan_mbrship_glp_vfi_type);
    552         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, DGLPf, vp);
    553         soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VFIf, vlan_vfi);
    554     }
    555 
    556     soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent,
    557         soc_feature(unit, soc_feature_base_valid) ? BASE_VALIDf : VALIDf, 1);
    558     BCM_IF_ERROR_RETURN(soc_mem_search(unit, EGR_VP_VLAN_MEMBERSHIPm, 
    559                          MEM_BLOCK_ALL, &idx,
    560                          &evvm_ent, &evvm_ent_result, 0));
    561 
    562     sp_state = soc_EGR_VP_VLAN_MEMBERSHIPm_field32_get(unit, &evvm_ent_result,
    563                                               SP_TREEf);
    564     if (sp_state == PVP_STP_DISABLED) {
    565         *flags = BCM_VLAN_GPORT_ADD_STP_DISABLE;
    566     } else if (sp_state == PVP_STP_LEARNING) {
    567         *flags = BCM_VLAN_GPORT_ADD_STP_LEARN;
    568     } else if (sp_state == PVP_STP_BLOCKING) {
    569         *flags = BCM_VLAN_GPORT_ADD_STP_BLOCK;
    570     } else {
    571         *flags = BCM_VLAN_GPORT_ADD_STP_FORWARD;
    572     }   
    573     untag = soc_EGR_VP_VLAN_MEMBERSHIPm_field32_get(unit, &evvm_ent_result,
    574                                               UNTAGf);
    575     *flags |= untag? BCM_VLAN_PORT_UNTAGGED:0; 
    576     return BCM_E_NONE;
    577 }
    578 
    579 /*
    580  * Function:
    581  *      bcm_td2_ing_vp_vlan_membership_get_all
    582  * Purpose:
    583  *      For the given vlan, get all the virtual ports and flags from
    584  *      ING_VP_VLAN_MEMBERSHIP table.
    585  * Parameters:
    586  *      unit - (IN) SOC unit number. 
    587  *      vlan - (IN) VLAN.
    588  *      vp_bitmap - (OUT) Bitmap of virtual ports.
    589  *      arr_size  - (IN) Number of elements in flags_arr.
    590  *      flags_arr - (OUT) Array of flags.
    591  * Returns:
    592  *      BCM_E_XXX
    593  */
    594 int
    595 bcm_td2_ing_vp_vlan_membership_get_all(int unit, bcm_vlan_t vlan,
    596         SHR_BITDCL *vp_bitmap, int arr_size, int *flags_arr)
    597 {
    598     int rv = BCM_E_NONE;
    599     soc_mem_t mem;
    600     int chunk_size, num_chunks, chunk_index;
    601     int alloc_size;
    602     uint8 *buf = NULL;
    603     int i, entry_index_min, entry_index_max;
    604     uint32 *buf_entry;
    605     int vp;
    606     int sp_state;
    607     soc_field_t vld_fld = VALIDf;
    608 
    609     if (NULL == vp_bitmap) {
    610         return BCM_E_PARAM;
    611     }
    612     if (arr_size != soc_mem_index_count(unit, SOURCE_VPm)) {
    613         return BCM_E_PARAM;
    614     } 
    615     if (NULL == flags_arr) {
    616         return BCM_E_PARAM;
    617     } 
    618 
    619     mem = ING_VP_VLAN_MEMBERSHIPm;
    620     if (soc_feature(unit, soc_feature_base_valid)) {
    621         vld_fld = BASE_VALIDf;
    622     }
    623 
    624     chunk_size = 1024;
    625     num_chunks = soc_mem_index_count(unit, mem) / chunk_size;
    626     if (soc_mem_index_count(unit, mem) % chunk_size) {
    627         num_chunks++;
    628     }
    629 
    630     alloc_size = sizeof(ing_vp_vlan_membership_entry_t) * chunk_size;
    631     buf = soc_cm_salloc(unit, alloc_size, "ING_VP_VLAN_MEMBERSHIP buffer");
    632     if (NULL == buf) {
    633         rv = BCM_E_MEMORY;
    634         goto cleanup;
    635     }
    636 
    637     for (chunk_index = 0; chunk_index < num_chunks; chunk_index++) {
    638 
    639         /* Get a chunk of entries */
    640         entry_index_min = chunk_index * chunk_size;
    641         entry_index_max = entry_index_min + chunk_size - 1;
    642         if (entry_index_max > soc_mem_index_max(unit, mem)) {
    643             entry_index_max = soc_mem_index_max(unit, mem);
    644         }
    645         rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY,
    646                 entry_index_min, entry_index_max, buf);
    647         if (SOC_FAILURE(rv)) {
    648             goto cleanup;
    649         }
    650 
    651         /* Read each entry of the chunk to extract VP and flags */
    652         for (i = 0; i < (entry_index_max - entry_index_min + 1); i++) {
    653             buf_entry = soc_mem_table_idx_to_pointer(unit,
    654                     mem, uint32 *, buf, i);
    655 
    656             if (soc_mem_field32_get(unit, mem, buf_entry, vld_fld) == 0) {
    657                 continue;
    658             }
    659             if (soc_mem_field32_get(unit, mem, buf_entry, VLANf) != vlan) {
    660                 continue;
    661             }
    662 
    663             vp = soc_mem_field32_get(unit, mem, buf_entry, VPf);
    664             if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan) &&
    665                 !_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv) &&
    666                 !_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender) &&
    667                 !_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
    668                 continue;
    669             }
    670             SHR_BITSET(vp_bitmap, vp);
    671 
    672             sp_state = soc_mem_field32_get(unit, mem, buf_entry, SP_TREEf);
    673             if (sp_state == PVP_STP_DISABLED) {
    674                 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_DISABLE;
    675             } else if (sp_state == PVP_STP_LEARNING) {
    676                 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_LEARN;
    677             } else if (sp_state == PVP_STP_BLOCKING) {
    678                 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_BLOCK;
    679             } else {
    680                 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_FORWARD;
    681             }   
    682         }
    683     }
    684 
    685 cleanup:
    686     if (buf) {
    687         soc_cm_sfree(unit, buf);
    688     }
    689 
    690     return rv;
    691 }
    692 
    693 /*
    694  * Function:
    695  *      bcm_td2_egr_vp_vlan_membership_get_all
    696  * Purpose:
    697  *      For the given vlan, get all the virtual ports and flags from
    698  *      EGR_VP_VLAN_MEMBERSHIP table.
    699  * Parameters:
    700  *      unit - (IN) SOC unit number. 
    701  *      vlan - (IN) VLAN.
    702  *      vp_bitmap - (OUT) Bitmap of virtual ports.
    703  *      arr_size  - (IN) Number of elements in flags_arr.
    704  *      flags_arr - (OUT) Array of flags.
    705  * Returns:
    706  *      BCM_E_XXX
    707  */
    708 int
    709 bcm_td2_egr_vp_vlan_membership_get_all(int unit, bcm_vlan_t vlan,
    710         SHR_BITDCL *vp_bitmap, int arr_size, int *flags_arr)
    711 {
    712     int rv = BCM_E_NONE;
    713     soc_mem_t mem;
    714     int chunk_size, num_chunks, chunk_index;
    715     int alloc_size;
    716     uint8 *buf = NULL;
    717     int i, entry_index_min, entry_index_max;
    718     uint32 *buf_entry;
    719     int vp;
    720     int sp_state;
    721     int untag;
    722     soc_field_t vld_fld = VALIDf;
    723 
    724     if (NULL == vp_bitmap) {
    725         return BCM_E_PARAM;
    726     }
    727     if (arr_size != soc_mem_index_count(unit, SOURCE_VPm)) {
    728         return BCM_E_PARAM;
    729     } 
    730     if (NULL == flags_arr) {
    731         return BCM_E_PARAM;
    732     } 
    733 
    734     mem = EGR_VP_VLAN_MEMBERSHIPm;
    735     if (soc_feature(unit, soc_feature_base_valid)) {
    736         vld_fld = BASE_VALIDf;
    737     }
    738 
    739     chunk_size = 1024;
    740     num_chunks = soc_mem_index_count(unit, mem) / chunk_size;
    741     if (soc_mem_index_count(unit, mem) % chunk_size) {
    742         num_chunks++;
    743     }
    744 
    745     alloc_size = sizeof(egr_vp_vlan_membership_entry_t) * chunk_size;
    746     buf = soc_cm_salloc(unit, alloc_size, "EGR_VP_VLAN_MEMBERSHIP buffer");
    747     if (NULL == buf) {
    748         rv = BCM_E_MEMORY;
    749         goto cleanup;
    750     }
    751 
    752     for (chunk_index = 0; chunk_index < num_chunks; chunk_index++) {
    753 
    754         /* Get a chunk of entries */
    755         entry_index_min = chunk_index * chunk_size;
    756         entry_index_max = entry_index_min + chunk_size - 1;
    757         if (entry_index_max > soc_mem_index_max(unit, mem)) {
    758             entry_index_max = soc_mem_index_max(unit, mem);
    759         }
    760         rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY,
    761                 entry_index_min, entry_index_max, buf);
    762         if (SOC_FAILURE(rv)) {
    763             goto cleanup;
    764         }
    765 
    766         /* Read each entry of the chunk to extract VP and flags */
    767         for (i = 0; i < (entry_index_max - entry_index_min + 1); i++) {
    768             buf_entry = soc_mem_table_idx_to_pointer(unit,
    769                     mem, uint32 *, buf, i);
    770 
    771             if (soc_mem_field32_get(unit, mem, buf_entry, vld_fld) == 0) {
    772                 continue;
    773             }
    774             if (soc_mem_field32_get(unit, mem, buf_entry, VLANf) != vlan) {
    775                 continue;
    776             }
    777 
    778             vp = soc_mem_field32_get(unit, mem, buf_entry, VPf);
    779             if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan) &&
    780                 !_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv) &&
    781                 !_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender) &&
    782                 !_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
    783                 continue;
    784             }
    785             SHR_BITSET(vp_bitmap, vp);
    786 
    787             sp_state = soc_mem_field32_get(unit, mem, buf_entry, SP_TREEf);
    788             if (sp_state == PVP_STP_DISABLED) {
    789                 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_DISABLE;
    790             } else if (sp_state == PVP_STP_LEARNING) {
    791                 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_LEARN;
    792             } else if (sp_state == PVP_STP_BLOCKING) {
    793                 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_BLOCK;
    794             } else {
    795                 flags_arr[vp] = BCM_VLAN_GPORT_ADD_STP_FORWARD;
    796             }   
    797 
    798             untag = soc_mem_field32_get(unit, mem, buf_entry, UNTAGf);
    799             if (untag) {
    800                 flags_arr[vp] |= BCM_VLAN_PORT_UNTAGGED;
    801             }
    802         }
    803     }
    804 
    805 cleanup:
    806     if (buf) {
    807         soc_cm_sfree(unit, buf);
    808     }
    809 
    810     return rv;
    811 }
    812 
    813 /*
    814  * Function:
    815  *      bcm_td2_ing_vp_vlan_membership_delete_all
    816  * Purpose:
    817  *      For the given vlan, delete all the virtual ports from
    818  *      ING_VP_VLAN_MEMBERSHIP table.
    819  * Parameters:
    820  *      unit - (IN) SOC unit number. 
    821  *      vlan - (IN) VLAN.
    822  * Returns:
    823  *      BCM_E_XXX
    824  */
    825 int
    826 bcm_td2_ing_vp_vlan_membership_delete_all(int unit, bcm_vlan_t vlan_vpn)
    827 {
    828     int rv = BCM_E_NONE;
    829     soc_mem_t mem;
    830     int chunk_size, num_chunks, chunk_index;
    831     int alloc_size;
    832     uint8 *buf = NULL;
    833     int i, entry_index_min, entry_index_max;
    834     uint32 *buf_entry;
    835     int vp, key_type, glp_vlan_vfi = 0;
    836     int vlan_vfi;
    837     soc_field_t vlan_vfi_field;
    838     soc_field_t vld_fld = VALIDf;
    839 
    840 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
    841     if (_BCM_VPN_VFI_IS_SET(vlan_vpn)) {
    842         vlan_vfi_field = VFIf;
    843         _BCM_VPN_GET(vlan_vfi, _BCM_VPN_TYPE_VFI, vlan_vpn);
    844     } else
    845 #endif
    846     {
    847         vlan_vfi = vlan_vpn;
    848         vlan_vfi_field = VLANf;
    849     }
    850 
    851     mem = ING_VP_VLAN_MEMBERSHIPm;
    852     if (soc_feature(unit, soc_feature_base_valid)) {
    853         vld_fld = BASE_VALIDf;
    854     }
    855 
    856     /* Set default key_type to vp_vlan_type */
    857     key_type = _bcm_vp_vlan_mbrship_vp_vlan_type;
    858 
    859     chunk_size = 1024;
    860     num_chunks = soc_mem_index_count(unit, mem) / chunk_size;
    861     if (soc_mem_index_count(unit, mem) % chunk_size) {
    862         num_chunks++;
    863     }
    864 
    865     alloc_size = sizeof(ing_vp_vlan_membership_entry_t) * chunk_size;
    866     buf = soc_cm_salloc(unit, alloc_size, "ING_VP_VLAN_MEMBERSHIP buffer");
    867     if (NULL == buf) {
    868         rv = BCM_E_MEMORY;
    869         goto cleanup;
    870     }
    871 
    872     for (chunk_index = 0; chunk_index < num_chunks; chunk_index++) {
    873 
    874         /* Get a chunk of entries */
    875         entry_index_min = chunk_index * chunk_size;
    876         entry_index_max = entry_index_min + chunk_size - 1;
    877         if (entry_index_max > soc_mem_index_max(unit, mem)) {
    878             entry_index_max = soc_mem_index_max(unit, mem);
    879         }
    880         rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY,
    881                 entry_index_min, entry_index_max, buf);
    882         if (SOC_FAILURE(rv)) {
    883             goto cleanup;
    884         }
    885 
    886         /* Read each entry of the chunk */
    887         for (i = 0; i < (entry_index_max - entry_index_min + 1); i++) {
    888             buf_entry = soc_mem_table_idx_to_pointer(unit,
    889                     mem, uint32 *, buf, i);
    890 
    891             if (soc_mem_field32_get(unit, mem, buf_entry, vld_fld) == 0) {
    892                 continue;
    893             }
    894             if (soc_mem_field32_get(unit, mem, buf_entry, vlan_vfi_field) != vlan_vfi) {
    895                 continue;
    896             }
    897 
    898             glp_vlan_vfi = 0;
    899             /* Get the VP */
    900             vp = soc_mem_field32_get(unit, mem, buf_entry, VPf);
    901 
    902             /* Set key_type if is valid field, it is so TD2+ onwards. The below
    903                sections do not need this check since those key_types are not
    904                valid for earlier devices */
    905             if (soc_feature(unit, soc_feature_key_type_valid_on_vp_vlan_membership)) {
    906                 /* Get the key_type */
    907                 key_type = soc_mem_field32_get(unit, mem, buf_entry, KEY_TYPEf);
    908                 /* If the key_type is GLP_VLAN, set the flag */
    909                 if ((key_type == _bcm_vp_vlan_mbrship_glp_vlan_type) ||
    910                     (key_type == _bcm_vp_vlan_mbrship_glp_vfi_type)) {
    911                     glp_vlan_vfi = 1;
    912                     vp = soc_mem_field32_get(unit, mem, buf_entry, SGLPf);
    913                 }
    914             }
    915 
    916             if (!glp_vlan_vfi && !_bcm_vp_used_get(unit, vp, _bcmVpTypeAny)) {
    917                 continue;
    918             }
    919             rv = bcm_td2_ing_vp_vlan_membership_delete(unit, vp, vlan_vfi, key_type);
    920             if (BCM_FAILURE(rv)) {
    921                 goto cleanup;
    922             }
    923         }
    924     }
    925 
    926 cleanup:
    927     if (buf) {
    928         soc_cm_sfree(unit, buf);
    929     }
    930 
    931     return rv;
    932 }
    933 
    934 /*
    935  * Function:
    936  *      bcm_td2_egr_vp_vlan_membership_delete_all
    937  * Purpose:
    938  *      For the given vlan, delete all the virtual ports from
    939  *      EGR_VP_VLAN_MEMBERSHIP table.
    940  * Parameters:
    941  *      unit - (IN) SOC unit number. 
    942  *      vlan - (IN) VLAN.
    943  * Returns:
    944  *      BCM_E_XXX
    945  */
    946 int
    947 bcm_td2_egr_vp_vlan_membership_delete_all(int unit, bcm_vlan_t vlan_vpn)
    948 {
    949     int rv = BCM_E_NONE;
    950     soc_mem_t mem;
    951     int chunk_size, num_chunks, chunk_index;
    952     int alloc_size;
    953     uint8 *buf = NULL;
    954     int i, entry_index_min, entry_index_max;
    955     uint32 *buf_entry;
    956     int vp, key_type, glp_vlan_vfi = 0;
    957     int vlan_vfi;
    958     soc_field_t vlan_vfi_field;
    959     soc_field_t vld_fld = VALIDf;
    960 
    961 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
    962     if (_BCM_VPN_VFI_IS_SET(vlan_vpn)) {
    963         vlan_vfi_field = VFIf;
    964         _BCM_VPN_GET(vlan_vfi, _BCM_VPN_TYPE_VFI, vlan_vpn);
    965     } else
    966 #endif
    967     {
    968         vlan_vfi = vlan_vpn;
    969         vlan_vfi_field = VLANf;
    970     }
    971 
    972     mem = EGR_VP_VLAN_MEMBERSHIPm;
    973     if (soc_feature(unit, soc_feature_base_valid)) {
    974         vld_fld = BASE_VALIDf;
    975     }
    976 
    977     /* Set default key_type to vp_vlan_type */
    978     key_type = _bcm_vp_vlan_mbrship_vp_vlan_type;
    979 
    980     chunk_size = 1024;
    981     num_chunks = soc_mem_index_count(unit, mem) / chunk_size;
    982     if (soc_mem_index_count(unit, mem) % chunk_size) {
    983         num_chunks++;
    984     }
    985 
    986     alloc_size = sizeof(egr_vp_vlan_membership_entry_t) * chunk_size;
    987     buf = soc_cm_salloc(unit, alloc_size, "EGR_VP_VLAN_MEMBERSHIP buffer");
    988     if (NULL == buf) {
    989         rv = BCM_E_MEMORY;
    990         goto cleanup;
    991     }
    992 
    993     for (chunk_index = 0; chunk_index < num_chunks; chunk_index++) {
    994 
    995         /* Get a chunk of entries */
    996         entry_index_min = chunk_index * chunk_size;
    997         entry_index_max = entry_index_min + chunk_size - 1;
    998         if (entry_index_max > soc_mem_index_max(unit, mem)) {
    999             entry_index_max = soc_mem_index_max(unit, mem);
   1000         }
   1001         rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY,
   1002                 entry_index_min, entry_index_max, buf);
   1003         if (SOC_FAILURE(rv)) {
   1004             goto cleanup;
   1005         }
   1006 
   1007         /* Read each entry of the chunk */
   1008         for (i = 0; i < (entry_index_max - entry_index_min + 1); i++) {
   1009             buf_entry = soc_mem_table_idx_to_pointer(unit,
   1010                     mem, uint32 *, buf, i);
   1011 
   1012             if (soc_mem_field32_get(unit, mem, buf_entry, vld_fld) == 0) {
   1013                 continue;
   1014             }
   1015             if (soc_mem_field32_get(unit, mem, buf_entry, vlan_vfi_field) != vlan_vfi) {
   1016                 continue;
   1017             }
   1018 
   1019             glp_vlan_vfi = 0;
   1020             /* Get the VP */
   1021             vp = soc_mem_field32_get(unit, mem, buf_entry, VPf);
   1022 
   1023             /* Set key_type if is valid field, it is so TD2+ onwards. The below
   1024                sections do not need this check since those key_types are not
   1025                valid for earlier devices */
   1026             if (soc_feature(unit, soc_feature_key_type_valid_on_vp_vlan_membership)) {
   1027                 /* Get the key_type */
   1028                 key_type = soc_mem_field32_get(unit, mem, buf_entry, KEY_TYPEf);
   1029                 /* If the key_type is GLP_VLAN, set the flag */
   1030                 if ((key_type == _bcm_vp_vlan_mbrship_glp_vlan_type) ||
   1031                     (key_type == _bcm_vp_vlan_mbrship_glp_vfi_type)) {
   1032                     glp_vlan_vfi = 1;
   1033                     vp = soc_mem_field32_get(unit, mem, buf_entry, DGLPf);
   1034                 }
   1035             }
   1036 
   1037             if (!glp_vlan_vfi && !_bcm_vp_used_get(unit, vp, _bcmVpTypeAny)) {
   1038                 continue;
   1039             }
   1040             rv = bcm_td2_egr_vp_vlan_membership_delete(unit, vp, vlan_vfi, key_type);
   1041             if (BCM_FAILURE(rv)) {
   1042                 goto cleanup;
   1043             }
   1044         }
   1045     }
   1046 
   1047 cleanup:
   1048     if (buf) {
   1049         soc_cm_sfree(unit, buf);
   1050     }
   1051 
   1052     return rv;
   1053 }
   1054 
   1055 /*
   1056  * Function:
   1057  *      bcm_td2_vp_vlan_stp_set
   1058  * Purpose:
   1059  *      Set the spanning tree state for a virtual port
   1060  * Parameters:
   1061  *      unit      - (IN) BCM device number
   1062  *      vp        - (IN) VP number
   1063  *      vlan      - (IN) VLAN 
   1064  *      stp_state - (IN) State to set
   1065  * Returns:
   1066  *      BCM_E_XXX
   1067  */
   1068 int
   1069 bcm_td2_vp_vlan_stp_set(int unit, int vp, bcm_vlan_t vlan, int stp_state)
   1070 {
   1071     int rv = BCM_E_NONE;
   1072     int idx;
   1073     int hw_stp_state;
   1074     ing_vp_vlan_membership_entry_t ivvm_ent;
   1075     ing_vp_vlan_membership_entry_t ivvm_ent_result;
   1076     egr_vp_vlan_membership_entry_t evvm_ent;
   1077     egr_vp_vlan_membership_entry_t evvm_ent_result;
   1078 
   1079     /* Translate API space port state to hw stp port state. */
   1080     BCM_IF_ERROR_RETURN(_bcm_stg_stp_translate(unit, stp_state, &hw_stp_state));
   1081     
   1082     /* Ingress direction */
   1083     sal_memset(&ivvm_ent, 0, sizeof(ivvm_ent));
   1084     soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VPf, vp);
   1085     soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VLANf, vlan);
   1086     soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent,
   1087         soc_feature(unit, soc_feature_base_valid) ? BASE_VALIDf : VALIDf, 1);
   1088     
   1089     BCM_IF_ERROR_RETURN(soc_mem_search(unit, ING_VP_VLAN_MEMBERSHIPm, 
   1090                          MEM_BLOCK_ALL, &idx,
   1091                          &ivvm_ent, &ivvm_ent_result, 0));
   1092     soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent_result, SP_TREEf, 
   1093                          hw_stp_state);
   1094     BCM_IF_ERROR_RETURN(soc_mem_write(unit, ING_VP_VLAN_MEMBERSHIPm,
   1095                           MEM_BLOCK_ALL, idx, &ivvm_ent_result));
   1096     
   1097     /* Egress direction */
   1098     sal_memset(&evvm_ent, 0, sizeof(evvm_ent));
   1099     soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VPf, vp);
   1100     soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent, VLANf, vlan);
   1101     soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent,
   1102         soc_feature(unit, soc_feature_base_valid) ? BASE_VALIDf : VALIDf, 1);
   1103     
   1104     BCM_IF_ERROR_RETURN(soc_mem_search(unit, EGR_VP_VLAN_MEMBERSHIPm, 
   1105                          MEM_BLOCK_ALL, &idx,
   1106                          &evvm_ent, &evvm_ent_result, 0));
   1107     soc_EGR_VP_VLAN_MEMBERSHIPm_field32_set(unit, &evvm_ent_result, SP_TREEf, 
   1108                          hw_stp_state);
   1109     BCM_IF_ERROR_RETURN(soc_mem_write(unit, EGR_VP_VLAN_MEMBERSHIPm,
   1110                           MEM_BLOCK_ALL, idx, &evvm_ent_result));
   1111     
   1112     return rv;
   1113 }
   1114 
   1115 /*
   1116  * Function:
   1117  *      bcm_td2_vp_vlan_stp_get
   1118  * Purpose:
   1119  *      Get the spanning tree state for a virtual port
   1120  * Parameters:
   1121  *      unit      - (IN) BCM device number
   1122  *      vp        - (IN) VP number
   1123  *      vlan      - (IN) VLAN 
   1124  *      stp_state - (OUT) State to set
   1125  * Returns:
   1126  *      BCM_E_XXX
   1127  */
   1128 int
   1129 bcm_td2_vp_vlan_stp_get(int unit, int vp, bcm_vlan_t vlan, int *stp_state)
   1130 {
   1131     int rv = BCM_E_NONE;
   1132     int idx;
   1133     int hw_stp_state;
   1134     ing_vp_vlan_membership_entry_t ivvm_ent;
   1135     ing_vp_vlan_membership_entry_t ivvm_ent_result;
   1136 
   1137     sal_memset(&ivvm_ent, 0, sizeof(ivvm_ent));
   1138     soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VPf, vp);
   1139     soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent, VLANf, vlan);
   1140     soc_ING_VP_VLAN_MEMBERSHIPm_field32_set(unit, &ivvm_ent,
   1141         soc_feature(unit, soc_feature_base_valid) ? BASE_VALIDf : VALIDf, 1);
   1142     
   1143     BCM_IF_ERROR_RETURN(soc_mem_search(unit, ING_VP_VLAN_MEMBERSHIPm, 
   1144                          MEM_BLOCK_ALL, &idx,
   1145                          &ivvm_ent, &ivvm_ent_result, 0));
   1146     hw_stp_state = soc_ING_VP_VLAN_MEMBERSHIPm_field32_get(unit, &ivvm_ent_result, 
   1147                          SP_TREEf);
   1148     
   1149     /* Translate hw stp port state to API format. */
   1150     BCM_IF_ERROR_RETURN(_bcm_stg_pvp_translate(unit, hw_stp_state, stp_state));
   1151     
   1152     return rv;
   1153 }
   1154 
   1155 /*
   1156  * Function:
   1157  *      bcm_td2_vp_vlan_membership_add
   1158  * Purpose:
   1159  *      create a VP_VLAN_MEMBERSHIP entry
   1160  *
   1161  * Parameters:
   1162  *      unit - (IN) BCM device number
   1163  *      vp   - (IN) VP number
   1164  *      vlan - (IN) VLAN
   1165  * Returns:
   1166  *      BCM_E_XXX
   1167  */
   1168 int
   1169 bcm_td2_vp_vlan_membership_add(int unit, int vp, bcm_vlan_t vlan, int flags)
   1170 {
   1171     int rv = BCM_E_NONE;
   1172     int vlan_vfi = 0;
   1173     _bcm_vp_vlan_mbrship_key_type_e key_type;
   1174 
   1175     if ((flags & BCM_VLAN_GPORT_ADD_INGRESS_ONLY) &&
   1176         (flags & BCM_VLAN_GPORT_ADD_EGRESS_ONLY)) {
   1177         return BCM_E_PARAM;
   1178     }
   1179 
   1180 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   1181     if (_BCM_VPN_VFI_IS_SET(vlan)) {
   1182         _BCM_VPN_GET(vlan_vfi, _BCM_VPN_TYPE_VFI, vlan);
   1183         key_type = _bcm_vp_vlan_mbrship_glp_vfi_type;
   1184     } else
   1185 #endif
   1186     {
   1187         vlan_vfi = vlan;
   1188         key_type = _bcm_vp_vlan_mbrship_glp_vlan_type;
   1189     }
   1190 
   1191     if (!(flags & BCM_VLAN_GPORT_ADD_EGRESS_ONLY)) {
   1192         BCM_IF_ERROR_RETURN(bcm_td2_ing_vp_vlan_membership_add(unit,
   1193                     vp, vlan_vfi, flags, key_type));
   1194     }
   1195 
   1196     if (!(flags & BCM_VLAN_GPORT_ADD_INGRESS_ONLY)) {
   1197         BCM_IF_ERROR_RETURN(bcm_td2_egr_vp_vlan_membership_add(unit,
   1198                     vp, vlan_vfi, flags, key_type));
   1199     }
   1200 
   1201     return rv;
   1202 }
   1203 
   1204 /*
   1205  * Function:
   1206  *      bcm_td2_vp_vlan_membership_delete
   1207  * Purpose:
   1208  *      delete VP_VLAN_MEMBERSHIP entry
   1209  *
   1210  * Parameters:
   1211  *      unit - (IN) BCM device number
   1212  *      vp   - (IN) VP number
   1213  *      vlan - (IN) VLAN
   1214  * Returns:
   1215  *      BCM_E_XXX
   1216  */
   1217 int
   1218 bcm_td2_vp_vlan_membership_delete(int unit, int vp, bcm_vlan_t vlan)
   1219 {
   1220     int rv = BCM_E_NONE;
   1221     int vlan_vfi = 0;
   1222     int ing_vp_vlan_membership_found = 0;
   1223     int egr_vp_vlan_membership_found = 0;
   1224     _bcm_vp_vlan_mbrship_key_type_e key_type;
   1225 
   1226 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   1227     if (_BCM_VPN_VFI_IS_SET(vlan)) {
   1228         _BCM_VPN_GET(vlan_vfi, _BCM_VPN_TYPE_VFI, vlan);
   1229         key_type = _bcm_vp_vlan_mbrship_glp_vfi_type;
   1230     } else
   1231 #endif
   1232     {
   1233         vlan_vfi = vlan;
   1234         key_type = _bcm_vp_vlan_mbrship_glp_vlan_type;
   1235     }
   1236 
   1237     rv = bcm_td2_ing_vp_vlan_membership_delete(unit, vp, vlan_vfi, key_type);
   1238     if (BCM_SUCCESS(rv)) {
   1239         ing_vp_vlan_membership_found = TRUE;
   1240     } else if (rv == BCM_E_NOT_FOUND) {
   1241         ing_vp_vlan_membership_found = FALSE;
   1242         rv = BCM_E_NONE;
   1243     } else {
   1244         return rv;
   1245     }
   1246 
   1247     rv = bcm_td2_egr_vp_vlan_membership_delete(unit, vp, vlan_vfi, key_type);
   1248     if (BCM_SUCCESS(rv)) {
   1249         egr_vp_vlan_membership_found = TRUE;
   1250     } else if (rv == BCM_E_NOT_FOUND) {
   1251         egr_vp_vlan_membership_found = FALSE;
   1252         rv = BCM_E_NONE;
   1253     } else {
   1254         return rv;
   1255     }
   1256 
   1257     if (!ing_vp_vlan_membership_found && !egr_vp_vlan_membership_found) {
   1258         return BCM_E_NOT_FOUND;
   1259     }
   1260 
   1261     return rv;
   1262 }
   1263 
   1264 /*
   1265  * Function:
   1266  *      bcm_td2_vp_vlan_membership_get
   1267  * Purpose:
   1268  *      get the STP state of VP_VLAN_MEMBERSHIP entry
   1269  *
   1270  * Parameters:
   1271  *      unit - (IN) BCM device number
   1272  *      vp   - (IN) VP number
   1273  *      vlan - (IN) VLAN
   1274  *      flags - (OUT) STP state
   1275  * Returns:
   1276  *      BCM_E_XXX
   1277  */
   1278 int
   1279 bcm_td2_vp_vlan_membership_get(int unit, int vp, bcm_vlan_t vlan, int *flags)
   1280 {
   1281     int rv = BCM_E_NONE;
   1282     int vlan_vfi = 0;
   1283     uint32 ing_flags = 0;
   1284     uint32 egr_flags = 0;
   1285     int ing_vp_vlan_membership_found = 0;
   1286     int egr_vp_vlan_membership_found = 0;
   1287     _bcm_vp_vlan_mbrship_key_type_e key_type;
   1288 
   1289 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   1290     if (_BCM_VPN_VFI_IS_SET(vlan)) {
   1291         _BCM_VPN_GET(vlan_vfi, _BCM_VPN_TYPE_VFI, vlan);
   1292         key_type = _bcm_vp_vlan_mbrship_glp_vfi_type;
   1293     } else
   1294 #endif
   1295     {
   1296         vlan_vfi = vlan;
   1297         key_type = _bcm_vp_vlan_mbrship_glp_vlan_type;
   1298     }
   1299 
   1300     rv = bcm_td2_ing_vp_vlan_membership_get(unit,
   1301                 vp, vlan_vfi, &ing_flags, key_type);
   1302     if (BCM_SUCCESS(rv)) {
   1303         ing_vp_vlan_membership_found = TRUE;
   1304         *flags |= ing_flags;
   1305         *flags |= BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP;
   1306     } else if (rv == BCM_E_NOT_FOUND) {
   1307         ing_vp_vlan_membership_found = FALSE;
   1308         rv = BCM_E_NONE;
   1309     } else {
   1310         return rv;
   1311     }
   1312 
   1313     rv = bcm_td2_egr_vp_vlan_membership_get(unit,
   1314                 vp, vlan_vfi, &egr_flags, key_type);
   1315     if (BCM_SUCCESS(rv)) {
   1316         egr_vp_vlan_membership_found = TRUE;
   1317         *flags |= egr_flags;
   1318         *flags |= BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP;
   1319     } else if (rv == BCM_E_NOT_FOUND) {
   1320         egr_vp_vlan_membership_found = FALSE;
   1321         rv = BCM_E_NONE;
   1322     } else {
   1323         return rv;
   1324     }
   1325 
   1326     if (!ing_vp_vlan_membership_found && !egr_vp_vlan_membership_found) {
   1327         return BCM_E_NOT_FOUND;
   1328     }
   1329 
   1330     if (ing_vp_vlan_membership_found && !egr_vp_vlan_membership_found) {
   1331         *flags |= BCM_VLAN_GPORT_ADD_INGRESS_ONLY;
   1332     } else if (!ing_vp_vlan_membership_found && egr_vp_vlan_membership_found) {
   1333         *flags |= BCM_VLAN_GPORT_ADD_EGRESS_ONLY;
   1334     }
   1335 
   1336     return rv;
   1337 }
   1338 
   1339 int
   1340 bcm_td2_vp_vlan_membership_get_all(int unit, bcm_vlan_t vlan, int array_max,
   1341                                     bcm_gport_t *gport_array, int *flags_array,
   1342                                     int *array_size)
   1343 {
   1344     int i = 0;
   1345     int rv = 0;
   1346     int num_vp = 0;
   1347     SHR_BITDCL *ing_vp_bitmap = NULL;
   1348     int *ing_flags_arr = NULL;
   1349     SHR_BITDCL *egr_vp_bitmap = NULL;
   1350     int *egr_flags_arr = NULL;
   1351     bcm_gport_t local_gport;
   1352     int index = 0;
   1353     int gport_found = 0;
   1354     int flags = 0;
   1355 
   1356     if ((*array_size == array_max) && (gport_array || flags_array)) {
   1357         return BCM_E_NONE;
   1358     }
   1359 
   1360     num_vp = soc_mem_index_count(unit, SOURCE_VPm);
   1361 
   1362     ing_vp_bitmap = sal_alloc(SHR_BITALLOCSIZE(num_vp), "ing_vp_bitmap");
   1363     if (NULL == ing_vp_bitmap) {
   1364         rv = BCM_E_MEMORY;
   1365         goto cleanup;
   1366     }
   1367     sal_memset(ing_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp));
   1368 
   1369     ing_flags_arr = sal_alloc(num_vp * sizeof(int), "ing_flags_arr");
   1370     if (NULL == ing_flags_arr) {
   1371         rv = BCM_E_MEMORY;
   1372         goto cleanup;
   1373     }
   1374     sal_memset(ing_flags_arr, 0, num_vp * sizeof(int));
   1375 
   1376     if (soc_feature(unit, soc_feature_ing_vp_vlan_membership)) {
   1377         rv = bcm_td2_ing_vp_vlan_membership_get_all(unit, vlan, ing_vp_bitmap,
   1378                 num_vp, ing_flags_arr);
   1379         if (BCM_FAILURE(rv)) {
   1380             goto cleanup;
   1381         }
   1382     }
   1383 
   1384     egr_vp_bitmap = sal_alloc(SHR_BITALLOCSIZE(num_vp), "egr_vp_bitmap");
   1385     if (NULL == egr_vp_bitmap) {
   1386         rv = BCM_E_MEMORY;
   1387         goto cleanup;
   1388     }
   1389     sal_memset(egr_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp));
   1390 
   1391     egr_flags_arr = sal_alloc(num_vp * sizeof(int), "egr_flags_arr");
   1392     if (NULL == egr_flags_arr) {
   1393         rv = BCM_E_MEMORY;
   1394         goto cleanup;
   1395     }
   1396     sal_memset(egr_flags_arr, 0, num_vp * sizeof(int));
   1397 
   1398     if (soc_feature(unit, soc_feature_egr_vp_vlan_membership)) {
   1399         rv = bcm_td2_egr_vp_vlan_membership_get_all(unit, vlan, egr_vp_bitmap,
   1400                 num_vp, egr_flags_arr);
   1401         if (BCM_FAILURE(rv)) {
   1402             goto cleanup;
   1403         }
   1404     }
   1405 
   1406     for (i = 0; i < num_vp; i++) {
   1407         if (!SHR_BITGET(ing_vp_bitmap, i) &&
   1408             !SHR_BITGET(egr_vp_bitmap, i)) {
   1409             continue;
   1410         }
   1411 
   1412         if ((*array_size == array_max) && (gport_array || flags_array)) {
   1413             break;
   1414         }
   1415 
   1416         if (_bcm_vp_used_get(unit, i, _bcmVpTypeVlan)) {
   1417             BCM_GPORT_VLAN_PORT_ID_SET(local_gport, i);
   1418         } else if (_bcm_vp_used_get(unit, i, _bcmVpTypeNiv)) {
   1419             BCM_GPORT_NIV_PORT_ID_SET(local_gport, i );
   1420         } else if (_bcm_vp_used_get(unit, i, _bcmVpTypeExtender)) {
   1421             BCM_GPORT_EXTENDER_PORT_ID_SET(local_gport, i);
   1422         } else if (_bcm_vp_used_get(unit, i, _bcmVpTypeVxlan)) {
   1423             BCM_GPORT_VXLAN_PORT_ID_SET(local_gport, i);
   1424         } else if (_bcm_vp_used_get(unit, i, _bcmVpTypeMpls)) {
   1425             BCM_GPORT_MPLS_PORT_ID_SET(local_gport, i);
   1426         } else {
   1427             rv = BCM_E_INTERNAL;
   1428             goto cleanup;
   1429         }
   1430 
   1431         if (NULL != gport_array) {
   1432             gport_found = 0;
   1433             for (index = 0; index < *array_size; index++) {
   1434                 if (gport_array[index] == local_gport) {
   1435                     gport_found = 1;
   1436                     break;
   1437                 }
   1438             }
   1439             if (gport_found == 1) {
   1440                 continue;
   1441             }
   1442             gport_array[*array_size] = local_gport;
   1443         }
   1444 
   1445         if (NULL != flags_array) {
   1446             flags_array[*array_size] = ing_flags_arr[i] |
   1447                                        egr_flags_arr[i] |
   1448                                        BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP;
   1449 
   1450             if (SHR_BITGET(ing_vp_bitmap, i) && !SHR_BITGET(egr_vp_bitmap, i)) {
   1451                 flags_array[*array_size] |= BCM_VLAN_GPORT_ADD_INGRESS_ONLY;
   1452             }
   1453 
   1454             if (!SHR_BITGET(ing_vp_bitmap, i) && SHR_BITGET(egr_vp_bitmap, i)) {
   1455                 flags_array[*array_size] |= BCM_VLAN_GPORT_ADD_EGRESS_ONLY;
   1456             }
   1457 
   1458             rv = bcm_tr2_vlan_gport_get(unit, vlan, local_gport, &flags);
   1459             if (BCM_FAILURE(rv)) {
   1460                 goto cleanup;
   1461             }
   1462             flags_array[*array_size] |= flags;
   1463         }
   1464 
   1465         (*array_size)++;
   1466     }
   1467 
   1468 cleanup:
   1469     if (NULL != ing_vp_bitmap) {
   1470         sal_free(ing_vp_bitmap);
   1471     }
   1472     if (NULL != ing_flags_arr) {
   1473         sal_free(ing_flags_arr);
   1474     }
   1475     if (NULL != egr_vp_bitmap) {
   1476         sal_free(egr_vp_bitmap);
   1477     }
   1478     if (NULL != egr_flags_arr) {
   1479         sal_free(egr_flags_arr);
   1480     }
   1481 
   1482     return rv;
   1483 
   1484 }
   1485 
   1486 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */