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


      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  * Module: VLAN management
      8  *
      9  * Purpose:
     10  *     These routines manage the VTABLE entries as well as VLAN-related
     11  *     fields in the PTABLE.
     12  *
     13  *     The bcm layer keeps the VTABLE and PTABLE coherent in terms of
     14  *     what ports belong to what VLANs and which ports are untagged.
     15  */
     16 
     17 #include <shared/bsl.h>
     18 
     19 #include <soc/drv.h>
     20 #include <soc/scache.h>
     21 #include <soc/hash.h>
     22 
     23 #include <sal/core/boot.h>
     24 #include <bcm/error.h>
     25 #include <bcm/vlan.h>
     26 
     27 #include <bcm_int/common/lock.h>
     28 #include <bcm_int/control.h>
     29 #include <bcm_int/esw/vlan.h>
     30 #include <bcm_int/esw/mbcm.h>
     31 #include <bcm_int/esw/stg.h>
     32 #include <bcm_int/esw/firebolt.h>
     33 #if defined(BCM_TRX_SUPPORT)
     34 #include <bcm_int/esw/triumph.h>
     35 #include <bcm_int/esw/mpls.h>
     36 #include <bcm_int/esw/trx.h>
     37 #endif /* BCM_TRX_SUPPORT */
     38 #if defined(BCM_TRIUMPH2_SUPPORT)
     39 #include <bcm_int/esw/triumph2.h>
     40 #include <bcm_int/common/multicast.h>
     41 #endif /* BCM_TRIUMPH2_SUPPORT */
     42 #if defined(BCM_TRIDENT_SUPPORT)
     43 #include <bcm_int/esw/trident.h>
     44 #endif /* BCM_TRIDENT_SUPPORT */
     45 #if defined(BCM_TRIDENT2_SUPPORT)
     46 #include <soc/trident2.h>
     47 #include <bcm_int/esw/trident2.h>
     48 #endif /* BCM_TRIDENT2_SUPPORT */
     49 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
     50 #include <soc/td2_td2p.h>
     51 #include <bcm_int/esw/trident2plus.h>
     52 #include <bcm_int/esw/vpn.h>
     53 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
     54 #if defined(BCM_TRIDENT3_SUPPORT)
     55 #include <soc/trident3.h>
     56 #include <soc/esw/cancun.h>
     57 #include <bcm_int/esw/trident3.h>
     58 #include <bcm_int/esw/flow.h>
     59 #endif /* BCM_TRIDENT3_SUPPORT */
     60 #if defined(BCM_HGPROXY_COE_SUPPORT)
     61 #include <bcm_int/esw/xgs5.h>
     62 #endif /* BCM_HGPROXY_COE_SUPPORT */
     63 #if defined(BCM_ENDURO_SUPPORT)
     64 #include <bcm_int/esw/enduro.h>
     65 #endif /* BCM_ENDURO_SUPPORT */
     66 #include <bcm_int/esw/virtual.h>
     67 #include <bcm_int/esw/mim.h>
     68 #include <bcm_int/esw/port.h>
     69 #include <bcm_int/esw/multicast.h>
     70 #ifdef BCM_WARM_BOOT_SUPPORT
     71 #include <bcm_int/esw/switch.h>
     72 #endif /* BCM_WARM_BOOT_SUPPORT */
     73 #include <bcm_int/esw/stack.h>
     74 #include <bcm_int/esw/ipmc.h>
     75 
     76 #ifdef BCM_TRIUMPH3_SUPPORT
     77 #include <bcm_int/esw/triumph3.h>
     78 #endif /* BCM_TRIUMPH3_SUPPORT */
     79 #if defined(BCM_KATANA2_SUPPORT)
     80 #include <soc/katana2.h>
     81 #include <bcm_int/esw/katana2.h>
     82 #include <bcm_int/esw/subport.h>
     83 #endif /* BCM_KATANA2_SUPPORT */
     84 #ifdef BCM_HURRICANE3_SUPPORT
     85 #include <bcm_int/esw/hurricane3.h>
     86 #include <soc/hurricane3.h>
     87 #endif /* BCM_HURRICANE3_SUPPORT */
     88 #ifdef BCM_GREYHOUND2_SUPPORT
     89 #include <bcm_int/esw/greyhound2.h>
     90 #include <soc/greyhound2.h>
     91 #endif /* BCM_GREYHOUND2_SUPPORT */
     92 #ifdef BCM_TOMAHAWK3_SUPPORT
     93 #include <bcm_int/esw/tomahawk3.h>
     94 #include <bcm_int/tomahawk3_dispatch.h>
     95 #endif /* BCM_TOMAHAWK3_SUPPORT */
     96 #ifdef BCM_HURRICANE2_SUPPORT
     97 #include <soc/hurricane2.h>
     98 #endif /* BCM_HURRICANE2_SUPPORT */
     99 
    100 #include <bcm_int/esw_dispatch.h>
    101 #include <bcm_int/api_xlate_port.h>
    102 #include <bcm_int/esw/flex_ctr.h>
    103 #include <bcm_int/esw/policer.h>
    104 
    105 
    106 bcm_vlan_info_t vlan_info[BCM_MAX_NUM_UNITS];
    107 
    108 #ifndef BCM_VLAN_VID_MAX
    109 #define BCM_VLAN_VID_MAX        4095
    110 #endif
    111 
    112 #define CHECK_INIT(unit)                                        \
    113         if (!vlan_info[unit].init)                              \
    114             return BCM_E_INIT
    115 
    116 STATIC int _bcm_vlan_port_add(int unit, bcm_vlan_t vid, pbmp_t pbmp,
    117                            pbmp_t ubmp, pbmp_t ing_pbmp, int flags);
    118 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
    119 STATIC
    120 bcm_error_t _bcm_esw_vlan_stat_get_table_info(
    121             int                        unit,
    122             bcm_vlan_t                 vlan,
    123             uint32                     *num_of_tables,
    124             bcm_stat_flex_table_info_t *table_info);
    125 static 
    126 bcm_error_t _bcm_esw_vlan_translate_stat_get_table_info(
    127             int                        unit, 
    128             bcm_gport_t                port,
    129             bcm_vlan_translate_key_t   key_type,
    130             bcm_vlan_t                 outer_vlan,
    131             bcm_vlan_t                 inner_vlan,
    132             uint32                     *num_of_tables,
    133             bcm_stat_flex_table_info_t *table_info);
    134 static 
    135 bcm_error_t _bcm_esw_vlan_translate_egress_stat_get_table_info(
    136             int                        unit, 
    137             int                        port_class,
    138             bcm_vlan_t                 outer_vlan,
    139             bcm_vlan_t                 inner_vlan,
    140             uint32                     *num_of_tables,
    141             bcm_stat_flex_table_info_t *table_info);
    142 #endif
    143 
    144 #ifdef BCM_WARM_BOOT_SUPPORT
    145 STATIC int _bcm_vlan_reinit(int unit);
    146 #define BCM_WB_VERSION_1_0                SOC_SCACHE_VERSION(1,0)
    147 #define BCM_WB_VERSION_1_1                SOC_SCACHE_VERSION(1,1)
    148 #define BCM_WB_VERSION_1_2                SOC_SCACHE_VERSION(1,2)
    149 #define BCM_WB_DEFAULT_VERSION            BCM_WB_VERSION_1_2
    150 #else
    151 #define    _bcm_vlan_reinit(unit)     (BCM_E_NONE)
    152 #endif /* BCM_WARM_BOOT_SUPPORT */
    153 
    154 /*
    155  * For BCM internal use to set vlan create default flood mode.
    156  * Follow the same locking convention as other members in the structure
    157  */
    158 /*
    159  * Set the default PFM to be used by vlan_create
    160  * Called from bcm_switch_control_set
    161  */
    162 int
    163 _bcm_esw_vlan_flood_default_set(int unit, bcm_vlan_mcast_flood_t mode)
    164 {
    165     bcm_vlan_info_t             *vi = &vlan_info[unit];
    166 
    167     vi->flood_mode = mode;
    168 
    169     return BCM_E_NONE;
    170 }
    171 
    172 /*
    173  * Get the default PFM used by vlan_create
    174  * Called from bcm_switch_control_get, bcm_vlan_create
    175  */
    176 int
    177 _bcm_esw_vlan_flood_default_get(int unit, bcm_vlan_mcast_flood_t *mode)
    178 {
    179     bcm_vlan_info_t             *vi = &vlan_info[unit];
    180 
    181     *mode = vi->flood_mode;
    182 
    183     return BCM_E_NONE;
    184 }
    185 
    186 /*
    187  * Set the PFM to be used in the Module Header for L2 packets when 
    188  * EGR_CONFIG.STATIC_MH_PFM == 1. When STATIC_MH_PFM==0, the PFM in 
    189  * the MH comes from the Vlan table.
    190  */
    191 int
    192 _bcm_esw_higig_flood_l2_set(int unit, bcm_vlan_mcast_flood_t mode)
    193 {
    194 #ifdef BCM_XGS3_SWITCH_SUPPORT
    195     uint32              rval;
    196 
    197     if (soc_feature(unit, soc_feature_static_pfm)) {
    198         if (mode >= BCM_VLAN_MCAST_FLOOD_COUNT) {
    199             return BCM_E_PARAM;
    200         }
    201         SOC_IF_ERROR_RETURN(READ_EGR_CONFIG_1r(unit, &rval));
    202         soc_reg_field_set(unit, EGR_CONFIG_1r, &rval, MH_PFMf, mode);
    203         SOC_IF_ERROR_RETURN(WRITE_EGR_CONFIG_1r(unit, rval));
    204         return BCM_E_NONE;
    205     }
    206 #endif
    207     return BCM_E_UNAVAIL;
    208 }
    209 
    210 /*
    211  * Get the PFM to be used in the Module Header for L2 packets when 
    212  * EGR_CONFIG.STATIC_MH_PFM == 1.
    213  */
    214 int
    215 _bcm_esw_higig_flood_l2_get(int unit, bcm_vlan_mcast_flood_t *mode)
    216 {
    217 #ifdef BCM_XGS3_SWITCH_SUPPORT
    218     uint32              rval;
    219 
    220     if (soc_feature(unit, soc_feature_static_pfm)) {
    221         SOC_IF_ERROR_RETURN(READ_EGR_CONFIG_1r(unit, &rval));
    222         *mode = soc_reg_field_get(unit, EGR_CONFIG_1r, rval, MH_PFMf);
    223         return BCM_E_NONE;
    224     }
    225 #endif
    226     return BCM_E_UNAVAIL;
    227 }
    228 
    229 /*
    230  * Function:
    231  *   _bcm_esw_vlan_xlate_key_type_value_get
    232  * Purpose:
    233  *   get the hardware specific vlan translation key type value from 
    234  *   the common vlan translation key type for VLAN_XLATE table
    235  *
    236  * Parameters:
    237  *    key_type -       input, common key type 
    238  *    key_type_value - output, hardware specific key type value 
    239  */
    240 int
    241 _bcm_esw_vlan_xlate_key_type_value_get(int unit, 
    242                      int key_type, int *key_type_value)
    243 {
    244 #if defined(BCM_TRIDENT2_SUPPORT)
    245     if (SOC_IS_TD2_TT2(unit)) {
    246         switch (key_type) {
    247         case VLXLT_HASH_KEY_TYPE_IVID_OVID:
    248             *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_IVID_OVID;
    249             break;
    250         case VLXLT_HASH_KEY_TYPE_OTAG:
    251             *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_OTAG;
    252             break;
    253         case VLXLT_HASH_KEY_TYPE_ITAG:
    254             *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_ITAG;
    255             break;
    256         case VLXLT_HASH_KEY_TYPE_VLAN_MAC:
    257             *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_VLAN_MAC;
    258             break;
    259         case VLXLT_HASH_KEY_TYPE_OVID:
    260             *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_OVID;
    261             break;
    262         case VLXLT_HASH_KEY_TYPE_IVID:
    263             *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_IVID;
    264             break;
    265         case VLXLT_HASH_KEY_TYPE_PRI_CFI:
    266             *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_PRI_CFI;
    267             break;
    268         case VLXLT_HASH_KEY_TYPE_HPAE:
    269             *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_HPAE;
    270             break;
    271         case VLXLT_HASH_KEY_TYPE_VIF:
    272             *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_VIF;
    273             break;
    274         case VLXLT_HASH_KEY_TYPE_VIF_VLAN:
    275             *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_VIF_VLAN;
    276             break;
    277         case VLXLT_HASH_KEY_TYPE_VIF_CVLAN:
    278             *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_VIF_CVLAN;
    279             break;
    280         case VLXLT_HASH_KEY_TYPE_VIF_OTAG:
    281             *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_VIF_OTAG;
    282             break;
    283         case VLXLT_HASH_KEY_TYPE_VIF_ITAG: 
    284             *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_VIF_ITAG;
    285             break;
    286         case VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT:
    287             *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT;
    288             break;
    289         case VLXLT_HASH_KEY_TYPE_L2GRE_DIP:
    290             *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_L2GRE_DIP;
    291             break;
    292         case VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN:
    293             *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN;
    294             break;
    295         case VLXLT_HASH_KEY_TYPE_IVID_VSAN:
    296             *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_IVID_VSAN;
    297             break;
    298         case VLXLT_HASH_KEY_TYPE_OVID_VSAN:
    299             *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_OVID_VSAN;
    300             break;
    301         case VLXLT_HASH_KEY_TYPE_VXLAN_DIP:
    302             *key_type_value = TD2_VLXLT_HASH_KEY_TYPE_VXLAN_DIP;
    303             break;
    304         default: 
    305             *key_type_value = 0;
    306             return BCM_E_UNAVAIL;
    307         }
    308     } else
    309 #endif /* BCM_TRIDENT2_SUPPORT */
    310 #if defined(BCM_TRIUMPH3_SUPPORT)
    311     if (SOC_IS_TRIUMPH3(unit)) {
    312         switch (key_type) {
    313             case VLXLT_HASH_KEY_TYPE_IVID_OVID:
    314                 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_IVID_OVID;
    315                 break;
    316             case VLXLT_HASH_KEY_TYPE_OTAG:
    317                 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_OTAG;
    318                 break;
    319             case VLXLT_HASH_KEY_TYPE_ITAG:
    320                 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_ITAG;
    321                 break;
    322             case VLXLT_HASH_KEY_TYPE_VLAN_MAC:
    323                 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_VLAN_MAC;
    324                 break;
    325             case VLXLT_HASH_KEY_TYPE_OVID:
    326                 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_OVID;
    327                 break;
    328             case VLXLT_HASH_KEY_TYPE_IVID:
    329                 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_IVID;
    330                 break;
    331             case VLXLT_HASH_KEY_TYPE_PRI_CFI:
    332                 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_PRI_CFI;
    333                 break;
    334             case VLXLT_HASH_KEY_TYPE_HPAE:
    335                 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_HPAE;
    336                 break;
    337             case VLXLT_HASH_KEY_TYPE_VIF:
    338                 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_VIF;
    339                 break;
    340             case VLXLT_HASH_KEY_TYPE_VIF_VLAN:
    341                 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_VIF_VLAN;
    342                 break;
    343             case VLXLT_HASH_KEY_TYPE_VIF_CVLAN:
    344                 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_VIF_CVLAN;
    345                 break;
    346             case VLXLT_HASH_KEY_TYPE_VIF_OTAG:
    347                 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_VIF_OTAG;
    348                 break;
    349             case VLXLT_HASH_KEY_TYPE_VIF_ITAG: 
    350                 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_VIF_ITAG;
    351                 break;
    352             case VLXLT_HASH_KEY_TYPE_L2GRE_DIP:
    353                 *key_type_value = TR3_VLXLT_HASH_KEY_TYPE_L2GRE_DIP;
    354                 break;
    355             default: 
    356                 *key_type_value = 0;
    357                 return BCM_E_UNAVAIL;
    358         }
    359     } else
    360 #endif
    361 #if defined(BCM_KATANA2_SUPPORT)
    362     if (SOC_IS_KATANA2(unit)) {
    363         switch (key_type) {
    364         case VLXLT_HASH_KEY_TYPE_IVID_OVID:
    365             *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_IVID_OVID;
    366             break;
    367         case VLXLT_HASH_KEY_TYPE_OTAG:
    368             *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_OTAG;
    369             break;
    370         case VLXLT_HASH_KEY_TYPE_ITAG:
    371             *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_ITAG;
    372             break;
    373         case VLXLT_HASH_KEY_TYPE_VLAN_MAC:
    374             *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_VLAN_MAC;
    375             break;
    376         case VLXLT_HASH_KEY_TYPE_OVID:
    377             *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_OVID;
    378             break;
    379         case VLXLT_HASH_KEY_TYPE_IVID:
    380             *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_IVID;
    381             break;
    382         case VLXLT_HASH_KEY_TYPE_PRI_CFI:
    383             *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_PRI_CFI;
    384             break;
    385         case VLXLT_HASH_KEY_TYPE_HPAE:
    386             *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_HPAE;
    387             break;
    388         case VLXLT_HASH_KEY_TYPE_VIF:
    389             *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_VIF;
    390             break;
    391         case VLXLT_HASH_KEY_TYPE_VIF_VLAN:
    392             *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_VIF_VLAN;
    393             break;
    394         case VLXLT_HASH_KEY_TYPE_VIF_CVLAN:
    395             *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_VIF_CVLAN;
    396             break;
    397         case VLXLT_HASH_KEY_TYPE_VIF_OTAG:
    398             *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_VIF_OTAG;
    399             break;
    400         case VLXLT_HASH_KEY_TYPE_VIF_ITAG: 
    401             *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_VIF_ITAG;
    402             break;
    403         case VLXLT_HASH_KEY_TYPE_LLVID:
    404             *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_LLTAG_VID;
    405             break;
    406         case VLXLT_HASH_KEY_TYPE_LLVID_OVID:
    407             *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_LLVID_OVID;
    408             break;
    409         case  VLXLT_HASK_KEY_TYPE_LLVID_IVID:
    410             *key_type_value = KT2_VLXLT_HASH_KEY_TYPE_LLVID_IVID;
    411             break;    
    412         default: 
    413             *key_type_value = 0;
    414             return BCM_E_UNAVAIL;
    415         }
    416     } else
    417 #endif /* BCM_KATANA2_SUPPORT */
    418 #if defined(BCM_HURRICANE2_SUPPORT)
    419     if (SOC_IS_HURRICANE2(unit)) {
    420         switch (key_type) {
    421             case VLXLT_HASH_KEY_TYPE_IVID_OVID:
    422                 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_IVID_OVID;
    423                 break;
    424             case VLXLT_HASH_KEY_TYPE_OTAG:
    425                 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_OTAG;
    426                 break;
    427             case VLXLT_HASH_KEY_TYPE_ITAG:
    428                 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_ITAG;
    429                 break;
    430             case VLXLT_HASH_KEY_TYPE_VLAN_MAC:
    431                 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_VLAN_MAC;
    432                 break;
    433             case VLXLT_HASH_KEY_TYPE_OVID:
    434                 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_OVID;
    435                 break;
    436             case VLXLT_HASH_KEY_TYPE_IVID:
    437                 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_IVID;
    438                 break;
    439             case VLXLT_HASH_KEY_TYPE_PRI_CFI:
    440                 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_PRI_CFI;
    441                 break;
    442             case VLXLT_HASH_KEY_TYPE_HPAE:
    443                 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_HPAE;
    444                 break;
    445             case VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID:
    446                 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID;
    447                 break;
    448             case VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG:
    449                 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG;
    450                 break;
    451             case VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG:
    452                 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG;
    453                 break;
    454             case VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID:
    455                 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID;
    456                 break;
    457             case VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID:
    458                 *key_type_value = HR2_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID;
    459                 break;
    460             default:
    461                 *key_type_value = 0;
    462                 return BCM_E_UNAVAIL;
    463         }
    464     } else
    465 #endif /* BCM_HURRICANE2_SUPPORT */
    466 
    467 #if defined(BCM_HURRICANE3_SUPPORT)
    468     if (SOC_IS_HURRICANE3(unit)) {
    469         switch (key_type){
    470             case VLXLT_HASH_KEY_TYPE_IVID_OVID:
    471                 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_IVID_OVID;
    472                 break;
    473             case VLXLT_HASH_KEY_TYPE_OTAG:
    474                 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_OTAG;
    475                 break;
    476             case VLXLT_HASH_KEY_TYPE_ITAG:
    477                 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_ITAG;
    478                 break;
    479             case VLXLT_HASH_KEY_TYPE_VLAN_MAC:
    480                 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_VLAN_MAC;
    481                 break;
    482             case VLXLT_HASH_KEY_TYPE_OVID:
    483                 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_OVID;
    484                 break;
    485             case VLXLT_HASH_KEY_TYPE_IVID:
    486                 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_IVID;
    487                 break;
    488             case VLXLT_HASH_KEY_TYPE_PRI_CFI:
    489                 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_PRI_CFI;
    490                 break;
    491             case VLXLT_HASH_KEY_TYPE_HPAE:
    492                 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_HPAE;
    493                 break;
    494             case VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID:
    495                 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID;
    496                 break;
    497             case VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG:
    498                 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG;
    499                 break;
    500             case VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG:
    501                 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG;
    502                 break;
    503             case VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID:
    504                 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID;
    505                 break;
    506             case VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID:
    507                 *key_type_value = HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID;
    508                 break;
    509             default: 
    510                 *key_type_value = 0;
    511                 return BCM_E_UNAVAIL;
    512         }
    513     } else
    514 #endif /* BCM_HURRICANE3_SUPPORT */
    515 #if defined(BCM_GREYHOUND2_SUPPORT)
    516     if (SOC_IS_GREYHOUND2(unit)) {
    517         switch (key_type){
    518             case VLXLT_HASH_KEY_TYPE_IVID_OVID:
    519                 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_IVID_OVID;
    520                 break;
    521             case VLXLT_HASH_KEY_TYPE_OTAG:
    522                 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_OTAG;
    523                 break;
    524             case VLXLT_HASH_KEY_TYPE_ITAG:
    525                 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_ITAG;
    526                 break;
    527             case VLXLT_HASH_KEY_TYPE_VLAN_MAC:
    528                 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_VLAN_MAC;
    529                 break;
    530             case VLXLT_HASH_KEY_TYPE_OVID:
    531                 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_OVID;
    532                 break;
    533             case VLXLT_HASH_KEY_TYPE_IVID:
    534                 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_IVID;
    535                 break;
    536             case VLXLT_HASH_KEY_TYPE_PRI_CFI:
    537                 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_PRI_CFI;
    538                 break;
    539             case VLXLT_HASH_KEY_TYPE_HPAE:
    540                 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_HPAE;
    541                 break;
    542             case VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID:
    543                 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID;
    544                 break;
    545             case VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG:
    546                 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG;
    547                 break;
    548             case VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG:
    549                 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG;
    550                 break;
    551             case VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID:
    552                 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID;
    553                 break;
    554             case VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID:
    555                 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID;
    556                 break;
    557             case VLXLT_HASH_KEY_TYPE_VNID:
    558                 *key_type_value = GH2_VLXLT_HASH_KEY_TYPE_VNID;
    559                 break;
    560             default:
    561                 *key_type_value = 0;
    562                 return BCM_E_UNAVAIL;
    563         }
    564     } else
    565 #endif /* BCM_GREYHOUND2_SUPPORT */
    566     {
    567         switch (key_type) {
    568             case VLXLT_HASH_KEY_TYPE_IVID_OVID:
    569                 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_IVID_OVID;
    570                 break;
    571             case VLXLT_HASH_KEY_TYPE_OTAG:
    572                 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_OTAG;
    573                 break;
    574             case VLXLT_HASH_KEY_TYPE_ITAG:
    575                 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_ITAG;
    576                 break;
    577             case VLXLT_HASH_KEY_TYPE_VLAN_MAC:
    578                 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC;
    579                 break;
    580             case VLXLT_HASH_KEY_TYPE_OVID:
    581                 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_OVID;
    582                 break;
    583             case VLXLT_HASH_KEY_TYPE_IVID:
    584                 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_IVID;
    585                 break;
    586             case VLXLT_HASH_KEY_TYPE_PRI_CFI:
    587                 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_PRI_CFI;
    588                 break;
    589             case VLXLT_HASH_KEY_TYPE_HPAE:
    590                 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_HPAE;
    591                 break;
    592             case VLXLT_HASH_KEY_TYPE_VIF:
    593                 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_VIF;
    594                 break;
    595             case VLXLT_HASH_KEY_TYPE_VIF_VLAN:
    596                 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_VIF_VLAN;
    597                 break;
    598             case VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT:
    599                 *key_type_value = TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT;
    600                 break;
    601             default: 
    602                 *key_type_value = 0;
    603                 return BCM_E_UNAVAIL;
    604         }
    605     }
    606     return BCM_E_NONE;
    607 }
    608 
    609 /*
    610  * Function:
    611  *   _bcm_esw_vlan_xlate_key_type_get
    612  * Purpose:
    613  *   get the common vlan translation key type from hardware specific 
    614  *   vlan translation key type value for VLAN_XLATE table
    615  *
    616  * Parameters:
    617  *    key_type_value - input, hardware specific key type value
    618  *    key_type -       output, common key type
    619  */
    620 int
    621 _bcm_esw_vlan_xlate_key_type_get(int unit, 
    622                      int key_type_value, int *key_type)
    623 {
    624 #if defined(BCM_TRIDENT2_SUPPORT)
    625     if (SOC_IS_TD2_TT2(unit)) {
    626         switch (key_type_value) {
    627         case TD2_VLXLT_HASH_KEY_TYPE_IVID_OVID:
    628             *key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID;
    629             break;
    630         case TD2_VLXLT_HASH_KEY_TYPE_OTAG:
    631             *key_type = VLXLT_HASH_KEY_TYPE_OTAG;
    632             break;
    633         case TD2_VLXLT_HASH_KEY_TYPE_ITAG:
    634             *key_type = VLXLT_HASH_KEY_TYPE_ITAG;
    635             break;
    636         case TD2_VLXLT_HASH_KEY_TYPE_VLAN_MAC:
    637             *key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC;
    638             break;
    639         case TD2_VLXLT_HASH_KEY_TYPE_OVID:
    640             *key_type = VLXLT_HASH_KEY_TYPE_OVID;
    641             break;
    642         case TD2_VLXLT_HASH_KEY_TYPE_IVID:
    643             *key_type = VLXLT_HASH_KEY_TYPE_IVID;
    644             break;
    645         case TD2_VLXLT_HASH_KEY_TYPE_PRI_CFI:
    646             *key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI;
    647             break;
    648         case TD2_VLXLT_HASH_KEY_TYPE_HPAE:
    649             *key_type = VLXLT_HASH_KEY_TYPE_HPAE;
    650             break;
    651         case TD2_VLXLT_HASH_KEY_TYPE_VIF:
    652             *key_type = VLXLT_HASH_KEY_TYPE_VIF;
    653             break;
    654         case TD2_VLXLT_HASH_KEY_TYPE_VIF_VLAN:
    655             *key_type = VLXLT_HASH_KEY_TYPE_VIF_VLAN;
    656             break;
    657         case TD2_VLXLT_HASH_KEY_TYPE_VIF_CVLAN:
    658             *key_type = VLXLT_HASH_KEY_TYPE_VIF_CVLAN;
    659             break;
    660         case TD2_VLXLT_HASH_KEY_TYPE_VIF_OTAG:
    661             *key_type = VLXLT_HASH_KEY_TYPE_VIF_OTAG;
    662             break;
    663         case TD2_VLXLT_HASH_KEY_TYPE_VIF_ITAG: 
    664             *key_type = VLXLT_HASH_KEY_TYPE_VIF_ITAG;
    665             break;
    666         case TD2_VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT:
    667             *key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT;
    668             break;
    669         case TD2_VLXLT_HASH_KEY_TYPE_L2GRE_DIP:
    670             *key_type = VLXLT_HASH_KEY_TYPE_L2GRE_DIP;
    671             break;
    672         case TD2_VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN:
    673             *key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN;
    674             break;
    675         case TD2_VLXLT_HASH_KEY_TYPE_IVID_VSAN:
    676             *key_type = VLXLT_HASH_KEY_TYPE_IVID_VSAN;
    677             break;
    678         case TD2_VLXLT_HASH_KEY_TYPE_OVID_VSAN:
    679             *key_type = VLXLT_HASH_KEY_TYPE_OVID_VSAN;
    680             break;
    681         case TD2_VLXLT_HASH_KEY_TYPE_VXLAN_DIP:
    682             *key_type = VLXLT_HASH_KEY_TYPE_VXLAN_DIP;
    683             break;
    684         default: 
    685             *key_type = 0;
    686             return BCM_E_UNAVAIL;
    687         }
    688     } else
    689 #endif /* BCM_TRIDENT2_SUPPORT */
    690 #if defined(BCM_TRIUMPH3_SUPPORT)
    691     if (SOC_IS_TRIUMPH3(unit)) {
    692         switch (key_type_value) {
    693             case TR3_VLXLT_HASH_KEY_TYPE_IVID_OVID:
    694                 *key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID;
    695                 break;
    696             case TR3_VLXLT_HASH_KEY_TYPE_OTAG:
    697                 *key_type = VLXLT_HASH_KEY_TYPE_OTAG;
    698                 break;
    699             case TR3_VLXLT_HASH_KEY_TYPE_ITAG:
    700                 *key_type = VLXLT_HASH_KEY_TYPE_ITAG;
    701                 break;
    702             case TR3_VLXLT_HASH_KEY_TYPE_VLAN_MAC:
    703                 *key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC;
    704                 break;
    705             case TR3_VLXLT_HASH_KEY_TYPE_OVID:
    706                 *key_type = VLXLT_HASH_KEY_TYPE_OVID;
    707                 break;
    708             case TR3_VLXLT_HASH_KEY_TYPE_IVID:
    709                 *key_type = VLXLT_HASH_KEY_TYPE_IVID;
    710                 break;
    711             case TR3_VLXLT_HASH_KEY_TYPE_PRI_CFI:
    712                 *key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI;
    713                 break;
    714             case TR3_VLXLT_HASH_KEY_TYPE_HPAE:
    715                 *key_type = VLXLT_HASH_KEY_TYPE_HPAE;
    716                 break;
    717             case TR3_VLXLT_HASH_KEY_TYPE_VIF:
    718                 *key_type = VLXLT_HASH_KEY_TYPE_VIF;
    719                 break;
    720             case TR3_VLXLT_HASH_KEY_TYPE_VIF_VLAN:
    721                 *key_type = VLXLT_HASH_KEY_TYPE_VIF_VLAN;
    722                 break;
    723             case TR3_VLXLT_HASH_KEY_TYPE_VIF_CVLAN:
    724                 *key_type = VLXLT_HASH_KEY_TYPE_VIF_CVLAN;
    725                 break;
    726             case TR3_VLXLT_HASH_KEY_TYPE_VIF_OTAG:
    727                 *key_type = VLXLT_HASH_KEY_TYPE_VIF_OTAG;
    728                 break;
    729             case TR3_VLXLT_HASH_KEY_TYPE_VIF_ITAG: 
    730                 *key_type = VLXLT_HASH_KEY_TYPE_VIF_ITAG;
    731                 break;
    732             case TR3_VLXLT_HASH_KEY_TYPE_L2GRE_DIP:
    733                 *key_type = TR3_VLXLT_HASH_KEY_TYPE_L2GRE_DIP;
    734                 break;
    735             default: 
    736                 *key_type = 0;
    737                 return BCM_E_UNAVAIL;
    738         }
    739     } else
    740 #endif
    741 #if defined(BCM_KATANA2_SUPPORT)
    742     if (SOC_IS_KATANA2(unit)) {
    743         switch (key_type_value) {
    744         case KT2_VLXLT_HASH_KEY_TYPE_IVID_OVID:
    745             *key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID;
    746             break;
    747         case KT2_VLXLT_HASH_KEY_TYPE_OTAG:
    748             *key_type = VLXLT_HASH_KEY_TYPE_OTAG;
    749             break;
    750         case KT2_VLXLT_HASH_KEY_TYPE_ITAG:
    751             *key_type = VLXLT_HASH_KEY_TYPE_ITAG;
    752             break;
    753         case KT2_VLXLT_HASH_KEY_TYPE_VLAN_MAC:
    754             *key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC;
    755             break;
    756         case KT2_VLXLT_HASH_KEY_TYPE_OVID:
    757             *key_type = VLXLT_HASH_KEY_TYPE_OVID;
    758             break;
    759         case KT2_VLXLT_HASH_KEY_TYPE_IVID:
    760             *key_type = VLXLT_HASH_KEY_TYPE_IVID;
    761             break;
    762         case KT2_VLXLT_HASH_KEY_TYPE_PRI_CFI:
    763             *key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI;
    764             break;
    765         case KT2_VLXLT_HASH_KEY_TYPE_HPAE:
    766             *key_type = VLXLT_HASH_KEY_TYPE_HPAE;
    767             break;
    768         case KT2_VLXLT_HASH_KEY_TYPE_VIF:
    769             *key_type = VLXLT_HASH_KEY_TYPE_VIF;
    770             break;
    771         case KT2_VLXLT_HASH_KEY_TYPE_VIF_VLAN:
    772             *key_type = VLXLT_HASH_KEY_TYPE_VIF_VLAN;
    773             break;
    774         case KT2_VLXLT_HASH_KEY_TYPE_VIF_CVLAN:
    775             *key_type = VLXLT_HASH_KEY_TYPE_VIF_CVLAN;
    776             break;
    777         case KT2_VLXLT_HASH_KEY_TYPE_VIF_OTAG:
    778             *key_type = VLXLT_HASH_KEY_TYPE_VIF_OTAG;
    779             break;
    780         case KT2_VLXLT_HASH_KEY_TYPE_VIF_ITAG: 
    781             *key_type = VLXLT_HASH_KEY_TYPE_VIF_ITAG;
    782             break;
    783         case KT2_VLXLT_HASH_KEY_TYPE_LLTAG_VID:
    784             *key_type = VLXLT_HASH_KEY_TYPE_LLVID;
    785             break;
    786         case KT2_VLXLT_HASH_KEY_TYPE_LLVID_IVID:
    787             *key_type = VLXLT_HASK_KEY_TYPE_LLVID_IVID;
    788             break;
    789         case KT2_VLXLT_HASH_KEY_TYPE_LLVID_OVID:
    790             *key_type = VLXLT_HASH_KEY_TYPE_LLVID_OVID;
    791             break;
    792         default: 
    793             *key_type = 0;
    794             return BCM_E_UNAVAIL;
    795         }
    796     } else
    797 #endif /* BCM_KATANA2_SUPPORT */
    798 #if defined(BCM_HURRICANE2_SUPPORT)
    799     if (SOC_IS_HURRICANE2(unit)) {
    800         switch (key_type_value) {
    801             case HR2_VLXLT_HASH_KEY_TYPE_IVID_OVID:
    802                 *key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID;
    803                 break;
    804             case HR2_VLXLT_HASH_KEY_TYPE_OTAG:
    805                 *key_type = VLXLT_HASH_KEY_TYPE_OTAG;
    806                 break;
    807             case HR2_VLXLT_HASH_KEY_TYPE_ITAG:
    808                 *key_type = VLXLT_HASH_KEY_TYPE_ITAG;
    809                 break;
    810             case HR2_VLXLT_HASH_KEY_TYPE_VLAN_MAC:
    811                 *key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC;
    812                 break;
    813             case HR2_VLXLT_HASH_KEY_TYPE_OVID:
    814                 *key_type = VLXLT_HASH_KEY_TYPE_OVID;
    815                 break;
    816             case HR2_VLXLT_HASH_KEY_TYPE_IVID:
    817                 *key_type = VLXLT_HASH_KEY_TYPE_IVID;
    818                 break;
    819             case HR2_VLXLT_HASH_KEY_TYPE_PRI_CFI:
    820                 *key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI;
    821                 break;
    822             case HR2_VLXLT_HASH_KEY_TYPE_HPAE:
    823                 *key_type = VLXLT_HASH_KEY_TYPE_HPAE;
    824                 break;
    825             case HR2_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID:
    826                 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID;
    827                 break;
    828             case HR2_VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG:
    829                 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG;
    830                 break;
    831             case HR2_VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG:
    832                 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG;
    833                 break;
    834             case HR2_VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID:
    835                 *key_type= VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID;
    836                 break;
    837             case HR2_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID:
    838                 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID;
    839                 break;
    840             default:
    841                 *key_type = 0;
    842                 return BCM_E_UNAVAIL;
    843         }
    844     } else
    845 #endif /* BCM_HURRICANE2_SUPPORT */
    846 #if defined(BCM_HURRICANE3_SUPPORT)
    847     if (SOC_IS_HURRICANE3(unit)) {
    848         switch (key_type_value){
    849             case HR3_VLXLT_HASH_KEY_TYPE_IVID_OVID:
    850                 *key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID;
    851                 break;
    852             case HR3_VLXLT_HASH_KEY_TYPE_OTAG:
    853                 *key_type = VLXLT_HASH_KEY_TYPE_OTAG;
    854                 break;
    855             case HR3_VLXLT_HASH_KEY_TYPE_ITAG:
    856                 *key_type = VLXLT_HASH_KEY_TYPE_ITAG;
    857                 break;
    858             case HR3_VLXLT_HASH_KEY_TYPE_VLAN_MAC:
    859                 *key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC;
    860                 break;
    861             case HR3_VLXLT_HASH_KEY_TYPE_OVID:
    862                 *key_type = VLXLT_HASH_KEY_TYPE_OVID;
    863                 break;
    864             case HR3_VLXLT_HASH_KEY_TYPE_IVID:
    865                 *key_type = VLXLT_HASH_KEY_TYPE_IVID;
    866                 break;
    867             case HR3_VLXLT_HASH_KEY_TYPE_PRI_CFI:
    868                 *key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI;
    869                 break;
    870             case HR3_VLXLT_HASH_KEY_TYPE_HPAE:
    871                 *key_type = VLXLT_HASH_KEY_TYPE_HPAE;
    872                 break;
    873             case HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID:
    874                 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID;
    875                 break;
    876             case HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG:
    877                 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG;
    878                 break;
    879             case HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG:
    880                 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG;
    881                 break;
    882             case HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID:
    883                 *key_type= VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID;
    884                 break;
    885             case HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID:
    886                 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID;
    887                 break;
    888             default:
    889                 *key_type = 0;
    890                 return BCM_E_UNAVAIL;
    891         }
    892     } else
    893 #endif /* BCM_HURRICANE3_SUPPORT */
    894 #if defined(BCM_GREYHOUND2_SUPPORT)
    895     if (SOC_IS_GREYHOUND2(unit)) {
    896         switch (key_type_value){
    897             case GH2_VLXLT_HASH_KEY_TYPE_IVID_OVID:
    898                 *key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID;
    899                 break;
    900             case GH2_VLXLT_HASH_KEY_TYPE_OTAG:
    901                 *key_type = VLXLT_HASH_KEY_TYPE_OTAG;
    902                 break;
    903             case GH2_VLXLT_HASH_KEY_TYPE_ITAG:
    904                 *key_type = VLXLT_HASH_KEY_TYPE_ITAG;
    905                 break;
    906             case GH2_VLXLT_HASH_KEY_TYPE_VLAN_MAC:
    907                 *key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC;
    908                 break;
    909             case GH2_VLXLT_HASH_KEY_TYPE_OVID:
    910                 *key_type = VLXLT_HASH_KEY_TYPE_OVID;
    911                 break;
    912             case GH2_VLXLT_HASH_KEY_TYPE_IVID:
    913                 *key_type = VLXLT_HASH_KEY_TYPE_IVID;
    914                 break;
    915             case GH2_VLXLT_HASH_KEY_TYPE_PRI_CFI:
    916                 *key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI;
    917                 break;
    918             case GH2_VLXLT_HASH_KEY_TYPE_HPAE:
    919                 *key_type = VLXLT_HASH_KEY_TYPE_HPAE;
    920                 break;
    921             case GH2_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID:
    922                 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID;
    923                 break;
    924             case GH2_VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG:
    925                 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG;
    926                 break;
    927             case GH2_VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG:
    928                 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG;
    929                 break;
    930             case GH2_VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID:
    931                 *key_type= VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID;
    932                 break;
    933             case GH2_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID:
    934                 *key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID;
    935                 break;
    936             case GH2_VLXLT_HASH_KEY_TYPE_VNID:
    937                 *key_type = VLXLT_HASH_KEY_TYPE_VNID;
    938                 break;
    939             default:
    940                 *key_type = 0;
    941                 return BCM_E_UNAVAIL;
    942         }
    943     } else
    944 #endif /* BCM_GREYHOUND2_SUPPORT */
    945     {
    946         switch (key_type_value) {
    947             case TR_VLXLT_HASH_KEY_TYPE_IVID_OVID:
    948                 *key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID;
    949                 break;
    950             case TR_VLXLT_HASH_KEY_TYPE_OTAG:
    951                 *key_type = VLXLT_HASH_KEY_TYPE_OTAG;
    952                 break;
    953             case TR_VLXLT_HASH_KEY_TYPE_ITAG:
    954                 *key_type = VLXLT_HASH_KEY_TYPE_ITAG;
    955                 break;
    956             case TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC:
    957                 *key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC;
    958                 break;
    959             case TR_VLXLT_HASH_KEY_TYPE_OVID:
    960                 *key_type = VLXLT_HASH_KEY_TYPE_OVID;
    961                 break;
    962             case TR_VLXLT_HASH_KEY_TYPE_IVID:
    963                 *key_type = VLXLT_HASH_KEY_TYPE_IVID;
    964                 break;
    965             case TR_VLXLT_HASH_KEY_TYPE_PRI_CFI:
    966                 *key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI;
    967                 break;
    968             case TR_VLXLT_HASH_KEY_TYPE_HPAE:
    969                 *key_type = VLXLT_HASH_KEY_TYPE_HPAE;
    970                 break;
    971             case TR_VLXLT_HASH_KEY_TYPE_VIF:
    972                 *key_type = VLXLT_HASH_KEY_TYPE_VIF;
    973                 break;
    974             case TR_VLXLT_HASH_KEY_TYPE_VIF_VLAN:
    975                 *key_type = VLXLT_HASH_KEY_TYPE_VIF_VLAN;
    976                 break;
    977             case TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT:
    978                 *key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT;
    979                 break;
    980             default: 
    981                 *key_type = 0;
    982                 return BCM_E_UNAVAIL;
    983         }
    984     }
    985     return BCM_E_NONE;
    986 }
    987 
    988 /*
    989  * Function:
    990  *   _bcm_esw_pt_vtkey_type_value_get
    991  * Purpose:
    992  * get the hardware specific port table vlan translation key type value
    993  * from the common vlan translation key type for PORT_TABLE VT_KEY_TYPE
    994  * field. In Triumph3, key type value in VLAN_XLATE differs from 
    995  * PORT_TABLE's VT_KEY_TYPE(_2) field
    996  *
    997  * Parameters:
    998  *    key_type -       input, common key type
    999  *    key_type_value - output, hardware specific PORT_TABLE key type value
   1000  */
   1001 int
   1002 _bcm_esw_pt_vtkey_type_value_get(int unit, 
   1003                      int key_type, int *key_type_value)
   1004 {
   1005 #if defined(BCM_TRIUMPH3_SUPPORT)
   1006     if (SOC_IS_TRIUMPH3(unit)) {
   1007         switch (key_type) {
   1008             case VLXLT_HASH_KEY_TYPE_IVID_OVID:
   1009                 *key_type_value = TR3_PT_XLT_KEY_TYPE_IVID_OVID;
   1010                 break;
   1011             case VLXLT_HASH_KEY_TYPE_OTAG:
   1012                 *key_type_value = TR3_PT_XLT_KEY_TYPE_OTAG;
   1013                 break;
   1014             case VLXLT_HASH_KEY_TYPE_ITAG:
   1015                 *key_type_value = TR3_PT_XLT_KEY_TYPE_ITAG;
   1016                 break;
   1017             case VLXLT_HASH_KEY_TYPE_VLAN_MAC:
   1018                 *key_type_value = TR3_PT_XLT_KEY_TYPE_VLAN_MAC;
   1019                 break;
   1020             case VLXLT_HASH_KEY_TYPE_OVID:
   1021                 *key_type_value = TR3_PT_XLT_KEY_TYPE_OVID;
   1022                 break;
   1023             case VLXLT_HASH_KEY_TYPE_IVID:
   1024                 *key_type_value = TR3_PT_XLT_KEY_TYPE_IVID;
   1025                 break;
   1026             case VLXLT_HASH_KEY_TYPE_PRI_CFI:
   1027                 *key_type_value = TR3_PT_XLT_KEY_TYPE_PRI_CFI;
   1028                 break;
   1029             case VLXLT_HASH_KEY_TYPE_HPAE:
   1030                 *key_type_value = TR3_PT_XLT_KEY_TYPE_HPAE;
   1031                 break;
   1032             case VLXLT_HASH_KEY_TYPE_VIF:
   1033                 *key_type_value = TR3_PT_XLT_KEY_TYPE_VIF;
   1034                 break;
   1035             case VLXLT_HASH_KEY_TYPE_VIF_VLAN:
   1036                 *key_type_value = TR3_PT_XLT_KEY_TYPE_VIF_VLAN;
   1037                 break;
   1038             case VLXLT_HASH_KEY_TYPE_VIF_CVLAN:
   1039                 *key_type_value = TR3_PT_XLT_KEY_TYPE_VIF_CVLAN;
   1040                 break;
   1041             case VLXLT_HASH_KEY_TYPE_VIF_OTAG:
   1042                 *key_type_value = TR3_PT_XLT_KEY_TYPE_VIF_OTAG;
   1043                 break;
   1044             case VLXLT_HASH_KEY_TYPE_VIF_ITAG: 
   1045                 *key_type_value = TR3_PT_XLT_KEY_TYPE_VIF_ITAG;
   1046                 break;
   1047             default: 
   1048                 *key_type_value = 0;
   1049                 return BCM_E_UNAVAIL;
   1050         }
   1051     } else
   1052 #endif
   1053     {
   1054         /* for other switches, PORT_TABLE key type value is same as the
   1055          * VLAN_XLATE key type value.
   1056          */
   1057         return _bcm_esw_vlan_xlate_key_type_value_get(unit, key_type,
   1058                                                       key_type_value);
   1059     }
   1060     return BCM_E_NONE;
   1061 }
   1062 
   1063 /*
   1064  * Function:
   1065  *   _bcm_esw_pt_vtkey_type_get
   1066  * Purpose:
   1067  * get the common vlan translation key type from hardware specific 
   1068  * PORT_TABLE vlan translation key type value
   1069  *
   1070  * Parameters:
   1071  *    key_type_value - input, common key type
   1072  *    key_type - output, hardware specific PORT_TABLE key type value
   1073  */
   1074 int
   1075 _bcm_esw_pt_vtkey_type_get(int unit, 
   1076                      int key_type_value, int *key_type)
   1077 {
   1078 #if defined(BCM_TRIUMPH3_SUPPORT)
   1079     if (SOC_IS_TRIUMPH3(unit)) {
   1080         switch (key_type_value) {
   1081             case TR3_PT_XLT_KEY_TYPE_IVID_OVID:
   1082                 *key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID;
   1083                 break;
   1084             case TR3_PT_XLT_KEY_TYPE_OTAG:
   1085                 *key_type = VLXLT_HASH_KEY_TYPE_OTAG;
   1086                 break;
   1087             case TR3_PT_XLT_KEY_TYPE_ITAG:
   1088                 *key_type = VLXLT_HASH_KEY_TYPE_ITAG;
   1089                 break;
   1090             case TR3_PT_XLT_KEY_TYPE_VLAN_MAC:
   1091                 *key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC;
   1092                 break;
   1093             case TR3_PT_XLT_KEY_TYPE_OVID:
   1094                 *key_type = VLXLT_HASH_KEY_TYPE_OVID;
   1095                 break;
   1096             case TR3_PT_XLT_KEY_TYPE_IVID:
   1097                 *key_type = VLXLT_HASH_KEY_TYPE_IVID;
   1098                 break;
   1099             case TR3_PT_XLT_KEY_TYPE_PRI_CFI:
   1100                 *key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI;
   1101                 break;
   1102             case TR3_PT_XLT_KEY_TYPE_HPAE:
   1103                 *key_type = VLXLT_HASH_KEY_TYPE_HPAE;
   1104                 break;
   1105             case TR3_PT_XLT_KEY_TYPE_VIF:
   1106                 *key_type = VLXLT_HASH_KEY_TYPE_VIF;
   1107                 break;
   1108             case TR3_PT_XLT_KEY_TYPE_VIF_VLAN:
   1109                 *key_type = VLXLT_HASH_KEY_TYPE_VIF_VLAN;
   1110                 break;
   1111             case TR3_PT_XLT_KEY_TYPE_VIF_CVLAN:
   1112                 *key_type = VLXLT_HASH_KEY_TYPE_VIF_CVLAN;
   1113                 break;
   1114             case TR3_PT_XLT_KEY_TYPE_VIF_OTAG:
   1115                 *key_type = VLXLT_HASH_KEY_TYPE_VIF_OTAG;
   1116                 break;
   1117             case TR3_PT_XLT_KEY_TYPE_VIF_ITAG: 
   1118                 *key_type = VLXLT_HASH_KEY_TYPE_VIF_ITAG;
   1119                 break;
   1120             default: 
   1121                 *key_type = 0;
   1122                 return BCM_E_UNAVAIL;
   1123         }
   1124     } else
   1125 #endif
   1126     {
   1127         /* For other devices, key type in VLAN_XLATE is same as in PORT_TABLE*/
   1128         return _bcm_esw_vlan_xlate_key_type_get(unit, key_type_value,
   1129                                                 key_type);
   1130     }
   1131     return BCM_E_NONE;
   1132 }
   1133 
   1134 /*
   1135  * Function:
   1136  *   _bcm_esw_egr_vtkey_type_value_get
   1137  * Purpose:
   1138  * get the hardware specific EGR_VLAN_CONTROL_1 egress vlan
   1139  * translation key type value from the common key type
   1140  *
   1141  * Parameters:
   1142  *    key_type -       input, common key type
   1143  *    key_type_value - output, hardware specific
   1144  *                     EGR_VLAN_CONTROL_1 table VT_ENABLE/VT2_ENABLE fields
   1145  */
   1146 int
   1147 _bcm_esw_egr_vtkey_type_value_get(int unit,
   1148                      int key_type, int *key_type_value)
   1149 {
   1150     switch (key_type) {
   1151         case bcmVlanTranslateEgressKeyPortGroupDouble:
   1152             /* For devices where feature 'egr_vlan_xlate_second_lookup' is enabled,
   1153              * VT_ENABLEf is a 2-bit field and explicit second lookup is allowed.
   1154              * This key_type is an alias of the existing key_type
   1155              * bcmVlanTranslateEgressKeyVlanPort in term of functionality,
   1156              * on these devices.*/
   1157             if (!(SOC_IS_APACHE(unit) &&
   1158                 soc_feature(unit, soc_feature_egr_vlan_xlate_second_lookup))) {
   1159                 return BCM_E_UNAVAIL;
   1160             }
   1161             /* passthru */
   1162             /* coverity[fallthrough: FALSE] */
   1163         case bcmVlanTranslateEgressKeyVlanPort:
   1164             /* Note: This is the default key type for first lookup */
   1165             *key_type_value = EVXLT_KEY_TYPE_PORT_GROUP_VLAN_DOUBLE;
   1166             break;
   1167         case bcmVlanTranslateEgressKeyPortDouble:
   1168             if (soc_feature(unit, soc_feature_egr_vlan_xlate_second_lookup)) {
   1169                 *key_type_value = EVXLT_KEY_TYPE_PORT_VLAN_DOUBLE;
   1170             } else {
   1171                 return BCM_E_UNAVAIL;
   1172             }
   1173             break;
   1174         case bcmVlanTranslateEgressKeyInvalid:
   1175             *key_type_value = EVXLT_KEY_TYPE_NOOP;
   1176             break;
   1177         default:
   1178             *key_type_value = 0;
   1179             return BCM_E_UNAVAIL;
   1180     }
   1181     return BCM_E_NONE;
   1182 }
   1183 
   1184 /*
   1185  * Function:
   1186  *   _bcm_esw_dvp_vtkey_type_value_get
   1187  * Purpose:
   1188  * get the hardware specific EGR_DVP_ATTRIBUTE egress vlan
   1189  * translation key type value from the common key type
   1190  *
   1191  * Parameters:
   1192  *    key_type -       input, common key type
   1193  *    key_type_value - output, hardware specific EGR_DVP_ATTRIBUTE key type value
   1194  */
   1195 int
   1196 _bcm_esw_dvp_vtkey_type_value_get(int unit, 
   1197                      int key_type, int *key_type_value)
   1198 {
   1199 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   1200     if (soc_feature(unit, soc_feature_egr_vlan_xlate_key_on_dvp)) {
   1201         if (key_type_value == NULL) {
   1202             return BCM_E_PARAM;
   1203         }
   1204         switch (key_type) {
   1205             case bcmVlanTranslateEgressKeyVpn:
   1206                 *key_type_value = TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_VFI;
   1207                 break;
   1208             case bcmVlanTranslateEgressKeyVpnGport:
   1209                 *key_type_value = TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_DVP_VFI;
   1210                 break;
   1211             case bcmVlanTranslateEgressKeyVpnGportGroup:
   1212                 *key_type_value = TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_GID_VFI;
   1213                 break;
   1214             case bcmVlanTranslateEgressKeyVlanPort:
   1215                 /* not supported now*/
   1216                 *key_type_value = 0;
   1217                 return BCM_E_UNAVAIL;
   1218             case bcmVlanTranslateEgressKeyInvalid:
   1219                 *key_type_value = TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_NOOP;
   1220                 break;
   1221             default: 
   1222                 *key_type_value = 0;
   1223                 return BCM_E_PARAM;
   1224         }
   1225         return BCM_E_NONE;
   1226     } else
   1227 #endif
   1228     {
   1229         return BCM_E_UNAVAIL;
   1230     }
   1231 }
   1232 
   1233 /*
   1234  * Function:
   1235  *   _bcm_esw_egr_vtkey_type_get
   1236  * Purpose:
   1237  * Get the common vlan translation key type from the hardware specific
   1238  * EGR_VLAN_CONTROL_1 vlan translation key type value VT_ENABLE/VT2_ENABLE
   1239  *
   1240  * Parameters:
   1241  *    key_type_value - input, common key type
   1242  *    key_type - output, hardware specific EGR_VLAN_CONTROL_1 key type value
   1243  */
   1244 int
   1245 _bcm_esw_egr_vtkey_type_get(int unit,
   1246                      int key_type_value, int *key_type)
   1247 {
   1248         if (key_type == NULL) {
   1249             return BCM_E_PARAM;
   1250         }
   1251         switch (key_type_value) {
   1252             case EVXLT_KEY_TYPE_PORT_GROUP_VLAN_DOUBLE:
   1253                 /* For devices where feature 'egr_vlan_xlate_second_lookup' is
   1254                  * enabled, VT_ENABLEf is a 2-bit field and explicit second
   1255                  * lookup is allowed. This key_type_value maps to both key_types.
   1256                  * Returning bcmVlanTranslateEgressKeyPortGroupDouble for those
   1257                  * devices where soc feature is enabled as it clears the
   1258                  * ambiguity in the naming of existing enums. Otherwise,
   1259                  * bcmVlanTranslateEgressKeyVlanPort is returned as before */
   1260                 if (SOC_IS_APACHE(unit) &&
   1261                     soc_feature(unit, soc_feature_egr_vlan_xlate_second_lookup)) {
   1262                     *key_type = bcmVlanTranslateEgressKeyPortGroupDouble;
   1263                 } else {
   1264                     *key_type = bcmVlanTranslateEgressKeyVlanPort;
   1265                 }
   1266                 break;
   1267             case EVXLT_KEY_TYPE_PORT_VLAN_DOUBLE:
   1268                 *key_type = bcmVlanTranslateEgressKeyPortDouble;
   1269                 break;
   1270             case EVXLT_KEY_TYPE_NOOP:
   1271                 *key_type = bcmVlanTranslateEgressKeyInvalid;
   1272                 break;
   1273             default:
   1274                 *key_type = 0;
   1275                 return BCM_E_PARAM;
   1276         }
   1277         return BCM_E_NONE;
   1278 }
   1279 
   1280 /*
   1281  * Function:
   1282  *   _bcm_esw_dvp_vtkey_type_get
   1283  * Purpose:
   1284  * get the common vlan translation key type from the hardware specific 
   1285  * EGR_DVP_ATTRIBUTE vlan translation key type value 
   1286  *
   1287  * Parameters:
   1288  *    key_type_value - input, common key type
   1289  *    key_type - output, hardware specific EGR_DVP_ATTRIBUTE key type value
   1290  */
   1291 int
   1292 _bcm_esw_dvp_vtkey_type_get(int unit, 
   1293                      int key_type_value, int *key_type)
   1294 {
   1295 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   1296     if (soc_feature(unit, soc_feature_egr_vlan_xlate_key_on_dvp)) {
   1297         if (key_type == NULL) {
   1298             return BCM_E_PARAM;
   1299         }
   1300         switch (key_type_value) {
   1301             case TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_VFI:
   1302                 *key_type = bcmVlanTranslateEgressKeyVpn;
   1303                 break;
   1304             case TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_DVP_VFI:
   1305                 *key_type = bcmVlanTranslateEgressKeyVpnGport;
   1306                 break;
   1307             case TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_GID_VFI:
   1308                 *key_type = bcmVlanTranslateEgressKeyVpnGportGroup;
   1309                 break;
   1310             case TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_NOOP:
   1311                 *key_type = bcmVlanTranslateEgressKeyInvalid;
   1312                 break;
   1313             case TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_DVP_OL_VLAN:
   1314             case TD2PLUS_DVP_EVLXLT_HASH_KEY_TYPE_PORT_UL_VLAN:
   1315                 *key_type = 0;
   1316                 return BCM_E_UNAVAIL;
   1317             default: 
   1318                 *key_type = 0;
   1319                 return BCM_E_PARAM;
   1320         }
   1321         return BCM_E_NONE;
   1322     } else
   1323 #endif
   1324     {
   1325         return BCM_E_UNAVAIL;
   1326     }
   1327 }
   1328 
   1329 /*
   1330  * MACRO:
   1331  *      _BCM_VBMP_INSERT
   1332  * Purpose:
   1333  *      Add a VLAN ID to a vbmap
   1334  */
   1335 #define _BCM_VBMP_INSERT(_bmp_, _vid_)    SHR_BITSET(((_bmp_).w), (_vid_))
   1336 
   1337 /*
   1338  * Macro:
   1339  *      _BCM_VBMP_REMOVE
   1340  * Purpose:
   1341  *      Delete a VLAN ID from a vbmp
   1342  */
   1343 #define _BCM_VBMP_REMOVE(_bmp_, _vid_)    SHR_BITCLR(((_bmp_).w), (_vid_))
   1344 
   1345 /*
   1346  * Macro :
   1347  *      _BCM_VBMP_LOOKUP
   1348  * Purpose:
   1349  *      Return TRUE if a VLAN ID exists in a vbmp, FALSE otherwise
   1350  */
   1351 #define _BCM_VBMP_LOOKUP(_bmp_, _vid_)    SHR_BITGET(((_bmp_).w), (_vid_))
   1352 
   1353 /*
   1354  * Function:
   1355  *      _bcm_vbmp_destroy
   1356  * Purpose:
   1357  *      Free all memory used by a active VLANs bitmap
   1358  */
   1359 
   1360 int
   1361 _bcm_vbmp_destroy(vbmp_t *bmp)
   1362 {
   1363     if (bmp->w != NULL) {
   1364         sal_free(bmp->w);
   1365         bmp->w = NULL;
   1366     }
   1367     return BCM_E_NONE;
   1368 }
   1369 
   1370 /*
   1371  * Function:
   1372  *      _bcm_vbmp_init
   1373  * Purpose:
   1374  *      Create new valid vlans bitmap.
   1375  */
   1376 
   1377 int
   1378 _bcm_vbmp_init(vbmp_t *bmp)
   1379 {
   1380     int alloc_size;
   1381 
   1382     /* Deinit previously allocated bitmap. */
   1383     _bcm_vbmp_destroy(bmp);
   1384 
   1385     alloc_size = SHR_BITALLOCSIZE(BCM_VLAN_COUNT);
   1386     bmp->w = sal_alloc(alloc_size, "Active vlans bitmap");
   1387     if (NULL == bmp->w) {
   1388         return (BCM_E_MEMORY);
   1389     }
   1390     sal_memset(bmp->w, 0, alloc_size);
   1391 
   1392     return BCM_E_NONE;
   1393 }
   1394 
   1395 /*
   1396  * Check for valid VLAN. If easy reload, check software state;
   1397  * otherwise, check hardware entry
   1398  */
   1399 int _bcm_vlan_valid_check(int unit, int table, vlan_tab_entry_t *vt, 
   1400                      bcm_vlan_t vid) 
   1401 {
   1402 #if defined(BCM_EASY_RELOAD_SUPPORT)                          
   1403     if (SOC_IS_RELOADING(unit)) {
   1404         vbmp_t vbmp;
   1405         
   1406         if (! ((table == EGR_VLANm) || (table == VLAN_TABm || table == VLAN_2_TABm))) {
   1407             return BCM_E_PARAM;
   1408         }
   1409         vbmp = (table == EGR_VLANm) ? vlan_info[unit].egr_vlan_bmp :
   1410                vlan_info[unit].vlan_tab_bmp;
   1411         if (! _BCM_VBMP_LOOKUP(vbmp, vid)) {       
   1412             return BCM_E_NOT_FOUND;                             
   1413         }
   1414     } else                                                    
   1415 #endif                                                        
   1416     {                                                         
   1417         if (!soc_mem_field32_get(unit, table, vt, VALIDf)) {  
   1418             return BCM_E_NOT_FOUND;                             
   1419         }
   1420     }
   1421     return BCM_E_NONE;
   1422 }
   1423     
   1424 #if defined(BCM_EASY_RELOAD_SUPPORT)                          
   1425 /*
   1426  * Set valid VLAN as software state for easy reload
   1427  */
   1428 int _bcm_vlan_valid_set(int unit, int table, bcm_vlan_t vid, int val)
   1429 {
   1430     vbmp_t vbmp;
   1431     if (! ((table == EGR_VLANm) || (table == VLAN_TABm || table == VLAN_2_TABm))) {
   1432         return BCM_E_PARAM;
   1433     }
   1434     vbmp = (table == EGR_VLANm) ? vlan_info[unit].egr_vlan_bmp :
   1435            vlan_info[unit].vlan_tab_bmp;
   1436     
   1437     if (val) {
   1438         _BCM_VBMP_INSERT(vbmp, vid);
   1439     } else {
   1440         _BCM_VBMP_REMOVE(vbmp, vid);
   1441     }
   1442     return BCM_E_NONE;
   1443 }
   1444 #endif
   1445 
   1446 /*
   1447  * Function:
   1448  *      _bcm_vlan_control_trust_gport
   1449  * Purpose:
   1450  *      Validate if a given VLAN control is capable of parsing GPORT internaly 
   1451  * Parameters:
   1452  *      type -  VLAN control to be checked 
   1453  * Returns:
   1454  *      BCM_E_NONE - control is capable of parsing GPORT.
   1455  *      BCM_E_INTERNAL - GPORT for the control should be parsed by the API
   1456  */
   1457 STATIC int
   1458 _bcm_vlan_control_trust_gport(bcm_vlan_control_port_t type)
   1459 {
   1460     int                     itter;
   1461     bcm_vlan_control_port_t types_arr[] = {
   1462         bcmVlanPortUseInnerPri,
   1463         bcmVlanPortUseOuterPri,
   1464         bcmVlanPortTranslateKeyFirst,
   1465         bcmVlanPortTranslateEgressKey
   1466         };
   1467 
   1468    for (itter = 0; itter < COUNTOF(types_arr); itter ++) {
   1469        if (types_arr[itter] == type) {
   1470            return BCM_E_NONE;
   1471        }
   1472    }
   1473 
   1474    return BCM_E_INTERNAL;
   1475 }
   1476 
   1477 
   1478 /*
   1479  * Function:
   1480  *      _bcm_vlan_1st (internal)
   1481  * Purpose:
   1482  *      Return the first defined VLAN ID that is not the default VLAN.
   1483  */
   1484 
   1485 STATIC INLINE bcm_vlan_t
   1486 _bcm_vlan_1st(int unit)
   1487 {
   1488     int idx;
   1489 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_MONTEREY_SUPPORT)
   1490     bcm_vlan_t          olp_vlan = BCM_VLAN_INVALID;
   1491     uint8 feature_xflow_macsec_olp = 0;
   1492     if (soc_feature(unit, soc_feature_xflow_macsec_olp)) {
   1493         olp_vlan = soc_property_get(unit, spn_XFLOW_MACSEC_OLP_VLAN, BCM_VLAN_INVALID);
   1494         feature_xflow_macsec_olp = 1;
   1495     }
   1496 #endif
   1497     for (idx = BCM_VLAN_MIN; idx < BCM_VLAN_COUNT; idx++) {
   1498 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_MONTEREY_SUPPORT)
   1499         if ((idx == olp_vlan) && (feature_xflow_macsec_olp)) {
   1500             continue;
   1501         }
   1502 #endif
   1503         if ((idx != vlan_info[unit].defl) &&
   1504             (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, idx))) {
   1505             return (idx);
   1506         }
   1507     }
   1508     return BCM_VLAN_INVALID;
   1509 }
   1510 
   1511 /*
   1512  * Function:
   1513  *      bcm_vlan_init
   1514  * Purpose:
   1515  *      Initialize the VLAN module.
   1516  * Parameters:
   1517  *      unit - StrataSwitch PCI device unit number (driver internal).
   1518  * Returns:
   1519  *      BCM_E_NONE - Success.
   1520  *      BCM_E_INTERNAL - Chip access failure.
   1521  */
   1522 
   1523 int
   1524 bcm_esw_vlan_init(int unit)
   1525 {
   1526     bcm_vlan_info_t             *vi = &vlan_info[unit];
   1527 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_WARM_BOOT_SUPPORT)
   1528     int    qm_size = 0;
   1529 #endif
   1530     int rv = BCM_E_NONE;
   1531 #ifdef BCM_WARM_BOOT_SUPPORT
   1532     soc_scache_handle_t scache_handle;
   1533     uint8 *vlan_scache_ptr;
   1534     uint32 vlan_scache_size;
   1535 #else
   1536 #endif /* BCM_WARM_BOOT_SUPPORT */
   1537 
   1538 #ifdef BCM_KATANA_SUPPORT
   1539     vlan_subnet_entry_t *vstab=NULL;
   1540     vlan_subnet_entry_t *vsnull=NULL;
   1541     vlan_subnet_entry_t *vstabp=NULL;
   1542     int index=0;
   1543     int vsbytes=0;
   1544 #endif
   1545     int vlan_auto_stack_soc;
   1546 
   1547 #ifdef BCM_TOMAHAWK3_SUPPORT
   1548     if (SOC_IS_TOMAHAWK3(unit)) {
   1549         return bcm_tomahawk3_vlan_init(unit);
   1550     }
   1551 #endif
   1552 
   1553     vlan_auto_stack_soc = soc_property_get(unit, spn_VLAN_AUTO_STACK, 0);
   1554     if (vlan_auto_stack_soc == 1) {
   1555         vi->vlan_auto_stack = 1;
   1556     } else if (vlan_auto_stack_soc == 2) {
   1557         vi->vlan_auto_stack = 0;
   1558     } else {
   1559 #ifdef BCM_VLAN_NO_AUTO_STACK
   1560         vi->vlan_auto_stack = 0;
   1561 #else
   1562         vi->vlan_auto_stack = 1;
   1563 #endif /* BCM_VLAN_NO_AUTO_STACK */
   1564     }
   1565 
   1566     if (SOC_WARM_BOOT(unit)) {
   1567         return(_bcm_vlan_reinit(unit));
   1568     } else {
   1569        
   1570         bcm_vlan_data_t         vd;
   1571         bcm_pbmp_t              temp_pbmp;
   1572 
   1573         /*
   1574          * Initialize hardware tables
   1575          */
   1576 
   1577         BCM_PBMP_CLEAR(temp_pbmp);
   1578         BCM_PBMP_ASSIGN(temp_pbmp, PBMP_ALL(unit));
   1579 #ifdef BCM_KATANA2_SUPPORT
   1580         if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
   1581             BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &temp_pbmp));
   1582         }
   1583 #endif
   1584         vd.vlan_tag = BCM_VLAN_DEFAULT;
   1585         BCM_PBMP_ASSIGN(vd.port_bitmap, temp_pbmp);
   1586         BCM_PBMP_REMOVE(vd.port_bitmap, PBMP_LB(unit));
   1587         BCM_PBMP_REMOVE(vd.port_bitmap, PBMP_RDB_ALL(unit));
   1588         BCM_PBMP_REMOVE(vd.port_bitmap, PBMP_FAE_ALL(unit));
   1589         BCM_PBMP_ASSIGN(vd.ut_port_bitmap, temp_pbmp);
   1590         BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_CMIC(unit));
   1591         BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_LB(unit));
   1592         BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_RDB_ALL(unit));
   1593         BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_FAE_ALL(unit));
   1594         BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_MACSEC_ALL(unit));
   1595 
   1596         /*
   1597          * A compile-time application policy may prefer to not add
   1598          * Ethernet or CPU ports to the default VLAN.
   1599          */
   1600 
   1601 #ifdef  BCM_VLAN_NO_DEFAULT_ETHER
   1602         BCM_PBMP_REMOVE(vd.port_bitmap, PBMP_E_ALL(unit));
   1603         BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_E_ALL(unit));
   1604 #endif  /* BCM_VLAN_NO_DEFAULT_ETHER */
   1605 #ifdef  BCM_VLAN_NO_DEFAULT_CPU
   1606         BCM_PBMP_REMOVE(vd.port_bitmap, PBMP_CMIC(unit));
   1607 #endif  /* BCM_VLAN_NO_DEFAULT_CPU */
   1608 
   1609         if (!vi->vlan_auto_stack) {
   1610             BCM_PBMP_REMOVE(vd.port_bitmap, SOC_PBMP_STACK_CURRENT(unit));
   1611             BCM_PBMP_REMOVE(vd.ut_port_bitmap, SOC_PBMP_STACK_CURRENT(unit));
   1612         }
   1613 
   1614 #if defined(BCM_RCPU_SUPPORT)
   1615         if (SOC_IS_RCPU_ONLY(unit) && vlan_info[unit].init) {
   1616             bcm_vlan_t idx;
   1617             soc_rcpu_cfg_t cfg;
   1618 
   1619             if (SOC_E_NONE != soc_cm_get_rcpu_cfg(unit, &cfg)) {
   1620                 cfg.vlan = BCM_VLAN_INVALID;
   1621             }
   1622 
   1623             /* Destroy previous VLANs */
   1624             for (idx = BCM_VLAN_MIN; idx < BCM_VLAN_COUNT; idx++) {
   1625                 if ((idx != vlan_info[unit].defl) &&
   1626                     (idx != cfg.vlan) && 
   1627                     (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, idx))) {
   1628                     BCM_IF_ERROR_RETURN
   1629                         (mbcm_driver[unit]->mbcm_vlan_destroy(unit, idx));
   1630                 }
   1631             }
   1632         }
   1633 #endif  /* BCM_RCPU_SUPPORT */
   1634 
   1635 #ifdef BCM_MCAST_FLOOD_DEFAULT
   1636         BCM_IF_ERROR_RETURN
   1637             (_bcm_esw_vlan_flood_default_set(unit, BCM_MCAST_FLOOD_DEFAULT));
   1638 #else
   1639         BCM_IF_ERROR_RETURN
   1640             (_bcm_esw_vlan_flood_default_set(unit,
   1641                                              BCM_VLAN_MCAST_FLOOD_UNKNOWN));
   1642 #endif
   1643 
   1644 #if defined (BCM_EASY_RELOAD_SUPPORT)
   1645         BCM_IF_ERROR_RETURN(_bcm_vbmp_init(&vi->egr_vlan_bmp));
   1646         BCM_IF_ERROR_RETURN(_bcm_vbmp_init(&vi->vlan_tab_bmp));
   1647 #endif
   1648 
   1649         BCM_IF_ERROR_RETURN
   1650             (mbcm_driver[unit]->mbcm_vlan_init(unit, &vd));
   1651 
   1652 
   1653 #ifdef BCM_TRIUMPH2_SUPPORT
   1654         if (soc_feature(unit, soc_feature_vlan_queue_map)) {
   1655             if (vi->qm_bmp != NULL) {
   1656                 sal_free(vi->qm_bmp);
   1657             }
   1658             if (vi->qm_it_bmp != NULL) {
   1659                 sal_free(vi->qm_it_bmp);
   1660             }
   1661 
   1662             qm_size = SHR_BITALLOCSIZE
   1663                 (1 << soc_mem_field_length(unit, VLAN_PROFILE_TABm,
   1664                                            PHB2_DOT1P_MAPPING_PTRf));
   1665             vi->qm_bmp = sal_alloc(qm_size, "VLAN queue mapping bitmap");
   1666             if (vi->qm_bmp == NULL) {
   1667                 return BCM_E_MEMORY;
   1668             }
   1669             sal_memset(vi->qm_bmp, 0, qm_size); 
   1670             vi->qm_it_bmp = sal_alloc(qm_size, "VLAN queue mapping bitmap");
   1671             if (vi->qm_it_bmp == NULL) {
   1672                 return BCM_E_MEMORY;
   1673             }
   1674         }
   1675 #endif
   1676 
   1677 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
   1678         if (soc_feature(unit, soc_feature_vlan_vp)) {
   1679 #ifdef BCM_ENDURO_SUPPORT
   1680             if (SOC_IS_ENDURO(unit)) {
   1681                 BCM_IF_ERROR_RETURN(bcm_enduro_vlan_virtual_init(unit));
   1682             } else
   1683 #endif /* BCM_ENDURO_SUPPORT */
   1684             {
   1685                 BCM_IF_ERROR_RETURN(bcm_tr2_vlan_virtual_init(unit));
   1686             } 
   1687         }
   1688 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
   1689 
   1690 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 
   1691 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   1692         if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
   1693             BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_init(unit));
   1694         } else
   1695 #endif
   1696         if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership) ||
   1697             soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) {
   1698             BCM_IF_ERROR_RETURN(bcm_td_vp_group_init(unit));
   1699         }
   1700 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
   1701 
   1702 #ifdef BCM_KATANA_SUPPORT
   1703 
   1704     /* ###################################################################### */
   1705     /* Temporary Work around for katata chip to initialize vlan_subnet table  */
   1706     /* with zero entries                                                      */
   1707     /* ###################################################################### */
   1708 
   1709     if (SOC_IS_KATANA(unit)) {
   1710         vsnull = soc_mem_entry_null(unit, VLAN_SUBNETm);
   1711         vsbytes = soc_mem_entry_words(unit, VLAN_SUBNETm);
   1712         vsbytes = WORDS2BYTES(vsbytes);
   1713         vstab = soc_cm_salloc(unit, 
   1714                               soc_mem_index_count(unit, VLAN_SUBNETm) * 
   1715                               sizeof(*vstab), "vlan_subnet");
   1716         if (vstab == NULL) {
   1717             return BCM_E_MEMORY;
   1718         }
   1719         rv = soc_mem_read_range(unit, VLAN_SUBNETm, MEM_BLOCK_ANY,
   1720                                 soc_mem_index_min(unit, VLAN_SUBNETm), 
   1721                                 soc_mem_index_max(unit, VLAN_SUBNETm), vstab);
   1722         if (BCM_FAILURE(rv)) {
   1723             soc_cm_sfree(unit, vstab);
   1724             return rv;
   1725         }
   1726         for(index = soc_mem_index_min(unit, VLAN_SUBNETm); 
   1727             index < soc_mem_index_count(unit, VLAN_SUBNETm); 
   1728             index++) {
   1729             vstabp = soc_mem_table_idx_to_pointer(unit,
   1730                             VLAN_SUBNETm, vlan_subnet_entry_t *,
   1731                             vstab, index);
   1732             sal_memcpy(vstabp,vsnull,vsbytes);
   1733         }
   1734         rv = soc_mem_write_range(unit, VLAN_SUBNETm, MEM_BLOCK_ALL,
   1735                                  soc_mem_index_min(unit, VLAN_SUBNETm), 
   1736                                  soc_mem_index_max(unit, VLAN_SUBNETm), vstab);
   1737         soc_cm_sfree(unit, vstab);
   1738         if (BCM_FAILURE(rv)) {
   1739             return rv;
   1740         }
   1741     }
   1742 #endif
   1743 
   1744         /*
   1745          * Initialize software structures
   1746          */
   1747         vi->defl = BCM_VLAN_DEFAULT;
   1748 
   1749 #ifdef BCM_WARM_BOOT_SUPPORT
   1750         /* Warm boot level 2 cache size */
   1751         /* Type for 'flood_mode' is an enum, which values fit in uint8 */
   1752         vlan_scache_size = sizeof(vi->defl);/* Default VLAN */
   1753         vlan_scache_size += sizeof(vi->old_egr_xlate_cnt); /* VLAN XLATE old_cnt */
   1754         vlan_scache_size += sizeof(uint8);  /* Flood mode */
   1755         if (soc_feature(unit, soc_feature_vlan_queue_map)) {
   1756             vlan_scache_size += (qm_size * 2);  /* (qm_bmp, qm_it_bmp) */
   1757         }
   1758 
   1759         if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership) ||
   1760             soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) {
   1761             vlan_scache_size += sizeof(uint8) * 2;  /* vp group unmanaged flags */
   1762         }
   1763 
   1764         if (BCM_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_1) {
   1765             /* VLAN info: VP Multicast control mode */
   1766             vlan_scache_size += sizeof(vi->vp_mode);
   1767         }
   1768 
   1769 #ifdef BCM_TRIDENT3_SUPPORT
   1770         if (soc_feature(unit, soc_feature_pvlan_on_vfi)) {
   1771             if (BCM_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_2) {
   1772                 vlan_scache_size += sizeof(vi->shared_vlan_enable);
   1773             }
   1774         }
   1775 #endif
   1776 
   1777         SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_VLAN, 0);
   1778         rv = _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE,
   1779                                      vlan_scache_size,
   1780                                      &vlan_scache_ptr, 
   1781                                      BCM_WB_DEFAULT_VERSION, NULL);
   1782         if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
   1783             return rv;
   1784         }
   1785         rv = BCM_E_NONE;
   1786 #endif /* BCM_WARM_BOOT_SUPPORT */
   1787 
   1788 
   1789         /* In case bcm_vlan_init is called more than once */
   1790         BCM_IF_ERROR_RETURN(_bcm_vbmp_init(&vi->bmp));
   1791         _BCM_VBMP_INSERT(vi->bmp, vd.vlan_tag);
   1792 
   1793         BCM_IF_ERROR_RETURN(_bcm_vbmp_init(&vi->pre_cfg_bmp));
   1794 
   1795 #if defined (BCM_EASY_RELOAD_SUPPORT)
   1796         _BCM_VBMP_INSERT(vi->egr_vlan_bmp, vd.vlan_tag);
   1797         _BCM_VBMP_INSERT(vi->vlan_tab_bmp, vd.vlan_tag);
   1798 #endif
   1799 
   1800         /* Free vlan translation arrays if any. */
   1801         if (NULL != vi->egr_trans) {
   1802             sal_free(vi->egr_trans);
   1803             vi->egr_trans = NULL;
   1804         }
   1805         if (NULL != vi->ing_trans) {
   1806             sal_free(vi->ing_trans);
   1807             vi->ing_trans = NULL;
   1808         }
   1809 
   1810         vi->count = 1;
   1811 
   1812     }
   1813 
   1814     vi->init = TRUE;
   1815 
   1816 #if defined(BCM_RCPU_SUPPORT)
   1817     if (SOC_IS_RCPU_ONLY(unit)) {
   1818         soc_rcpu_cfg_t cfg;
   1819         if (SOC_E_NONE == soc_cm_get_rcpu_cfg(unit, &cfg) && 
   1820             BCM_VLAN_DEFAULT != cfg.vlan) {
   1821             /* 
   1822              * RCPU vlan should have been created in remote device, sync 
   1823              * software status.
   1824              */
   1825             _BCM_VBMP_INSERT(vlan_info[unit].bmp, cfg.vlan);
   1826             vlan_info[unit].count++;
   1827         }
   1828     }
   1829 #endif  /* BCM_RCPU_SUPPORT */
   1830 
   1831     return rv;
   1832 }
   1833 
   1834 /*
   1835  * Function:
   1836  *      bcm_esw_vlan_detach
   1837  * Purpose:
   1838  *      De-initialize the VLAN module.
   1839  * Parameters:
   1840  *      unit - (IN) BCM device number.
   1841  * Returns:
   1842  *      BCM_E_XXX
   1843  */
   1844 
   1845 int 
   1846 bcm_esw_vlan_detach(int unit)
   1847 {
   1848     bcm_vlan_info_t *vi = &vlan_info[unit];
   1849     int rv = BCM_E_NONE;
   1850 
   1851 #ifdef BCM_TOMAHAWK3_SUPPORT
   1852     if (SOC_IS_TOMAHAWK3(unit)) {
   1853         return bcm_tomahawk3_vlan_detach(unit);
   1854     }
   1855 #endif
   1856 
   1857     BCM_LOCK(unit);
   1858 
   1859     _bcm_vbmp_destroy(&vi->bmp);
   1860     rv = _bcm_vbmp_destroy(&vi->pre_cfg_bmp);
   1861     if (BCM_FAILURE(rv)) {
   1862         BCM_UNLOCK(unit);
   1863         return (rv);
   1864     }
   1865 #if defined (BCM_EASY_RELOAD_SUPPORT)
   1866     rv = _bcm_vbmp_destroy(&vi->egr_vlan_bmp);
   1867     if (BCM_FAILURE(rv)) {
   1868         BCM_UNLOCK(unit);
   1869         return (rv);
   1870     }
   1871     rv = _bcm_vbmp_destroy(&vi->vlan_tab_bmp);
   1872     if (BCM_FAILURE(rv)) {
   1873         BCM_UNLOCK(unit);
   1874         return (rv);
   1875     }
   1876 #endif
   1877 
   1878     if (vi->egr_trans != NULL) {
   1879         sal_free(vi->egr_trans);
   1880         vi->egr_trans = NULL;
   1881     }
   1882     if (vi->ing_trans != NULL) {
   1883         sal_free(vi->ing_trans);
   1884         vi->ing_trans = NULL;
   1885     }
   1886 
   1887     vi->init = 0;
   1888 
   1889 #ifdef BCM_TRIUMPH2_SUPPORT
   1890     if (soc_feature(unit, soc_feature_gport_service_counters)) {
   1891         rv = _bcm_esw_flex_stat_detach(unit, _bcmFlexStatTypeService);
   1892     }
   1893     if (soc_feature(unit, soc_feature_vlan_queue_map)) {
   1894         sal_free(vi->qm_bmp);
   1895         vi->qm_bmp = NULL;
   1896         sal_free(vi->qm_it_bmp);
   1897         vi->qm_it_bmp  = NULL;
   1898     }
   1899 #endif /* BCM_TRIUMPH2_SUPPORT */
   1900 
   1901 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
   1902     || defined(BCM_RAVEN_SUPPORT)
   1903     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
   1904         rv = _bcm_xgs3_vlan_profile_detach(unit);
   1905     }
   1906 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || \
   1907           BCM_RAVEN_SUPPORT */
   1908 
   1909 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
   1910         if (soc_feature(unit, soc_feature_vlan_vp)) {
   1911 #ifdef BCM_ENDURO_SUPPORT
   1912             if (SOC_IS_ENDURO(unit)) {
   1913                 rv = bcm_enduro_vlan_virtual_detach(unit);
   1914                 if (BCM_FAILURE(rv)) {
   1915                     BCM_UNLOCK(unit);
   1916                     return (rv);
   1917                 }
   1918             } else
   1919 #endif /* BCM_ENDURO_SUPPORT */
   1920             {
   1921                 rv = bcm_tr2_vlan_virtual_detach(unit);
   1922                 if (BCM_FAILURE(rv)) {
   1923                     BCM_UNLOCK(unit);
   1924                     return (rv);
   1925                 }
   1926             } 
   1927         }
   1928 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
   1929 
   1930 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 
   1931 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   1932     if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
   1933         rv = bcm_td2p_vp_group_detach(unit);
   1934         if (BCM_FAILURE(rv)) {
   1935             BCM_UNLOCK(unit);
   1936             return (rv);
   1937         }
   1938     } else
   1939 #endif
   1940     if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership) ||
   1941         soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) {
   1942         rv = bcm_td_vp_group_detach(unit);
   1943         if (BCM_FAILURE(rv)) {
   1944             BCM_UNLOCK(unit);
   1945             return (rv);
   1946         }
   1947     }
   1948 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
   1949 
   1950     BCM_UNLOCK(unit);
   1951     return rv;
   1952 }
   1953 
   1954 /*
   1955  * Function:
   1956  *      _bcm_vlan_create
   1957  * Purpose:
   1958  *      Main body of bcm_vlan_create; assumes locking already done;
   1959  */
   1960 
   1961 STATIC int
   1962 _bcm_vlan_create(int unit, bcm_vlan_t vid)
   1963 {
   1964     bcm_stg_t   stg_defl;
   1965     int         rv;
   1966     rv = bcm_esw_stg_default_get(unit, &stg_defl);
   1967     if (rv == BCM_E_UNAVAIL) {
   1968         stg_defl = -1;
   1969     } else if (rv < 0) {
   1970         return rv;
   1971     }
   1972 
   1973 #ifdef BCM_SHADOW_SUPPORT
   1974     if (SOC_IS_SHADOW(unit)) {
   1975         return BCM_E_NONE;
   1976     }
   1977 #endif /* BCM_SHADOW_SUPPORT */
   1978 
   1979     if (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vid)) {
   1980         return BCM_E_EXISTS;
   1981     }
   1982 
   1983     BCM_IF_ERROR_RETURN
   1984         (mbcm_driver[unit]->mbcm_vlan_create(unit, vid));
   1985 
   1986     _BCM_VBMP_INSERT(vlan_info[unit].bmp, vid);
   1987     SHR_BITCLR(vlan_info[unit].pre_cfg_bmp.w,vid);
   1988     vlan_info[unit].count++;
   1989 
   1990     if (stg_defl >= 0) {
   1991         /* Must be after v bitmap insert */
   1992         BCM_IF_ERROR_RETURN
   1993             (bcm_esw_stg_vlan_add(unit, stg_defl, vid));
   1994     }
   1995 
   1996     return BCM_E_NONE;
   1997 }
   1998 
   1999 /*
   2000  * Function:
   2001  *      bcm_vlan_create
   2002  * Purpose:
   2003  *      Allocate and configure a VLAN on StrataSwitch.
   2004  * Parameters:
   2005  *      unit - StrataSwitch PCI device unit number (driver internal).
   2006  *      vid - VLAN ID to create.
   2007  * Returns:
   2008  *      BCM_E_NONE - Success.
   2009  *      BCM_E_INTERNAL - Chip access failure.
   2010  *      BCM_E_EXISTS - VLAN ID already in use.
   2011  * Notes:
   2012  *      VLAN is placed in the default STG and can be reassigned later.
   2013  */
   2014 
   2015 int
   2016 bcm_esw_vlan_create(int unit, bcm_vlan_t vid)
   2017 {
   2018     int                 rv;
   2019 
   2020     LOG_VERBOSE(BSL_LS_BCM_VLAN,
   2021                 (BSL_META_U(unit,
   2022                             "VLAN %d: create vid %d\n"),
   2023                  unit, vid));
   2024 
   2025     CHECK_INIT(unit);
   2026     VLAN_CHK_ID(unit, vid);
   2027     
   2028     /* Check if valid vlan id */
   2029     if (vid == BCM_VLAN_NONE) {
   2030       return BCM_E_PARAM;
   2031     }
   2032 
   2033     BCM_LOCK(unit);
   2034     rv = _bcm_vlan_create(unit, vid);
   2035 
   2036     if (vlan_info[unit].vlan_auto_stack) {
   2037         if (rv == BCM_E_NONE) {
   2038             soc_pbmp_t  stacked, empty_pbmp;
   2039 
   2040             SOC_PBMP_ASSIGN(stacked, SOC_PBMP_STACK_CURRENT(unit));
   2041             SOC_PBMP_CLEAR(empty_pbmp);
   2042 
   2043             rv = _bcm_vlan_port_add(unit, vid, stacked, empty_pbmp, stacked, 0);
   2044         }
   2045     }
   2046     BCM_UNLOCK(unit);
   2047 
   2048     return rv;
   2049 }
   2050 
   2051 /*
   2052  * Function:
   2053  *      _bcm_vlan_destroy
   2054  * Purpose:
   2055  *      Main body of bcm_vlan_destroy; assumes locking done.
   2056  */
   2057 
   2058 STATIC int
   2059 _bcm_vlan_destroy(int unit, bcm_vlan_t vid)
   2060 {
   2061     bcm_stg_t           stg;
   2062     int                 rv;
   2063 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
   2064     bcm_multicast_t     mc_group;
   2065     vlan_tab_entry_t    vtab;
   2066     int                 bc_index, umc_index, uuc_index;
   2067 #endif
   2068 
   2069     /* Cannot destroy default VLAN */
   2070     if (vid == vlan_info[unit].defl) {
   2071         return BCM_E_BADID;
   2072     }
   2073 
   2074     if (0 == _BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vid)) {
   2075         return BCM_E_NOT_FOUND;
   2076     }
   2077 
   2078 #if defined(BCM_RCPU_SUPPORT)
   2079     if (SOC_IS_RCPU_ONLY(unit)) {
   2080         soc_rcpu_cfg_t cfg;
   2081         if ((SOC_E_NONE == soc_cm_get_rcpu_cfg(unit, &cfg)) && 
   2082             (vid == cfg.vlan)) {
   2083             return BCM_E_BADID;
   2084         }
   2085     }
   2086 #endif  /* BCM_RCPU_SUPPORT */
   2087 
   2088     /* Remove VLAN from its spanning tree group */
   2089     BCM_IF_ERROR_RETURN
   2090         (bcm_esw_vlan_stg_get(unit, vid, &stg));
   2091 
   2092     rv = _bcm_stg_vlan_destroy(unit, stg, vid);
   2093     if (rv < 0 && rv != BCM_E_UNAVAIL) {
   2094         return rv;
   2095     }
   2096 
   2097 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
   2098     /* If virtual port switching is enabled, destroy the
   2099      * BC, UMC, and UUC multicast groups.
   2100      */
   2101     if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) {
   2102         BCM_IF_ERROR_RETURN
   2103             (soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vid, &vtab));
   2104 
   2105         if (soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf)) {
   2106             bc_index = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf);
   2107             if (BCM_SUCCESS(
   2108                 _bcm_tr_multicast_ipmc_group_type_get(unit, bc_index,
   2109                                                        &mc_group))) {
   2110                 BCM_IF_ERROR_RETURN(bcm_esw_multicast_destroy(unit, mc_group));
   2111             }
   2112 
   2113             umc_index = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UMC_IDXf);
   2114             if (umc_index != bc_index) {
   2115                 if (BCM_SUCCESS(
   2116                     _bcm_tr_multicast_ipmc_group_type_get(unit, umc_index,
   2117                                                            &mc_group))) {
   2118                     BCM_IF_ERROR_RETURN(bcm_esw_multicast_destroy(unit, mc_group));
   2119                  }
   2120             }
   2121 
   2122             uuc_index = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UUC_IDXf);
   2123             if ((uuc_index != bc_index) && (uuc_index != umc_index)) {
   2124                 if (BCM_SUCCESS(
   2125                     _bcm_tr_multicast_ipmc_group_type_get(unit, uuc_index,
   2126                                                            &mc_group))) {
   2127                     BCM_IF_ERROR_RETURN(bcm_esw_multicast_destroy(unit, mc_group));
   2128                 }
   2129             }
   2130         }
   2131     }
   2132 #endif
   2133 
   2134     BCM_IF_ERROR_RETURN
   2135         (mbcm_driver[unit]->mbcm_vlan_destroy(unit, vid));
   2136 
   2137     _BCM_VBMP_REMOVE(vlan_info[unit].bmp, vid);
   2138 
   2139     vlan_info[unit].count--;
   2140 
   2141     return BCM_E_NONE;
   2142 }
   2143 
   2144 /*
   2145  * Function:
   2146  *      bcm_vlan_destroy
   2147  * Purpose:
   2148  *      Deallocate VLAN from StrataSwitch.
   2149  * Parameters:
   2150  *      unit - StrataSwitch PCI device unit number (driver internal).
   2151  *      vid - VLAN ID to affect.
   2152  * Returns:
   2153  *      BCM_E_NONE              Success.
   2154  *      BCM_E_INTERNAL          Chip access failure.
   2155  *      BCM_E_BADID           Cannot remove default VLAN
   2156  *      BCM_E_NOT_FOUND VLAN ID not in use.
   2157  * Notes:
   2158  *      None.
   2159  */
   2160 
   2161 int
   2162 bcm_esw_vlan_destroy(int unit, bcm_vlan_t vid)
   2163 {
   2164     int         rv;
   2165 
   2166     LOG_VERBOSE(BSL_LS_BCM_VLAN,
   2167                 (BSL_META_U(unit,
   2168                             "VLAN %d: destroy vid %d\n"),
   2169                  unit, vid));
   2170 
   2171     CHECK_INIT(unit);
   2172     VLAN_CHK_ID(unit, vid);
   2173 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_MONTEREY_SUPPORT)
   2174     if (soc_feature(unit, soc_feature_xflow_macsec_olp)) {
   2175         if (vid == soc_property_get(unit, spn_XFLOW_MACSEC_OLP_VLAN, BCM_VLAN_INVALID)) {
   2176             return BCM_E_PARAM;
   2177         }
   2178     }
   2179 #endif
   2180     BCM_LOCK(unit);
   2181     rv = _bcm_vlan_destroy(unit, vid);
   2182     BCM_UNLOCK(unit);
   2183 
   2184     return rv;
   2185 }
   2186 
   2187 /*
   2188  * Function:
   2189  *      bcm_vlan_destroy_all
   2190  * Purpose:
   2191  *      Destroy all VLANs except the default VLAN
   2192  * Parameters:
   2193  *      unit - StrataSwitch PCI device unit number (driver internal).
   2194  * Returns:
   2195  *      BCM_E_NONE - Success.
   2196  *      BCM_E_INTERNAL - Chip access failure.
   2197  * Notes:
   2198  *      None.
   2199  */
   2200 
   2201 int
   2202 bcm_esw_vlan_destroy_all(int unit)
   2203 {
   2204     int                 rv = BCM_E_NONE;
   2205     bcm_vlan_t          vid;
   2206 
   2207     LOG_VERBOSE(BSL_LS_BCM_VLAN,
   2208                 (BSL_META_U(unit,
   2209                             "VLAN %d: destroy all VLANs\n"),
   2210                  unit));
   2211 
   2212     CHECK_INIT(unit);
   2213 
   2214     BCM_LOCK(unit);
   2215 
   2216 while ((vid = _bcm_vlan_1st(unit)) != BCM_VLAN_INVALID) {
   2217         if ((rv = bcm_esw_vlan_destroy(unit, vid)) < 0) {
   2218             break;
   2219         }
   2220     }
   2221 
   2222 #ifdef BCM_KATANA2_SUPPORT
   2223     if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) {
   2224         /* Clear parity status on L2 bulk operation */
   2225         if (BCM_FAILURE(rv)) {
   2226             BCM_UNLOCK(unit);
   2227             return (rv);
   2228         }
   2229         rv = soc_reg_field32_modify(unit, L2_BULK_CONTROLr,
   2230                                     REG_PORT_ANY, STARTf, 0);
   2231         if (BCM_FAILURE(rv)) {
   2232             BCM_UNLOCK(unit);
   2233             return (rv);
   2234         }
   2235         rv = soc_reg_field32_modify(unit, L2_BULK_CONTROLr,
   2236                                     REG_PORT_ANY, COMPLETEf, 0);
   2237     }
   2238 #endif
   2239     BCM_UNLOCK(unit);
   2240 
   2241     return rv;
   2242 }
   2243 
   2244 /*
   2245  * Function:
   2246  *      _bcm_vlan_port_add
   2247  * Purpose:
   2248  *      Main part of bcm_vlan_port_add; assumes locking already done.
   2249  */
   2250 
   2251 STATIC int
   2252 _bcm_vlan_port_add(int unit, bcm_vlan_t vid, pbmp_t pbmp, pbmp_t ubmp,
   2253                    pbmp_t ing_pbmp, int flags)
   2254 {
   2255     pbmp_t              vlan_pbmp, vlan_ubmp, vlan_ing_pbmp, orig_pbmp;
   2256     pbmp_t              stacked;
   2257 
   2258     /* No such thing as untagged CPU */
   2259     SOC_PBMP_REMOVE(ubmp, PBMP_CMIC(unit));
   2260 
   2261     /* Remove internal loopback port from vlan port bitmaps.
   2262      * Hardware does not perform ingress and egress VLAN membership checks 
   2263      * on internal loopback port. Also, on Triumph2, the port bitmaps in
   2264      * VLAN and EGR_VLAN tables do not include the internal loopback port.
   2265      */
   2266     SOC_PBMP_REMOVE(pbmp, PBMP_LB(unit));
   2267     SOC_PBMP_REMOVE(ubmp, PBMP_LB(unit));
   2268     SOC_PBMP_REMOVE(ing_pbmp, PBMP_LB(unit)); 
   2269 
   2270     /*
   2271      * Illegal to have untagged stack ports; remove inactive ports from bitmap
   2272      */
   2273     SOC_PBMP_STACK_ACTIVE_GET(unit, stacked);
   2274     SOC_PBMP_REMOVE(ubmp, stacked);
   2275     SOC_PBMP_REMOVE(pbmp, SOC_PBMP_STACK_INACTIVE(unit));
   2276     SOC_PBMP_REMOVE(ubmp, SOC_PBMP_STACK_INACTIVE(unit));
   2277     SOC_PBMP_REMOVE(ing_pbmp, SOC_PBMP_STACK_INACTIVE(unit));
   2278 
   2279     /* Don't add ports that are already there */
   2280     BCM_IF_ERROR_RETURN
   2281         (mbcm_driver[unit]->mbcm_vlan_port_get(unit, vid, &vlan_pbmp,
   2282                                                &vlan_ubmp, &vlan_ing_pbmp));
   2283     SOC_PBMP_ASSIGN(orig_pbmp, pbmp);
   2284     COMPILER_REFERENCE(orig_pbmp);
   2285     /* But do allow for making the port tagged/untagged if its already added to the vlan */
   2286     SOC_PBMP_XOR(vlan_ubmp, ubmp);
   2287     SOC_PBMP_REMOVE(vlan_pbmp, vlan_ubmp);
   2288     SOC_PBMP_REMOVE(pbmp, vlan_pbmp);
   2289     SOC_PBMP_REMOVE(ubmp, vlan_pbmp);
   2290     SOC_PBMP_REMOVE(ing_pbmp, vlan_ing_pbmp);
   2291 
   2292     if (SOC_PBMP_NOT_NULL(pbmp) || SOC_PBMP_NOT_NULL(ubmp) ||
   2293         SOC_PBMP_NOT_NULL(ing_pbmp)) {
   2294         BCM_IF_ERROR_RETURN
   2295             (mbcm_driver[unit]->mbcm_vlan_port_add
   2296              (unit, vid, pbmp, ubmp, ing_pbmp));
   2297     }
   2298 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT)
   2299     if (soc_feature(unit, soc_feature_vlan_egress_membership_l3_only) &&
   2300         (flags & BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY)) {
   2301         if (SOC_PBMP_NOT_NULL(pbmp)) {
   2302             SOC_PBMP_CLEAR(ing_pbmp);
   2303             SOC_PBMP_CLEAR(ubmp);
   2304             BCM_IF_ERROR_RETURN
   2305                 (_bcm_xgs3_vlan_table_port_remove(unit, vid, pbmp, ubmp,
   2306                                                   ing_pbmp, VLAN_TABLE(unit)));
   2307         }
   2308     }
   2309 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_HURRICANE3_SUPPORT */
   2310 
   2311 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
   2312     if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf) &&
   2313         BCM_VLAN_VALID(vid)) {
   2314 
   2315         vlan_tab_entry_t vtab;
   2316         int ipmc_group[3] = {0, 0, 0};
   2317         int do_not_add[3] = {0, 0, 0};
   2318         int              i;
   2319         int              rv;
   2320         bcm_multicast_t  mc_group;
   2321         pbmp_t           l2_pbmp, l3_pbmp;
   2322 
   2323         BCM_IF_ERROR_RETURN
   2324             (soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vid, &vtab));
   2325 
   2326         if (soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf)) {
   2327             /* If virtual port switching is enabled, update the 
   2328              * L2_BITMAP in the corresponding MC group
   2329              */
   2330 
   2331             ipmc_group[0] = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf);
   2332             ipmc_group[1] = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UMC_IDXf);
   2333             ipmc_group[2] = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UUC_IDXf);
   2334 
   2335             if (flags & BCM_VLAN_GPORT_ADD_BCAST_DO_NOT_ADD) {
   2336                 do_not_add[0] = 1;
   2337             }
   2338             if (flags & BCM_VLAN_GPORT_ADD_UNKNOWN_MCAST_DO_NOT_ADD) {
   2339                 do_not_add[1] = 1;
   2340             }
   2341             if (flags & BCM_VLAN_GPORT_ADD_UNKNOWN_UCAST_DO_NOT_ADD) {
   2342                 do_not_add[2] = 1;
   2343             }
   2344 
   2345             if ((ipmc_group[0] == ipmc_group[1]) && (do_not_add[0] != do_not_add[1])) {
   2346                 return BCM_E_PARAM;
   2347             }
   2348             if ((ipmc_group[0] == ipmc_group[2]) && (do_not_add[0] != do_not_add[2])) {
   2349                 return BCM_E_PARAM;
   2350             }
   2351             if ((ipmc_group[1] == ipmc_group[2]) && (do_not_add[1] != do_not_add[2])) {
   2352                 return BCM_E_PARAM;
   2353             }
   2354 
   2355             for (i = 0; i < 3; i++) {
   2356                 if (do_not_add[i]) {
   2357                     continue;
   2358                 }
   2359                 /* index:0 is reserved, check if multicast group is used */
   2360                 rv = _bcm_tr_multicast_ipmc_group_type_get(unit, ipmc_group[i], &mc_group);
   2361                 if (rv < 0) {
   2362                     /* if index is used, ensure error code is checked */
   2363                     if (ipmc_group[i] != 0) {
   2364                         return rv;
   2365                     }
   2366                     continue;
   2367                 }
   2368 
   2369                 BCM_IF_ERROR_RETURN(_bcm_esw_multicast_ipmc_read(unit, ipmc_group[i],
   2370                                                                  &l2_pbmp, 
   2371                                                                  &l3_pbmp));
   2372                 SOC_PBMP_OR(l2_pbmp, orig_pbmp);
   2373                 BCM_IF_ERROR_RETURN(_bcm_esw_multicast_ipmc_write(unit, 
   2374                                              ipmc_group[i], l2_pbmp, l3_pbmp, TRUE));
   2375             }
   2376         }
   2377     }
   2378 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
   2379 
   2380     return BCM_E_NONE;
   2381 }
   2382 
   2383 /*
   2384  * Function:
   2385  *      bcm_vlan_port_add
   2386  * Purpose:
   2387  *      Add ports to the specified vlan.
   2388  * Parameters:
   2389  *      unit - StrataSwitch PCI device unit number (driver internal).
   2390  *      vid - VLAN ID to add port to as a member.
   2391  *      pbmp - port bitmap for members of VLAN
   2392  *      ubmp - untagged members of VLAN
   2393  * Returns:
   2394  *      BCM_E_NONE - Success.
   2395  *      BCM_E_INTERNAL - Chip access failure.
   2396  *      BCM_E_NOT_FOUND - VLAN ID not in use.
   2397  */
   2398 
   2399 int
   2400 bcm_esw_vlan_port_add(int unit, bcm_vlan_t vid, pbmp_t pbmp, pbmp_t ubmp)
   2401 {
   2402     int                 rv = BCM_E_NONE;
   2403     bcm_pbmp_t          pbm, ubm;
   2404 
   2405 #ifdef BCM_TOMAHAWK3_SUPPORT
   2406     if (SOC_IS_TOMAHAWK3(unit)) {
   2407         return bcm_tomahawk3_vlan_port_add(unit, vid, pbmp, ubmp);
   2408     }
   2409 #endif
   2410 
   2411     CHECK_INIT(unit);
   2412     VLAN_CHK_ID(unit, vid);
   2413 
   2414     BCM_PBMP_CLEAR(pbm); 
   2415     BCM_PBMP_CLEAR(ubm); 
   2416  
   2417      /* we need to check if pbmp and ubmp are valid as well */
   2418      BCM_PBMP_ASSIGN(pbm,PBMP_ALL(unit));
   2419      BCM_PBMP_ASSIGN(ubm,PBMP_ALL(unit));
   2420 
   2421 #ifdef BCM_KATANA2_SUPPORT 
   2422      if (SOC_IS_KATANA2(unit) && (soc_feature(unit, soc_feature_linkphy_coe) ||
   2423                                      soc_feature(unit, soc_feature_subtag_coe))) {
   2424          _bcm_kt2_subport_pbmp_update(unit, &pbm);
   2425          _bcm_kt2_subport_pbmp_update(unit, &ubm);
   2426      }
   2427 #endif 
   2428  
   2429      BCM_PBMP_AND(pbm,pbmp);
   2430      BCM_PBMP_AND(ubm,ubmp);
   2431  
   2432      if(!(BCM_PBMP_EQ(pbm, pbmp) && BCM_PBMP_EQ(ubm, ubmp))) {
   2433          return BCM_E_PARAM;
   2434      }
   2435  
   2436     LOG_VERBOSE(BSL_LS_BCM_VLAN,
   2437                 (BSL_META_U(unit,
   2438                             "VLAN %d: port add: vid %d. pbm 0x%x. utpbm 0x%x.\n"),
   2439                  unit, vid, SOC_PBMP_WORD_GET(pbmp, 0),
   2440                  SOC_PBMP_WORD_GET(ubmp, 0)));
   2441 
   2442     BCM_LOCK(unit);
   2443     rv = _bcm_vlan_port_add(unit, vid, pbmp, ubmp, pbmp, 0);
   2444     BCM_UNLOCK(unit);
   2445 
   2446     return rv;
   2447 }
   2448 
   2449 /*
   2450  * Function:
   2451  *      _bcm_vlan_port_remove
   2452  * Purpose:
   2453  *      Main part of bcm_vlan_port_remove; assumes locking already done.
   2454  */
   2455 
   2456 STATIC int
   2457 _bcm_vlan_port_remove(int unit, bcm_vlan_t vid, pbmp_t pbmp, pbmp_t ubmp,
   2458                       pbmp_t ing_pbmp, soc_field_t *dlf_type)
   2459 {
   2460     pbmp_t vlan_pbmp, vlan_ubmp, vlan_ing_pbmp, orig_pbmp;
   2461     int    rv = BCM_E_NONE;
   2462 
   2463     /* Don't remove ports that are not there */
   2464 
   2465     BCM_LOCK(unit);
   2466 
   2467     rv = (mbcm_driver[unit]->mbcm_vlan_port_get
   2468           (unit, vid, &vlan_pbmp, &vlan_ubmp, &vlan_ing_pbmp));
   2469     if (rv < 0) {
   2470         BCM_UNLOCK(unit);
   2471         return rv;
   2472     }
   2473 
   2474     SOC_PBMP_ASSIGN(orig_pbmp, pbmp);
   2475     if (!soc_mem_field_valid(unit, VLAN_TABLE(unit), ING_PORT_BITMAPf) &&
   2476         !(soc_feature(unit, soc_feature_vlan_vfi_membership))) {
   2477         SOC_PBMP_OR(vlan_pbmp, vlan_ing_pbmp);
   2478         SOC_PBMP_AND(pbmp, vlan_pbmp);
   2479     }
   2480     COMPILER_REFERENCE(orig_pbmp);
   2481 
   2482     rv = (mbcm_driver[unit]->mbcm_vlan_port_remove(unit, vid, pbmp, ubmp, 
   2483                                                    ing_pbmp));
   2484     if (rv < 0) {
   2485         BCM_UNLOCK(unit);
   2486         return rv;
   2487     }
   2488 
   2489 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
   2490     if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf) &&
   2491         BCM_VLAN_VALID(vid)) {
   2492 
   2493         vlan_tab_entry_t vtab;
   2494         soc_field_t grp_type[3] = {BC_IDXf, UMC_IDXf, UUC_IDXf};
   2495         int              i;
   2496         int              mc_index;
   2497         bcm_multicast_t  mc_group;
   2498         pbmp_t           l2_pbmp, l3_pbmp;
   2499         soc_field_t * group_type;
   2500 
   2501         if (dlf_type == NULL) {
   2502             group_type = grp_type;
   2503         } else {
   2504             group_type = dlf_type;
   2505         } 
   2506 
   2507         rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vid, &vtab);
   2508         if (BCM_FAILURE(rv)) {
   2509             BCM_UNLOCK(unit);
   2510             return (rv);
   2511         }
   2512 
   2513         if (soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf)) {
   2514             /* If virtual port switching is enabled, update the 
   2515              * L2_BITMAP in the corresponding MC group
   2516              */
   2517 
   2518             for (i = 0; i < 3; i++) {
   2519                 if (group_type[i] == 0) {
   2520                     continue;
   2521                 }
   2522                 mc_index = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab,
   2523                         group_type[i]);
   2524 
   2525                 /* index:0 is reserved, check if multicast group is used */
   2526                 rv = _bcm_tr_multicast_ipmc_group_type_get(unit, mc_index,
   2527                         &mc_group);
   2528                 if (rv < 0) {
   2529                     if (mc_index != 0) {
   2530                         BCM_UNLOCK(unit);
   2531                         return rv;
   2532                     } 
   2533                     continue;
   2534                 }
   2535 
   2536                 rv = _bcm_esw_multicast_ipmc_read(unit, mc_index,
   2537                         &l2_pbmp, &l3_pbmp);
   2538                 if (rv < 0) {
   2539                     BCM_UNLOCK(unit);
   2540                     return rv;
   2541                 }
   2542 
   2543                 BCM_PBMP_REMOVE(l2_pbmp, orig_pbmp);
   2544 
   2545                 rv = _bcm_esw_multicast_ipmc_write(unit, mc_index,
   2546                         l2_pbmp, l3_pbmp, TRUE);
   2547                 if (rv < 0) {
   2548                     BCM_UNLOCK(unit);
   2549                     return rv;
   2550                 }
   2551             }
   2552         }
   2553     }
   2554 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
   2555 
   2556     BCM_UNLOCK(unit);
   2557 
   2558     return BCM_E_NONE;
   2559 }
   2560 
   2561 /*
   2562  * Function:
   2563  *      bcm_vlan_port_remove
   2564  * Purpose:
   2565  *      Remove ports from a specified vlan.
   2566  * Parameters:
   2567  *      unit - StrataSwitch PCI device unit number (driver internal).
   2568  *      vid - VLAN ID to remove port(s) from.
   2569  *      pbmp - port bitmap for ports to remove.
   2570  * Returns:
   2571  *      BCM_E_NONE - Success.
   2572  *      BCM_E_INTERNAL - Chip access failure.
   2573  *      BCM_E_NOT_FOUND - VLAN ID not in use.
   2574  * Notes:
   2575  *      None.
   2576  */
   2577 
   2578 int
   2579 bcm_esw_vlan_port_remove(int unit, bcm_vlan_t vid, pbmp_t pbmp)
   2580 {
   2581     int                 rv = BCM_E_NONE;
   2582 
   2583 #ifdef BCM_TOMAHAWK3_SUPPORT
   2584     if (SOC_IS_TOMAHAWK3(unit)) {
   2585         return bcm_tomahawk3_vlan_port_remove(unit, vid, pbmp);
   2586     }
   2587 #endif
   2588 
   2589     LOG_VERBOSE(BSL_LS_BCM_VLAN,
   2590                 (BSL_META_U(unit,
   2591                             "VLAN %d: port remove: vid %d. pbm 0x%x.\n"),
   2592                  unit, vid, SOC_PBMP_WORD_GET(pbmp, 0)));
   2593 
   2594     CHECK_INIT(unit);
   2595     VLAN_CHK_ID(unit, vid);
   2596     /* As we are passing only one pbmp parameter to API bcm_vlan_port_remove,
   2597      * the expected result is to remove same pbmp from PORT_BITMAPf, UT_BITMAPf
   2598      * and ING_PORT_BITMAPf. Hence, same pbmp is passed as argument for ubmp
   2599      * and ing_pbmp to _bcm_vlan_port_remove*/
   2600     rv = _bcm_vlan_port_remove(unit, vid, pbmp, pbmp, pbmp, NULL);
   2601 
   2602     return rv;
   2603 }
   2604 
   2605 /*
   2606  * Function:
   2607  *      _bcm_vlan_port_get
   2608  * Purpose:
   2609  *      Retrieves a list of the member ports of an existing VLAN.
   2610  */
   2611 STATIC int
   2612 _bcm_vlan_port_get(int unit, bcm_vlan_t vid, pbmp_t *pbmp, pbmp_t *ubmp,
   2613                    pbmp_t *ing_pbmp)
   2614 {
   2615     int                 rv;
   2616 
   2617     BCM_LOCK(unit);
   2618     rv = mbcm_driver[unit]->mbcm_vlan_port_get
   2619         (unit, vid, pbmp, ubmp, ing_pbmp);
   2620 
   2621     LOG_VERBOSE(BSL_LS_BCM_VLAN,
   2622                 (BSL_META_U(unit,
   2623                             "VLAN %d: bcm_vlan_port_get: vid %d. pbm 0x%x upbm 0x%x.\n"),
   2624                  unit, vid, SOC_PBMP_WORD_GET(*ing_pbmp, 0),
   2625                  SOC_PBMP_WORD_GET(*ubmp, 0)));
   2626 
   2627     BCM_UNLOCK(unit);
   2628 
   2629     return rv;
   2630 }
   2631 
   2632 /*
   2633  * Function:
   2634  *      bcm_vlan_port_get
   2635  * Purpose:
   2636  *      Retrieves a list of the member ports of an existing VLAN.
   2637  * Parameters:
   2638  *      unit - StrataSwitch PCI device unit number (driver internal).
   2639  *      vid - VLAN ID to lookup.
   2640  *      tag_pbmp - (output) member port bitmap (ignored if NULL)
   2641  *      untag_pbmp - (output) untagged port bitmap (ignored if NULL)
   2642  * Returns:
   2643  *      BCM_E_NONE - Success (port bitmaps filled in).
   2644  *      BCM_E_INTERNAL - Chip access failure.
   2645  *      BCM_E_NOT_FOUND - No such VLAN defined.
   2646  */
   2647 
   2648 int
   2649 bcm_esw_vlan_port_get(int unit, bcm_vlan_t vid, pbmp_t *pbmp, pbmp_t *ubmp)
   2650 {
   2651     pbmp_t ing_pbmp;
   2652 
   2653     CHECK_INIT(unit);
   2654     VLAN_CHK_ID(unit, vid);
   2655 
   2656     if (0 == _BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vid)) {
   2657         return BCM_E_NOT_FOUND;
   2658     }
   2659 
   2660     BCM_IF_ERROR_RETURN
   2661         (_bcm_vlan_port_get(unit, vid, pbmp, ubmp, &ing_pbmp));
   2662 
   2663     SOC_PBMP_OR(*pbmp, ing_pbmp);
   2664 
   2665     return BCM_E_NONE;
   2666 
   2667 }
   2668 
   2669 /*
   2670  * Function:
   2671  *      _bcm_vlan_list
   2672  * Purpose:
   2673  *      Main body of bcm_vlan_list() and bcm_vlan_list_by_pbmp().
   2674  *      Assumes locking already done.
   2675  * Parameters:
   2676  *      list_all - if TRUE, lists all ports and ignores list_pbmp.
   2677  *      list_pbmp - if list_all is FALSE, lists only VLANs containing
   2678  *              any of the ports in list_pbmp.
   2679  */
   2680 
   2681 STATIC int
   2682 _bcm_vlan_list(int unit, bcm_vlan_data_t **listp, int *countp,
   2683                int list_all, pbmp_t list_pbmp)
   2684 {
   2685     bcm_vlan_data_t     *list;
   2686     int                 count, i, rv;
   2687     int                 idx;
   2688     int                 valid_count;
   2689     pbmp_t              pbmp, ubmp, tbmp;
   2690 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_MONTEREY_SUPPORT)
   2691     bcm_vlan_t          olp_vlan = BCM_VLAN_INVALID;
   2692 #endif
   2693 
   2694     *countp = 0;
   2695     *listp = NULL;
   2696 
   2697     if (!list_all && SOC_PBMP_IS_NULL(list_pbmp)) {     /* Empty list */
   2698         return BCM_E_NONE;
   2699     }
   2700 
   2701     count = vlan_info[unit].count;
   2702 
   2703     if (count == 0) {
   2704         return BCM_E_NONE;                      /* Empty list */
   2705     }
   2706 
   2707     if ((list = sal_alloc(count * sizeof (list[0]), "vlan_list")) == NULL) {
   2708         return BCM_E_MEMORY;
   2709     }
   2710 
   2711     i = 0;
   2712     valid_count = 0;
   2713 
   2714 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_MONTEREY_SUPPORT)
   2715     if (soc_feature(unit, soc_feature_xflow_macsec_olp)) {
   2716         olp_vlan = soc_property_get(unit, spn_XFLOW_MACSEC_OLP_VLAN, BCM_VLAN_INVALID);
   2717     }
   2718 #endif
   2719 
   2720     for (idx = BCM_VLAN_MIN; idx < BCM_VLAN_COUNT; idx++) {
   2721         if (0 == _BCM_VBMP_LOOKUP(vlan_info[unit].bmp, idx)) {
   2722             continue;
   2723         }
   2724 
   2725 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_MONTEREY_SUPPORT)
   2726         if (olp_vlan == idx) {
   2727             count -= 1;
   2728             continue;
   2729         }
   2730 #endif
   2731         rv = bcm_esw_vlan_port_get(unit, idx, &pbmp, &ubmp);
   2732         if (BCM_FAILURE(rv)) {
   2733             sal_free(list);
   2734             return rv;
   2735         }
   2736         valid_count++;
   2737 
   2738         SOC_PBMP_ASSIGN(tbmp, list_pbmp);
   2739         SOC_PBMP_AND(tbmp, pbmp);
   2740         if (list_all || SOC_PBMP_NOT_NULL(tbmp)) {
   2741             list[i].vlan_tag = idx;
   2742             BCM_PBMP_ASSIGN(list[i].port_bitmap, pbmp);
   2743             BCM_PBMP_ASSIGN(list[i].ut_port_bitmap, ubmp);
   2744             i++;
   2745 
   2746         }
   2747         if (valid_count == count)   {
   2748             break;
   2749         }
   2750     } 
   2751     assert(!list_all || i == count);  /* If list_all, make sure all listed */
   2752 
   2753     *countp = i;
   2754     *listp = list;
   2755     return BCM_E_NONE;
   2756 }
   2757 
   2758 /*
   2759  * Function:
   2760  *      bcm_vlan_list
   2761  * Purpose:
   2762  *      Returns an array of all defined VLANs and their port bitmaps.
   2763  * Parameters:
   2764  *      unit - StrataSwitch PCI device unit number
   2765  *      listp - Place where pointer to return array will be stored,
   2766  *              which will be NULL if there are zero VLANs defined.
   2767  *      countp - Place where number of entries in array will be stored,
   2768  *              which will be 0 if there are zero VLANs defined.
   2769  * Returns:
   2770  *      BCM_E_NONE - Success.
   2771  *      BCM_E_INTERNAL - Chip access failure.
   2772  *      BCM_E_MEMORY - Out of system memory.
   2773  * Notes:
   2774  *      The caller is responsible for freeing the memory that is
   2775  *      returned, using bcm_vlan_list_destroy.
   2776  */
   2777 
   2778 int
   2779 bcm_esw_vlan_list(int unit, bcm_vlan_data_t **listp, int *countp)
   2780 {
   2781     int         rv;
   2782     pbmp_t      empty_pbm;
   2783 
   2784     CHECK_INIT(unit);
   2785 
   2786     SOC_PBMP_CLEAR(empty_pbm);
   2787     BCM_LOCK(unit);
   2788     rv = _bcm_vlan_list(unit, listp, countp, TRUE, empty_pbm);
   2789     BCM_UNLOCK(unit);
   2790 
   2791     return rv;
   2792 }
   2793 
   2794 /*
   2795  * Function:
   2796  *      bcm_esw_vlan_list_by_pbmp
   2797  * Purpose:
   2798  *      Returns an array of defined VLANs and port bitmaps.
   2799  *      Only VLANs that containing any of the specified ports are listed.
   2800  * Parameters:
   2801  *      unit - StrataSwitch PCI device unit number
   2802  *      pbmp - Bitmap of ports
   2803  *      listp - Place where pointer to return array will be stored,
   2804  *              which will be NULL if there are zero VLANs defined.
   2805  *      countp - Place where number of entries in array will be stored,
   2806  *              which will be 0 if there are zero VLANs defined.
   2807  * Returns:
   2808  *      BCM_E_NONE              Success.
   2809  *      BCM_E_INTERNAL          Chip access failure.
   2810  *      BCM_E_MEMORY            Out of system memory.
   2811  * Notes:
   2812  *      The caller is responsible for freeing the memory that is
   2813  *      returned, using bcm_vlan_list_destroy.
   2814  */
   2815 
   2816 int
   2817 bcm_esw_vlan_list_by_pbmp(int unit, pbmp_t pbmp,
   2818                           bcm_vlan_data_t **listp, int *countp)
   2819 {
   2820     int         rv;
   2821 
   2822     CHECK_INIT(unit);
   2823 
   2824     BCM_LOCK(unit);
   2825     rv = _bcm_vlan_list(unit, listp, countp, FALSE, pbmp);
   2826     BCM_UNLOCK(unit);
   2827 
   2828     return rv;
   2829 }
   2830 
   2831 /*
   2832  * Function:
   2833  *      bcm_vlan_list_destroy
   2834  * Purpose:
   2835  *      Destroy a list returned by bcm_vlan_list.
   2836  *      Also works for the zero-VLAN case (NULL list).
   2837  * Parameters:
   2838  *      unit - StrataSwitch PCI device unit number
   2839  *      list - List returned by bcm_vlan_list
   2840  *      count - Count returned by bcm_vlan_list
   2841  * Returns:
   2842  *      BCM_E_NONE              Success.
   2843  * Notes:
   2844  *      None.
   2845  */
   2846 
   2847 int
   2848 bcm_esw_vlan_list_destroy(int unit, bcm_vlan_data_t *list, int count)
   2849 {
   2850     COMPILER_REFERENCE(unit);
   2851     COMPILER_REFERENCE(count);
   2852 
   2853     if (list != NULL) {
   2854         sal_free(list);
   2855     }
   2856 
   2857     return BCM_E_NONE;
   2858 }
   2859 
   2860 /*
   2861  * Function:
   2862  *      bcm_vlan_default_get
   2863  * Purpose:
   2864  *      Get the default VLAN ID
   2865  * Parameters:
   2866  *      unit - StrataSwitch PCI device unit number (driver internal).
   2867  *      vid_ptr - (OUT) Target to receive the VLAN ID.
   2868  * Returns:
   2869  *      BCM_E_NONE - Success.
   2870  */
   2871 int
   2872 bcm_esw_vlan_default_get(int unit, bcm_vlan_t *vid_ptr)
   2873 {
   2874     *vid_ptr = vlan_info[unit].defl;
   2875 
   2876     return BCM_E_NONE;
   2877 }
   2878 
   2879 /*
   2880  * Function:
   2881  *      _bcm_vlan_default_set
   2882  * Purpose:
   2883  *      Main part of bcm_vlan_default_set; assumes locking already done.
   2884  */
   2885 
   2886 STATIC int
   2887 _bcm_vlan_default_set(int unit, bcm_vlan_t vid)
   2888 {
   2889     if (!BCM_VLAN_VALID(vid)) {
   2890         return BCM_E_PARAM;
   2891     }
   2892 
   2893     if (0 == _BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vid)) {
   2894         return BCM_E_NOT_FOUND;
   2895     }
   2896 
   2897     vlan_info[unit].defl = vid;
   2898     return BCM_E_NONE;
   2899 }
   2900 
   2901 /*
   2902  * Function:
   2903  *      bcm_vlan_default_set
   2904  * Purpose:
   2905  *      Set the default VLAN ID
   2906  * Parameters:
   2907  *      unit - StrataSwitch PCI device unit number (driver internal).
   2908  *      vid - The new default VLAN
   2909  * Returns:
   2910  *      BCM_E_NONE - Success.
   2911  * Notes:
   2912  *      The new default VLAN must already exist.
   2913  */
   2914 
   2915 int
   2916 bcm_esw_vlan_default_set(int unit, bcm_vlan_t vid)
   2917 {
   2918     int                 rv;
   2919 
   2920     LOG_VERBOSE(BSL_LS_BCM_VLAN,
   2921                 (BSL_META_U(unit,
   2922                             "VLAN %d: dflt vid set: %d\n"),
   2923                  unit, vid));
   2924 
   2925     CHECK_INIT(unit);
   2926 
   2927     BCM_LOCK(unit);
   2928     rv = _bcm_vlan_default_set(unit, vid);
   2929 
   2930 #ifdef BCM_WARM_BOOT_SUPPORT
   2931     SOC_CONTROL_LOCK(unit);
   2932     SOC_CONTROL(unit)->scache_dirty = 1;
   2933     SOC_CONTROL_UNLOCK(unit);
   2934 #endif
   2935 
   2936     BCM_UNLOCK(unit);
   2937 
   2938     return rv;
   2939 }
   2940 
   2941 /*
   2942  * Function:
   2943  *      bcm_vlan_stg_get
   2944  * Purpose:
   2945  *      Retrieve the VTABLE STG for the specified vlan
   2946  * Parameters:
   2947  *      unit - StrataSwitch PCI device unit number.
   2948  *      vid - VLAN ID.
   2949  *      stg_ptr - (OUT) Pointer to store stgid for return.
   2950  * Returns:
   2951  *      BCM_E_XXX
   2952  */
   2953 
   2954 int
   2955 bcm_esw_vlan_stg_get(int unit, bcm_vlan_t vid, bcm_stg_t *stg_ptr)
   2956 {
   2957     int         rv;
   2958 
   2959     CHECK_INIT(unit);
   2960 
   2961     BCM_LOCK(unit);
   2962     rv = mbcm_driver[unit]->mbcm_vlan_stg_get(unit, vid, stg_ptr);
   2963     BCM_UNLOCK(unit);
   2964 
   2965     return rv;
   2966 }
   2967 
   2968 /*
   2969  * Function:
   2970  *      bcm_vlan_stg_set
   2971  * Purpose:
   2972  *      Update the VTABLE STG for the specified vlan
   2973  * Parameters:
   2974  *      unit  - StrataSwitch PCI device unit number
   2975  *      vid - VLAN ID
   2976  *      stg - New spanning tree group number for VLAN
   2977  * Returns:
   2978  *      BCM_E_XXX
   2979  */
   2980 
   2981 int
   2982 bcm_esw_vlan_stg_set(int unit, bcm_vlan_t vid, bcm_stg_t stg)
   2983 {
   2984     int         rv;
   2985 
   2986     CHECK_INIT(unit);
   2987 
   2988     BCM_LOCK(unit);
   2989     rv = bcm_esw_stg_vlan_add(unit, stg, vid);
   2990     BCM_UNLOCK(unit);
   2991 
   2992     return rv;
   2993 }
   2994 
   2995 /*
   2996  * Function:
   2997  *      _bcm_vlan_stp_set
   2998  * Purpose:
   2999  *      Main part of bcm_vlan_stp_set; assumes locking already done.
   3000  */
   3001 
   3002 STATIC int
   3003 _bcm_vlan_stp_set(int unit, bcm_vlan_t vid, bcm_port_t port, int stp_state)
   3004 {
   3005     bcm_stg_t   stgid;
   3006 
   3007     BCM_IF_ERROR_RETURN(bcm_esw_vlan_stg_get(unit, vid, &stgid));
   3008     BCM_IF_ERROR_RETURN(bcm_esw_stg_stp_set(unit, stgid, port, stp_state));
   3009 
   3010     return BCM_E_NONE;
   3011 }
   3012 
   3013 /*
   3014  * Function:
   3015  *      bcm_vlan_stp_set
   3016  * Purpose:
   3017  *      Set the spanning tree state for a port in the whole spanning
   3018  *      tree group that contains the specified VLAN.
   3019  * Parameters:
   3020  *      unit - StrataSwitch PCI device unit number
   3021  *      vid - VLAN ID
   3022  *      port - Port
   3023  *      stp_state - State to set
   3024  * Returns:
   3025  *      BCM_E_XXX
   3026  */
   3027 
   3028 int
   3029 bcm_esw_vlan_stp_set(int unit, bcm_vlan_t vid,
   3030                             bcm_port_t port, int stp_state)
   3031 {
   3032     int         rv;
   3033 
   3034 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 
   3035     int         vp = -1;
   3036     /* Extender */
   3037     if (soc_feature(unit, soc_feature_port_extension) && 
   3038         BCM_GPORT_IS_EXTENDER_PORT(port)) {
   3039         vp = BCM_GPORT_EXTENDER_PORT_ID_GET(port);
   3040         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender)) {
   3041             return BCM_E_NOT_FOUND;
   3042         }
   3043     }
   3044     
   3045     if (vp != -1) {
   3046         if (soc_feature(unit, soc_feature_ing_vp_vlan_membership) &&
   3047             soc_feature(unit, soc_feature_egr_vp_vlan_membership)) {
   3048             return bcm_td2_vp_vlan_stp_set(unit, vp, vid, stp_state);
   3049         }
   3050         return BCM_E_UNAVAIL;
   3051     }
   3052 #endif
   3053 
   3054     BCM_LOCK(unit);
   3055     rv = _bcm_vlan_stp_set(unit, vid, port, stp_state);
   3056     BCM_UNLOCK(unit);
   3057 
   3058     return rv;
   3059 }
   3060 
   3061 /*
   3062  * Function:
   3063  *      _bcm_vlan_stp_get
   3064  * Purpose:
   3065  *      Main part of bcm_vlan_stp_get; assumes locking already done.
   3066  */
   3067 
   3068 STATIC int
   3069 _bcm_vlan_stp_get(int unit, bcm_vlan_t vid,
   3070                        bcm_port_t port, int *stp_state)
   3071 {
   3072     bcm_stg_t   stgid;
   3073 
   3074     BCM_IF_ERROR_RETURN(bcm_esw_vlan_stg_get(unit, vid, &stgid));
   3075     BCM_IF_ERROR_RETURN(bcm_esw_stg_stp_get(unit, stgid, port, stp_state));
   3076 
   3077     return BCM_E_NONE;
   3078 }
   3079 
   3080 /*
   3081  * Function:
   3082  *      bcm_vlan_stp_get
   3083  * Purpose:
   3084  *      Get the spanning tree state for a port in the whole spanning
   3085  *      tree group that contains the specified VLAN.
   3086  * Parameters:
   3087  *      unit - StrataSwitch PCI device unit number.
   3088  *      vid - VLAN ID.
   3089  *      port - Port
   3090  *      stp_state - (OUT) State to return.
   3091  * Returns:
   3092  *      BCM_E_XXX
   3093  */
   3094 
   3095 int
   3096 bcm_esw_vlan_stp_get(int unit, bcm_vlan_t vid,
   3097                             bcm_port_t port, int *stp_state)
   3098 {
   3099     int         rv;
   3100 
   3101 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
   3102     int         vp = -1;
   3103     /* Extender */
   3104     if (soc_feature(unit, soc_feature_port_extension) && 
   3105         BCM_GPORT_IS_EXTENDER_PORT(port)) {
   3106         vp = BCM_GPORT_EXTENDER_PORT_ID_GET(port);
   3107         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender)) {
   3108             return BCM_E_NOT_FOUND;
   3109         }
   3110     }
   3111     
   3112     if (vp != -1) {
   3113         if (soc_feature(unit, soc_feature_ing_vp_vlan_membership) &&
   3114             soc_feature(unit, soc_feature_egr_vp_vlan_membership)) {
   3115             return bcm_td2_vp_vlan_stp_get(unit, vp, vid, stp_state);
   3116         }
   3117         return BCM_E_UNAVAIL;
   3118     }
   3119 #endif
   3120 
   3121     BCM_LOCK(unit);
   3122     rv = _bcm_vlan_stp_get(unit, vid, port, stp_state);
   3123     BCM_UNLOCK(unit);
   3124 
   3125     return rv;
   3126 }
   3127 
   3128 /*
   3129  * Function:
   3130  *      bcm_esw_vlan_policer_get
   3131  * Purpose:
   3132  *     Retrieve the Policer ID accociated for the specified physical port.
   3133  * Parameters:
   3134  *     Unit                  - (IN) unit number 
   3135  *     vlan                  - (IN) VLAN 
   3136  *     policer               - (OUT) policer Id 
   3137  * Returns:
   3138  *     BCM_E_XXX 
   3139  */
   3140 int bcm_esw_vlan_policer_get(
   3141     int unit,
   3142     bcm_vlan_t vlan,
   3143     bcm_policer_t *policer)
   3144 {
   3145     int rv = BCM_E_NONE;
   3146     vlan_tab_entry_t   vt;
   3147     
   3148 #ifdef BCM_TOMAHAWK3_SUPPORT
   3149     if (SOC_IS_TOMAHAWK3(unit)) {
   3150         return BCM_E_UNAVAIL;
   3151     }
   3152 #endif
   3153 
   3154     VLAN_CHK_ID(unit, vlan);
   3155     BCM_IF_ERROR_RETURN(_check_global_meter_init(unit));
   3156     *policer = 0;
   3157     rv = _bcm_esw_get_policer_from_table(unit, VLAN_TABm, vlan, &vt, 
   3158                                                  policer, 0); 
   3159     if (BCM_FAILURE(rv)) {
   3160         LOG_ERROR(BSL_LS_BCM_VLAN,
   3161                   (BSL_META_U(unit,
   3162                               "Unable to read vlan table entry\n")));
   3163         return (rv);
   3164     }
   3165     return rv;
   3166 
   3167 }
   3168 
   3169 /*
   3170  * Function:
   3171  *     bcm_esw_vlan_policer_set
   3172  * Purpose:
   3173  *     Set the Policer ID accociated for the specified physical port. 
   3174  * Parameters:
   3175  *     Unit                  - (IN) unit number 
   3176  *     vlan                  - (IN) VLAN 
   3177  *     policer               - (IN) policer Id 
   3178  * Returns:
   3179  *     BCM_E_XXX 
   3180  */
   3181 int bcm_esw_vlan_policer_set(
   3182     int unit,
   3183     bcm_vlan_t vlan,
   3184     bcm_policer_t policer)
   3185 {
   3186     int rv = BCM_E_NONE;
   3187     vlan_tab_entry_t   vt;
   3188 
   3189 #ifdef BCM_TOMAHAWK3_SUPPORT
   3190     if (SOC_IS_TOMAHAWK3(unit)) {
   3191         return BCM_E_UNAVAIL;
   3192     }
   3193 #endif
   3194 
   3195     VLAN_CHK_ID(unit, vlan);
   3196     if (!soc_feature(unit, soc_feature_global_meter)) {
   3197         return BCM_E_UNAVAIL;
   3198     }
   3199     BCM_IF_ERROR_RETURN(_check_global_meter_init(unit));
   3200     rv = _bcm_esw_policer_validate(unit, &policer);
   3201     if (BCM_FAILURE(rv)) {
   3202         LOG_VERBOSE(BSL_LS_BCM_VLAN,
   3203                 (BSL_META_U(unit,
   3204                             "Invalid policer id passed: %x \n"),
   3205                  policer));
   3206         return (rv);
   3207     }
   3208 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   3209     if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_APACHE(unit)) {
   3210         int offset_mode = 0;
   3211         offset_mode = (((policer) & BCM_POLICER_GLOBAL_METER_MODE_MASK) >>
   3212                 BCM_POLICER_GLOBAL_METER_MODE_SHIFT);
   3213 
   3214         if ((offset_mode == 0) && (policer != 0)) {
   3215             /*
   3216              * Not a Global meter policer, 
   3217              * policer zero is used to detach already configured policer
   3218              */
   3219             return (BCM_E_PARAM);
   3220         } 
   3221     } 
   3222 #endif
   3223     soc_mem_lock(unit, VLAN_TABm);
   3224     rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, vlan, &vt);
   3225     if (BCM_FAILURE(rv)) {
   3226         LOG_ERROR(BSL_LS_BCM_VLAN,
   3227                   (BSL_META_U(unit,
   3228                               "Unable to read vlan table entry\n")));
   3229         soc_mem_unlock(unit, VLAN_TABm);
   3230         return (rv);
   3231     }
   3232 
   3233     rv = _bcm_esw_add_policer_to_table(unit, policer,
   3234                                            VLAN_TABm, vlan, (void *)(&vt));
   3235     if (BCM_FAILURE(rv)) {
   3236         LOG_ERROR(BSL_LS_BCM_VLAN,
   3237                   (BSL_META_U(unit,
   3238                               "Unable to add policer to vlan table entry\n")));
   3239         soc_mem_unlock(unit, VLAN_TABm);
   3240         return (rv);
   3241     }
   3242     rv = soc_mem_write(unit, VLAN_TABm, MEM_BLOCK_ANY, vlan, &vt);
   3243     if (BCM_FAILURE(rv)) {
   3244         LOG_ERROR(BSL_LS_BCM_VLAN,
   3245                   (BSL_META_U(unit,
   3246                               "Unable to add policer to vlan table entry\n")));
   3247         soc_mem_unlock(unit, VLAN_TABm);
   3248         return (rv);
   3249     }
   3250     soc_mem_unlock(unit, VLAN_TABm);
   3251     return rv;
   3252 } 
   3253 /*
   3254  * Port-based VLAN actions
   3255  */
   3256 /* 
   3257  * Function:
   3258  *      bcm_vlan_port_default_action_set
   3259  * Purpose: 
   3260  *      Set the port's default vlan tag actions
   3261  * Parameters:
   3262  *      unit       - (IN) BCM unit.
   3263  *      port       - (IN) Port number.
   3264  *      action     - (IN) Vlan tag actions
   3265  * Returns:
   3266  *      BCM_E_XXX
   3267  */
   3268 int
   3269 bcm_esw_vlan_port_default_action_set(int unit, bcm_port_t port,
   3270                                      bcm_vlan_action_set_t *action)
   3271 {   
   3272     int rv = BCM_E_UNAVAIL;
   3273 
   3274 #ifdef BCM_TOMAHAWK3_SUPPORT
   3275     if (SOC_IS_TOMAHAWK3(unit)) {
   3276         rv = bcm_tomahawk3_vlan_port_default_action_set(unit, port, action);
   3277     } else
   3278 #endif
   3279 #ifdef BCM_TRX_SUPPORT
   3280     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   3281         bcm_port_t  local_port;
   3282 
   3283 #ifdef BCM_HGPROXY_COE_SUPPORT
   3284         if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   3285             BCM_GPORT_IS_SET(port) &&
   3286             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   3287             local_port = port;
   3288         } else
   3289 #endif
   3290         {
   3291             BCM_IF_ERROR_RETURN(
   3292                 _bcm_esw_port_gport_validate(unit, port, &local_port));
   3293         }
   3294 
   3295         PORT_LOCK(unit);
   3296 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
   3297         if (SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
   3298             rv = _bcm_trx_vlan_port_default_action_profile_set(unit,
   3299                      local_port, action);
   3300         } else
   3301 #endif
   3302         {
   3303             rv = _bcm_trx_vlan_port_default_action_set(unit,
   3304                      local_port, action);
   3305         }
   3306         PORT_UNLOCK(unit);
   3307     }
   3308 #endif /* BCM_TRX_SUPPORT */
   3309 
   3310     return rv;
   3311 }
   3312 
   3313 /*  
   3314  * Function:
   3315  *      bcm_vlan_port_default_action_get
   3316  * Purpose:
   3317  *      Get the port's default vlan tag actions
   3318  * Parameters:
   3319  *      unit       - (IN) BCM unit.
   3320  *      port       - (IN) Port number.
   3321  *      action     - (OUT) Vlan tag actions
   3322  * Returns:
   3323  *      BCM_E_XXX
   3324  */
   3325 int
   3326 bcm_esw_vlan_port_default_action_get(int unit, bcm_port_t port,
   3327                                      bcm_vlan_action_set_t *action)
   3328 {
   3329     int rv = BCM_E_UNAVAIL;
   3330 
   3331 #ifdef BCM_TOMAHAWK3_SUPPORT
   3332     if (SOC_IS_TOMAHAWK3(unit)) {
   3333         rv = bcm_tomahawk3_vlan_port_default_action_get(unit, port, action);
   3334     } else
   3335 #endif
   3336 #ifdef BCM_TRX_SUPPORT
   3337     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   3338         bcm_port_t  local_port;
   3339 
   3340 #ifdef BCM_HGPROXY_COE_SUPPORT
   3341         if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   3342             BCM_GPORT_IS_SET(port) &&
   3343             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   3344             local_port = port;
   3345         } else
   3346 #endif
   3347         {
   3348             BCM_IF_ERROR_RETURN(
   3349                 _bcm_esw_port_gport_validate(unit, port, &local_port));
   3350         }
   3351 
   3352         bcm_vlan_action_set_t_init(action);
   3353         PORT_LOCK(unit);
   3354         rv = _bcm_trx_vlan_port_default_action_get(unit, local_port, action);
   3355         PORT_UNLOCK(unit);
   3356     }
   3357 #endif /* BCM_TRIUMPH_SUPPORT */
   3358 
   3359     return rv;
   3360 }
   3361 
   3362 
   3363 /*  
   3364  * Function:
   3365  *      bcm_vlan_port_default_action_delete
   3366  * Purpose:
   3367  *      Delete the port's default vlan tag actions
   3368  * Parameters:
   3369  *      unit       - (IN) BCM unit.
   3370  *      port       - (IN) Port number.
   3371  * Returns:
   3372  *      BCM_E_XXX
   3373  */
   3374 int
   3375 bcm_esw_vlan_port_default_action_delete(int unit, bcm_port_t port)
   3376 {
   3377     int rv = BCM_E_UNAVAIL;
   3378 
   3379 #ifdef BCM_TOMAHAWK3_SUPPORT
   3380     if (SOC_IS_TOMAHAWK3(unit)) {
   3381         rv = bcm_tomahawk3_vlan_port_default_action_delete(unit, port);
   3382     } else
   3383 #endif
   3384 #ifdef BCM_TRX_SUPPORT
   3385     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   3386         bcm_port_t  local_port;
   3387 
   3388         BCM_IF_ERROR_RETURN(
   3389             _bcm_esw_port_gport_validate(unit, port, &local_port));
   3390 
   3391         PORT_LOCK(unit);
   3392 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
   3393         if (SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
   3394             /* Increase ref count of default profile */
   3395             BCM_IF_ERROR_RETURN
   3396                 (_bcm_port_vlan_protocol_data_entry_reference(unit, 0, 16));
   3397             rv = _bcm_trx_vlan_port_default_action_profile_delete(unit, local_port);
   3398         } else
   3399 #endif
   3400         {
   3401             rv = _bcm_trx_vlan_port_default_action_delete(unit, local_port);
   3402         }
   3403         PORT_UNLOCK(unit);
   3404     }
   3405 #endif /* BCM_TRX_SUPPORT */
   3406 
   3407     return rv;
   3408 }
   3409 
   3410 /*
   3411  * Function:
   3412  *      bcm_vlan_port_egress_default_action_set
   3413  * Purpose:
   3414  *      Set the egress port's default vlan tag actions
   3415  * Parameters:
   3416  *      unit       - (IN) BCM unit.
   3417  *      port       - (IN) Port number.
   3418  *      action     - (IN) Vlan tag actions
   3419  * Returns:
   3420  *      BCM_E_XXX
   3421  */
   3422 int
   3423 bcm_esw_vlan_port_egress_default_action_set(int unit,
   3424                                             bcm_port_t port,
   3425                                             bcm_vlan_action_set_t *action)
   3426 {
   3427     int rv = BCM_E_UNAVAIL;
   3428 
   3429 #ifdef BCM_TOMAHAWK3_SUPPORT
   3430     if (SOC_IS_TOMAHAWK3(unit)) {
   3431         rv =
   3432          bcm_tomahawk3_vlan_port_egress_default_action_set(unit, port, action);
   3433     } else
   3434 #endif
   3435 #ifdef BCM_TRX_SUPPORT
   3436     if (SOC_IS_TRX(unit) && ((soc_feature(unit, soc_feature_vlan_action)) ||
   3437         (soc_feature(unit, soc_feature_fast_egr_vlan_action)) || 
   3438         (soc_feature(unit, soc_feature_egr_vlan_action)))) {
   3439         bcm_port_t  local_port; 
   3440 
   3441         BCM_IF_ERROR_RETURN(
   3442             _bcm_esw_port_gport_validate(unit, port, &local_port));
   3443 
   3444         rv = _bcm_trx_vlan_port_egress_default_action_set(unit,
   3445                                                           local_port, action);
   3446     }
   3447 #endif /* BCM_TRX_SUPPORT */
   3448 
   3449     return rv;
   3450 }
   3451 
   3452 /*
   3453  * Function:
   3454  *      bcm_vlan_port_egress_default_action_get
   3455  * Purpose:
   3456  *      Get the egress port's default vlan tag actions
   3457  * Parameters:
   3458  *      unit       - (IN) BCM unit.
   3459  *      port       - (IN) Port number.
   3460  *      action     - (OUT) Vlan tag actions
   3461  * Returns:
   3462  *      BCM_E_XXX
   3463  */     
   3464 int
   3465 bcm_esw_vlan_port_egress_default_action_get(int unit,
   3466                                             bcm_port_t port,
   3467                                             bcm_vlan_action_set_t *action)
   3468 {
   3469     int rv = BCM_E_UNAVAIL;
   3470 
   3471 #ifdef BCM_TOMAHAWK3_SUPPORT
   3472     if (SOC_IS_TOMAHAWK3(unit)) {
   3473         rv =
   3474          bcm_tomahawk3_vlan_port_egress_default_action_get(unit, port, action);
   3475     } else
   3476 #endif
   3477 #ifdef BCM_TRX_SUPPORT
   3478     if (SOC_IS_TRX(unit) && ((soc_feature(unit, soc_feature_vlan_action)) ||
   3479         (soc_feature(unit, soc_feature_fast_egr_vlan_action)) || 
   3480         (soc_feature(unit, soc_feature_egr_vlan_action)))) {
   3481         bcm_port_t  local_port;
   3482 
   3483         BCM_IF_ERROR_RETURN(
   3484             _bcm_esw_port_gport_validate(unit, port, &local_port));
   3485 
   3486         bcm_vlan_action_set_t_init(action);
   3487         rv = _bcm_trx_vlan_port_egress_default_action_get(unit, local_port, 
   3488                                                           action);
   3489     }
   3490 #endif /* BCM_TRX_SUPPORT */
   3491 
   3492     return rv;
   3493 }
   3494 
   3495 /*
   3496  * Function:
   3497  *      bcm_vlan_port_egress_default_action_delete
   3498  * Purpose:
   3499  *      delete the egress port's default vlan tag actions
   3500  * Parameters:
   3501  *      unit       - (IN) BCM unit.
   3502  *      port       - (IN) Port number.
   3503  * Returns:
   3504  *      BCM_E_XXX
   3505  */     
   3506 int
   3507 bcm_esw_vlan_port_egress_default_action_delete(int unit, bcm_port_t port)
   3508 {
   3509     int rv = BCM_E_UNAVAIL;
   3510 
   3511 #ifdef BCM_TOMAHAWK3_SUPPORT
   3512     if (SOC_IS_TOMAHAWK3(unit)) {
   3513         rv = bcm_tomahawk3_vlan_port_egress_default_action_delete(unit, port);
   3514     } else
   3515 #endif
   3516 #ifdef BCM_TRX_SUPPORT
   3517     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   3518         bcm_port_t  local_port;
   3519 
   3520         BCM_IF_ERROR_RETURN(
   3521             _bcm_esw_port_gport_validate(unit, port, &local_port));
   3522 
   3523         rv = _bcm_trx_vlan_port_egress_default_action_delete(unit, local_port);
   3524 
   3525         /* The port is using the default profile */
   3526         _bcm_trx_egr_vlan_action_profile_entry_increment
   3527             (unit, BCM_TRX_EGR_VLAN_ACTION_PROFILE_DEFAULT);
   3528     }
   3529 #endif /* BCM_TRX_SUPPORT */
   3530 
   3531     return rv;
   3532 }
   3533 
   3534 /*
   3535  * Protocol-based VLAN actions
   3536  */
   3537 
   3538 /*
   3539  * Function   :
   3540  *      bcm_vlan_port_protocol_action_add
   3541  * Description   :
   3542  *      Add protocol based VLAN with specified action.
   3543  *      If the entry already exists, update the action.
   3544  * Parameters   :
   3545  *      unit      (IN) BCM unit number
   3546  *      port      (IN) Port number
   3547  *      frame     (IN) Frame type
   3548  *      ether     (IN) 16 bit ether type
   3549  *      action    (IN) Action for outer tag and inner tag
   3550  * Note:
   3551  *    Program VLAN_PROTOCOL_DATAm and VLAN_PROTOCOLm.
   3552  */
   3553 int
   3554 bcm_esw_vlan_port_protocol_action_add(int unit,
   3555                                       bcm_port_t port,
   3556                                       bcm_port_frametype_t frame,
   3557                                       bcm_port_ethertype_t ether,
   3558                                       bcm_vlan_action_set_t *action)
   3559 {
   3560     int rv = BCM_E_UNAVAIL;
   3561 
   3562 #ifdef BCM_TOMAHAWK3_SUPPORT
   3563     if (!SOC_IS_TOMAHAWK3(unit))
   3564 #endif
   3565 #ifdef BCM_TRX_SUPPORT
   3566     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   3567         bcm_port_t  local_port; 
   3568 
   3569         BCM_IF_ERROR_RETURN(
   3570             _bcm_esw_port_gport_validate(unit, port, &local_port));
   3571 
   3572         if (IS_HG_PORT(unit, local_port)){
   3573             return SOC_E_PORT;
   3574         }
   3575 
   3576         PORT_LOCK(unit);
   3577         rv =  _bcm_trx_vlan_port_protocol_action_add(unit, local_port, frame,
   3578                                                      ether, action);
   3579         PORT_UNLOCK(unit);
   3580     }
   3581 #endif /* BCM_TRX_SUPPORT */
   3582     return (rv);
   3583 }
   3584 /*
   3585  * Function   :
   3586  *      bcm_vlan_port_protocol_action_get
   3587  * Description   :
   3588  *      Get protocol based VLAN with specified action.
   3589  * Parameters   :
   3590  *      unit      (IN) BCM unit number
   3591  *      port      (IN) Port number
   3592  *      frame     (IN) Frame type
   3593  *      ether     (IN) 16 bit ether type
   3594  *      action    (OUT) Action for outer and inner tag
   3595  * Note:
   3596  */
   3597 int
   3598 bcm_esw_vlan_port_protocol_action_get(int unit,
   3599                                       bcm_port_t port,
   3600                                       bcm_port_frametype_t frame,
   3601                                       bcm_port_ethertype_t ether,
   3602                                       bcm_vlan_action_set_t *action)
   3603 {
   3604     int rv = BCM_E_UNAVAIL;
   3605 #ifdef BCM_TOMAHAWK3_SUPPORT
   3606     if (!SOC_IS_TOMAHAWK3(unit))
   3607 #endif
   3608 #ifdef BCM_TRX_SUPPORT
   3609     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   3610         bcm_port_t  local_port; 
   3611 
   3612         BCM_IF_ERROR_RETURN(
   3613             _bcm_esw_port_gport_validate(unit, port, &local_port));
   3614 
   3615         bcm_vlan_action_set_t_init(action);
   3616         PORT_LOCK(unit);
   3617         rv = _bcm_trx_vlan_port_protocol_action_get(unit, local_port, frame,
   3618                                                      ether, action);
   3619         PORT_UNLOCK(unit);
   3620         return rv;
   3621     }
   3622 #endif /* BCM_TRX_SUPPORT */
   3623 
   3624     return (rv);
   3625 }
   3626 
   3627 
   3628 /*
   3629  * Function   :
   3630  *      bcm_vlan_port_protocol_action_delete
   3631  * Description   :
   3632  *      Delete protocol based VLAN action.
   3633  * Parameters   :
   3634  *      unit      (IN) BCM unit number
   3635  *      port      (IN) Port number
   3636  *      frame     (IN) Frame type
   3637  *      ether     (IN) 16 bit ether type
   3638  * Note:
   3639  *    Program VLAN_PROTOCOL_DATAm and VLAN_PROTOCOLm.
   3640  */
   3641 int
   3642 bcm_esw_vlan_port_protocol_action_delete(int unit,bcm_port_t port,
   3643                                          bcm_port_frametype_t frame,
   3644                                          bcm_port_ethertype_t ether)
   3645 {
   3646     int rv = BCM_E_UNAVAIL; 
   3647 #ifdef BCM_TOMAHAWK3_SUPPORT
   3648     if (!SOC_IS_TOMAHAWK3(unit))
   3649 #endif
   3650 #ifdef BCM_TRX_SUPPORT
   3651     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   3652         bcm_port_t  local_port;
   3653 
   3654         BCM_IF_ERROR_RETURN(
   3655             _bcm_esw_port_gport_validate(unit, port, &local_port));
   3656 
   3657 
   3658         PORT_LOCK(unit);
   3659         rv = _bcm_trx_vlan_port_protocol_delete(unit, local_port, frame, ether);
   3660         PORT_UNLOCK(unit);
   3661         return rv;
   3662     }
   3663 #endif /* BCM_TRX_SUPPORT */
   3664     return (rv);
   3665 }
   3666 
   3667 
   3668 /*
   3669  * Function   :
   3670  *      bcm_vlan_port_protocol_action_delete_all
   3671  * Description   :
   3672  *      Delete all protocol based VLAN actiona.
   3673  * Parameters   :
   3674  *      unit      (IN) BCM unit number
   3675  *      port      (IN) Port number
   3676  * Note:
   3677  *    Program VLAN_PROTOCOL_DATAm and VLAN_PROTOCOLm.
   3678  */
   3679 int
   3680 bcm_esw_vlan_port_protocol_action_delete_all(int unit,bcm_port_t port)
   3681 {
   3682     int rv = BCM_E_UNAVAIL; 
   3683 
   3684 #ifdef BCM_TOMAHAWK3_SUPPORT
   3685     if (!SOC_IS_TOMAHAWK3(unit))
   3686 #endif
   3687 #ifdef BCM_TRX_SUPPORT
   3688     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   3689         bcm_port_t  local_port; 
   3690 
   3691         BCM_IF_ERROR_RETURN(
   3692             _bcm_esw_port_gport_validate(unit, port, &local_port));
   3693 
   3694         PORT_LOCK(unit);
   3695         rv = _bcm_trx_vlan_port_protocol_delete_all(unit, local_port);
   3696         PORT_UNLOCK(unit);
   3697     }
   3698 #endif /* BCM_TRX_SUPPORT */
   3699     return (rv);
   3700 }
   3701 
   3702 /*
   3703  * Function   :
   3704  *      bcm_esw_vlan_port_protocol_action_traverse
   3705  * Description   :
   3706  *      Traverse over vlan port protocol actions. 
   3707  * Parameters   :
   3708  *      unit      (IN) BCM unit number
   3709  *      cb        (IN) User provided call back function
   3710  *      user_data (IN) User provided data
   3711  * Note:
   3712  *    Program VLAN_PROTOCOL_DATAm and VLAN_PROTOCOLm.
   3713  */
   3714 int
   3715 bcm_esw_vlan_port_protocol_action_traverse(int unit, 
   3716                                 bcm_vlan_port_protocol_action_traverse_cb cb,
   3717                                            void *user_data)
   3718 {
   3719     int rv = BCM_E_UNAVAIL; 
   3720 #ifdef BCM_TOMAHAWK3_SUPPORT
   3721     if (!SOC_IS_TOMAHAWK3(unit))
   3722 #endif
   3723 #ifdef BCM_TRX_SUPPORT
   3724     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   3725         PORT_LOCK(unit);
   3726         rv = _bcm_trx_vlan_port_protocol_action_traverse(unit, cb, user_data);
   3727         PORT_UNLOCK(unit);
   3728     }
   3729 #endif /* BCM_TRX_SUPPORT */
   3730     return (rv);
   3731 }
   3732 
   3733 
   3734 /*
   3735  * Mac based vlans
   3736  */
   3737 int
   3738 bcm_esw_vlan_mac_add(int unit, bcm_mac_t mac, bcm_vlan_t vid, int prio)
   3739 {
   3740 
   3741     VLAN_CHK_ID(unit, vid);
   3742     if (prio < BCM_PRIO_MIN || prio > BCM_PRIO_MAX) {
   3743         return BCM_E_PARAM;
   3744     }
   3745 
   3746 #ifdef BCM_TRX_SUPPORT
   3747     if (SOC_IS_TRX(unit)) {
   3748         bcm_vlan_action_set_t action;
   3749 
   3750         if (!soc_feature(unit, soc_feature_vlan_action)
   3751             || !soc_feature(unit, soc_feature_mac_based_vlan)) {
   3752             return BCM_E_UNAVAIL;
   3753         }
   3754         prio &= ~BCM_PRIO_DROP_FIRST;
   3755 
   3756         if ((prio & ~BCM_VLAN_XLATE_PRIO_MASK) != 0) {
   3757             return BCM_E_PARAM;
   3758         }
   3759 
   3760         bcm_vlan_action_set_t_init(&action);
   3761         action.new_outer_vlan = vid;
   3762         action.new_inner_vlan = 0;
   3763         action.priority = prio;
   3764         action.dt_outer_prio = bcmVlanActionReplace;
   3765         action.ot_outer_prio = bcmVlanActionReplace;
   3766         action.it_outer      = bcmVlanActionAdd;
   3767         action.it_inner_prio = bcmVlanActionNone;
   3768         action.ut_outer      = bcmVlanActionAdd;
   3769         if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   3770             action.ut_outer_pkt_prio = bcmVlanActionAdd;
   3771         }
   3772 
   3773 #if defined(BCM_TRIDENT3_SUPPORT)
   3774         if (SOC_IS_TRIDENT3X(unit)) {
   3775             return _bcm_td3_vlan_mac_action_add(unit, mac, &action);
   3776         } else
   3777 #endif
   3778         {
   3779         return _bcm_trx_vlan_mac_action_add(unit, mac, &action);
   3780     }
   3781     }
   3782 #endif /* BCM_TRX_SUPPORT */
   3783 #if defined(BCM_TRIUMPH3_SUPPORT)
   3784     if (SOC_IS_TRIUMPH3(unit)) {
   3785         vlan_xlate_entry_t vxent;
   3786         prio &= ~BCM_PRIO_DROP_FIRST;
   3787 
   3788         if ((prio & ~BCM_VLAN_XLATE_PRIO_MASK) != 0) {
   3789             return BCM_E_PARAM;
   3790         }
   3791 
   3792         sal_memset(&vxent, 0, sizeof(vxent));
   3793         soc_mem_mac_addr_set(unit, VLAN_XLATEm, (uint32 *)(&vxent), 
   3794                        VLAN_MAC__MAC_ADDRf, mac);
   3795         soc_VLAN_XLATEm_field32_set(unit, &vxent, VLAN_MAC__OVIDf, vid);
   3796         soc_VLAN_XLATEm_field32_set(unit, &vxent, VLAN_MAC__OPRIf, prio);
   3797         soc_VLAN_XLATEm_field32_set(unit, &vxent, VALIDf, 1);
   3798 
   3799         return soc_mem_insert(unit, VLAN_XLATEm, MEM_BLOCK_ALL, &vxent);
   3800     } else
   3801 #endif  /* BCM_TRIUMPH3_SUPPORT */
   3802     {
   3803 #ifdef BCM_XGS3_SWITCH_SUPPORT
   3804     if (SOC_IS_XGS3_SWITCH(unit)) {
   3805         vlan_mac_entry_t  vment;
   3806         prio &= ~BCM_PRIO_DROP_FIRST;
   3807 
   3808         if ((prio & ~BCM_VLAN_XLATE_PRIO_MASK) != 0) {
   3809             return BCM_E_PARAM;
   3810         }
   3811 
   3812         sal_memset(&vment, 0, sizeof(vment));
   3813         soc_VLAN_MACm_mac_addr_set(unit, &vment, MAC_ADDRf, mac);
   3814         soc_VLAN_MACm_field32_set(unit, &vment, VLAN_IDf, vid);
   3815         soc_VLAN_MACm_field32_set(unit, &vment, PRIf, prio);
   3816         soc_VLAN_MACm_field32_set(unit, &vment, VALIDf, 1);
   3817 
   3818         return soc_mem_insert(unit, VLAN_MACm, MEM_BLOCK_ALL, &vment);
   3819     }
   3820 #endif
   3821     }
   3822     return BCM_E_UNAVAIL;
   3823 }
   3824 
   3825 int
   3826 bcm_esw_vlan_mac_delete(int unit, bcm_mac_t mac)
   3827 {
   3828 #ifdef BCM_TRX_SUPPORT
   3829     if (SOC_IS_TRX(unit)) {
   3830         if (!soc_feature(unit, soc_feature_vlan_action)
   3831             || !soc_feature(unit, soc_feature_mac_based_vlan)) {
   3832             return BCM_E_UNAVAIL;
   3833         }
   3834 #if defined(BCM_TRIDENT3_SUPPORT)
   3835         if (SOC_IS_TRIDENT3X(unit)) {
   3836             return _bcm_td3_vlan_mac_delete(unit, mac);
   3837         } else
   3838 #endif
   3839         {
   3840         return _bcm_trx_vlan_mac_delete(unit, mac);
   3841     }
   3842     }
   3843 #endif /* BCM_TRX_SUPPORT */
   3844 #if defined(BCM_TRIUMPH3_SUPPORT)
   3845     if (SOC_IS_TRIUMPH3(unit)) {
   3846         vlan_xlate_entry_t vxent;
   3847         int     rv;
   3848 
   3849         sal_memset(&vxent, 0, sizeof(vxent));
   3850         soc_mem_mac_addr_set(unit, VLAN_XLATEm, (uint32 *)(&vxent),
   3851                        VLAN_MAC__MAC_ADDRf, mac);
   3852         rv = soc_mem_delete(unit, VLAN_XLATEm, MEM_BLOCK_ALL, &vxent);
   3853         if (rv == SOC_E_NOT_FOUND) {
   3854             rv = SOC_E_NONE;
   3855         }
   3856         return rv;
   3857     } else
   3858 #endif  /* BCM_TRIUMPH3_SUPPORT */
   3859     {
   3860 #ifdef BCM_XGS3_SWITCH_SUPPORT
   3861     if (SOC_IS_XGS3_SWITCH(unit)) {
   3862         vlan_mac_entry_t  vment;
   3863         int     rv;
   3864 
   3865         sal_memset(&vment, 0, sizeof(vment));
   3866         soc_VLAN_MACm_mac_addr_set(unit, &vment, MAC_ADDRf, mac);
   3867         rv = soc_mem_delete(unit, VLAN_MACm, MEM_BLOCK_ALL, &vment);
   3868         if (rv == SOC_E_NOT_FOUND) {
   3869             rv = SOC_E_NONE;
   3870         }
   3871         return rv;
   3872     }
   3873 #endif
   3874     }
   3875     return BCM_E_UNAVAIL;
   3876 }
   3877 
   3878 
   3879 int
   3880 bcm_esw_vlan_mac_delete_all(int unit)
   3881 {
   3882 #ifdef BCM_TRX_SUPPORT
   3883     if (SOC_IS_TRX(unit)) {
   3884         if (!soc_feature(unit, soc_feature_vlan_action)
   3885             || !soc_feature(unit, soc_feature_mac_based_vlan)) {            
   3886             return BCM_E_UNAVAIL;
   3887         }
   3888 #if defined(BCM_TRIDENT3_SUPPORT)
   3889         if (SOC_IS_TRIDENT3X(unit)) {
   3890             return _bcm_td3_vlan_mac_delete_all(unit);
   3891         } else
   3892 #endif
   3893         {
   3894         return _bcm_trx_vlan_mac_delete_all(unit);
   3895     }
   3896     }
   3897 #endif /* BCM_TRX_SUPPORT */
   3898 #if defined(BCM_TRIUMPH3_SUPPORT)
   3899     if (SOC_IS_TRIUMPH3(unit)) {
   3900         return soc_mem_clear(unit, VLAN_XLATEm, MEM_BLOCK_ALL, 0);
   3901     } else
   3902 #endif  /* BCM_TRIUMPH3_SUPPORT */
   3903     {
   3904 #ifdef BCM_XGS3_SWITCH_SUPPORT
   3905     if (SOC_IS_XGS3_SWITCH(unit)) {
   3906         return soc_mem_clear(unit, VLAN_MACm, MEM_BLOCK_ALL, 0);
   3907     }
   3908 #endif
   3909     }
   3910     return BCM_E_UNAVAIL;
   3911 }
   3912 
   3913 /*
   3914  * Function:
   3915  *      bcm_esw_vlan_mac_action_add
   3916  * Purpose:
   3917  *     Add an association from MAC address to VLAN actions, which are
   3918  *             used for VLAN tag/s assignment to untagged packets.
   3919  *      
   3920  * Parameters:
   3921  *      unit    - (IN) BCM device number.
   3922  *      mac     - (IN) Mac address. 
   3923  *      action    (IN) Action for outer and inner tag
   3924  * Returns:
   3925  *      BCM_E_XXX
   3926  */
   3927 int
   3928 bcm_esw_vlan_mac_action_add(int unit, bcm_mac_t mac, bcm_vlan_action_set_t *action)
   3929 {
   3930 #if defined(BCM_TRX_SUPPORT)
   3931     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)
   3932         && soc_feature(unit, soc_feature_mac_based_vlan)) {
   3933 #if defined(BCM_TRIDENT3_SUPPORT)
   3934         if (SOC_IS_TRIDENT3X(unit)) {
   3935             return _bcm_td3_vlan_mac_action_add(unit, mac, action);
   3936         } else
   3937 #endif
   3938         {
   3939         return _bcm_trx_vlan_mac_action_add(unit, mac, action);
   3940     }
   3941     }
   3942 #endif /* BCM_TRX_SUPPORT */
   3943     return BCM_E_UNAVAIL;
   3944 }
   3945 
   3946 /*
   3947  * Function:
   3948  *      bcm_esw_vlan_mac_action_get
   3949  * Purpose:
   3950  *    Retrive an association from MAC address to VLAN actions, which
   3951  *    are used for VLAN tag assignment to untagged packets.
   3952  *      
   3953  * Parameters:
   3954  *      unit    - (IN) BCM device number.
   3955  *      mac     - (IN) Mac address. 
   3956  *      action    (OUT) Action for outer and inner tag
   3957  * Returns:
   3958  *      BCM_E_XXX
   3959  */
   3960 int
   3961 bcm_esw_vlan_mac_action_get(int unit, bcm_mac_t mac, bcm_vlan_action_set_t *action)
   3962 {
   3963 #if defined(BCM_TRX_SUPPORT)
   3964     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)
   3965         && soc_feature(unit, soc_feature_mac_based_vlan)) {        
   3966 
   3967         bcm_vlan_action_set_t_init(action);
   3968 #if defined(BCM_TRIDENT3_SUPPORT)
   3969         if (SOC_IS_TRIDENT3X(unit)) {
   3970             return _bcm_td3_vlan_mac_action_get(unit, mac, action);
   3971         } else
   3972 #endif
   3973         {
   3974         return _bcm_trx_vlan_mac_action_get(unit, mac, action);
   3975     }
   3976     }
   3977 #endif /* BCM_TRX_SUPPORT */
   3978     return BCM_E_UNAVAIL;
   3979 }
   3980 
   3981 /*
   3982  * Function:
   3983  *      bcm_esw_vlan_mac_action_delete
   3984  * Purpose:
   3985  *    Remove an association from MAC address to VLAN actions, which
   3986  *    are used for VLAN tag assignment to untagged packets.
   3987  *      
   3988  * Parameters:
   3989  *      unit    - (IN) BCM device number.
   3990  *      mac     - (IN) Mac address. 
   3991  * Returns:
   3992  *      BCM_E_XXX
   3993  */
   3994 int
   3995 bcm_esw_vlan_mac_action_delete(int unit, bcm_mac_t mac)
   3996 {
   3997 #ifdef BCM_TRX_SUPPORT
   3998     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)
   3999         && soc_feature(unit, soc_feature_mac_based_vlan)) {        
   4000 #if defined(BCM_TRIDENT3_SUPPORT)
   4001         if (SOC_IS_TRIDENT3X(unit)) {
   4002             return _bcm_td3_vlan_mac_delete(unit, mac);
   4003         } else
   4004 #endif
   4005         {
   4006         return _bcm_trx_vlan_mac_delete(unit, mac);
   4007     }
   4008     }
   4009 #endif /* BCM_TRX_SUPPORT */
   4010     return BCM_E_UNAVAIL;
   4011 }
   4012 
   4013 /*
   4014  * Function:
   4015  *      bcm_esw_vlan_mac_action_delete_all
   4016  * Purpose:
   4017  *    Remove all MAC addresses to VLAN actions associations.
   4018  *    Mac to VLAN actions are used for VLAN tag assignment to untagged packets.
   4019  *      
   4020  * Parameters:
   4021  *      unit    - (IN) BCM device number.
   4022  * Returns:
   4023  *      BCM_E_XXX
   4024  */
   4025 int
   4026 bcm_esw_vlan_mac_action_delete_all(int unit)
   4027 {
   4028 #ifdef BCM_TRX_SUPPORT
   4029     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)
   4030         && soc_feature(unit, soc_feature_mac_based_vlan)) {        
   4031 #if defined(BCM_TRIDENT3_SUPPORT)
   4032         if (SOC_IS_TRIDENT3X(unit)) {
   4033             return _bcm_td3_vlan_mac_delete_all(unit);
   4034         } else
   4035 #endif
   4036         {
   4037         return _bcm_trx_vlan_mac_delete_all(unit);
   4038     }
   4039     }
   4040 #endif /* BCM_TRX_SUPPORT */
   4041     return BCM_E_UNAVAIL;
   4042 }
   4043 
   4044 /*
   4045  * Function   :
   4046  *      bcm_vlan_mac_action_traverse
   4047  * Description   :
   4048  *      Traverse over vlan mac actions, which are used for VLAN
   4049  *      tag/s assignment to untagged packets.
   4050  * Parameters   :
   4051  *      unit            (IN) BCM unit number
   4052  *      cb              (IN) Call back function
   4053  *      user_data       (IN) User provided data to pass to a call back
   4054  */
   4055 int 
   4056 bcm_esw_vlan_mac_action_traverse(int unit, 
   4057                                  bcm_vlan_mac_action_traverse_cb cb, 
   4058                                  void *user_data)
   4059 {
   4060 #ifdef BCM_TRX_SUPPORT
   4061     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)
   4062         && soc_feature(unit, soc_feature_mac_based_vlan)) {        
   4063 #if defined(BCM_TRIDENT3_SUPPORT)
   4064         if (SOC_IS_TRIDENT3X(unit)) {
   4065             return _bcm_td3_vlan_mac_action_traverse(unit, cb, user_data);
   4066         } else
   4067 #endif
   4068         {
   4069         return _bcm_trx_vlan_mac_action_traverse(unit, cb, user_data);
   4070     }
   4071     }
   4072 #endif /* BCM_TRX_SUPPORT */
   4073     return BCM_E_UNAVAIL;
   4074 }
   4075 
   4076 #ifdef BCM_FIREBOLT_SUPPORT
   4077 #ifdef BCM_WARM_BOOT_SUPPORT 
   4078 STATIC int
   4079 _bcm_fb_vlan_translate_reload(int unit, int xtable)
   4080 {
   4081     soc_mem_t           mem;
   4082     int                 addvid, index_min, index_max, index_count, i, rv;
   4083     uint32              *vtcachep, vtcache;
   4084     vlan_xlate_entry_t  *vtentries, *vtent;
   4085     uint32              ve_valid, ve_port, ve_vid, ve_add;
   4086 
   4087     if (!soc_feature(unit, soc_feature_vlan_translation)) {
   4088         return BCM_E_NONE;
   4089     }
   4090 
   4091     switch (xtable) {
   4092     case BCM_VLAN_XLATE_ING:
   4093         mem = VLAN_XLATEm;
   4094         addvid = 0;
   4095         break;
   4096     case BCM_VLAN_XLATE_EGR:
   4097         mem = EGR_VLAN_XLATEm;
   4098         addvid = -1;
   4099         break;
   4100     case BCM_VLAN_XLATE_DTAG:
   4101         mem = VLAN_XLATEm;
   4102         addvid = 1;
   4103         break;
   4104     default:
   4105         return BCM_E_INTERNAL;
   4106     }
   4107 
   4108     index_min = soc_mem_index_min(unit, mem);
   4109     index_max = soc_mem_index_max(unit, mem);
   4110     index_count = soc_mem_index_count(unit, mem);
   4111 
   4112     soc_mem_lock(unit, mem);
   4113 
   4114     /* get vt cache, allocate if necessary */
   4115     if (mem == EGR_VLAN_XLATEm) {
   4116         vtcachep = vlan_info[unit].egr_trans;
   4117     } else {
   4118         vtcachep = vlan_info[unit].ing_trans;
   4119     }
   4120     if (vtcachep == NULL) {
   4121         vtcachep = sal_alloc(sizeof(*vtcachep) * (index_max+1),
   4122                              "vlan trans cache");
   4123         if (vtcachep == NULL) {
   4124             soc_mem_unlock(unit, mem);
   4125             return BCM_E_MEMORY;
   4126         }
   4127         sal_memset(vtcachep, 0, sizeof(*vtcachep) * (index_max+1));
   4128         if (mem == EGR_VLAN_XLATEm) {
   4129             vlan_info[unit].egr_trans = vtcachep;
   4130         } else {
   4131             vlan_info[unit].ing_trans = vtcachep;
   4132         }
   4133     }
   4134 
   4135     vtentries = soc_cm_salloc(unit, index_count * sizeof(*vtentries),
   4136                               "vlan trans dma");
   4137     if (vtentries == NULL) {
   4138         soc_mem_unlock(unit, mem);
   4139         return BCM_E_MEMORY;
   4140     }
   4141     rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, index_min, index_max,
   4142                             vtentries);
   4143     if (rv < 0) {
   4144         soc_cm_sfree(unit, vtentries);
   4145         sal_free(vtcachep);
   4146         if (mem == EGR_VLAN_XLATEm) {
   4147             vlan_info[unit].egr_trans = NULL;
   4148         } else {
   4149             vlan_info[unit].ing_trans = NULL;
   4150         }
   4151         soc_mem_unlock(unit, mem);
   4152         return rv;
   4153     }
   4154     for (i = 0; i < index_count; i++) {
   4155         vtent = soc_mem_table_idx_to_pointer(unit, mem, vlan_xlate_entry_t *,
   4156                                              vtentries, i);
   4157         vtcache = 0;
   4158         ve_valid = soc_mem_field32_get(unit, mem, vtent, VALIDf);
   4159         if (ve_valid) {
   4160             if (soc_mem_field_valid(unit, mem, KEY_TYPEf) && 
   4161                 (soc_mem_field32_get(unit, mem, vtent, KEY_TYPEf) != 0)) {
   4162                 continue;
   4163             } 
   4164             if (soc_mem_field_valid(unit, mem, ENTRY_TYPEf) && 
   4165                 (soc_mem_field32_get(unit, mem, vtent, ENTRY_TYPEf) != 0)) {
   4166                 continue;
   4167             }
   4168             BCM_VTCACHE_VALID_SET(vtcache, 1);
   4169             if (soc_mem_field_valid(unit, mem, DST_PORTf)) {
   4170                 ve_port = soc_mem_field32_get(unit, mem, vtent, DST_PORTf);
   4171             } else if (soc_mem_field_valid(unit, mem, PORT_NUMf)) {
   4172                 ve_port = soc_mem_field32_get(unit, mem, vtent, PORT_NUMf);
   4173             } else {
   4174                 ve_port = soc_mem_field32_get(unit, mem, vtent, PORTf);
   4175             }
   4176             BCM_VTCACHE_PORT_SET(vtcache, ve_port);
   4177             ve_vid = soc_mem_field32_get(unit, mem, vtent, OLD_VLAN_IDf);
   4178             BCM_VTCACHE_VID_SET(vtcache, ve_vid);
   4179             if (addvid >= 0) {
   4180                 if (soc_mem_field_valid(unit, mem, ADD_VIDf)) {
   4181                     ve_add = soc_mem_field32_get(unit, mem, vtent, ADD_VIDf);
   4182                     BCM_VTCACHE_ADD_SET(vtcache, ve_add);
   4183                 }
   4184             }
   4185         }
   4186         vtcachep[index_min + i] = vtcache;
   4187     }
   4188     soc_cm_sfree(unit, vtentries);
   4189     soc_mem_unlock(unit, mem);
   4190     return BCM_E_NONE;
   4191 }
   4192 #else
   4193 #define _bcm_fb_vlan_translate_reload(unit, xtable)    (BCM_E_NONE)
   4194 #endif /* BCM_WARM_BOOT_SUPPORT */
   4195 #endif /* BCM_FIREBOLT_SUPPORT */
   4196 
   4197 /*
   4198  * Function:
   4199  *      bcm_esw_vlan_translate_get
   4200  * Purpose:
   4201  *      Get vlan translation
   4202  * Parameters:
   4203  *      unit - StrataSwitch PCI device unit number (driver internal).
   4204  *      port - port numebr
   4205  *      old_vid - Old VLAN ID to has translation for
   4206  *      new_vid - New VLAN ID that packet will get
   4207  *      prio    - Priority
   4208  * Returns:
   4209  *      BCM_E_NONE - Translation found, new_vid nad prio will have the values.
   4210  *      BCM_E_NOT_FOUND - Translation does not exist
   4211  *      BCM_E_XXX  - Other error
   4212  * Notes:
   4213  *      None.
   4214  */
   4215 
   4216 int 
   4217 bcm_esw_vlan_translate_get (int unit, bcm_port_t port, bcm_vlan_t old_vid,
   4218                             bcm_vlan_t *new_vid, int *prio)
   4219 {
   4220 
   4221     bcm_module_t        modid;
   4222     bcm_trunk_t         tgid = -1;
   4223     int                 id = -1;
   4224 
   4225 #ifdef BCM_TOMAHAWK3_SUPPORT
   4226     if (SOC_IS_TOMAHAWK3(unit)) {
   4227         return BCM_E_UNAVAIL;
   4228     }
   4229 #endif
   4230 
   4231     CHECK_INIT(unit);
   4232     VLAN_CHK_ID(unit, old_vid);
   4233     if (NULL == new_vid) {
   4234         return BCM_E_PARAM;
   4235     }
   4236     if (NULL == prio) {
   4237         return BCM_E_PARAM;
   4238     }
   4239     
   4240 #ifdef BCM_TRX_SUPPORT
   4241     if (SOC_IS_TRX(unit)) {
   4242         bcm_gport_t gport;
   4243         bcm_vlan_action_set_t action;
   4244 
   4245         if (!soc_feature(unit, soc_feature_vlan_action)) {
   4246             return BCM_E_UNAVAIL;
   4247         }
   4248         if (BCM_GPORT_IS_SET(port)) {
   4249             gport = port;
   4250         } else {
   4251             if (!SOC_PORT_VALID(unit, port)) {
   4252                 return BCM_E_PORT;
   4253             }
   4254             BCM_IF_ERROR_RETURN(
   4255                 bcm_esw_port_gport_get(unit, port, &gport));
   4256         }
   4257         bcm_vlan_action_set_t_init(&action);
   4258 
   4259         BCM_IF_ERROR_RETURN
   4260             (_bcm_trx_vlan_translate_action_get(unit, gport,
   4261                                                bcmVlanTranslateKeyPortOuter,
   4262                                                old_vid, 0, &action));
   4263 
   4264         if (bcmVlanActionReplace == action.ot_outer){
   4265             *new_vid = action.new_outer_vlan;
   4266             *prio = action.priority;
   4267             return BCM_E_NONE;
   4268         }
   4269 
   4270         BCM_IF_ERROR_RETURN
   4271             (_bcm_trx_vlan_translate_action_get(unit, gport, 
   4272                                                bcmVlanTranslateKeyPortInner,
   4273                                                0, old_vid, &action));
   4274         if (bcmVlanActionAdd == action.it_outer) {
   4275             *new_vid = action.new_inner_vlan;
   4276             *prio = action.priority;
   4277             return BCM_E_NONE;
   4278         }
   4279 
   4280         return BCM_E_NOT_FOUND;
   4281     }
   4282 #endif /* BCM_TRX_SUPPORT */
   4283 
   4284     if (BCM_GPORT_IS_SET(port)) {
   4285         BCM_IF_ERROR_RETURN(
   4286             _bcm_esw_gport_resolve(unit, port, &modid, &port, &tgid, &id));
   4287         if (-1 != tgid || -1 != id) {
   4288             return BCM_E_PORT;
   4289         }
   4290     } else {
   4291         if (!SOC_PORT_VALID(unit, port)) { 
   4292             return BCM_E_PORT; 
   4293         }
   4294         BCM_IF_ERROR_RETURN(
   4295             bcm_esw_stk_my_modid_get(unit, &modid));
   4296     }
   4297 
   4298 #ifdef BCM_FIREBOLT_SUPPORT
   4299     if (SOC_IS_FBX(unit)) {
   4300         return _bcm_fb_vlan_translate_get(unit, port, old_vid, new_vid, prio,
   4301                                           BCM_VLAN_XLATE_ING);
   4302     }
   4303 #endif /* BCM_FIREBOLT_SUPPORT */
   4304 
   4305     return BCM_E_UNAVAIL;
   4306 }
   4307 
   4308 
   4309 
   4310 /*
   4311  * Function:
   4312  *      bcm_esw_vlan_translate_add
   4313  * Purpose:
   4314  *      Add vlan translation
   4315  * Parameters:
   4316  *      unit - StrataSwitch PCI device unit number (driver internal).
   4317  *      port - port numebr
   4318  *      old_vid - Old VLAN ID to has translation for
   4319  *      new_vid - New VLAN ID that packet will get
   4320  *      prio    - Priority
   4321  * Returns:
   4322  *      BCM_E_NONE - Translation found, new_vid nad prio will have the values.
   4323  *      BCM_E_NOT_FOUND - Translation does not exist
   4324  *      BCM_E_XXX  - Other error
   4325  * Notes:
   4326  *      None.
   4327  */
   4328 int
   4329 bcm_esw_vlan_translate_add(int unit, int port, bcm_vlan_t old_vid,
   4330                            bcm_vlan_t new_vid, int prio)
   4331 {
   4332     bcm_module_t        modid;
   4333     bcm_trunk_t         tgid = -1;
   4334     int                 id = -1; 
   4335 
   4336 #ifdef BCM_TOMAHAWK3_SUPPORT
   4337     if (SOC_IS_TOMAHAWK3(unit)) {
   4338         return BCM_E_UNAVAIL;
   4339     }
   4340 #endif
   4341 
   4342     CHECK_INIT(unit);
   4343     VLAN_CHK_ID(unit, old_vid);
   4344     VLAN_CHK_ID(unit, new_vid);
   4345 
   4346     /* XGS does not support translation of VLAN ID 0 */
   4347     if (old_vid == 0) {
   4348         return BCM_E_PARAM;
   4349     }
   4350 
   4351     if ((prio != -1) && ((prio & BCM_PRIO_MASK) > BCM_PRIO_MAX)) {
   4352         return BCM_E_PARAM;
   4353     }
   4354 
   4355 #ifdef BCM_TRX_SUPPORT
   4356     if (SOC_IS_TRX(unit)) {
   4357         bcm_vlan_action_set_t action;
   4358         bcm_gport_t gport;
   4359 
   4360         if (!soc_feature(unit, soc_feature_vlan_action)) {
   4361             return BCM_E_UNAVAIL;
   4362         }
   4363         if (BCM_GPORT_IS_SET(port)) {
   4364             gport = port;
   4365         } else {
   4366             if (!SOC_PORT_VALID(unit, port)) { 
   4367                 return BCM_E_PORT; 
   4368             }
   4369             BCM_IF_ERROR_RETURN(
   4370                 bcm_esw_port_gport_get(unit, port, &gport));
   4371         }
   4372 
   4373         /* add an entry for inner-tagged packets */
   4374         bcm_vlan_action_set_t_init(&action);
   4375         action.new_outer_vlan = new_vid;
   4376         action.priority = prio;
   4377         action.it_outer = bcmVlanActionAdd;
   4378         action.it_inner = bcmVlanActionDelete;
   4379         action.it_inner_prio = bcmVlanActionNone;
   4380 
   4381         BCM_IF_ERROR_RETURN
   4382             (_bcm_trx_vlan_translate_action_add(unit, gport, 
   4383                                                bcmVlanTranslateKeyPortInner,
   4384                                                0, old_vid, &action));
   4385 
   4386         /* add an entry for outer-tagged packets */
   4387         bcm_vlan_action_set_t_init(&action);
   4388         action.new_outer_vlan = new_vid;
   4389         action.priority = prio;
   4390         action.ot_outer      = bcmVlanActionReplace;
   4391         action.ot_outer_prio = bcmVlanActionReplace;
   4392         action.dt_outer      = bcmVlanActionReplace;
   4393         action.dt_outer_prio = bcmVlanActionReplace;
   4394 
   4395         BCM_IF_ERROR_RETURN
   4396             (_bcm_trx_vlan_translate_action_add(unit, gport,
   4397                                                bcmVlanTranslateKeyPortOuter,
   4398                                                old_vid, 0, &action));
   4399         return BCM_E_NONE;
   4400     }
   4401 #endif /* BCM_TRX_SUPPORT */
   4402 
   4403     if (BCM_GPORT_IS_SET(port)) {
   4404         BCM_IF_ERROR_RETURN(
   4405             _bcm_esw_gport_resolve(unit, port, &modid, &port, &tgid, &id));
   4406         if (-1 != tgid || -1 != id) {
   4407             return BCM_E_PORT;
   4408         }
   4409     } else {
   4410         if (SOC_IS_RAVEN(unit)) {
   4411            if (port != -1) {
   4412               if (!SOC_PORT_VALID(unit, port)) {
   4413                   return BCM_E_PORT;
   4414               }
   4415            }
   4416         } else {
   4417             if (!SOC_PORT_VALID(unit, port)) {
   4418                 return BCM_E_PORT;
   4419             }
   4420         }
   4421         BCM_IF_ERROR_RETURN(
   4422             bcm_esw_stk_my_modid_get(unit, &modid));
   4423     }
   4424 
   4425 #ifdef BCM_FIREBOLT_SUPPORT
   4426     if (SOC_IS_FBX(unit)) {
   4427         return _bcm_fb_vlan_translate_add(unit, port, old_vid, new_vid, prio,
   4428                                           BCM_VLAN_XLATE_ING);
   4429     }
   4430 #endif
   4431 
   4432     return BCM_E_UNAVAIL;
   4433 }
   4434 
   4435 /*
   4436  * Function:
   4437  *      bcm_esw_vlan_translate_delete
   4438  * Purpose:
   4439  *      Delete vlan translation
   4440  * Parameters:
   4441  *      unit - StrataSwitch PCI device unit number (driver internal).
   4442  *      port - port numebr
   4443  *      old_vid - Old VLAN ID to delete translation for
   4444  * Returns:
   4445  *      BCM_E_NONE - Translation found, new_vid nad prio will have the values.
   4446  *      BCM_E_NOT_FOUND - Translation does not exist
   4447  *      BCM_E_XXX  - Other error
   4448  * Notes:
   4449  *      None.
   4450  */
   4451 
   4452 int
   4453 bcm_esw_vlan_translate_delete(int unit, int port, bcm_vlan_t old_vid)
   4454 {
   4455     bcm_module_t        modid;
   4456     bcm_trunk_t         tgid = -1;
   4457     int                 id = -1;
   4458 
   4459 #ifdef BCM_TOMAHAWK3_SUPPORT
   4460     if (SOC_IS_TOMAHAWK3(unit)) {
   4461         return BCM_E_UNAVAIL;
   4462     }
   4463 #endif
   4464 
   4465     CHECK_INIT(unit);
   4466     VLAN_CHK_ID(unit, old_vid);
   4467 
   4468     /* XGS does not support translation of VLAN ID 0 */
   4469     if (old_vid == 0) {
   4470         return BCM_E_PARAM;
   4471     }
   4472 
   4473 #ifdef BCM_TRX_SUPPORT
   4474     if (SOC_IS_TRX(unit)) {
   4475         bcm_gport_t gport;
   4476         int         rv1, rv2;
   4477 
   4478         rv1 = rv2 = BCM_E_NONE;
   4479         if (!soc_feature(unit, soc_feature_vlan_action)) {
   4480             return BCM_E_UNAVAIL;
   4481         }
   4482         if (BCM_GPORT_IS_SET(port)) {
   4483             gport = port;
   4484         } else {
   4485             if (!SOC_PORT_VALID(unit, port)) { 
   4486                 return BCM_E_PORT; 
   4487             }
   4488             BCM_IF_ERROR_RETURN(
   4489                 bcm_esw_port_gport_get(unit, port, &gport));
   4490         }
   4491         rv1 = _bcm_trx_vlan_translate_action_delete(unit, gport, 
   4492                                                   bcmVlanTranslateKeyPortInner,
   4493                                                   0, old_vid);
   4494         if (BCM_SUCCESS(rv1) || (rv1 == BCM_E_NOT_FOUND)) {
   4495             rv2 = _bcm_trx_vlan_translate_action_delete(unit, gport, 
   4496                                                   bcmVlanTranslateKeyPortOuter,
   4497                                                   old_vid, 0);
   4498         } else {
   4499             return (rv1);
   4500         }
   4501 
   4502         if (BCM_SUCCESS(rv1) && (rv2 == BCM_E_NOT_FOUND)) {
   4503             return (rv1);
   4504         }
   4505         return (rv2);
   4506     }
   4507 #endif /* BCM_TRX_SUPPORT */
   4508 
   4509     if (BCM_GPORT_IS_SET(port)) {
   4510         BCM_IF_ERROR_RETURN(
   4511             _bcm_esw_gport_resolve(unit, port, &modid, &port, &tgid, &id));
   4512         if (-1 != tgid || -1 != id) {
   4513             return BCM_E_PORT;
   4514         }
   4515     } else {
   4516         if (SOC_IS_RAVEN(unit)) {
   4517             if (port != -1) {
   4518                 if (!SOC_PORT_VALID(unit, port)) {
   4519                     return BCM_E_PORT; 
   4520                 }
   4521             }
   4522         } else {
   4523             if (!SOC_PORT_VALID(unit, port)) {
   4524                   return BCM_E_PORT;
   4525             }
   4526         }
   4527         BCM_IF_ERROR_RETURN(
   4528             bcm_esw_stk_my_modid_get(unit, &modid));
   4529     }
   4530 
   4531 #ifdef BCM_FIREBOLT_SUPPORT
   4532     if (SOC_IS_FBX(unit)) {
   4533         return _bcm_fb_vlan_translate_delete(unit, port, old_vid,
   4534                                              BCM_VLAN_XLATE_ING);
   4535     }
   4536 #endif
   4537 
   4538     return BCM_E_UNAVAIL;
   4539 }
   4540 
   4541 
   4542 int
   4543 bcm_esw_vlan_translate_delete_all(int unit)
   4544 {
   4545 #ifdef BCM_TOMAHAWK3_SUPPORT
   4546     if (SOC_IS_TOMAHAWK3(unit)) {
   4547         return BCM_E_UNAVAIL;
   4548     }
   4549 #endif
   4550 
   4551     CHECK_INIT(unit);
   4552 
   4553 #ifdef BCM_TRX_SUPPORT
   4554     if (SOC_IS_TRX(unit)) {
   4555         if (!soc_feature(unit, soc_feature_vlan_action)) {
   4556             return BCM_E_UNAVAIL;
   4557         }
   4558         return _bcm_trx_vlan_translate_action_delete_all(unit);
   4559     }
   4560 #endif /* BCM_TRX_SUPPORT */
   4561 
   4562 #ifdef BCM_FIREBOLT_SUPPORT
   4563     if (SOC_IS_FBX(unit)) {
   4564         int rv;
   4565 
   4566         rv = _bcm_fb_vlan_translate_delete(unit, -1, BCM_VLAN_NONE,
   4567                                              BCM_VLAN_XLATE_ING);
   4568         if (BCM_SUCCESS(rv) || (rv == BCM_E_NOT_FOUND)) {
   4569             return BCM_E_NONE;
   4570         }
   4571 
   4572         return rv;
   4573     }
   4574 #endif
   4575 
   4576     return BCM_E_UNAVAIL;
   4577 }
   4578 
   4579 /*
   4580  * Function   :
   4581  *      bcm_vlan_translate_action_add
   4582  * Description   :
   4583  *      Add an entry to ingress VLAN translation table.
   4584  * Parameters   :
   4585  *      unit            (IN) BCM unit number
   4586  *      port            (IN) Generic port
   4587  *      key_type        (IN) Key Type : bcmVlanTranslateKey*
   4588  *      outer_vlan      (IN) Packet outer VLAN ID
   4589  *      inner_vlan      (IN) Packet inner VLAN ID
   4590  *      action          (IN) Action for outer and inner tag
   4591  */
   4592 int
   4593 bcm_esw_vlan_translate_action_add(int unit,
   4594                                   bcm_gport_t port,
   4595                                   bcm_vlan_translate_key_t key_type,
   4596                                   bcm_vlan_t outer_vlan,
   4597                                   bcm_vlan_t inner_vlan,
   4598                                   bcm_vlan_action_set_t *action)
   4599 {
   4600 #ifdef BCM_TOMAHAWK3_SUPPORT
   4601     if (SOC_IS_TOMAHAWK3(unit)) {
   4602         return BCM_E_UNAVAIL;
   4603     }
   4604 #endif
   4605 
   4606     CHECK_INIT(unit);
   4607 
   4608 #ifdef BCM_TRX_SUPPORT
   4609     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   4610         return _bcm_trx_vlan_translate_action_add(unit, port, 
   4611                                                  key_type, outer_vlan,
   4612                                                  inner_vlan, action);
   4613     }
   4614 #endif /* BCM_TRX_SUPPORT */
   4615 
   4616     return BCM_E_UNAVAIL;
   4617 }
   4618 
   4619 /*
   4620  * Function   :
   4621  *      bcm_vlan_translate_action_get
   4622  * Description   :
   4623  *      Get an entry to ingress VLAN translation table.
   4624  * Parameters   :
   4625  *      unit            (IN) BCM unit number
   4626  *      port            (IN) Generic port
   4627  *      key_type        (IN) Key Type : bcmVlanTranslateKey*
   4628  *      outer_vlan      (IN) Packet outer VLAN ID
   4629  *      inner_vlan      (IN) Packet inner VLAN ID
   4630  *      action          (OUT) Action for outer and inner tag
   4631  */
   4632 int 
   4633 bcm_esw_vlan_translate_action_get (int unit, bcm_gport_t port,
   4634                                    bcm_vlan_translate_key_t key_type,
   4635                                    bcm_vlan_t outer_vlan,
   4636                                    bcm_vlan_t inner_vlan,
   4637                                    bcm_vlan_action_set_t *action)
   4638 {
   4639 #ifdef BCM_TOMAHAWK3_SUPPORT
   4640     if (SOC_IS_TOMAHAWK3(unit)) {
   4641         return BCM_E_UNAVAIL;
   4642     }
   4643 #endif
   4644 
   4645     CHECK_INIT(unit);
   4646 
   4647 #ifdef BCM_TRX_SUPPORT
   4648     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   4649         bcm_vlan_action_set_t_init(action);
   4650         return _bcm_trx_vlan_translate_action_get(unit, port, key_type, 
   4651                                                  outer_vlan, inner_vlan, 
   4652                                                  action);
   4653     }
   4654 #endif /* BCM_TRX_SUPPORT */
   4655 
   4656     return BCM_E_UNAVAIL;
   4657 }
   4658 
   4659 
   4660 /*
   4661  * Function   :
   4662  *      _bcm_trx_vlan_translate_action_traverse_int_cb
   4663  * Description   :
   4664  *      Internal call back function to call user provided call back 
   4665  *      entries in Triumph and call given call back.
   4666  * Parameters   :
   4667  *      unit            (IN) BCM unit number
   4668  *      trvs_info       (IN) Traverse structure that contain all relevant info
   4669  */
   4670 int 
   4671 _bcm_esw_vlan_translate_action_traverse_int_cb(int unit, void *trv_info, 
   4672                                                int *stop)
   4673 {
   4674     _bcm_vlan_translate_traverse_t          *trvs_str;
   4675     _translate_action_traverse_cb_t   *usr_cb_st;
   4676 
   4677     if ((NULL == trv_info) || (NULL == stop)){
   4678         return BCM_E_PARAM;
   4679     }
   4680     trvs_str = (_bcm_vlan_translate_traverse_t *)trv_info;
   4681     usr_cb_st = (_translate_action_traverse_cb_t *)trvs_str->user_cb_st;
   4682 
   4683     *stop = FALSE;
   4684     return usr_cb_st->usr_cb(unit, trvs_str->gport, trvs_str->key_type,
   4685                              trvs_str->outer_vlan, trvs_str->inner_vlan,
   4686                              trvs_str->action, trvs_str->user_data);  
   4687 }
   4688 
   4689 /*
   4690  * Function   :
   4691  *      _bcm_esw_vlan_translate_egress_action_traverse_int_cb
   4692  * Description   :
   4693  *      Internal call back function to call user provided call back 
   4694  *      entries in Triumph and call given call back.
   4695  * Parameters   :
   4696  *      unit            (IN) BCM unit number
   4697  *      trvs_info       (IN) Traverse structure that contain all relevant info
   4698  */
   4699 int 
   4700 _bcm_esw_vlan_translate_egress_action_traverse_int_cb(int unit, void *trv_info,
   4701                                                       int *stop)
   4702 {
   4703     _bcm_vlan_translate_traverse_t              *trvs_str;
   4704     _translate_egress_action_traverse_cb_t      *usr_cb_st;
   4705 
   4706     if ((NULL == trv_info) || (NULL == stop)){
   4707         return BCM_E_PARAM;
   4708     }
   4709     trvs_str = (_bcm_vlan_translate_traverse_t *)trv_info;
   4710     usr_cb_st = (_translate_egress_action_traverse_cb_t *)trvs_str->user_cb_st;
   4711 
   4712     *stop = FALSE;
   4713 
   4714     return usr_cb_st->usr_cb(unit, trvs_str->port_class,
   4715                              trvs_str->outer_vlan, 
   4716                              trvs_str->inner_vlan, 
   4717                              trvs_str->action,
   4718                              trvs_str->user_data);
   4719 }
   4720 
   4721 /*
   4722  * Function   :
   4723  *      _bcm_esw_vlan_translate_action_range_traverse_int_cb
   4724  * Description   :
   4725  *      Internal call back function to call user provided call back 
   4726  *      entries in Triumph and call given call back.
   4727  * Parameters   :
   4728  *      unit            (IN) BCM unit number
   4729  *      trvs_info       (IN) Traverse structure that contain all relevant info
   4730  */
   4731 int 
   4732 _bcm_esw_vlan_translate_action_range_traverse_int_cb(int unit, void *trv_info,
   4733                                                      int *stop)
   4734 {
   4735     _bcm_vlan_translate_traverse_t  *trvs_str;
   4736     _translate_action_range_traverse_cb_t *usr_cb_st;
   4737 
   4738     if ((NULL == trv_info) || (NULL == stop)){
   4739         return BCM_E_PARAM;
   4740     }
   4741     trvs_str = (_bcm_vlan_translate_traverse_t *)trv_info;
   4742     usr_cb_st = (_translate_action_range_traverse_cb_t *)trvs_str->user_cb_st;
   4743 
   4744     *stop = FALSE;
   4745     return usr_cb_st->usr_cb(unit, trvs_str->gport, trvs_str->outer_vlan, 
   4746                              trvs_str->outer_vlan_high, trvs_str->inner_vlan, 
   4747                              trvs_str->inner_vlan_high, trvs_str->action, 
   4748                              trvs_str->user_data);  
   4749 }
   4750 
   4751 /*
   4752  * Function   :
   4753  *      _bcm_esw_vlan_translate_range_traverse_int_cb
   4754  * Description   :
   4755  *      Internal call back function to call user provided call back 
   4756  *      entries and call given call back.
   4757  * Parameters   :
   4758  *      unit            (IN) BCM unit number
   4759  *      trvs_info       (IN) Traverse structure that contain all relevant info
   4760  */
   4761 int 
   4762 _bcm_esw_vlan_translate_range_traverse_int_cb(int unit, void *trv_info,
   4763                                                      int *stop)
   4764 {
   4765     _bcm_vlan_translate_traverse_t  *trvs_str;
   4766     _translate_range_traverse_cb_t *usr_cb_st;
   4767 
   4768     if ((NULL == trv_info) || (NULL == stop)){
   4769         return BCM_E_PARAM;
   4770     }
   4771     trvs_str = (_bcm_vlan_translate_traverse_t *)trv_info;
   4772     usr_cb_st = (_translate_range_traverse_cb_t *)trvs_str->user_cb_st;
   4773 
   4774     *stop = FALSE;
   4775     if ((trvs_str->key_type == bcmVlanTranslateKeyPortOuter) &&
   4776             (trvs_str->action->dt_outer == bcmVlanActionReplace) &&
   4777             (trvs_str->action->dt_inner == bcmVlanActionNone) &&
   4778             (trvs_str->action->ot_outer == bcmVlanActionReplace) &&
   4779             (trvs_str->action->ot_inner == bcmVlanActionNone)) {
   4780         return usr_cb_st->usr_cb(unit, trvs_str->gport, trvs_str->outer_vlan, 
   4781                 trvs_str->outer_vlan_high, 
   4782                 trvs_str->action->new_outer_vlan,
   4783                 trvs_str->action->priority, trvs_str->user_data);  
   4784     } else {
   4785         return BCM_E_NONE;
   4786     }
   4787 }
   4788 
   4789 /*
   4790  * Function   :
   4791  *      _bcm_esw_vlan_translate_traverse_int_cb
   4792  * Description   :
   4793  *      Internal call back function to call user provided call back 
   4794  * Parameters   :
   4795  *      unit            (IN) BCM unit number
   4796  *      trvs_info       (IN) Traverse structure that contain all relevant info
   4797  */
   4798 int 
   4799 _bcm_esw_vlan_translate_traverse_int_cb(int unit, void *trv_info, int *stop)
   4800 {
   4801     _bcm_vlan_translate_traverse_t  *trvs_str;
   4802     _translate_traverse_cb_t        *usr_cb_st;
   4803     bcm_vlan_t                      old_vlan, new_vlan;
   4804 
   4805     if ((NULL == trv_info) || (NULL == stop)){
   4806         return BCM_E_PARAM;
   4807     }
   4808     trvs_str = (_bcm_vlan_translate_traverse_t *)trv_info;
   4809     usr_cb_st = (_translate_traverse_cb_t *)trvs_str->user_cb_st;
   4810     if (BCM_VLAN_INVALID != trvs_str->outer_vlan) {
   4811         old_vlan = trvs_str->outer_vlan;
   4812     } else {
   4813         old_vlan = trvs_str->inner_vlan;
   4814     }
   4815 
   4816     if (BCM_VLAN_INVALID != trvs_str->action->new_outer_vlan) {
   4817         new_vlan = trvs_str->action->new_outer_vlan;
   4818     } else {
   4819         new_vlan = trvs_str->action->new_inner_vlan;
   4820     }
   4821 
   4822     *stop = FALSE;
   4823     return usr_cb_st->usr_cb(unit, trvs_str->gport, old_vlan, new_vlan, 
   4824                              trvs_str->action->priority, trvs_str->user_data); 
   4825 }
   4826 
   4827 
   4828 /*
   4829  * Function   :
   4830  *      _bcm_esw_vlan_translate_egress_traverse_int_cb
   4831  * Description   :
   4832  *      Internal call back function to call user provided call back 
   4833  * Parameters   :
   4834  *      unit            (IN) BCM unit number
   4835  *      trvs_info       (IN) Traverse structure that contain all relevant info
   4836  */
   4837 int 
   4838 _bcm_esw_vlan_translate_egress_traverse_int_cb(int unit, void *trv_info, 
   4839                                                int *stop)
   4840 {
   4841     _bcm_vlan_translate_traverse_t  *trvs_str;
   4842     _translate_egress_traverse_cb_t *usr_cb_st;
   4843     bcm_vlan_t                      old_vlan, new_vlan;
   4844     bcm_gport_t gport = 0;
   4845 
   4846     if ((NULL == trv_info) || (NULL == stop)){
   4847         return BCM_E_PARAM;
   4848     }
   4849     trvs_str = (_bcm_vlan_translate_traverse_t *)trv_info;
   4850     usr_cb_st = (_translate_egress_traverse_cb_t *)trvs_str->user_cb_st;
   4851     if (BCM_VLAN_INVALID != trvs_str->outer_vlan) {
   4852         old_vlan = trvs_str->outer_vlan;
   4853     } else {
   4854         old_vlan = trvs_str->inner_vlan;
   4855     }
   4856 
   4857     if (BCM_VLAN_INVALID != trvs_str->action->new_outer_vlan) {
   4858         new_vlan = trvs_str->action->new_outer_vlan;
   4859     } else {
   4860         new_vlan = trvs_str->action->new_inner_vlan;
   4861     }
   4862 
   4863     *stop = FALSE;
   4864     if (!BCM_GPORT_IS_SET(trvs_str->port_class)) {
   4865     if (bcm_esw_port_gport_get(unit, trvs_str->port_class, &gport) != 
   4866         BCM_E_NONE) {
   4867         return BCM_E_PORT; 
   4868     }
   4869     }
   4870 
   4871     return usr_cb_st->usr_cb(unit, gport, old_vlan, new_vlan, 
   4872                              trvs_str->action->priority, trvs_str->user_data); 
   4873 }
   4874 
   4875 /*
   4876  * Function   :
   4877  *      _bcm_esw_vlan_dtag_traverse_int_cb
   4878  * Description   :
   4879  *      Internal call back function to call user provided call back 
   4880  * Parameters   :
   4881  *      unit            (IN) BCM unit number
   4882  *      trvs_info       (IN) Traverse structure that contain all relevant info
   4883  */
   4884 int 
   4885 _bcm_esw_vlan_dtag_traverse_int_cb(int unit, void *trv_info, int *stop)
   4886 {
   4887     _bcm_vlan_translate_traverse_t  *trvs_str;
   4888     _dtag_traverse_cb_t             *usr_cb_st;
   4889     bcm_vlan_t                      old_vlan, new_vlan;
   4890 
   4891     if ((NULL == trv_info) || (NULL == stop)){
   4892         return BCM_E_PARAM;
   4893     }
   4894     trvs_str = (_bcm_vlan_translate_traverse_t *)trv_info;
   4895     usr_cb_st = (_dtag_traverse_cb_t *)trvs_str->user_cb_st;
   4896     if (BCM_VLAN_INVALID != trvs_str->outer_vlan) {
   4897         old_vlan = trvs_str->outer_vlan;
   4898     } else {
   4899         old_vlan = trvs_str->inner_vlan;
   4900     }
   4901 
   4902     if (BCM_VLAN_INVALID != trvs_str->action->new_outer_vlan) {
   4903         new_vlan = trvs_str->action->new_outer_vlan;
   4904     } else {
   4905         new_vlan = trvs_str->action->new_inner_vlan;
   4906     }
   4907     
   4908     *stop = FALSE;
   4909     return usr_cb_st->usr_cb(unit, trvs_str->gport, old_vlan, new_vlan, 
   4910                              trvs_str->action->priority, trvs_str->user_data); 
   4911 }
   4912 
   4913 /*
   4914  * Function   :
   4915  *      _bcm_esw_vlan_dtag_range_traverse_int_cb
   4916  * Description   :
   4917  *      Internal call back function to call user provided call back 
   4918  *      entries and call given call back.
   4919  * Parameters   :
   4920  *      unit            (IN) BCM unit number
   4921  *      trvs_info       (IN) Traverse structure that contain all relevant info
   4922  */
   4923 int 
   4924 _bcm_esw_vlan_dtag_range_traverse_int_cb(int unit, void *trv_info,
   4925                                                      int *stop)
   4926 {
   4927     _bcm_vlan_translate_traverse_t  *trvs_str;
   4928     _dtag_range_traverse_cb_t *usr_cb_st;
   4929 
   4930     if ((NULL == trv_info) || (NULL == stop)){
   4931         return BCM_E_PARAM;
   4932     }
   4933     trvs_str = (_bcm_vlan_translate_traverse_t *)trv_info;
   4934     usr_cb_st = (_dtag_range_traverse_cb_t *)trvs_str->user_cb_st;
   4935 
   4936     *stop = FALSE;
   4937     if ((trvs_str->key_type == bcmVlanTranslateKeyPortInner) &&
   4938             (trvs_str->action->it_outer == bcmVlanActionAdd) &&
   4939             (trvs_str->action->it_inner == bcmVlanActionNone)) {
   4940         return usr_cb_st->usr_cb(unit, trvs_str->gport, trvs_str->inner_vlan, 
   4941                 trvs_str->inner_vlan_high, 
   4942                 trvs_str->action->new_outer_vlan,
   4943                 trvs_str->action->priority, trvs_str->user_data);  
   4944     } else {
   4945         return BCM_E_NONE;
   4946     }
   4947 }
   4948 
   4949 /*
   4950  * Function:
   4951  *     _bcm_esw_vlan_translate_entry_valid
   4952  * Description:
   4953  *      Check if given Vlan Translate entry is Valid
   4954  * Parameters:
   4955  *      unit         device number
   4956  *      mem          memory to operate on
   4957  *      vent         entry read from HW
   4958  *      valid       (OUT) Entry valid indicator
   4959  * Return:
   4960  *     BCM_E_XXX
   4961  */
   4962 
   4963 STATIC int
   4964 _bcm_esw_vlan_translate_entry_valid(int unit, soc_mem_t mem, uint32 *vent, int *valid)
   4965 {
   4966     uint32      fval = 0;
   4967 
   4968     if (INVALIDm == mem) {
   4969         return BCM_E_MEMORY;
   4970     }
   4971 
   4972     if ((NULL == vent) || (NULL == valid)) {
   4973         return BCM_E_PARAM;
   4974     }
   4975 
   4976 #if defined(BCM_TRX_SUPPORT) || defined (BCM_FIREBOLT_SUPPORT)
   4977     if (SOC_IS_FBX(unit)) {
   4978 
   4979 #ifdef BCM_TRIUMPH3_SUPPORT
   4980         if (SOC_IS_TRIUMPH3(unit) && (mem == VLAN_XLATE_EXTDm)) {
   4981             /* both VALID_0 and VALID_1 fields need to be set */
   4982             if ((!soc_mem_field32_get(unit, mem, vent, VALID_0f)) ||
   4983                 (!soc_mem_field32_get(unit, mem, vent, VALID_1f))) {
   4984                 *valid = FALSE;
   4985                 return (BCM_E_NONE);
   4986             }
   4987 
   4988             /* qualify with key type: odd number */
   4989             fval = soc_mem_field32_get(unit, mem, vent, KEY_TYPE_0f);
   4990             fval &= 0x1;
   4991         } else
   4992 #endif /* BCM_TRIUMPH3_SUPPORT */
   4993 #ifdef BCM_TRIDENT3_SUPPORT
   4994         if (SOC_IS_TRIDENT3X(unit)) {
   4995             if (mem == VLAN_XLATE_1_DOUBLEm ||
   4996                 mem == VLAN_XLATE_2_DOUBLEm ||
   4997                 mem == EGR_VLAN_XLATE_1_DOUBLEm ||
   4998                 mem == EGR_VLAN_XLATE_2_DOUBLEm) {
   4999                 /* both VALID_0 and VALID_1 fields need to be set */
   5000                 if ((!soc_mem_field32_get(unit, mem, vent, BASE_VALID_0f)) ||
   5001                     (!soc_mem_field32_get(unit, mem, vent, BASE_VALID_1f))) {
   5002                     *valid = FALSE;
   5003                 } else {
   5004                     *valid = TRUE;
   5005                 }
   5006             } else if (mem == VLAN_XLATE_1_SINGLEm ||
   5007                 mem == VLAN_XLATE_2_SINGLEm ||
   5008                 mem == EGR_VLAN_XLATE_1_SINGLEm ||
   5009                 mem == EGR_VLAN_XLATE_2_SINGLEm) {
   5010                 fval = soc_mem_field32_get(unit, mem, vent, BASE_VALIDf);
   5011                 *valid = fval ? TRUE : FALSE;
   5012             } else {
   5013                 fval = soc_mem_field32_get(unit, mem, vent, VALIDf);
   5014                 *valid = fval ? TRUE : FALSE;
   5015             }
   5016             return (BCM_E_NONE);
   5017         } else
   5018 #endif /* BCM_TRIDENT3_SUPPORT */
   5019         {
   5020             fval = soc_mem_field32_get(unit, mem, vent, VALIDf);
   5021         }
   5022     } 
   5023 #endif /* BCM_TRX_SUPPORT || BCM_FIREBOLT_SUPPORT */
   5024 
   5025     *valid = fval ? TRUE : FALSE;
   5026 
   5027     return (BCM_E_NONE);
   5028 }
   5029 
   5030 
   5031 /*
   5032  * Function:
   5033  *     _bcm_esw_vlan_translate_entry_parse
   5034  * Description:
   5035  *      Parser function to parse vlan translate entry into truverse structure
   5036  *      will call per chip parser
   5037  * Parameters:
   5038  *      unit         device number
   5039  *      mem          memory to operate on
   5040  *      vent        entry read from HW
   5041  *      trvs_info    Structure to fill 
   5042  * Return:
   5043  *     BCM_E_XXX
   5044  */
   5045 
   5046 STATIC int
   5047 _bcm_esw_vlan_translate_entry_parse(int unit, soc_mem_t mem, uint32 *vent, 
   5048                                     _bcm_vlan_translate_traverse_t *trvs_info)
   5049 {
   5050 #ifdef BCM_TRX_SUPPORT
   5051 
   5052     if (SOC_IS_TRX(unit)) {
   5053         return _bcm_trx_vlan_translate_parse(unit, mem, vent, trvs_info);
   5054     }
   5055 #endif /* BCM_TRX_SUPPORT */
   5056 #ifdef BCM_FIREBOLT_SUPPORT
   5057     if (SOC_IS_FBX(unit)) {
   5058         return _bcm_fb_vlan_translate_parse(unit, mem, vent, trvs_info);
   5059     } 
   5060 #endif /* BCM_FIREBOLT_SUPPORT */
   5061     return (BCM_E_UNAVAIL);
   5062 }
   5063 
   5064 /*
   5065  * Function   :
   5066  *      _bcm_esw_vlan_translate_traverse_mem
   5067  * Description   :
   5068  *      Traverse over all translate entries and call parse function 
   5069  *      based on the unit
   5070  * Parameters   :
   5071  *      unit            (IN) BCM unit number
   5072  *      cb              (IN) Call back function
   5073  *      user_data       (IN) User provided data to pass to a call back
   5074  */
   5075 int 
   5076 _bcm_esw_vlan_translate_traverse_mem(int unit, soc_mem_t mem, 
   5077                                    _bcm_vlan_translate_traverse_t *trvs_info)
   5078 {
   5079     /* Indexes to iterate over memories, chunks and entries */
   5080     int             chnk_idx, ent_idx, chnk_idx_max, mem_idx_max;
   5081     int             buf_size, chunksize, chnk_end;
   5082     /* Buffer to store chunk of L2 table we currently work on */
   5083     uint32          *vt_tbl_chnk;
   5084     uint32          *vent;
   5085     int             valid, stop, rv = BCM_E_NONE;
   5086     
   5087     if (INVALIDm == mem) {
   5088         return BCM_E_MEMORY;
   5089     }
   5090     if (!soc_mem_index_count(unit, mem)) {
   5091         return BCM_E_NONE;
   5092     }
   5093 
   5094     chunksize = soc_property_get(unit, spn_VLANDELETE_CHUNKS,
   5095                                  VLAN_MEM_CHUNKS_DEFAULT);
   5096 
   5097     buf_size = 4 * SOC_MAX_MEM_FIELD_WORDS * chunksize;
   5098     vt_tbl_chnk = soc_cm_salloc(unit, buf_size, "vlan translate traverse");
   5099     if (NULL == vt_tbl_chnk) {
   5100         return BCM_E_MEMORY;
   5101     }
   5102 
   5103     mem_idx_max = soc_mem_index_max(unit, mem);
   5104     for (chnk_idx = soc_mem_index_min(unit, mem); 
   5105          chnk_idx <= mem_idx_max; 
   5106          chnk_idx += chunksize) {
   5107         sal_memset((void *)vt_tbl_chnk, 0, buf_size);
   5108 
   5109         chnk_idx_max = 
   5110             ((chnk_idx + chunksize) <= mem_idx_max) ? 
   5111             chnk_idx + chunksize - 1: mem_idx_max;
   5112 
   5113         rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY,
   5114                                 chnk_idx, chnk_idx_max, vt_tbl_chnk);
   5115         if (SOC_FAILURE(rv)) {
   5116             break;
   5117         }
   5118         chnk_end = (chnk_idx_max - chnk_idx);
   5119         for (ent_idx = 0 ; ent_idx <= chnk_end; ent_idx ++) {
   5120 
   5121             vent = 
   5122                 soc_mem_table_idx_to_pointer(unit, mem, uint32 *, 
   5123                                              vt_tbl_chnk, ent_idx);
   5124             rv = _bcm_esw_vlan_translate_entry_valid(unit, mem, vent, &valid);
   5125             if (BCM_FAILURE(rv)) {
   5126                 break;
   5127             }
   5128             if (!valid) {
   5129                 continue;
   5130             }
   5131             rv = _bcm_esw_vlan_translate_entry_parse(unit, mem, vent, trvs_info);
   5132             if (rv == BCM_E_NOT_FOUND) { /* for entries not exposed to user */ 
   5133                 continue;
   5134             } else if (BCM_FAILURE(rv)) {
   5135                 break;
   5136             }
   5137             rv = trvs_info->int_cb(unit, trvs_info, &stop);
   5138             if (BCM_FAILURE(rv)) {
   5139                 break;
   5140             }
   5141             /* 
   5142                Only get cb function that will use internal traverse should mark
   5143                stop condition as true upon a match 
   5144              */
   5145             if (stop) {     
   5146                 break;
   5147             }
   5148         }
   5149     }
   5150     soc_cm_sfree(unit, vt_tbl_chnk);
   5151     return rv;        
   5152 }
   5153 
   5154 
   5155 
   5156 /*
   5157  * Function   :
   5158  *      bcm_vlan_translate_traverse
   5159  * Description   :
   5160  *      Traverse over all translate entries and call given call back with 
   5161  *      new vid and prio.
   5162  * Parameters   :
   5163  *      unit            (IN) BCM unit number
   5164  *      cb              (IN) Call back function
   5165  *      user_data       (IN) User provided data to pass to a call back
   5166  */
   5167 int
   5168 bcm_esw_vlan_translate_traverse(int unit, bcm_vlan_translate_traverse_cb cb, 
   5169                             void *user_data)
   5170 {
   5171 
   5172         
   5173     _bcm_vlan_translate_traverse_t      trvs_st;
   5174     bcm_vlan_action_set_t               action;
   5175     _translate_traverse_cb_t            usr_cb_st;
   5176     int  rv;
   5177     soc_mem_t                           mem = INVALIDm;
   5178 
   5179 #ifdef BCM_TOMAHAWK3_SUPPORT
   5180     if (SOC_IS_TOMAHAWK3(unit)) {
   5181         return (BCM_E_UNAVAIL);
   5182     }
   5183 #endif
   5184 
   5185     if (!cb) {
   5186         return (BCM_E_PARAM);
   5187     }
   5188 
   5189     sal_memset(&trvs_st, 0, sizeof(_bcm_vlan_translate_traverse_t));
   5190     sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t));
   5191     sal_memset(&usr_cb_st, 0, sizeof(_translate_traverse_cb_t));
   5192 
   5193     usr_cb_st.usr_cb = cb;
   5194 
   5195     trvs_st.user_data = user_data;
   5196     trvs_st.action = &action;
   5197     trvs_st.user_cb_st = (void *)&usr_cb_st;
   5198     trvs_st.int_cb = _bcm_esw_vlan_translate_traverse_int_cb;
   5199 
   5200 #ifdef BCM_TRX_SUPPORT
   5201     if (SOC_IS_TRX(unit)) {
   5202         mem = VLAN_XLATEm;
   5203         if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
   5204             mem = VLAN_XLATE_1_DOUBLEm;
   5205         }
   5206         if (!soc_feature(unit, soc_feature_vlan_action)) {
   5207             return BCM_E_UNAVAIL;
   5208         }
   5209     }
   5210 #endif /* BCM_FIREBOLT_SUPPORT */
   5211 #ifdef BCM_FIREBOLT_SUPPORT
   5212     if (SOC_IS_FBX(unit)) {
   5213         if (!soc_feature(unit, soc_feature_vlan_translation)) {
   5214             return BCM_E_UNAVAIL;
   5215         }
   5216         mem = VLAN_XLATEm;
   5217         if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
   5218             mem = VLAN_XLATE_1_DOUBLEm;
   5219         }
   5220     }
   5221 #endif /* BCM_FIREBOLT_SUPPORT */
   5222     if (INVALIDm == mem) {
   5223         return BCM_E_UNAVAIL;
   5224     }
   5225     rv = _bcm_esw_vlan_translate_traverse_mem(unit, mem, &trvs_st);
   5226 #ifdef BCM_TRIUMPH3_SUPPORT
   5227     if (SOC_IS_TRIUMPH3(unit)) {
   5228         /* for the extended table */
   5229         mem = VLAN_XLATE_EXTDm;
   5230         rv = _bcm_esw_vlan_translate_traverse_mem(unit, mem, &trvs_st);
   5231     }
   5232 #endif
   5233     return rv;
   5234 }
   5235 
   5236 
   5237 /*
   5238  * Function   :
   5239  *      bcm_vlan_translate_egress_traverse
   5240  * Description   :
   5241  *      Traverse over all translate entries and call given call back with 
   5242  *      new vid and prio.
   5243  * Parameters   :
   5244  *      unit            (IN) BCM unit number
   5245  *      cb              (IN) Call back function
   5246  *      user_data       (IN) User provided data to pass to a call back
   5247  */
   5248 int
   5249 bcm_esw_vlan_translate_egress_traverse(int unit, 
   5250                                    bcm_vlan_translate_egress_traverse_cb cb, 
   5251                                    void *user_data)
   5252 {
   5253 
   5254         
   5255     _bcm_vlan_translate_traverse_t      trvs_st;
   5256     bcm_vlan_action_set_t               action;
   5257     _translate_egress_traverse_cb_t     usr_cb_st;
   5258     soc_mem_t                           mem = INVALIDm;
   5259 
   5260 #ifdef BCM_TOMAHAWK3_SUPPORT
   5261     if (SOC_IS_TOMAHAWK3(unit)) {
   5262         return (BCM_E_UNAVAIL);
   5263     }
   5264 #endif
   5265 
   5266     if (!cb) {
   5267         return (BCM_E_PARAM);
   5268     }
   5269 
   5270     sal_memset(&trvs_st, 0, sizeof(_bcm_vlan_translate_traverse_t));
   5271     sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t));
   5272     sal_memset(&usr_cb_st, 0, sizeof(_translate_egress_traverse_cb_t));
   5273 
   5274     usr_cb_st.usr_cb = cb;
   5275 
   5276     trvs_st.user_data = user_data;
   5277     trvs_st.action = &action;
   5278     trvs_st.user_cb_st = (void *)&usr_cb_st;
   5279     trvs_st.int_cb = _bcm_esw_vlan_translate_egress_traverse_int_cb;
   5280 
   5281 
   5282 #ifdef BCM_TRX_SUPPORT
   5283     if (SOC_IS_TRX(unit)) {
   5284         soc_control_t           *sc = SOC_CONTROL(unit);
   5285         
   5286     if (!soc_feature(unit, soc_feature_vlan_action)) {
   5287         return BCM_E_UNAVAIL;
   5288     }
   5289 
   5290         /* If port class is changed system should not allow */
   5291         /* To use this API since it leads to confused outcome */
   5292         if (sc->soc_flags & SOC_F_XLATE_EGR_BLOCKED) {
   5293             return BCM_E_CONFIG;
   5294         }
   5295         mem = EGR_VLAN_XLATEm;
   5296         if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) {
   5297             mem = EGR_VLAN_XLATE_1_DOUBLEm;
   5298         }
   5299     }
   5300 #endif /* BCM_FIREBOLT_SUPPORT */
   5301 #ifdef BCM_FIREBOLT_SUPPORT
   5302     if (SOC_IS_FBX(unit)) {
   5303         if (!soc_feature(unit, soc_feature_vlan_translation)) {
   5304             return BCM_E_UNAVAIL;
   5305         }
   5306         mem = EGR_VLAN_XLATEm;
   5307         if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) {
   5308             mem = EGR_VLAN_XLATE_1_DOUBLEm;
   5309         }
   5310     }
   5311 #endif /* BCM_FIREBOLT_SUPPORT */
   5312 
   5313     if (INVALIDm == mem) {
   5314         return BCM_E_UNAVAIL;
   5315     }
   5316     return _bcm_esw_vlan_translate_traverse_mem(unit, mem, &trvs_st);
   5317 }
   5318 
   5319 /*
   5320  * Function   :
   5321  *      bcm_vlan_translate_egress_traverse
   5322  * Description   :
   5323  *      Traverse over all translate entries and call given call back with 
   5324  *      new vid and prio.
   5325  * Parameters   :
   5326  *      unit            (IN) BCM unit number
   5327  *      cb              (IN) Call back function
   5328  *      user_data       (IN) User provided data to pass to a call back
   5329  */
   5330 int
   5331 bcm_esw_vlan_dtag_traverse(int unit, 
   5332                        bcm_vlan_dtag_traverse_cb cb, 
   5333                        void *user_data)
   5334 {
   5335     _bcm_vlan_translate_traverse_t      trvs_st;
   5336     bcm_vlan_action_set_t               action;
   5337     _dtag_traverse_cb_t                 usr_cb_st;
   5338     soc_mem_t                           mem = INVALIDm;
   5339 
   5340 #ifdef BCM_TOMAHAWK3_SUPPORT
   5341     if (SOC_IS_TOMAHAWK3(unit)) {
   5342         return (BCM_E_UNAVAIL);
   5343     }
   5344 #endif
   5345 
   5346     if (!cb) {
   5347         return (BCM_E_PARAM);
   5348     }
   5349 
   5350     sal_memset(&trvs_st, 0, sizeof(_bcm_vlan_translate_traverse_t));
   5351     sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t));
   5352     sal_memset(&usr_cb_st, 0, sizeof(_dtag_traverse_cb_t));
   5353 
   5354     usr_cb_st.usr_cb = cb;
   5355 
   5356     trvs_st.user_data = user_data;
   5357     trvs_st.action = &action;
   5358     trvs_st.user_cb_st = (void *)&usr_cb_st;
   5359     trvs_st.int_cb = _bcm_esw_vlan_dtag_traverse_int_cb;
   5360 
   5361 #ifdef BCM_TRX_SUPPORT
   5362     if (SOC_IS_TRX(unit)) {
   5363         mem = VLAN_XLATEm;
   5364         if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
   5365             mem = VLAN_XLATE_1_DOUBLEm;
   5366         }
   5367         if (!soc_feature(unit, soc_feature_vlan_action)) {
   5368             return BCM_E_UNAVAIL;
   5369         }
   5370     }
   5371 #endif /* BCM_FIREBOLT_SUPPORT */
   5372 #ifdef BCM_FIREBOLT_SUPPORT
   5373     if (SOC_IS_FBX(unit)) {
   5374         if (!soc_feature(unit, soc_feature_vlan_translation)) {
   5375             return BCM_E_UNAVAIL;
   5376         }
   5377         mem = VLAN_XLATEm;
   5378         if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
   5379             mem = VLAN_XLATE_1_DOUBLEm;
   5380         }
   5381     }
   5382 #endif /* BCM_FIREBOLT_SUPPORT */
   5383 
   5384     if (INVALIDm == mem) {
   5385         return BCM_E_UNAVAIL;
   5386     }
   5387     return _bcm_esw_vlan_translate_traverse_mem(unit, mem, &trvs_st);
   5388 }
   5389 
   5390 /*
   5391  * Function   :
   5392  *      bcm_vlan_translate_action_traverse
   5393  * Description   :
   5394  *      Traverse over all translate entries and call given callback with 
   5395  *      action structure
   5396  * Parameters   :
   5397  *      unit            (IN) BCM unit number
   5398  *      cb              (IN) Call back function
   5399  *      user_data       (IN) User provided data to pass to a call back
   5400  */
   5401 int 
   5402 bcm_esw_vlan_translate_action_traverse(int unit, 
   5403                                    bcm_vlan_translate_action_traverse_cb cb, 
   5404                                    void *user_data)
   5405 {
   5406     _bcm_vlan_translate_traverse_t      trvs_st;
   5407     bcm_vlan_action_set_t               action;
   5408     _translate_action_traverse_cb_t     usr_cb_st;
   5409     int rv = BCM_E_UNAVAIL;
   5410 
   5411 #ifdef BCM_TOMAHAWK3_SUPPORT
   5412     if (SOC_IS_TOMAHAWK3(unit)) {
   5413         return (BCM_E_UNAVAIL);
   5414     }
   5415 #endif
   5416 
   5417     if (!cb) {
   5418         return (BCM_E_PARAM);
   5419     }
   5420 
   5421     sal_memset(&trvs_st, 0, sizeof(_bcm_vlan_translate_traverse_t));
   5422     sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t));
   5423     sal_memset(&usr_cb_st, 0, sizeof(_translate_action_traverse_cb_t));
   5424 
   5425     usr_cb_st.usr_cb = cb;
   5426 
   5427     trvs_st.user_data = user_data;
   5428     trvs_st.action = &action;
   5429     trvs_st.user_cb_st = (void *)&usr_cb_st;
   5430     
   5431 #ifdef BCM_TRX_SUPPORT
   5432     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   5433         soc_mem_t mem = VLAN_XLATEm;
   5434         if (SOC_IS_TRIDENT3X(unit)) {
   5435             mem = VLAN_XLATE_1_DOUBLEm;
   5436         }
   5437         trvs_st.int_cb = _bcm_esw_vlan_translate_action_traverse_int_cb;
   5438         rv = _bcm_esw_vlan_translate_traverse_mem(unit, mem, &trvs_st);
   5439     }
   5440 #endif /* BCM_TRX_SUPPORT */
   5441 
   5442 #ifdef BCM_TRIUMPH3_SUPPORT
   5443     if (SOC_IS_TRIUMPH3(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   5444         trvs_st.int_cb = _bcm_esw_vlan_translate_action_traverse_int_cb;
   5445         /* for the extended table */
   5446         rv = _bcm_esw_vlan_translate_traverse_mem(unit, VLAN_XLATE_EXTDm, 
   5447                                 &trvs_st);
   5448     }
   5449 #endif
   5450 
   5451     return rv;
   5452 }
   5453 
   5454 /*
   5455  * Function   :
   5456  *      bcm_vlan_translate_egress_action_traverse
   5457  * Description   :
   5458  *      Traverse over all translate entries and call given callback with 
   5459  *      action structure
   5460  * Parameters   :
   5461  *      unit            (IN) BCM unit number
   5462  *      cb              (IN) Call back function
   5463  *      user_data       (IN) User provided data to pass to a call back
   5464  */
   5465 int 
   5466 bcm_esw_vlan_translate_egress_action_traverse(int unit, 
   5467                             bcm_vlan_translate_egress_action_traverse_cb cb, 
   5468                             void *user_data)
   5469 {
   5470     _bcm_vlan_translate_traverse_t          trvs_st;
   5471     bcm_vlan_action_set_t                   action;
   5472     _translate_egress_action_traverse_cb_t  usr_cb_st;
   5473 #ifdef BCM_TRX_SUPPORT
   5474     soc_mem_t mem = EGR_VLAN_XLATEm;
   5475 
   5476     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) {
   5477         mem = EGR_VLAN_XLATE_1_DOUBLEm;
   5478     }
   5479 #endif
   5480 #ifdef BCM_TOMAHAWK3_SUPPORT
   5481     if (SOC_IS_TOMAHAWK3(unit)) {
   5482         return (BCM_E_UNAVAIL);
   5483     }
   5484 #endif
   5485 
   5486     if (!cb) {
   5487         return (BCM_E_PARAM);
   5488     }
   5489 
   5490     sal_memset(&trvs_st, 0, sizeof(_bcm_vlan_translate_traverse_t));
   5491     sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t));
   5492     sal_memset(&usr_cb_st, 0, sizeof(_translate_egress_action_traverse_cb_t));
   5493 
   5494     usr_cb_st.usr_cb = cb;
   5495 
   5496     trvs_st.user_data = user_data;
   5497     trvs_st.action = &action;
   5498     trvs_st.user_cb_st = (void *)&usr_cb_st;
   5499     
   5500 #ifdef BCM_TRX_SUPPORT
   5501     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   5502         trvs_st.int_cb = _bcm_esw_vlan_translate_egress_action_traverse_int_cb;
   5503         return _bcm_esw_vlan_translate_traverse_mem(unit, mem, &trvs_st);
   5504     }
   5505 #endif /* BCM_TRX_SUPPORT */
   5506     return BCM_E_UNAVAIL;
   5507 }
   5508 
   5509 
   5510 /*
   5511  * Function:
   5512  *      bcm_vlan_translate_action_delete
   5513  * Purpose:
   5514  *      Delete a vlan translate lookup entry.
   5515  * Parameters:
   5516  *      unit            (IN) BCM unit number
   5517  *      port            (IN) Generic port 
   5518  *      key_type        (IN) Key Type : bcmVlanTranslateKey*
   5519  *      outer_vlan      (IN) Packet outer VLAN ID
   5520  *      inner_vlan      (IN) Packet inner VLAN ID
   5521  */
   5522 int
   5523 bcm_esw_vlan_translate_action_delete(int unit,
   5524                                      bcm_gport_t port,
   5525                                      bcm_vlan_translate_key_t key_type,
   5526                                      bcm_vlan_t outer_vlan,
   5527                                      bcm_vlan_t inner_vlan)
   5528 {
   5529 #ifdef BCM_TOMAHAWK3_SUPPORT
   5530     if (SOC_IS_TOMAHAWK3(unit)) {
   5531         return (BCM_E_UNAVAIL);
   5532     }
   5533 #endif
   5534 
   5535     CHECK_INIT(unit);
   5536 
   5537 #ifdef BCM_TRX_SUPPORT
   5538     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   5539         return _bcm_trx_vlan_translate_action_delete(unit, port, 
   5540                                                     key_type, outer_vlan,
   5541                                                     inner_vlan);
   5542     }
   5543 #endif /* BCM_TRX_SUPPORT */
   5544 
   5545     return BCM_E_UNAVAIL;
   5546 }
   5547 
   5548 int
   5549 bcm_esw_vlan_translate_range_add(int unit, int port, bcm_vlan_t old_vid_low,
   5550                                  bcm_vlan_t old_vid_high, bcm_vlan_t new_vid,
   5551                                  int int_prio)
   5552 {
   5553     bcm_gport_t     gport;
   5554     
   5555     CHECK_INIT(unit);
   5556     VLAN_CHK_ID(unit, old_vid_low);
   5557     VLAN_CHK_ID(unit, old_vid_high);
   5558     VLAN_CHK_ID(unit, new_vid);
   5559     if (old_vid_high < old_vid_low) {
   5560         return BCM_E_PARAM;
   5561     }
   5562 
   5563     if (BCM_GPORT_IS_SET(port)) {
   5564         gport = port;
   5565     } else {
   5566         if (!SOC_PORT_VALID(unit, port)) {
   5567             return BCM_E_PORT;
   5568         }
   5569         BCM_IF_ERROR_RETURN(
   5570             bcm_esw_port_gport_get(unit, port, &gport));
   5571     }
   5572 
   5573     if (soc_feature(unit, soc_feature_vlan_translation_range)) {
   5574 #ifdef BCM_TRX_SUPPORT
   5575         if (SOC_IS_TRX(unit)) {
   5576             bcm_vlan_action_set_t action;
   5577             
   5578             /* add vlan range and translate entry for inner-tagged packets */
   5579             bcm_vlan_action_set_t_init(&action);
   5580             action.new_outer_vlan = new_vid;
   5581             action.priority = int_prio;
   5582             action.it_outer = bcmVlanActionAdd;
   5583             action.it_inner = bcmVlanActionDelete;
   5584             action.it_inner_prio = bcmVlanActionNone;
   5585 
   5586             BCM_IF_ERROR_RETURN
   5587                 (_bcm_trx_vlan_translate_action_range_add(unit, gport,
   5588                                         BCM_VLAN_INVALID, BCM_VLAN_INVALID, 
   5589                                         old_vid_low, old_vid_high, 
   5590                                         &action));
   5591 
   5592             
   5593 
   5594             /* Add vlan translate entry for outer-tagged packets.
   5595              * This translate entry uses the range established above
   5596              * for free on devices which only support one range space
   5597              * between inner and outer tagged packets. */
   5598             bcm_vlan_action_set_t_init(&action);
   5599             action.new_outer_vlan = new_vid;
   5600             action.priority      = int_prio;
   5601             action.ot_outer      = bcmVlanActionReplace;
   5602             action.ot_outer_prio = bcmVlanActionReplace;
   5603             action.dt_outer      = bcmVlanActionReplace;
   5604             action.dt_outer_prio = bcmVlanActionReplace;
   5605 
   5606 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 
   5607             if (soc_feature(unit, soc_feature_vlan_xlate_dtag_range)) {
   5608                 BCM_IF_ERROR_RETURN
   5609                     (_bcm_trx_vlan_translate_action_range_add(unit, gport,
   5610                                         old_vid_low, old_vid_high, 
   5611                                         BCM_VLAN_INVALID, BCM_VLAN_INVALID, 
   5612                                         &action));
   5613             } else
   5614 #endif
   5615             {
   5616                 BCM_IF_ERROR_RETURN
   5617                     (_bcm_trx_vlan_translate_action_add(unit, gport,
   5618                                         bcmVlanTranslateKeyPortOuter,
   5619                                         old_vid_low, BCM_VLAN_INVALID,
   5620                                         &action));
   5621             }
   5622             return BCM_E_NONE;
   5623         }
   5624 #endif /* BCM_TRX_SUPPORT */
   5625     }
   5626 
   5627     return BCM_E_UNAVAIL;
   5628 }
   5629 
   5630 int bcm_esw_vlan_translate_range_get (int unit, bcm_port_t port,
   5631                                       bcm_vlan_t old_vlan_low,
   5632                                       bcm_vlan_t old_vlan_high,
   5633                                       bcm_vlan_t *new_vid, int *prio)
   5634 {
   5635     bcm_gport_t     gport;
   5636 
   5637     CHECK_INIT(unit);
   5638     VLAN_CHK_ID(unit, old_vlan_low);
   5639     VLAN_CHK_ID(unit, old_vlan_high);
   5640 
   5641     if (BCM_GPORT_IS_SET(port)) {
   5642         gport = port;
   5643     } else {
   5644         if (!SOC_PORT_VALID(unit, port)) {
   5645             return BCM_E_PORT;
   5646         }
   5647         BCM_IF_ERROR_RETURN(
   5648             bcm_esw_port_gport_get(unit, port, &gport));
   5649     }
   5650 
   5651     if ((NULL == new_vid) || NULL == prio ){
   5652         return BCM_E_PARAM;
   5653     }
   5654     if (old_vlan_high < old_vlan_low) {
   5655         return BCM_E_PARAM;
   5656     }
   5657 
   5658     if (soc_feature(unit, soc_feature_vlan_translation_range)) {
   5659 #ifdef BCM_TRX_SUPPORT
   5660         if (SOC_IS_TRX(unit)) {
   5661             bcm_vlan_action_set_t action;
   5662             
   5663             bcm_vlan_action_set_t_init(&action);
   5664             BCM_IF_ERROR_RETURN
   5665                 (_bcm_trx_vlan_translate_action_range_get(unit, gport,
   5666                                         old_vlan_low, old_vlan_high, 
   5667                                         BCM_VLAN_INVALID, BCM_VLAN_INVALID,
   5668                                         &action));
   5669             if (BCM_VLAN_INVALID != action.new_outer_vlan) {
   5670                 *new_vid = action.new_outer_vlan;
   5671                 *prio = action.priority;
   5672                 return BCM_E_NONE;
   5673             } 
   5674 
   5675             BCM_IF_ERROR_RETURN
   5676                 (_bcm_trx_vlan_translate_action_range_get(unit, gport,
   5677                                         BCM_VLAN_INVALID, BCM_VLAN_INVALID,
   5678                                         old_vlan_low, old_vlan_high, 
   5679                                         &action));
   5680 
   5681             if (BCM_VLAN_INVALID != action.new_outer_vlan) {
   5682                 *new_vid = action.new_outer_vlan;
   5683                 *prio = action.priority;
   5684                 return BCM_E_NONE;
   5685             }
   5686         
   5687             return BCM_E_NOT_FOUND;
   5688         }
   5689 #endif /* BCM_TRX_SUPPORT */
   5690     }
   5691 
   5692     return BCM_E_UNAVAIL;
   5693 }
   5694 
   5695 
   5696 int
   5697 bcm_esw_vlan_translate_range_delete(int unit, int port,
   5698                                     bcm_vlan_t old_vid_low,
   5699                                     bcm_vlan_t old_vid_high)
   5700 {
   5701     bcm_gport_t gport;
   5702 
   5703     CHECK_INIT(unit);
   5704     VLAN_CHK_ID(unit, old_vid_low);
   5705     VLAN_CHK_ID(unit, old_vid_high);
   5706     if (old_vid_high < old_vid_low) {
   5707         return BCM_E_PARAM;
   5708     }
   5709 
   5710     if (BCM_GPORT_IS_SET(port)) {
   5711         gport = port;
   5712     } else {
   5713         if (!SOC_PORT_VALID(unit, port)) {
   5714             return BCM_E_PORT;
   5715         }
   5716         BCM_IF_ERROR_RETURN(
   5717             bcm_esw_port_gport_get(unit, port, &gport));
   5718     }
   5719 
   5720     if (soc_feature(unit, soc_feature_vlan_translation_range)) {
   5721 #ifdef BCM_TRX_SUPPORT
   5722         if (SOC_IS_TRX(unit)) {
   5723             int rv = BCM_E_NONE;
   5724 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
   5725             if (soc_feature(unit, soc_feature_vlan_xlate_dtag_range)) {
   5726                 /* Delete outer vlan translate entry and range */
   5727                 rv = _bcm_trx_vlan_translate_action_range_delete(unit, gport,
   5728                                         old_vid_low, old_vid_high,
   5729                                         BCM_VLAN_INVALID, BCM_VLAN_INVALID); 
   5730             } else
   5731 #endif
   5732             {
   5733                 /* Delete outer vlan translate entry */
   5734                 rv = _bcm_trx_vlan_translate_action_delete(unit, gport,
   5735                                                bcmVlanTranslateKeyPortOuter,
   5736                                                old_vid_low, BCM_VLAN_INVALID);
   5737             }
   5738 
   5739             /* Delete inner vlan translate entry and range */
   5740             if (BCM_SUCCESS(rv) || (rv == BCM_E_NOT_FOUND) ) {
   5741             BCM_IF_ERROR_RETURN
   5742                 (_bcm_trx_vlan_translate_action_range_delete(unit, gport,
   5743                                         BCM_VLAN_INVALID, BCM_VLAN_INVALID, 
   5744                                         old_vid_low, old_vid_high));
   5745             } else {
   5746                 return (rv);
   5747             }
   5748             
   5749             return (BCM_E_NONE);
   5750         }
   5751 #endif /* BCM_TRX_SUPPORT */
   5752     }
   5753 
   5754     return BCM_E_UNAVAIL;
   5755 }
   5756 
   5757 int
   5758 bcm_esw_vlan_translate_range_delete_all(int unit)
   5759 {
   5760     if (soc_feature(unit, soc_feature_vlan_translation_range)) {
   5761 #ifdef BCM_TRX_SUPPORT
   5762         if (SOC_IS_TRX(unit)) {
   5763             return _bcm_trx_vlan_translate_action_range_delete_all(unit);
   5764         }
   5765 #endif /* BCM_TRX_SUPPORT */
   5766     }
   5767 
   5768     return BCM_E_UNAVAIL;
   5769 }
   5770 
   5771 int 
   5772 bcm_esw_vlan_dtag_range_add(int unit, int port,
   5773                             bcm_vlan_t old_vid_low, 
   5774                             bcm_vlan_t old_vid_high,
   5775                             bcm_vlan_t new_vid, int int_prio)
   5776 {
   5777     bcm_gport_t gport;
   5778 
   5779     CHECK_INIT(unit);
   5780     VLAN_CHK_ID(unit, old_vid_low);
   5781     VLAN_CHK_ID(unit, old_vid_high);
   5782     VLAN_CHK_ID(unit, new_vid);
   5783     if (old_vid_high < old_vid_low) {
   5784         return BCM_E_PARAM;
   5785     }
   5786     if ((int_prio < BCM_PRIO_MIN) || (int_prio > BCM_PRIO_MAX)) {
   5787         return BCM_E_PARAM;
   5788     }
   5789 
   5790     if (BCM_GPORT_IS_SET(port)) {
   5791         gport = port;
   5792     } else {
   5793         if (!SOC_PORT_VALID(unit, port)) {
   5794             return BCM_E_PORT;
   5795         }
   5796         BCM_IF_ERROR_RETURN(
   5797             bcm_esw_port_gport_get(unit, port, &gport));
   5798     }
   5799 
   5800     if (soc_feature(unit, soc_feature_vlan_translation_range)) {
   5801 #ifdef BCM_TRX_SUPPORT
   5802         if (SOC_IS_TRX(unit)) {
   5803             bcm_vlan_action_set_t action;
   5804 
   5805             bcm_vlan_action_set_t_init(&action);
   5806             action.new_outer_vlan = new_vid;
   5807             action.priority = int_prio;
   5808             /* For inner tagged packets, set the outer tag action and outer
   5809              * packet prio action to ADD.
   5810              * For all other packet types, the action is initialized to NONE.
   5811              */
   5812             action.it_outer = bcmVlanActionAdd;
   5813             if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   5814                 action.it_outer_pkt_prio = bcmVlanActionAdd;
   5815             } else {
   5816                 action.it_outer_pkt_prio = bcmVlanActionNone;
   5817             }
   5818             return _bcm_trx_vlan_translate_action_range_add(unit, gport,
   5819                                           BCM_VLAN_INVALID, BCM_VLAN_INVALID,
   5820                                           old_vid_low, old_vid_high,
   5821                                           &action);
   5822         }
   5823 #endif /* BCM_TRX_SUPPORT */
   5824     }
   5825 
   5826     return BCM_E_UNAVAIL;
   5827 }
   5828 
   5829 
   5830 int 
   5831 bcm_esw_vlan_dtag_range_get (int unit, bcm_port_t port,
   5832                              bcm_vlan_t old_vid_low,
   5833                              bcm_vlan_t old_vid_high,
   5834                              bcm_vlan_t *new_vid,
   5835                              int *prio)
   5836 {
   5837     bcm_gport_t     gport;
   5838 
   5839     CHECK_INIT(unit);
   5840     VLAN_CHK_ID(unit, old_vid_low);
   5841     VLAN_CHK_ID(unit, old_vid_high);
   5842     
   5843     if ((NULL == new_vid) || NULL == prio ){
   5844         return BCM_E_PARAM;
   5845     }
   5846     if (old_vid_high < old_vid_low) {
   5847         return BCM_E_PARAM;
   5848     }
   5849     if (BCM_GPORT_IS_SET(port)) {
   5850         gport = port;
   5851     } else {
   5852         if (!SOC_PORT_VALID(unit, port)) {
   5853             return BCM_E_PORT;
   5854         }
   5855         BCM_IF_ERROR_RETURN(
   5856             bcm_esw_port_gport_get(unit, port, &gport));
   5857     }
   5858 
   5859     if (soc_feature(unit, soc_feature_vlan_translation_range)) {
   5860 #ifdef BCM_TRX_SUPPORT
   5861         if (SOC_IS_TRX(unit)) {
   5862             bcm_vlan_action_set_t action;
   5863 
   5864             bcm_vlan_action_set_t_init(&action);
   5865             BCM_IF_ERROR_RETURN
   5866                 (_bcm_trx_vlan_translate_action_range_get(unit, gport,
   5867                                         BCM_VLAN_INVALID, BCM_VLAN_INVALID,
   5868                                         old_vid_low, old_vid_high, 
   5869                                         &action));
   5870             if (BCM_VLAN_INVALID != action.new_outer_vlan) {
   5871                 *new_vid = action.new_outer_vlan;
   5872                 *prio = action.priority;
   5873                 return BCM_E_NONE;
   5874             }
   5875 
   5876             return BCM_E_NOT_FOUND;
   5877         }
   5878 #endif /* BCM_TRX_SUPPORT */
   5879     }
   5880 
   5881     return BCM_E_UNAVAIL;
   5882 }
   5883 
   5884 
   5885 int 
   5886 bcm_esw_vlan_dtag_range_delete(int unit, int port, 
   5887                                bcm_vlan_t old_vid_low,
   5888                                bcm_vlan_t old_vid_high)
   5889 {
   5890     bcm_gport_t     gport;
   5891 
   5892     CHECK_INIT(unit);
   5893     VLAN_CHK_ID(unit, old_vid_low);
   5894     VLAN_CHK_ID(unit, old_vid_high);
   5895     if (old_vid_high < old_vid_low) {
   5896         return BCM_E_PARAM;
   5897     }
   5898     if (BCM_GPORT_IS_SET(port)) {
   5899         gport = port;
   5900     } else {
   5901         if (!SOC_PORT_VALID(unit, port)) {
   5902             return BCM_E_PORT;
   5903         }
   5904         BCM_IF_ERROR_RETURN(
   5905             bcm_esw_port_gport_get(unit, port, &gport));
   5906     }
   5907 
   5908     if (soc_feature(unit, soc_feature_vlan_translation_range)) {
   5909 #ifdef BCM_TRX_SUPPORT
   5910         if (SOC_IS_TRX(unit)) {
   5911             return _bcm_trx_vlan_translate_action_range_delete(unit, gport,
   5912                                           BCM_VLAN_INVALID, BCM_VLAN_INVALID,
   5913                                           old_vid_low, old_vid_high);
   5914         }
   5915 #endif /* BCM_TRX_SUPPORT */
   5916     }
   5917 
   5918     return BCM_E_UNAVAIL;
   5919 }
   5920 
   5921 int 
   5922 bcm_esw_vlan_dtag_range_delete_all(int unit)
   5923 {
   5924     if (soc_feature(unit, soc_feature_vlan_translation_range)) {
   5925 #ifdef BCM_TRX_SUPPORT
   5926         if (SOC_IS_TRX(unit)) {
   5927             return _bcm_trx_vlan_translate_action_range_delete_all(unit);
   5928         }
   5929 #endif /* BCM_TRX_SUPPORT */
   5930     }
   5931 
   5932     return BCM_E_UNAVAIL;
   5933 }
   5934 
   5935 /*
   5936  * Function :
   5937  *      bcm_vlan_translate_action_range_add
   5938  * Description :
   5939  *   Add an entry to the VLAN Translation table, which assigns
   5940  *   VLAN actions for packets matching within the VLAN range(s).
   5941  * Parameters :
   5942  *      unit            (IN) BCM unit number
   5943  *      port            (IN) Ingress gport (generic port)
   5944  *      outer_vlan_low  (IN) Outer VLAN ID Low
   5945  *      outer_vlan_high (IN) Outer VLAN ID High
   5946  *      inner_vlan_low  (IN) Inner VLAN ID Low
   5947  *      inner_vlan_high (IN) Inner VLAN ID High
   5948  *      action          (IN) Action for outer and inner tag
   5949  *
   5950  * Notes :
   5951  *   For translation of double-tagged packets, specify a valid
   5952  *   VLAN ID value for outer_vlan_low/high and inner_vlan_low/high.
   5953  *   For translation of single outer-tagged packets, specify a
   5954  *   valid VLAN ID for outer_vlan_low/high and BCM_VLAN_INVALID
   5955  *   for inner_vlan_low/high. For translation of single inner-tagged
   5956  *   packets, specify a valid VLAN ID for inner_vlan_low/high and
   5957  *   BCM_VLAN_INVALID for outer_vlan_low/high.
   5958  */
   5959 
   5960 int
   5961 bcm_esw_vlan_translate_action_range_add(int unit, bcm_gport_t port,
   5962                                         bcm_vlan_t outer_vlan_low,
   5963                                         bcm_vlan_t outer_vlan_high,
   5964                                         bcm_vlan_t inner_vlan_low,
   5965                                         bcm_vlan_t inner_vlan_high,
   5966                                         bcm_vlan_action_set_t *action)
   5967 {
   5968 #ifdef BCM_TOMAHAWK3_SUPPORT
   5969     if (SOC_IS_TOMAHAWK3(unit)) {
   5970         return BCM_E_UNAVAIL;
   5971     }
   5972 #endif
   5973 
   5974     CHECK_INIT(unit);
   5975     /* BCM_VLAN_INVALID is valid input for this API */
   5976     if (BCM_VLAN_INVALID != outer_vlan_low)
   5977         VLAN_CHK_ID(unit, outer_vlan_low);
   5978     if (BCM_VLAN_INVALID != outer_vlan_high)
   5979         VLAN_CHK_ID(unit, outer_vlan_high);
   5980     if (BCM_VLAN_INVALID != inner_vlan_low)
   5981         VLAN_CHK_ID(unit, inner_vlan_low);
   5982     if (BCM_VLAN_INVALID != inner_vlan_high)
   5983         VLAN_CHK_ID(unit, inner_vlan_high);
   5984     if (NULL == action)
   5985         return BCM_E_PARAM;
   5986     
   5987     if (port == BCM_GPORT_INVALID)
   5988         return BCM_E_PORT;
   5989     
   5990 #ifdef BCM_TRX_SUPPORT
   5991     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   5992         return _bcm_trx_vlan_translate_action_range_add(unit, port,
   5993                                              outer_vlan_low, outer_vlan_high,
   5994                                              inner_vlan_low, inner_vlan_high, 
   5995                                              action);
   5996     }
   5997 #endif /* BCM_TRX_SUPPORT */
   5998     return BCM_E_UNAVAIL;
   5999 }
   6000 
   6001 
   6002 /*
   6003  * Function :
   6004  *      bcm_esw_vlan_translate_action_range_get
   6005  * Description :
   6006  *   Get an entry to the VLAN Translation table, which assigns
   6007  *   VLAN actions for packets matching within the VLAN range(s).
   6008  * Parameters :
   6009  *      unit            (IN) BCM unit number
   6010  *      port            (IN) Ingress gport (generic port)
   6011  *      outer_vlan_low  (IN) Outer VLAN ID Low
   6012  *      outer_vlan_high (IN) Outer VLAN ID High
   6013  *      inner_vlan_low  (IN) Inner VLAN ID Low
   6014  *      inner_vlan_high (IN) Inner VLAN ID High
   6015  *      action          (OUT) Action for outer and inner tag
   6016  *
   6017  * Notes :
   6018  *   For translation of double-tagged packets, specify a valid
   6019  *   VLAN ID value for outer_vlan_low/high and inner_vlan_low/high.
   6020  *   For translation of single outer-tagged packets, specify a
   6021  *   valid VLAN ID for outer_vlan_low/high and BCM_VLAN_INVALID
   6022  *   for inner_vlan_low/high. For translation of single inner-tagged
   6023  *   packets, specify a valid VLAN ID for inner_vlan_low/high and
   6024  *   BCM_VLAN_INVALID for outer_vlan_low/high.
   6025  */
   6026 int 
   6027 bcm_esw_vlan_translate_action_range_get (int unit, bcm_gport_t port,
   6028                                          bcm_vlan_t outer_vlan_low,
   6029                                          bcm_vlan_t outer_vlan_high,
   6030                                          bcm_vlan_t inner_vlan_low,
   6031                                          bcm_vlan_t inner_vlan_high,
   6032                                          bcm_vlan_action_set_t *action)
   6033 {
   6034 #ifdef BCM_TOMAHAWK3_SUPPORT
   6035     if (SOC_IS_TOMAHAWK3(unit)) {
   6036         return BCM_E_UNAVAIL;
   6037     }
   6038 #endif
   6039 
   6040     CHECK_INIT(unit);
   6041     /* BCM_VLAN_INVALID is valid input for this API */
   6042     if (BCM_VLAN_INVALID != outer_vlan_low)
   6043         VLAN_CHK_ID(unit, outer_vlan_low);
   6044     if (BCM_VLAN_INVALID != outer_vlan_high)
   6045         VLAN_CHK_ID(unit, outer_vlan_high);
   6046     if (BCM_VLAN_INVALID != inner_vlan_low)
   6047         VLAN_CHK_ID(unit, inner_vlan_low);
   6048     if (BCM_VLAN_INVALID != inner_vlan_high)
   6049         VLAN_CHK_ID(unit, inner_vlan_high);
   6050     if (NULL == action)
   6051         return BCM_E_PARAM;
   6052     
   6053     if (port == BCM_GPORT_INVALID)
   6054         return BCM_E_PORT;
   6055         
   6056 #ifdef BCM_TRX_SUPPORT
   6057     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   6058         bcm_vlan_action_set_t_init(action);
   6059         return _bcm_trx_vlan_translate_action_range_get(unit, port,
   6060                                              outer_vlan_low, outer_vlan_high,
   6061                                              inner_vlan_low, inner_vlan_high, 
   6062                                              action);
   6063     }
   6064 #endif /* BCM_TRX_SUPPORT */
   6065     return BCM_E_UNAVAIL;
   6066 }
   6067 
   6068 /*
   6069  * Function :
   6070  *      bcm_vlan_translate_action_range_delete
   6071  * Description :
   6072  *   Delete an entry from the VLAN Translation table for the 
   6073  *   specified VLAN range(s).
   6074  * Parameters :
   6075  *      unit            (IN) BCM unit number
   6076  *      port            (IN) Ingress gport (generic port)
   6077  *      outer_vlan_low  (IN) Outer VLAN ID Low
   6078  *      outer_vlan_high (IN) Outer VLAN ID High
   6079  *      inner_vlan_low  (IN) Inner VLAN ID Low
   6080  *      inner_vlan_high (IN) Inner VLAN ID High
   6081  *
   6082  * Notes :
   6083  *   For translation of double-tagged packets, specify a valid
   6084  *   VLAN ID value for outer_vlan_low/high and inner_vlan_low/high.
   6085  *   For translation of single outer-tagged packets, specify a
   6086  *   valid VLAN ID for outer_vlan_low/high and BCM_VLAN_INVALID
   6087  *   for inner_vlan_low/high. For translation of single inner-tagged
   6088  *   packets, specify a valid VLAN ID for inner_vlan_low/high and
   6089  *   BCM_VLAN_INVALID for outer_vlan_low/high.
   6090  */
   6091 
   6092 int
   6093 bcm_esw_vlan_translate_action_range_delete(int unit, bcm_gport_t port,
   6094                                            bcm_vlan_t outer_vlan_low,
   6095                                            bcm_vlan_t outer_vlan_high,
   6096                                            bcm_vlan_t inner_vlan_low,
   6097                                            bcm_vlan_t inner_vlan_high)
   6098 {
   6099 #ifdef BCM_TOMAHAWK3_SUPPORT
   6100     if (SOC_IS_TOMAHAWK3(unit)) {
   6101         return BCM_E_UNAVAIL;
   6102     }
   6103 #endif
   6104 
   6105     CHECK_INIT(unit);
   6106     /* BCM_VLAN_INVALID is valid input for this API */
   6107     if (BCM_VLAN_INVALID != outer_vlan_low)
   6108         VLAN_CHK_ID(unit, outer_vlan_low);
   6109     if (BCM_VLAN_INVALID != outer_vlan_high)
   6110         VLAN_CHK_ID(unit, outer_vlan_high);
   6111     if (BCM_VLAN_INVALID != inner_vlan_low)
   6112         VLAN_CHK_ID(unit, inner_vlan_low);
   6113     if (BCM_VLAN_INVALID != inner_vlan_high)
   6114         VLAN_CHK_ID(unit, inner_vlan_high);
   6115     
   6116     if (port == BCM_GPORT_INVALID)
   6117         return BCM_E_PORT;
   6118 
   6119 #ifdef BCM_TRX_SUPPORT
   6120     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   6121         return _bcm_trx_vlan_translate_action_range_delete(unit, port,
   6122                                              outer_vlan_low, outer_vlan_high,
   6123                                              inner_vlan_low, inner_vlan_high);
   6124     }
   6125 #endif /* BCM_TRX_SUPPORT */
   6126     return BCM_E_UNAVAIL;
   6127 }
   6128 
   6129 /*
   6130  * Function :
   6131  *      bcm_vlan_translate_action_range_delete_all
   6132  * Description :
   6133  *     Delete all VLAN range entries from the VLAN Translation table.
   6134  * Parameters :
   6135  *      unit            (IN) BCM unit number
   6136  */
   6137 
   6138 int
   6139 bcm_esw_vlan_translate_action_range_delete_all(int unit)
   6140 {
   6141 #ifdef BCM_TOMAHAWK3_SUPPORT
   6142     if (SOC_IS_TOMAHAWK3(unit)) {
   6143         return BCM_E_UNAVAIL;
   6144     }
   6145 #endif
   6146 
   6147     CHECK_INIT(unit);
   6148 
   6149 #ifdef BCM_TRX_SUPPORT
   6150     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   6151         return _bcm_trx_vlan_translate_action_range_delete_all(unit);
   6152     }
   6153 #endif /* BCM_TRX_SUPPORT */
   6154     return BCM_E_UNAVAIL;
   6155 }
   6156 
   6157 
   6158 /*
   6159  * Function :
   6160  *      bcm_vlan_translate_action_range_traverse
   6161  * Description :
   6162  *   Traverses over VLAN Translation table and call provided callback 
   6163  *   with valid entries.
   6164  * Parameters :
   6165  *      unit            (IN) BCM unit number
   6166  *      cb              (IN) User callback function
   6167  *      user_data       (IN) Pointer to user specific data
   6168  * Return:
   6169  *
   6170  *      BCM_E_XXX
   6171  */
   6172 int 
   6173 bcm_esw_vlan_translate_action_range_traverse(int unit,
   6174     bcm_vlan_translate_action_range_traverse_cb cb, void *user_data)
   6175 {
   6176     _bcm_vlan_translate_traverse_t          trvs_st;
   6177     bcm_vlan_action_set_t                   action;
   6178     _translate_action_range_traverse_cb_t   usr_cb_st;
   6179     
   6180     if (!soc_feature(unit, soc_feature_vlan_translation_range)) {
   6181         return BCM_E_UNAVAIL;
   6182     }
   6183     if (!cb) {
   6184         return (BCM_E_PARAM);
   6185     }
   6186 
   6187     sal_memset(&trvs_st, 0, sizeof(_bcm_vlan_translate_traverse_t));
   6188     sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t));
   6189     sal_memset(&usr_cb_st, 0, sizeof(_translate_action_range_traverse_cb_t));
   6190 
   6191     usr_cb_st.usr_cb = cb;
   6192 
   6193     trvs_st.user_data = user_data;
   6194     trvs_st.action = &action;
   6195     trvs_st.user_cb_st = (void *)&usr_cb_st;
   6196     trvs_st.int_cb = _bcm_esw_vlan_translate_action_range_traverse_int_cb;
   6197 
   6198 #if defined(BCM_TRX_SUPPORT)
   6199     if (SOC_IS_TRX(unit)) {
   6200         return _bcm_trx_vlan_translate_action_range_traverse(unit, &trvs_st);
   6201     }
   6202 #endif /* BCM_TRX_SUPPORT */
   6203 
   6204     return BCM_E_UNAVAIL;
   6205 }
   6206 
   6207 
   6208 /*
   6209  * Function :
   6210  *      bcm_vlan_translate_range_traverse
   6211  * Description :
   6212  *   Traverses over VLAN translate table and call provided callback 
   6213  *   with valid entries.
   6214  * Parameters :
   6215  *      unit            (IN) BCM unit number
   6216  *      cb              (IN) User callback function
   6217  *      user_data       (IN) Pointer to user specific data
   6218  * Return:
   6219  *
   6220  *      BCM_E_XXX
   6221  */
   6222 int 
   6223 bcm_esw_vlan_translate_range_traverse(int unit, 
   6224                                   bcm_vlan_translate_range_traverse_cb cb,
   6225                                   void *user_data)
   6226 {
   6227 
   6228     _bcm_vlan_translate_traverse_t          trvs_st;
   6229     bcm_vlan_action_set_t                   action;
   6230     _translate_range_traverse_cb_t          usr_cb_st;
   6231     
   6232     if (!soc_feature(unit, soc_feature_vlan_translation_range)) {
   6233         return BCM_E_UNAVAIL;
   6234     }
   6235     if (!cb) {
   6236         return (BCM_E_PARAM);
   6237     }
   6238 
   6239     sal_memset(&trvs_st, 0, sizeof(_bcm_vlan_translate_traverse_t));
   6240     sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t));
   6241     sal_memset(&usr_cb_st, 0, sizeof(_translate_range_traverse_cb_t));
   6242 
   6243     usr_cb_st.usr_cb = cb;
   6244 
   6245     trvs_st.user_data = user_data;
   6246     trvs_st.action = &action;
   6247     trvs_st.user_cb_st = (void *)&usr_cb_st;
   6248     
   6249 
   6250 #if defined(BCM_TRX_SUPPORT)
   6251     if (SOC_IS_TRX(unit)) {
   6252         trvs_st.int_cb = _bcm_esw_vlan_translate_range_traverse_int_cb;  
   6253         return _bcm_trx_vlan_translate_action_range_traverse(unit, &trvs_st);
   6254     }
   6255 #endif /* BCM_TRX_SUPPORT */
   6256 
   6257     return BCM_E_UNAVAIL;
   6258 }
   6259 
   6260 /*
   6261  * Function :
   6262  *      bcm_vlan_dtag_range_traverse
   6263  * Description :
   6264  *   Traverses over VLAN double tagging table and call provided callback 
   6265  *   with valid entries.
   6266  * Parameters :
   6267  *      unit            (IN) BCM unit number
   6268  *      cb              (IN) User callback function
   6269  *      user_data       (IN) Pointer to user specific data
   6270  * Return:
   6271  *
   6272  *      BCM_E_XXX
   6273  */
   6274 int 
   6275 bcm_esw_vlan_dtag_range_traverse(int unit, bcm_vlan_dtag_range_traverse_cb cb,
   6276                              void *user_data)
   6277 {
   6278 
   6279     _bcm_vlan_translate_traverse_t          trvs_st;
   6280     bcm_vlan_action_set_t                   action;
   6281     _dtag_range_traverse_cb_t               usr_cb_st;
   6282     
   6283     if (!soc_feature(unit, soc_feature_vlan_translation_range)) {
   6284         return BCM_E_UNAVAIL;
   6285     }
   6286     if (!cb) {
   6287         return (BCM_E_PARAM);
   6288     }
   6289 
   6290     sal_memset(&trvs_st, 0, sizeof(_bcm_vlan_translate_traverse_t));
   6291     sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t));
   6292     sal_memset(&usr_cb_st, 0, sizeof(_dtag_range_traverse_cb_t));
   6293 
   6294     usr_cb_st.usr_cb = cb;
   6295 
   6296     trvs_st.user_data = user_data;
   6297     trvs_st.action = &action;
   6298     trvs_st.user_cb_st = (void *)&usr_cb_st;
   6299     
   6300 #if defined(BCM_TRX_SUPPORT)
   6301     trvs_st.int_cb = _bcm_esw_vlan_dtag_range_traverse_int_cb;  
   6302     if (SOC_IS_TRX(unit)) {
   6303         return _bcm_trx_vlan_translate_action_range_traverse(unit, &trvs_st);
   6304     }
   6305 #endif /* BCM_TRX_SUPPORT */
   6306     
   6307     return BCM_E_UNAVAIL;
   6308 }
   6309 
   6310 
   6311 int
   6312 bcm_esw_vlan_translate_egress_add(int unit, int port, bcm_vlan_t old_vid,
   6313                                   bcm_vlan_t new_vid, int prio)
   6314 {
   6315 
   6316     bcm_module_t        modid = -1;
   6317     bcm_trunk_t         tgid = -1;
   6318     int                 id = -1;
   6319 
   6320 #ifdef BCM_TOMAHAWK3_SUPPORT
   6321     if (SOC_IS_TOMAHAWK3(unit)) {
   6322         return BCM_E_UNAVAIL;
   6323     }
   6324 #endif
   6325 
   6326     CHECK_INIT(unit);
   6327     VLAN_CHK_ID(unit, old_vid);
   6328     VLAN_CHK_ID(unit, new_vid);
   6329 
   6330     /* XGS does not support translation of VLAN ID 0 */
   6331     if (old_vid == 0) {
   6332         return BCM_E_PARAM;
   6333     }
   6334 
   6335     if (BCM_GPORT_IS_SET(port)) {
   6336         if (!BCM_GPORT_IS_TUNNEL(port)) {
   6337             BCM_IF_ERROR_RETURN(
   6338                 _bcm_esw_gport_resolve(unit, port, &modid, &port, &tgid, &id));
   6339         }
   6340         if ((-1 != tgid || -1 != id) && !BCM_GPORT_IS_TUNNEL(port)) {
   6341             return BCM_E_PORT;
   6342         }
   6343     } else {
   6344         if (SOC_IS_RAVEN(unit)) {
   6345             if (port != -1) {
   6346                 if (!SOC_PORT_VALID(unit, port)) {
   6347                     return BCM_E_PORT; 
   6348                 }
   6349             }
   6350         } else {
   6351             if (!SOC_PORT_VALID(unit, port)) {
   6352                   return BCM_E_PORT;
   6353             }
   6354         }
   6355         BCM_IF_ERROR_RETURN(
   6356             bcm_esw_stk_my_modid_get(unit, &modid));
   6357     }
   6358 
   6359 #ifdef BCM_TRX_SUPPORT
   6360     if (SOC_IS_TRX(unit)) {
   6361         bcm_vlan_action_set_t   action;
   6362         soc_control_t           *sc = SOC_CONTROL(unit);
   6363         bcm_vlan_info_t         *vi = &vlan_info[unit];
   6364         int                     rv = BCM_E_NONE;
   6365         
   6366         if (!soc_feature(unit, soc_feature_vlan_action)) {
   6367             return BCM_E_UNAVAIL;
   6368         }
   6369 
   6370         /* If port class is changed system should not allow */
   6371         /* To use this API since it leads to confused outcome */
   6372         if (sc->soc_flags & SOC_F_XLATE_EGR_BLOCKED) {
   6373             return BCM_E_CONFIG;
   6374         }
   6375 
   6376         bcm_vlan_action_set_t_init(&action);
   6377         action.new_outer_vlan = new_vid;
   6378         action.new_inner_vlan = 0;
   6379         action.priority = prio;
   6380         action.ot_outer = bcmVlanActionReplace;
   6381         action.dt_outer = bcmVlanActionReplace;
   6382 
   6383         rv = _bcm_trx_vlan_translate_egress_action_add(unit, port, 
   6384                                                         old_vid, 0, 
   6385                                                         &action);
   6386         /* In case of usage of this API on Triumph and newer devices */
   6387         /* port parameter is pretended to be a port_class therefore */
   6388         /* port_class will remain unchanged as long as there are entries */
   6389         /* in egress vlan translation table added using this API */
   6390         if (BCM_SUCCESS(rv)) {
   6391             sc->soc_flags |= SOC_F_PORT_CLASS_BLOCKED;
   6392             vi->old_egr_xlate_cnt++;
   6393 #ifdef BCM_WARM_BOOT_SUPPORT
   6394             SOC_CONTROL_LOCK(unit);
   6395             SOC_CONTROL(unit)->scache_dirty = 1;
   6396             SOC_CONTROL_UNLOCK(unit);
   6397 #endif
   6398         }
   6399 
   6400         return rv;
   6401     }
   6402 #endif /* BCM_TRX_SUPPORT */
   6403 
   6404 
   6405 #ifdef BCM_FIREBOLT_SUPPORT
   6406     if (SOC_IS_FBX(unit)) {
   6407         return _bcm_fb_vlan_translate_add(unit, port, old_vid, new_vid, prio,
   6408                                           BCM_VLAN_XLATE_EGR);
   6409     }
   6410 #endif
   6411 
   6412     return BCM_E_UNAVAIL;
   6413 }
   6414 
   6415 
   6416 /*
   6417  * Function:
   6418  *      bcm_vlan_translate_egress_get
   6419  * Purpose:
   6420  *      Get vlan egress translation
   6421  * Parameters:
   6422  *      unit - StrataSwitch PCI device unit number (driver internal).
   6423  *      port - port numebr
   6424  *      old_vid - Old VLAN ID to has translation for
   6425  *      new_vid - New VLAN ID that packet will get
   6426  *      prio    - Priority
   6427  * Returns:
   6428  *      BCM_E_NONE - Translation found, new_vid nad prio will have the values.
   6429  *      BCM_E_NOT_FOUND - Translation does not exist
   6430  *      BCM_E_XXX  - Other error
   6431  * Notes:
   6432  *      None.
   6433  */
   6434 int bcm_esw_vlan_translate_egress_get (int unit, bcm_port_t port,
   6435                                        bcm_vlan_t old_vid,
   6436                                        bcm_vlan_t *new_vid,
   6437                                        int *prio)
   6438 {
   6439     bcm_module_t        modid;
   6440     bcm_trunk_t         tgid = -1;
   6441     int                 id = -1;
   6442 
   6443 #ifdef BCM_TOMAHAWK3_SUPPORT
   6444     if (SOC_IS_TOMAHAWK3(unit)) {
   6445         return BCM_E_UNAVAIL;
   6446     }
   6447 #endif
   6448 
   6449     CHECK_INIT(unit);
   6450     VLAN_CHK_ID(unit, old_vid);
   6451 
   6452     /* XGS does not support translation of VLAN ID 0 */
   6453     if (old_vid == 0) {
   6454         return BCM_E_PARAM;
   6455     }
   6456 
   6457     if ((NULL == new_vid) ||(NULL == prio)){
   6458         return BCM_E_PARAM;
   6459     }
   6460 
   6461     if (BCM_GPORT_IS_SET(port)) {
   6462         if (!BCM_GPORT_IS_TUNNEL(port)) {
   6463             BCM_IF_ERROR_RETURN(
   6464                 _bcm_esw_gport_resolve(unit, port, &modid, &port, &tgid, &id));
   6465         }
   6466         if ((-1 != tgid || -1 != id) && !BCM_GPORT_IS_TUNNEL(port)) {
   6467             return BCM_E_PORT;
   6468         }
   6469     } else {
   6470         if (!SOC_PORT_VALID(unit, port)) { 
   6471             return BCM_E_PORT; 
   6472         }
   6473         BCM_IF_ERROR_RETURN(
   6474             bcm_esw_stk_my_modid_get(unit, &modid));
   6475     }
   6476 
   6477 #ifdef BCM_TRX_SUPPORT
   6478     if (SOC_IS_TRX(unit)) {
   6479         bcm_vlan_action_set_t   action;
   6480         soc_control_t           *sc = SOC_CONTROL(unit);
   6481         
   6482         if (!soc_feature(unit, soc_feature_vlan_action)) {
   6483             return BCM_E_UNAVAIL;
   6484         }
   6485 
   6486         /* If port class is changed system should not allow */
   6487         /* To use this API since it leads to confused outcome */
   6488         if (sc->soc_flags & SOC_F_XLATE_EGR_BLOCKED) {
   6489             return BCM_E_CONFIG;
   6490         }
   6491 
   6492         bcm_vlan_action_set_t_init(&action);
   6493         BCM_IF_ERROR_RETURN(
   6494             _bcm_trx_vlan_translate_egress_action_get(unit, port, old_vid,
   6495                                                       0, &action));
   6496         *new_vid = action.new_outer_vlan;
   6497         *prio = action.priority;
   6498 
   6499         return BCM_E_NONE;
   6500     }
   6501 #endif /* BCM_TRX_SUPPORT */
   6502 
   6503 #ifdef BCM_FIREBOLT_SUPPORT
   6504     if (SOC_IS_FBX(unit)) {
   6505         return _bcm_fb_vlan_translate_get(unit, port, old_vid, new_vid,
   6506                                           prio, BCM_VLAN_XLATE_EGR);
   6507     }
   6508 #endif
   6509 
   6510     return BCM_E_UNAVAIL;
   6511 }
   6512 
   6513 int
   6514 bcm_esw_vlan_translate_egress_delete(int unit, int port, bcm_vlan_t old_vid)
   6515 {
   6516     bcm_module_t        modid;
   6517     bcm_trunk_t         tgid = -1;
   6518     int                 id = -1;
   6519 
   6520 #ifdef BCM_TOMAHAWK3_SUPPORT
   6521     if (SOC_IS_TOMAHAWK3(unit)) {
   6522         return BCM_E_UNAVAIL;
   6523     }
   6524 #endif
   6525 
   6526     CHECK_INIT(unit);
   6527     VLAN_CHK_ID(unit, old_vid);
   6528 
   6529     if (BCM_GPORT_IS_SET(port)) {
   6530         if (!BCM_GPORT_IS_TUNNEL(port)) {
   6531             BCM_IF_ERROR_RETURN(
   6532                 _bcm_esw_gport_resolve(unit, port, &modid, &port, &tgid, &id));
   6533         }
   6534         if ((-1 != tgid || -1 != id) && !BCM_GPORT_IS_TUNNEL(port)) {
   6535             return BCM_E_PORT;
   6536         }
   6537     } else {
   6538         if (SOC_IS_RAVEN(unit)) {
   6539             if (port != -1) {
   6540                 if (!SOC_PORT_VALID(unit, port)) {
   6541                     return BCM_E_PORT; 
   6542                 }
   6543             }
   6544         } else {
   6545             if (!SOC_PORT_VALID(unit, port)) {
   6546                   return BCM_E_PORT;
   6547             }
   6548         }
   6549         BCM_IF_ERROR_RETURN(
   6550             bcm_esw_stk_my_modid_get(unit, &modid));
   6551     }
   6552 
   6553 #ifdef BCM_TRX_SUPPORT
   6554     if (SOC_IS_TRX(unit)) {
   6555 
   6556         /* XGS does not support translation of VLAN ID 0 */
   6557         if (old_vid == 0) {
   6558             return BCM_E_PARAM;
   6559         }
   6560 
   6561         if (!soc_feature(unit, soc_feature_vlan_action)) {
   6562             return BCM_E_UNAVAIL;
   6563         } else {
   6564             soc_control_t           *sc = SOC_CONTROL(unit);
   6565             bcm_vlan_info_t         *vi = &vlan_info[unit];
   6566             int                     rv = BCM_E_NONE;
   6567 
   6568             /* If port class is changed system should not allow */
   6569             /* To use this API since it leads to confused outcome */
   6570             if (sc->soc_flags & SOC_F_XLATE_EGR_BLOCKED) {
   6571                 return BCM_E_CONFIG;
   6572             }
   6573 
   6574             rv = _bcm_trx_vlan_translate_egress_action_delete(unit, port, 
   6575                                                            old_vid, 0);
   6576 
   6577             /* In case of usage of this API on Triumph and newer devices */
   6578             /* port parameter is pretended to be a port_class therefore */
   6579             /* port_class operation will be permited only when last entry */
   6580             /* in egress vlan translation table removed using this API */
   6581             if (BCM_SUCCESS(rv)) {
   6582                 vi->old_egr_xlate_cnt--;
   6583 #ifdef BCM_WARM_BOOT_SUPPORT
   6584                 SOC_CONTROL_LOCK(unit);
   6585                 SOC_CONTROL(unit)->scache_dirty = 1;
   6586                 SOC_CONTROL_UNLOCK(unit);
   6587 #endif
   6588                 if (0 == vi->old_egr_xlate_cnt) {
   6589                     sc->soc_flags &= ~SOC_F_PORT_CLASS_BLOCKED;
   6590                 }
   6591             }
   6592             return rv;
   6593         }
   6594     }
   6595 #endif /* BCM_TRX_SUPPORT */
   6596 
   6597 #ifdef BCM_FIREBOLT_SUPPORT
   6598     if (SOC_IS_FBX(unit)) {
   6599         return _bcm_fb_vlan_translate_delete(unit, port, old_vid,
   6600                                              BCM_VLAN_XLATE_EGR);
   6601     }
   6602 #endif
   6603 
   6604     return BCM_E_UNAVAIL;
   6605 }
   6606 
   6607 int
   6608 bcm_esw_vlan_translate_egress_delete_all(int unit)
   6609 {
   6610 #ifdef BCM_TOMAHAWK3_SUPPORT
   6611     if (SOC_IS_TOMAHAWK3(unit)) {
   6612         return BCM_E_UNAVAIL;
   6613     }
   6614 #endif
   6615 #ifdef BCM_TRX_SUPPORT
   6616     if (SOC_IS_TRX(unit)) {
   6617         if (!soc_feature(unit, soc_feature_vlan_action)) {
   6618             return BCM_E_UNAVAIL;
   6619         } else {
   6620             soc_control_t           *sc = SOC_CONTROL(unit);
   6621             bcm_vlan_info_t         *vi = &vlan_info[unit];
   6622             int                     rv = BCM_E_NONE;
   6623 
   6624             /* If port class is changed system should not allow */
   6625             /* To use this API since it leads to confused outcome */
   6626             if (sc->soc_flags & SOC_F_XLATE_EGR_BLOCKED) {
   6627                 return BCM_E_CONFIG;
   6628             }
   6629 
   6630             rv = _bcm_trx_vlan_translate_egress_action_delete_all(unit);
   6631 
   6632             /* In case of usage of this API on Triumph and newer devices */
   6633             /* port parameter is pretended to be a port_class therefore */
   6634             /* port_class operation will be permited when all entries */
   6635             /* in egress vlan translation table removed using this API */
   6636             if (BCM_SUCCESS(rv)) {
   6637                 sc->soc_flags &= ~SOC_F_PORT_CLASS_BLOCKED;
   6638                 vi->old_egr_xlate_cnt = 0;
   6639 #ifdef BCM_WARM_BOOT_SUPPORT
   6640                 SOC_CONTROL_LOCK(unit);
   6641                 SOC_CONTROL(unit)->scache_dirty = 1;
   6642                 SOC_CONTROL_UNLOCK(unit);
   6643 #endif
   6644             }
   6645             return rv;
   6646         }
   6647     }
   6648 #endif /* BCM_TRX_SUPPORT */
   6649 
   6650 #ifdef BCM_FIREBOLT_SUPPORT
   6651     if (SOC_IS_FBX(unit)) {
   6652         int rv;
   6653         rv = _bcm_fb_vlan_translate_delete(unit, -1, BCM_VLAN_NONE,
   6654                                              BCM_VLAN_XLATE_EGR);
   6655         if (BCM_SUCCESS(rv) || (rv == BCM_E_NOT_FOUND)) {
   6656             return BCM_E_NONE;
   6657         }
   6658 
   6659         return rv;
   6660     }
   6661 #endif
   6662 
   6663     return BCM_E_UNAVAIL;
   6664 }
   6665 
   6666 /*
   6667  * Function   :
   6668  *      _bcm_esw_vlan_translate_egress_action_add
   6669  * Description   :
   6670  *      Helper function to converge the two APIs
   6671  *      bcm_vlan_translate_egress_action_add and
   6672  *      bcm_vlan_translate_egress_gport_action_add
   6673  * Parameters   :
   6674  *      unit            (IN) BCM unit number
   6675  *      port_class      (IN) Group ID of ingress port
   6676  *      outer_vlan      (IN) Packet outer VLAN ID
   6677  *      inner_vlan      (IN) Packet inner VLAN ID
   6678  *      action          (IN) Action for outer and inner tag
   6679  */
   6680 static int
   6681 _bcm_esw_vlan_translate_egress_action_add(int unit, int port_class,
   6682                                           bcm_vlan_t outer_vlan,
   6683                                           bcm_vlan_t inner_vlan,
   6684                                           bcm_vlan_action_set_t *action,
   6685                                           int handle_modport_gport)
   6686 {   
   6687     bcm_module_t        modid;
   6688     bcm_trunk_t         tgid = -1;
   6689     int                 id = -1; 
   6690 
   6691     CHECK_INIT(unit);
   6692 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 
   6693     if (soc_feature(unit, soc_feature_vp_sharing)) { 
   6694         int num_vfi = 0;
   6695         bcm_vpn_t vpn_min = 0, vpn_max = 0;
   6696         if (outer_vlan > BCM_VLAN_MAX) {
   6697             num_vfi = soc_mem_index_count(unit, VFIm);
   6698             _BCM_VPN_SET(vpn_min, _BCM_VPN_TYPE_VFI, 0);
   6699             vpn_max = vpn_min + num_vfi - 1;
   6700             if (outer_vlan > vpn_max) {
   6701                 return (BCM_E_PARAM);
   6702             } else if ((outer_vlan >= vpn_min) &&
   6703                        (outer_vlan <= vpn_max)) {
   6704                 if (inner_vlan != BCM_VLAN_INVALID) {
   6705                     return BCM_E_PARAM;
   6706                 }
   6707             } else {
   6708                 return BCM_E_PARAM;
   6709             }
   6710         } else {
   6711             VLAN_CHK_ID(unit, inner_vlan);
   6712         }
   6713     } else
   6714 #endif /* BCM_TRIDENT2PLUS_SUPPORT &&  INCLUDE_L3 */
   6715     {
   6716         VLAN_CHK_ID(unit, outer_vlan);
   6717         VLAN_CHK_ID(unit, inner_vlan);
   6718     }
   6719 
   6720     if (NULL == action) {
   6721         return BCM_E_PARAM;
   6722     }
   6723 
   6724     if (BCM_GPORT_IS_SET(port_class)) {
   6725         if (!BCM_GPORT_IS_TUNNEL(port_class) &&
   6726             !BCM_GPORT_IS_MIM_PORT(port_class) && 
   6727             !BCM_GPORT_IS_NIV_PORT(port_class) && 
   6728             !BCM_GPORT_IS_MPLS_PORT(port_class) &&
   6729             !BCM_GPORT_IS_VLAN_PORT(port_class) &&
   6730             !BCM_GPORT_IS_VXLAN_PORT(port_class) &&
   6731             !BCM_GPORT_IS_EXTENDER_PORT(port_class) &&
   6732             !BCM_GPORT_IS_L2GRE_PORT(port_class) &&
   6733             !(handle_modport_gport &&
   6734               (BCM_GPORT_IS_MODPORT(port_class) ||
   6735               BCM_GPORT_IS_SUBPORT_PORT(port_class))))
   6736         {
   6737             BCM_IF_ERROR_RETURN(
   6738                 _bcm_esw_gport_resolve(unit, port_class, &modid, &port_class, 
   6739                                        &tgid, &id));
   6740         }
   6741         if ((-1 != tgid || -1 != id) && !BCM_GPORT_IS_TUNNEL(port_class) &&
   6742             !BCM_GPORT_IS_MIM_PORT(port_class) && 
   6743             !BCM_GPORT_IS_NIV_PORT(port_class) &&
   6744             !BCM_GPORT_IS_MPLS_PORT(port_class) &&
   6745             !BCM_GPORT_IS_VLAN_PORT(port_class) &&
   6746             !BCM_GPORT_IS_EXTENDER_PORT(port_class) &&
   6747             !BCM_GPORT_IS_VXLAN_PORT(port_class) &&
   6748             !BCM_GPORT_IS_L2GRE_PORT(port_class))
   6749         {
   6750             return BCM_E_PORT;
   6751         }
   6752     } else 
   6753 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   6754     if (inner_vlan == BCM_VLAN_INVALID) {
   6755         BCM_IF_ERROR_RETURN
   6756                    (bcm_td2p_dvp_group_validate(unit, port_class));
   6757     } else 
   6758 #endif /* BCM_TRIDENT2PLUS_SUPPORT &&  INCLUDE_L3 */
   6759     {
   6760         if (!SOC_PORT_CLASS_VALID(unit, port_class)) { 
   6761             return BCM_E_PORT; 
   6762         }
   6763     }
   6764 
   6765 #ifdef BCM_TRX_SUPPORT
   6766     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   6767         return _bcm_trx_vlan_translate_egress_action_add(unit, port_class, 
   6768                                              outer_vlan, inner_vlan, 
   6769                                              action);
   6770     }
   6771 #endif /* BCM_TRX_SUPPORT */
   6772 
   6773     return BCM_E_UNAVAIL;
   6774 }
   6775 
   6776 /*
   6777  * Function   :
   6778  *      _bcm_esw_vlan_translate_egress_action_get
   6779  * Description   :
   6780  *      Helper function to converge the APIs
   6781  *      bcm_vlan_translate_egress_action_get and
   6782  *      bcm_vlan_translate_egress_gport_action_get
   6783  * Parameters   :
   6784  *      unit            (IN) BCM unit number
   6785  *      port_class      (IN) Group ID of ingress port
   6786  *      outer_vlan      (IN) Packet outer VLAN ID
   6787  *      inner_vlan      (IN) Packet inner VLAN ID
   6788  *      action          (OUT) Action for outer and inner tag
   6789  */
   6790 static int
   6791 _bcm_esw_vlan_translate_egress_action_get (int unit, int port_class,
   6792                                           bcm_vlan_t outer_vlan,
   6793                                           bcm_vlan_t inner_vlan,
   6794                                           bcm_vlan_action_set_t *action,
   6795                                           int handle_modport_gport)
   6796 {
   6797     bcm_module_t        modid;
   6798     bcm_trunk_t         tgid = -1;
   6799     int                 id = -1; 
   6800 
   6801     CHECK_INIT(unit);
   6802 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   6803     if (soc_feature(unit, soc_feature_vp_sharing)) { 
   6804         int num_vfi = 0;
   6805         bcm_vpn_t vpn_min = 0, vpn_max = 0;
   6806         if (outer_vlan > BCM_VLAN_MAX) {
   6807             num_vfi = soc_mem_index_count(unit, VFIm);
   6808             _BCM_VPN_SET(vpn_min, _BCM_VPN_TYPE_VFI, 0);
   6809             vpn_max = vpn_min + num_vfi - 1;
   6810             if (outer_vlan > vpn_max) {
   6811                 return (BCM_E_PARAM);
   6812             } else if ((outer_vlan >= vpn_min) &&
   6813                        (outer_vlan <= vpn_max)) {
   6814                 if (inner_vlan != BCM_VLAN_INVALID) {
   6815                     return BCM_E_PARAM;
   6816                 }
   6817             } else {
   6818                 return BCM_E_PARAM;
   6819             }
   6820         } else {
   6821             VLAN_CHK_ID(unit, inner_vlan);
   6822         }
   6823     } else
   6824 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */
   6825     {
   6826         VLAN_CHK_ID(unit, outer_vlan);
   6827         VLAN_CHK_ID(unit, inner_vlan);
   6828     }
   6829 
   6830     if (NULL == action) {
   6831         return BCM_E_PARAM;
   6832     }
   6833 
   6834     if (BCM_GPORT_IS_SET(port_class)) {
   6835         if (!BCM_GPORT_IS_TUNNEL(port_class) &&
   6836             !BCM_GPORT_IS_MIM_PORT(port_class) &&
   6837             !BCM_GPORT_IS_NIV_PORT(port_class) &&
   6838             !BCM_GPORT_IS_MPLS_PORT(port_class) &&
   6839             !BCM_GPORT_IS_VLAN_PORT(port_class) &&
   6840             !BCM_GPORT_IS_VXLAN_PORT(port_class) &&
   6841             !BCM_GPORT_IS_EXTENDER_PORT(port_class) &&
   6842             !BCM_GPORT_IS_L2GRE_PORT(port_class) &&
   6843             !(handle_modport_gport &&
   6844               (BCM_GPORT_IS_MODPORT(port_class) ||
   6845               BCM_GPORT_IS_SUBPORT_PORT(port_class))))
   6846         {
   6847             BCM_IF_ERROR_RETURN(
   6848                 _bcm_esw_gport_resolve(unit, port_class, &modid, &port_class, 
   6849                                        &tgid, &id));
   6850         }
   6851         if ((-1 != tgid || -1 != id) && !BCM_GPORT_IS_TUNNEL(port_class) &&
   6852             !BCM_GPORT_IS_MIM_PORT(port_class) &&
   6853             !BCM_GPORT_IS_NIV_PORT(port_class) &&
   6854             !BCM_GPORT_IS_EXTENDER_PORT(port_class) &&
   6855             !BCM_GPORT_IS_MPLS_PORT(port_class) &&
   6856             !BCM_GPORT_IS_VLAN_PORT(port_class) && 
   6857             !BCM_GPORT_IS_VXLAN_PORT(port_class) &&
   6858             !BCM_GPORT_IS_L2GRE_PORT(port_class)) 
   6859         {
   6860             return BCM_E_PORT;
   6861         }
   6862     } else {
   6863 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   6864         if (inner_vlan == BCM_VLAN_INVALID) {
   6865             BCM_IF_ERROR_RETURN
   6866                        (bcm_td2p_dvp_group_validate(unit, port_class));
   6867         } else
   6868 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */
   6869         if (!SOC_PORT_CLASS_VALID(unit, port_class)) { 
   6870             return BCM_E_PORT; 
   6871         }
   6872     }
   6873 
   6874 #ifdef BCM_TRX_SUPPORT
   6875     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   6876         return _bcm_trx_vlan_translate_egress_action_get(unit, port_class, 
   6877                                                         outer_vlan, inner_vlan, 
   6878                                                         action);
   6879     }
   6880 #endif /* BCM_TRX_SUPPORT */
   6881 
   6882     return BCM_E_UNAVAIL;
   6883 }
   6884 
   6885 /*
   6886  * Function:
   6887  *      _bcm_esw_vlan_translate_egress_action_delete
   6888  * Purpose:
   6889  *      Helper function to converge the APIs
   6890  *      bcm_vlan_translate_egress_action_delete and
   6891  *      bcm_vlan_translate_egress_gport_action_delete
   6892  * Parameters:
   6893  *      unit            (IN) BCM unit number
   6894  *      port_class      (IN) Group ID of ingress port
   6895  *      outer_vlan      (IN) Packet outer VLAN ID
   6896  *      inner_vlan      (IN) Packet inner VLAN ID
   6897  */
   6898 int
   6899 _bcm_esw_vlan_translate_egress_action_delete(int unit, int port_class,
   6900                                              bcm_vlan_t outer_vlan,
   6901                                              bcm_vlan_t inner_vlan,
   6902                                              int handle_modport_gport)
   6903 {
   6904     bcm_module_t        modid;
   6905     bcm_trunk_t         tgid = -1;
   6906     int                 id = -1; 
   6907 
   6908     CHECK_INIT(unit); 
   6909 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 
   6910     if (soc_feature(unit, soc_feature_vp_sharing)) { 
   6911         int num_vfi = 0;
   6912         bcm_vpn_t vpn_min = 0, vpn_max = 0;
   6913         if (outer_vlan > BCM_VLAN_MAX) {
   6914             num_vfi = soc_mem_index_count(unit, VFIm);
   6915             _BCM_VPN_SET(vpn_min, _BCM_VPN_TYPE_VFI, 0);
   6916             vpn_max = vpn_min + num_vfi - 1;
   6917             if (outer_vlan > vpn_max) {
   6918                 return (BCM_E_PARAM);
   6919             } else if ((outer_vlan >= vpn_min) &&
   6920                        (outer_vlan <= vpn_max)) {
   6921                 if (inner_vlan != BCM_VLAN_INVALID) {
   6922                     return BCM_E_PARAM;
   6923                 }
   6924             } else {
   6925                 return BCM_E_PARAM;
   6926             }
   6927         }  else {
   6928             VLAN_CHK_ID(unit, inner_vlan);
   6929         }
   6930     } else
   6931 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */
   6932     {
   6933         VLAN_CHK_ID(unit, outer_vlan);
   6934         VLAN_CHK_ID(unit, inner_vlan);
   6935     }
   6936 
   6937     if (BCM_GPORT_IS_SET(port_class)) {
   6938         if (!BCM_GPORT_IS_TUNNEL(port_class) &&
   6939             !BCM_GPORT_IS_MIM_PORT(port_class) &&
   6940             !BCM_GPORT_IS_NIV_PORT(port_class) &&
   6941             !BCM_GPORT_IS_EXTENDER_PORT(port_class) &&
   6942             !BCM_GPORT_IS_MPLS_PORT(port_class) &&
   6943             !BCM_GPORT_IS_VLAN_PORT(port_class) &&
   6944             !BCM_GPORT_IS_VXLAN_PORT(port_class) &&
   6945             !BCM_GPORT_IS_L2GRE_PORT(port_class) &&
   6946             !(handle_modport_gport &&
   6947               (BCM_GPORT_IS_MODPORT(port_class) ||
   6948               BCM_GPORT_IS_SUBPORT_PORT(port_class))))
   6949         {
   6950             BCM_IF_ERROR_RETURN(
   6951                 _bcm_esw_gport_resolve(unit, port_class, &modid, &port_class, 
   6952                                        &tgid, &id));
   6953         }
   6954         if ((-1 != tgid || -1 != id) && !BCM_GPORT_IS_TUNNEL(port_class) &&
   6955             !BCM_GPORT_IS_MIM_PORT(port_class) &&
   6956             !BCM_GPORT_IS_NIV_PORT(port_class) &&
   6957             !BCM_GPORT_IS_EXTENDER_PORT(port_class) &&
   6958             !BCM_GPORT_IS_MPLS_PORT(port_class) &&
   6959             !BCM_GPORT_IS_VLAN_PORT(port_class) &&
   6960             !BCM_GPORT_IS_VXLAN_PORT(port_class) &&
   6961             !BCM_GPORT_IS_L2GRE_PORT(port_class)) 
   6962         {
   6963             return BCM_E_PORT;
   6964         }
   6965     } else {
   6966 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 
   6967         if (inner_vlan == BCM_VLAN_INVALID) {
   6968             BCM_IF_ERROR_RETURN
   6969                        (bcm_td2p_dvp_group_validate(unit, port_class));
   6970         } else
   6971 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */
   6972         if (!SOC_PORT_CLASS_VALID(unit, port_class)) { 
   6973             return BCM_E_PORT; 
   6974         }
   6975     }
   6976 
   6977 #ifdef BCM_TRX_SUPPORT
   6978     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)) {
   6979         return _bcm_trx_vlan_translate_egress_action_delete(unit, port_class, 
   6980                                                            outer_vlan, 
   6981                                                            inner_vlan);
   6982     }
   6983 #endif /* BCM_TRX_SUPPORT */
   6984 
   6985     return BCM_E_UNAVAIL;
   6986 }
   6987 
   6988 /*
   6989  * Function   :
   6990  *      bcm_vlan_translate_egress_action_add
   6991  * Description   :
   6992  *      Add an entry to egress VLAN translation table.
   6993  * Parameters   :
   6994  *      unit            (IN) BCM unit number
   6995  *      port_class      (IN) Group ID of ingress port
   6996  *      outer_vlan      (IN) Packet outer VLAN ID
   6997  *      inner_vlan      (IN) Packet inner VLAN ID
   6998  *      action          (IN) Action for outer and inner tag
   6999  */
   7000 int
   7001 bcm_esw_vlan_translate_egress_action_add(int unit, int port_class,
   7002                                          bcm_vlan_t outer_vlan,
   7003                                          bcm_vlan_t inner_vlan,
   7004                                          bcm_vlan_action_set_t *action)
   7005 {
   7006     int handle_modport_gport = 0;
   7007 #ifdef BCM_TOMAHAWK3_SUPPORT
   7008     if (SOC_IS_TOMAHAWK3(unit)) {
   7009         return BCM_E_UNAVAIL;
   7010     }
   7011 #endif
   7012     return _bcm_esw_vlan_translate_egress_action_add(unit, port_class,
   7013             outer_vlan, inner_vlan, action, handle_modport_gport);
   7014 }
   7015 
   7016 /*
   7017  * Function   :
   7018  *      bcm_vlan_translate_egress_action_get
   7019  * Description   :
   7020  *      Get an entry to egress VLAN translation table.
   7021  * Parameters   :
   7022  *      unit            (IN) BCM unit number
   7023  *      port_class      (IN) Group ID of ingress port
   7024  *      outer_vlan      (IN) Packet outer VLAN ID
   7025  *      inner_vlan      (IN) Packet inner VLAN ID
   7026  *      action          (OUT) Action for outer and inner tag
   7027  */
   7028 int
   7029 bcm_esw_vlan_translate_egress_action_get (int unit, int port_class,
   7030                                           bcm_vlan_t outer_vlan,
   7031                                           bcm_vlan_t inner_vlan,
   7032                                           bcm_vlan_action_set_t *action)
   7033 {
   7034     int handle_modport_gport = 0;
   7035 #ifdef BCM_TOMAHAWK3_SUPPORT
   7036     if (SOC_IS_TOMAHAWK3(unit)) {
   7037         return BCM_E_UNAVAIL;
   7038     }
   7039 #endif
   7040 
   7041     bcm_vlan_action_set_t_init(action);
   7042     return _bcm_esw_vlan_translate_egress_action_get(unit, port_class,
   7043             outer_vlan, inner_vlan, action, handle_modport_gport);
   7044 
   7045 }
   7046 
   7047 /*
   7048  * Function:
   7049  *      bcm_vlan_translate_egress_action_delete
   7050  * Purpose:
   7051  *      Delete an egress vlan translate lookup entry.
   7052  * Parameters:
   7053  *      unit            (IN) BCM unit number
   7054  *      port_class      (IN) Group ID of ingress port
   7055  *      outer_vlan      (IN) Packet outer VLAN ID
   7056  *      inner_vlan      (IN) Packet inner VLAN ID
   7057  */
   7058 int
   7059 bcm_esw_vlan_translate_egress_action_delete(int unit, int port_class,
   7060                                             bcm_vlan_t outer_vlan,
   7061                                             bcm_vlan_t inner_vlan)
   7062 {
   7063     int handle_modport_gport = 0;
   7064 #ifdef BCM_TOMAHAWK3_SUPPORT
   7065     if (SOC_IS_TOMAHAWK3(unit)) {
   7066         return BCM_E_UNAVAIL;
   7067     }
   7068 #endif
   7069     return _bcm_esw_vlan_translate_egress_action_delete(unit, port_class,
   7070             outer_vlan, inner_vlan, handle_modport_gport);
   7071 }
   7072 
   7073 /*
   7074  * Function   :
   7075  *      bcm_esw_vlan_translate_egress_gport_action_add
   7076  * Description   :
   7077  *      Add an entry to egress VLAN translation table based on gport
   7078  * Parameters   :
   7079  *      unit            (IN) BCM unit number
   7080  *      port            (IN) Egress gport
   7081  *      outer_vlan      (IN) Packet outer VLAN ID
   7082  *      inner_vlan      (IN) Packet inner VLAN ID
   7083  *      action          (IN) Action for outer and inner tag
   7084  */
   7085 int
   7086 bcm_esw_vlan_translate_egress_gport_action_add (int unit, bcm_gport_t port,
   7087                                                 bcm_vlan_t outer_vlan,
   7088                                                 bcm_vlan_t inner_vlan,
   7089                                                 bcm_vlan_action_set_t *action)
   7090 {
   7091     int handle_modport_gport = 0;
   7092 #ifdef BCM_TOMAHAWK3_SUPPORT
   7093     if (SOC_IS_TOMAHAWK3(unit)) {
   7094         return BCM_E_UNAVAIL;
   7095     }
   7096 #endif
   7097     if (soc_feature(unit, soc_feature_egr_vxlate_supports_dgpp)) {
   7098         handle_modport_gport = 1;
   7099     }
   7100     return _bcm_esw_vlan_translate_egress_action_add(unit, port,
   7101             outer_vlan, inner_vlan, action, handle_modport_gport);
   7102 }
   7103 
   7104 /*
   7105  * Function   :
   7106  *      bcm_esw_vlan_translate_egress_gport_action_get
   7107  * Description   :
   7108  *      Get a gport based entry from egress VLAN translation table.
   7109  * Parameters   :
   7110  *      unit            (IN) BCM unit number
   7111  *      port            (IN) Egress gport
   7112  *      outer_vlan      (IN) Packet outer VLAN ID
   7113  *      inner_vlan      (IN) Packet inner VLAN ID
   7114  *      action          (OUT) Action for outer and inner tag
   7115  */
   7116 int 
   7117 bcm_esw_vlan_translate_egress_gport_action_get (int unit, bcm_gport_t port,
   7118                                                 bcm_vlan_t outer_vlan,
   7119                                                 bcm_vlan_t inner_vlan,
   7120                                                 bcm_vlan_action_set_t *action)
   7121 {
   7122     int handle_modport_gport = 0;
   7123 #ifdef BCM_TOMAHAWK3_SUPPORT
   7124     if (SOC_IS_TOMAHAWK3(unit)) {
   7125         return BCM_E_UNAVAIL;
   7126     }
   7127 #endif
   7128     if (soc_feature(unit, soc_feature_egr_vxlate_supports_dgpp)) {
   7129         handle_modport_gport = 1;
   7130     }
   7131 
   7132     bcm_vlan_action_set_t_init(action);
   7133     return _bcm_esw_vlan_translate_egress_action_get(unit, port,
   7134             outer_vlan, inner_vlan, action, handle_modport_gport);
   7135 }
   7136 
   7137 /*
   7138  * Function:
   7139  *      bcm_esw_vlan_translate_egress_gport_action_delete
   7140  * Purpose:
   7141  *      Delete a gport based egress vlan translate entry.
   7142  * Parameters:
   7143  *      unit            (IN) BCM unit number
   7144  *      port            (IN) Egress gport
   7145  *      outer_vlan      (IN) Packet outer VLAN ID
   7146  *      inner_vlan      (IN) Packet inner VLAN ID
   7147  */
   7148 int
   7149 bcm_esw_vlan_translate_egress_gport_action_delete(int unit, bcm_gport_t port,
   7150                                                   bcm_vlan_t outer_vlan,
   7151                                                   bcm_vlan_t inner_vlan)
   7152 {
   7153     int handle_modport_gport = 0;
   7154 #ifdef BCM_TOMAHAWK3_SUPPORT
   7155     if (SOC_IS_TOMAHAWK3(unit)) {
   7156         return BCM_E_UNAVAIL;
   7157     }
   7158 #endif
   7159     if (soc_feature(unit, soc_feature_egr_vxlate_supports_dgpp)) {
   7160         handle_modport_gport = 1;
   7161     }
   7162     return _bcm_esw_vlan_translate_egress_action_delete(unit, port,
   7163             outer_vlan, inner_vlan, handle_modport_gport);
   7164 }
   7165 
   7166 int
   7167 bcm_esw_vlan_dtag_add(int unit, int port, bcm_vlan_t inner_vid,
   7168                       bcm_vlan_t outer_vid, int prio)
   7169 {
   7170     bcm_module_t        modid;
   7171     bcm_trunk_t         tgid = -1;
   7172     int                 id = -1;
   7173 
   7174 #ifdef BCM_TOMAHAWK3_SUPPORT
   7175     if (SOC_IS_TOMAHAWK3(unit)) {
   7176         return BCM_E_UNAVAIL;
   7177     }
   7178 #endif
   7179 
   7180     CHECK_INIT(unit);
   7181     VLAN_CHK_ID(unit, inner_vid);
   7182     VLAN_CHK_ID(unit, outer_vid);
   7183 
   7184 #ifdef BCM_TRX_SUPPORT
   7185     if (SOC_IS_TRX(unit)) {
   7186         bcm_vlan_action_set_t action;
   7187         bcm_gport_t gport;
   7188 
   7189         if (!soc_feature(unit, soc_feature_vlan_action)) {
   7190             return BCM_E_UNAVAIL;
   7191         }
   7192         if (BCM_GPORT_IS_SET(port)) {
   7193             gport = port;
   7194         } else {
   7195             if (!SOC_PORT_VALID(unit, port)) { 
   7196                 return BCM_E_PORT; 
   7197             }
   7198             BCM_IF_ERROR_RETURN(
   7199                 bcm_esw_port_gport_get(unit, port, &gport));
   7200         }
   7201 
   7202         bcm_vlan_action_set_t_init(&action);
   7203         action.new_outer_vlan = outer_vid;
   7204         action.priority = prio;
   7205         /* For inner tagged packets, set the outer tag action and outer pkt 
   7206          * priority action to ADD.
   7207          * For all other packet types, the action is initialized to NONE.
   7208          */
   7209         action.it_outer = bcmVlanActionAdd;
   7210         if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   7211             action.it_outer_pkt_prio = bcmVlanActionAdd;
   7212         } else {
   7213             action.it_outer_pkt_prio = bcmVlanActionNone;
   7214         }
   7215         return _bcm_trx_vlan_translate_action_add(unit, gport,
   7216                                                  bcmVlanTranslateKeyPortInner,
   7217                                                  0, inner_vid, &action);
   7218     }
   7219 #endif /* BCM_TRX_SUPPORT */
   7220 
   7221     if (BCM_GPORT_IS_SET(port)) {
   7222         BCM_IF_ERROR_RETURN(
   7223             _bcm_esw_gport_resolve(unit, port, &modid, &port, &tgid, &id));
   7224         if (-1 != tgid || -1 != id) {
   7225             return BCM_E_PORT;
   7226         }
   7227     } else {
   7228         if (!SOC_PORT_VALID(unit, port)) { 
   7229             return BCM_E_PORT; 
   7230         }
   7231         BCM_IF_ERROR_RETURN(
   7232             bcm_esw_stk_my_modid_get(unit, &modid));
   7233     }
   7234 
   7235 #ifdef BCM_FIREBOLT_SUPPORT
   7236     if (SOC_IS_FBX(unit)) {
   7237         return _bcm_fb_vlan_translate_add(unit, port, inner_vid, outer_vid,
   7238                                           prio, BCM_VLAN_XLATE_DTAG);
   7239     }
   7240 #endif
   7241 
   7242     return BCM_E_UNAVAIL;
   7243 }
   7244 
   7245 /*
   7246  * Function:
   7247  *      bcm_esw_vlan_dtag_get
   7248  * Purpose:
   7249  *      Get vlan translation for double tagging
   7250  * Parameters:
   7251  *      unit - StrataSwitch PCI device unit number (driver internal).
   7252  *      port - port numebr
   7253  *      old_vid - Old VLAN ID to has translation for
   7254  *      new_vid - New VLAN ID that packet will get
   7255  *      prio    - Priority
   7256  * Returns:
   7257  *      BCM_E_NONE - Translation found, new_vid and prio will have the values.
   7258  *      BCM_E_NOT_FOUND - Translation does not exist
   7259  *      BCM_E_XXX  - Other error
   7260  * Notes:
   7261  *      None.
   7262  */
   7263 int 
   7264 bcm_esw_vlan_dtag_get (int unit, bcm_port_t port,
   7265                        bcm_vlan_t old_vid,
   7266                        bcm_vlan_t *new_vid,
   7267                        int *prio)
   7268 {
   7269     bcm_module_t        modid;
   7270     bcm_trunk_t         tgid = -1;
   7271     int                 id = -1;
   7272 
   7273 #ifdef BCM_TOMAHAWK3_SUPPORT
   7274     if (SOC_IS_TOMAHAWK3(unit)) {
   7275         return BCM_E_UNAVAIL;
   7276     }
   7277 #endif
   7278 
   7279     CHECK_INIT(unit);
   7280     VLAN_CHK_ID(unit, old_vid);
   7281 
   7282 #ifdef BCM_TRX_SUPPORT
   7283     if (SOC_IS_TRX(unit)) {
   7284         bcm_gport_t gport;
   7285         bcm_vlan_action_set_t action;
   7286 
   7287         if (!soc_feature(unit, soc_feature_vlan_action)) {
   7288             return BCM_E_UNAVAIL;
   7289         }
   7290         if (BCM_GPORT_IS_SET(port)) {
   7291             gport = port;
   7292         } else {
   7293             if (!SOC_PORT_VALID(unit, port)) {
   7294                 return BCM_E_PORT;
   7295             }
   7296             BCM_IF_ERROR_RETURN(
   7297                 bcm_esw_port_gport_get(unit, port, &gport));
   7298         }
   7299         bcm_vlan_action_set_t_init(&action);
   7300         BCM_IF_ERROR_RETURN(
   7301             _bcm_trx_vlan_translate_action_get(unit, gport,
   7302                                                  bcmVlanTranslateKeyPortInner,
   7303                                                0, old_vid, &action));
   7304         if (bcmVlanActionAdd == action.it_outer) {
   7305             *new_vid = action.new_outer_vlan;
   7306             *prio = action.priority;
   7307 
   7308             return BCM_E_NONE;
   7309         } 
   7310 
   7311         return BCM_E_NOT_FOUND;
   7312     }
   7313 #endif /* BCM_TRX_SUPPORT */
   7314 
   7315     if (BCM_GPORT_IS_SET(port)) {
   7316         BCM_IF_ERROR_RETURN(
   7317             _bcm_esw_gport_resolve(unit, port, &modid, &port, &tgid, &id));
   7318         if (-1 != tgid || -1 != id) {
   7319             return BCM_E_PORT;
   7320         }
   7321     } else {
   7322         if (!SOC_PORT_VALID(unit, port)) { 
   7323             return BCM_E_PORT; 
   7324         }
   7325         BCM_IF_ERROR_RETURN(
   7326             bcm_esw_stk_my_modid_get(unit, &modid));
   7327     }
   7328 
   7329 #ifdef BCM_FIREBOLT_SUPPORT
   7330     if (SOC_IS_FBX(unit)) {
   7331         return _bcm_fb_vlan_translate_get(unit, port, old_vid, new_vid,
   7332                                           prio, BCM_VLAN_XLATE_DTAG);
   7333     }
   7334 #endif
   7335 
   7336     return BCM_E_UNAVAIL;
   7337 }
   7338 
   7339 
   7340 int
   7341 bcm_esw_vlan_dtag_delete(int unit, int port, bcm_vlan_t vid)
   7342 {
   7343     bcm_module_t        modid;
   7344     bcm_trunk_t         tgid = -1;
   7345     int                 id = -1;
   7346 
   7347 #ifdef BCM_TOMAHAWK3_SUPPORT
   7348     if (SOC_IS_TOMAHAWK3(unit)) {
   7349         return BCM_E_UNAVAIL;
   7350     }
   7351 #endif
   7352 
   7353     CHECK_INIT(unit);
   7354     VLAN_CHK_ID(unit, vid);
   7355 
   7356 #ifdef BCM_TRX_SUPPORT
   7357     if (SOC_IS_TRX(unit)) {
   7358         bcm_gport_t gport;
   7359 
   7360         if (!soc_feature(unit, soc_feature_vlan_action)) {
   7361             return BCM_E_UNAVAIL;
   7362         }
   7363         if (BCM_GPORT_IS_SET(port)) {
   7364             gport = port;
   7365         } else {
   7366             if (!SOC_PORT_VALID(unit, port)) { 
   7367                 return BCM_E_PORT; 
   7368             }
   7369             BCM_IF_ERROR_RETURN(
   7370                 bcm_esw_port_gport_get(unit, port, &gport));
   7371         }
   7372 
   7373         return _bcm_trx_vlan_translate_action_delete(unit, gport,
   7374                                                     bcmVlanTranslateKeyPortInner,
   7375                                                     0, vid);
   7376     }
   7377 #endif /* BCM_TRX_SUPPORT */
   7378 
   7379     if (BCM_GPORT_IS_SET(port)) {
   7380         BCM_IF_ERROR_RETURN(
   7381             _bcm_esw_gport_resolve(unit, port, &modid, &port, &tgid, &id));
   7382         if (-1 != tgid || -1 != id) {
   7383             return BCM_E_PORT;
   7384         }
   7385     } else {
   7386         if (!SOC_PORT_VALID(unit, port)) { 
   7387             return BCM_E_PORT; 
   7388         }
   7389         BCM_IF_ERROR_RETURN(
   7390             bcm_esw_stk_my_modid_get(unit, &modid));
   7391     }
   7392 
   7393 #ifdef BCM_FIREBOLT_SUPPORT
   7394     if (SOC_IS_FBX(unit)) {
   7395         return _bcm_fb_vlan_translate_delete(unit, port, vid,
   7396                                              BCM_VLAN_XLATE_DTAG);
   7397     }
   7398 #endif
   7399 
   7400     return BCM_E_UNAVAIL;
   7401 }
   7402 
   7403 int
   7404 bcm_esw_vlan_dtag_delete_all(int unit)
   7405 {
   7406 #ifdef BCM_TOMAHAWK3_SUPPORT
   7407     if (SOC_IS_TOMAHAWK3(unit)) {
   7408         return BCM_E_UNAVAIL;
   7409     }
   7410 #endif
   7411 
   7412     CHECK_INIT(unit);
   7413 
   7414 #ifdef BCM_TRX_SUPPORT
   7415     if (SOC_IS_TRX(unit)) {
   7416         if (!soc_feature(unit, soc_feature_vlan_action)) {
   7417             return BCM_E_UNAVAIL;
   7418         }
   7419         return _bcm_trx_vlan_translate_action_delete_all(unit);
   7420     }
   7421 #endif /* BCM_TRX_SUPPORT */
   7422 
   7423 #ifdef BCM_FIREBOLT_SUPPORT
   7424     if (SOC_IS_FBX(unit)) {
   7425         int rv; 
   7426 
   7427         rv = _bcm_fb_vlan_translate_delete(unit, -1, BCM_VLAN_NONE,
   7428                                              BCM_VLAN_XLATE_DTAG);
   7429         if (BCM_SUCCESS(rv) || (BCM_E_NOT_FOUND == rv)) {
   7430             return BCM_E_NONE;
   7431         }
   7432 
   7433         return rv;
   7434     }
   7435 #endif
   7436 
   7437     return BCM_E_UNAVAIL;
   7438 }
   7439 
   7440 /*
   7441  * IP based vlans
   7442  */
   7443 
   7444 #ifdef BCM_XGS3_SWITCH_SUPPORT
   7445 static void
   7446 _ip6_prefix_to_mask(int prefix, bcm_ip6_t mask)
   7447 {
   7448     int i;
   7449 
   7450     sal_memset(mask, 0, sizeof(bcm_ip6_t));
   7451     /* Construct the mask from the prefix */
   7452     for (i = 0; prefix > 8; prefix -= 8, i++) {
   7453         mask[i] = 0xff;
   7454     }
   7455     mask[i] = 0xff << (8 - prefix);
   7456 }
   7457 
   7458 static int
   7459 _ip6_mask_to_prefix(bcm_ip6_t mask)
   7460 {
   7461     int i;
   7462     int prefix;
   7463     for (i = 0, prefix = 0; mask[i] == 0xff; i++) {
   7464         prefix += 8;
   7465     }
   7466     switch(mask[i]) {
   7467         case 0x80:
   7468             prefix += 1;
   7469             break;
   7470         case 0xc0:
   7471             prefix += 2;
   7472             break;
   7473         case 0xe0:
   7474             prefix += 3;
   7475             break;
   7476         case 0xf0:
   7477             prefix += 4;
   7478             break;
   7479         case 0xf8:
   7480             prefix += 5;
   7481             break;
   7482         case 0xfc:
   7483             prefix += 6;
   7484             break;
   7485         case 0xfe:
   7486             prefix += 7;
   7487             break;
   7488         case 0:
   7489             break;
   7490         default:
   7491             return(-1);
   7492     }
   7493     return prefix;
   7494 }
   7495 
   7496 static void
   7497 _ip4cat(uint8 * buf, bcm_ip_t ip)
   7498 {
   7499     int i;
   7500     for (i = 3; i > -1; i--) {
   7501         buf[i] = ip & 0x00ff;
   7502         ip >>= 8;
   7503     }
   7504 }
   7505 
   7506 /*
   7507  * On XGS3, VLAN_SUBNET.IP_ADDR stores only a top half (64 bits) of
   7508  * the IPV6 address. Comparing it against a full length of a parameter
   7509  * will have certainly result in a mismatch. There should be a
   7510  * special type for a stored part of the address; meanwhile, a
   7511  * symbolic constant is used.
   7512  */
   7513 
   7514 #define VLAN_SUBNET_IP_ADDR_LENGTH 8
   7515 
   7516 /* Macro to copy bcm_ip6_t addr into uint32[] for soc_mem_field_set call */
   7517 #define VLAN_IP6_TO_HW_FORMAT(_ip, _reg)        \
   7518     do { \
   7519         _reg[0] = (_ip[4] << 24) | (_ip[5] << 16) | (_ip[6] << 8) | _ip[7]; \
   7520         _reg[1] = (_ip[0] << 24) | (_ip[1] << 16) | (_ip[2] << 8) | _ip[3]; \
   7521     } while (0)
   7522 
   7523 /* Macro to copy uint32[] addr values from soc_mem_field_get into bcm_ip6_t */
   7524 #define VLAN_HW_FORMAT_TO_IP6(_reg, _ip)        \
   7525     do { \
   7526        _ip[3] = (_reg[1]) & 0xff;               \
   7527        _ip[2] = (_reg[1] >> 8) & 0xff;          \
   7528        _ip[1] = (_reg[1] >> 16) & 0xff;         \
   7529        _ip[0] = (_reg[1] >> 24) & 0xff;         \
   7530        _ip[7] = (_reg[0]) & 0xff;               \
   7531        _ip[6] = (_reg[0] >> 8) & 0xff;          \
   7532        _ip[5] = (_reg[0] >> 16) & 0xff;         \
   7533        _ip[4] = (_reg[0] >> 24) & 0xff;         \
   7534     } while (0)
   7535 
   7536 static int
   7537 _xgs3_vlan_ipv6_add(int unit,
   7538                     bcm_ip6_t ip, bcm_ip6_t mask, bcm_vlan_t vid, int prio)
   7539 {
   7540     int i, imin, imax, nent, vsbytes;
   7541     int match = -1, empty = -1, insert = -1;
   7542     int rv;
   7543     vlan_subnet_entry_t * vstab, * vsnull, *vstabp;
   7544     int prefix;
   7545     uint32 hw_ip[2], hw_nm[2];
   7546 
   7547     VLAN_CHK_ID(unit, vid);
   7548     VLAN_CHK_PRIO(unit, prio);
   7549 
   7550     VLAN_IP6_TO_HW_FORMAT(ip, hw_ip);
   7551     VLAN_IP6_TO_HW_FORMAT(mask, hw_nm);
   7552 
   7553     imin = soc_mem_index_min(unit, VLAN_SUBNETm);
   7554     imax = soc_mem_index_max(unit, VLAN_SUBNETm);
   7555     nent = soc_mem_index_count(unit, VLAN_SUBNETm);
   7556     vsbytes = soc_mem_entry_words(unit, VLAN_SUBNETm);
   7557     vsbytes = WORDS2BYTES(vsbytes);
   7558 
   7559     prefix = _ip6_mask_to_prefix(mask);
   7560     if (prefix < 0) {
   7561         return BCM_E_PARAM;
   7562     }
   7563 
   7564     vstab = soc_cm_salloc(unit, nent * sizeof(*vstab), "vlan_subnet");
   7565     if (vstab == NULL) {
   7566         return BCM_E_MEMORY;
   7567     }
   7568 
   7569     vsnull = soc_mem_entry_null(unit, VLAN_SUBNETm);
   7570 
   7571     soc_mem_lock(unit, VLAN_SUBNETm);
   7572     rv = soc_mem_read_range(unit, VLAN_SUBNETm, MEM_BLOCK_ANY,
   7573                             imin, imax, vstab);
   7574     if (rv < 0) {
   7575         soc_mem_unlock(unit, VLAN_SUBNETm);
   7576         soc_cm_sfree(unit, vstab);
   7577         return rv;
   7578     }
   7579 
   7580     for(i = 0; i < nent; i++) {
   7581         uint32 enm[2], eip[2];
   7582         bcm_ip6_t temp_nm;
   7583         int epx;
   7584         vstabp = soc_mem_table_idx_to_pointer(unit,
   7585                         VLAN_SUBNETm, vlan_subnet_entry_t *,
   7586                         vstab, i);
   7587         if (sal_memcmp(vstabp, vsnull, vsbytes) == 0) {
   7588             empty = i;
   7589             break;
   7590         }
   7591         soc_mem_field_get(unit, VLAN_SUBNETm,
   7592                 (uint32 *) vstabp, MASKf, (uint32 *) enm);
   7593 
   7594         /* copy mask into bcm_ip6_t */
   7595         sal_memset(temp_nm, 0, sizeof(bcm_ip6_t));
   7596         VLAN_HW_FORMAT_TO_IP6(enm, temp_nm);
   7597 
   7598         epx = _ip6_mask_to_prefix(temp_nm);
   7599         if (epx < 0) {
   7600             soc_mem_unlock(unit, VLAN_SUBNETm);
   7601             soc_cm_sfree(unit, vstab);
   7602             return BCM_E_PARAM;
   7603         }
   7604         if ((epx < prefix) && (insert < 0)) {
   7605             insert = i;
   7606         }
   7607         if (sal_memcmp(hw_nm, enm, VLAN_SUBNET_IP_ADDR_LENGTH) != 0) {
   7608             continue;
   7609         }
   7610         soc_mem_field_get(unit, VLAN_SUBNETm,
   7611                 (uint32 *) vstabp, IP_ADDRf, (uint32 *) eip);
   7612 
   7613         if (sal_memcmp(hw_ip, eip, VLAN_SUBNET_IP_ADDR_LENGTH) == 0) {
   7614             match = i;
   7615         }
   7616     }
   7617 
   7618     if (match >= 0) {   /* found an exact match */
   7619         vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm,
   7620                             vlan_subnet_entry_t *, vstab, match);
   7621         soc_VLAN_SUBNETm_field32_set(unit, vstabp, VLAN_IDf, vid);
   7622         soc_VLAN_SUBNETm_field32_set(unit, vstabp, PRIf, prio);
   7623         soc_VLAN_SUBNETm_field32_set(unit, vstabp, VALIDf, 1);
   7624 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_SCORPION_SUPPORT)
   7625         if (soc_mem_field_valid(unit, VLAN_SUBNETm, RESERVED_MASKf)) {
   7626             soc_mem_field32_set(unit, VLAN_SUBNETm, vstabp, RESERVED_MASKf, 0);
   7627         }
   7628         if (soc_mem_field_valid(unit, VLAN_SUBNETm, RESERVED_KEYf)) {
   7629             soc_mem_field32_set(unit, VLAN_SUBNETm, vstabp, RESERVED_KEYf, 0);
   7630         }
   7631 #endif /* BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */
   7632         rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ALL, match, vstabp);
   7633     } else if (empty < 0) {
   7634         rv = BCM_E_FULL;
   7635     } else {
   7636         if (insert < 0) {
   7637             insert = empty;
   7638         }
   7639 
   7640         for (i = empty; i > insert; i--) {
   7641             vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm,
   7642                             vlan_subnet_entry_t *, vstab, (i - 1));
   7643             rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ANY, i, vstabp);
   7644             if (rv < 0) {
   7645                 break;
   7646             }
   7647             rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ANY, i - 1, &vsnull);
   7648             if (rv < 0) {
   7649                 break;
   7650             }
   7651         }
   7652         vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm,
   7653                         vlan_subnet_entry_t *, vstab, insert);
   7654         sal_memset(vstabp, 0, vsbytes);
   7655         soc_VLAN_SUBNETm_field32_set(unit, vstabp, VLAN_IDf, vid);
   7656         soc_VLAN_SUBNETm_field32_set(unit, vstabp, PRIf, prio);
   7657         soc_VLAN_SUBNETm_field32_set(unit, vstabp, VALIDf, 1);
   7658         soc_mem_field_set(unit, VLAN_SUBNETm,
   7659                 (uint32 *) vstabp, IP_ADDRf, (uint32 *) hw_ip);
   7660         soc_mem_field_set(unit, VLAN_SUBNETm,
   7661                 (uint32 *) vstabp, MASKf, (uint32 *) hw_nm);
   7662 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_SCORPION_SUPPORT)
   7663         if (soc_mem_field_valid(unit, VLAN_SUBNETm, RESERVED_MASKf)) {
   7664             soc_mem_field32_set(unit, VLAN_SUBNETm, vstabp, RESERVED_MASKf, 0);
   7665         }
   7666         if (soc_mem_field_valid(unit, VLAN_SUBNETm, RESERVED_KEYf)) {
   7667             soc_mem_field32_set(unit, VLAN_SUBNETm, vstabp, RESERVED_KEYf, 0);
   7668         }
   7669 #endif /* BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */
   7670 
   7671         if (rv >= 0) {
   7672             rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ALL,
   7673                     insert, vstabp);
   7674         }
   7675     }
   7676 
   7677     soc_mem_unlock(unit, VLAN_SUBNETm);
   7678     soc_cm_sfree(unit, vstab);
   7679     return rv;
   7680 }
   7681 
   7682 static int
   7683 _xgs3_vlan_ipv6_delete(int unit, bcm_ip6_t ip, bcm_ip6_t mask)
   7684 {
   7685     int i, imin, imax, nent, vsbytes;
   7686     int match = -1, empty = -1;
   7687     int rv;
   7688     vlan_subnet_entry_t * vstab, * vsnull,  *vstabp;
   7689     uint32 hw_ip[2], hw_nm[2];
   7690 
   7691     VLAN_IP6_TO_HW_FORMAT(ip, hw_ip);
   7692     VLAN_IP6_TO_HW_FORMAT(mask, hw_nm);
   7693 #ifdef BCM_TRIDENT_SUPPORT
   7694     if (SOC_IS_TD_TT(unit)) {
   7695         hw_ip[0] &= hw_nm[0];
   7696         hw_ip[1] &= hw_nm[1];
   7697     }
   7698 #endif /* BCM_TRIDENT_SUPPORT */
   7699 
   7700     imin = soc_mem_index_min(unit, VLAN_SUBNETm);
   7701     imax = soc_mem_index_max(unit, VLAN_SUBNETm);
   7702     nent = soc_mem_index_count(unit, VLAN_SUBNETm);
   7703     vsbytes = soc_mem_entry_words(unit, VLAN_SUBNETm);
   7704     vsbytes = WORDS2BYTES(vsbytes);
   7705     vstab = soc_cm_salloc(unit, nent * sizeof(*vstab), "vlan_subnet");
   7706 
   7707     if (vstab == NULL) {
   7708         return BCM_E_MEMORY;
   7709     }
   7710 
   7711     vsnull = soc_mem_entry_null(unit, VLAN_SUBNETm);
   7712 
   7713     soc_mem_lock(unit, VLAN_SUBNETm);
   7714     rv = soc_mem_read_range(unit, VLAN_SUBNETm, MEM_BLOCK_ANY,
   7715                             imin, imax, vstab);
   7716     if (rv < 0) {
   7717         soc_mem_unlock(unit, VLAN_SUBNETm);
   7718         soc_cm_sfree(unit, vstab);
   7719         return rv;
   7720     }
   7721 
   7722     for(i = 0; i < nent; i++) {
   7723         uint32 enm[2], eip[2];
   7724         vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm,
   7725                         vlan_subnet_entry_t *, vstab, i);
   7726         if (sal_memcmp(vstabp, vsnull, vsbytes) == 0) {
   7727             empty = i;
   7728             break;
   7729         }
   7730         soc_mem_field_get(unit, VLAN_SUBNETm,
   7731                 (uint32 *) vstabp, MASKf, (uint32 *) enm);
   7732         if (sal_memcmp(hw_nm, enm, VLAN_SUBNET_IP_ADDR_LENGTH) != 0) {
   7733             continue;
   7734         }
   7735         soc_mem_field_get(unit, VLAN_SUBNETm,
   7736                 (uint32 *) vstabp, IP_ADDRf, (uint32 *) eip);
   7737         if (sal_memcmp(hw_ip, eip, VLAN_SUBNET_IP_ADDR_LENGTH) == 0) {
   7738             match = i;
   7739         }
   7740     }
   7741 
   7742     if (match < 0) {
   7743         soc_mem_unlock(unit, VLAN_SUBNETm);
   7744         soc_cm_sfree(unit, vstab);
   7745         return BCM_E_NOT_FOUND;
   7746     }
   7747 
   7748     if (empty == -1) {
   7749         empty = nent;
   7750     }
   7751 
   7752     for (i = match; (i < empty - 1) && (rv == BCM_E_NONE); i++) {
   7753         vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm,
   7754                         vlan_subnet_entry_t *, vstab, (i + 1));
   7755         rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ANY, i, vstabp);
   7756     }
   7757 
   7758     if (rv >= 0) {
   7759         rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ANY, empty - 1, vsnull);
   7760     }
   7761 
   7762     soc_mem_unlock(unit, VLAN_SUBNETm);
   7763     soc_cm_sfree(unit, vstab);
   7764     return rv;
   7765 }
   7766 
   7767 static int
   7768 _xgs3_vlan_ipv6_delete_all(int unit)
   7769 {
   7770     int i, imax;
   7771     int rv = BCM_E_NONE;
   7772     vlan_subnet_entry_t * vsnull = soc_mem_entry_null(unit, VLAN_SUBNETm);
   7773 
   7774     soc_mem_lock(unit, VLAN_SUBNETm);
   7775     imax = soc_mem_index_max(unit, VLAN_SUBNETm);
   7776 
   7777     for (i = soc_mem_index_min(unit, VLAN_SUBNETm); i <= imax; i++) {
   7778         rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ALL, i, vsnull);
   7779         if (rv < 0) {
   7780             break;
   7781         }
   7782     }
   7783 
   7784     soc_mem_unlock(unit, VLAN_SUBNETm);
   7785     return rv;
   7786 }
   7787 #endif
   7788 
   7789 /*
   7790  * Vlan selection based on IPv4 addresses
   7791  */
   7792 
   7793 /*
   7794  * Function:
   7795  *      bcm_vlan_ip4_add
   7796  * Purpose:
   7797  *      Add an IPv4 subnet lookup to select vlan and priority for
   7798  *      untagged packets
   7799  * Parameters:
   7800  *      unit -          device number
   7801  *      ipaddr -        IPv4 address
   7802  *      netmask -       network mask of ipaddr to match
   7803  *      vid -           VLAN number to give matching packets
   7804  *      prio -          priority to give matching packets
   7805  * Returns:
   7806  *      BCM_E_XXX
   7807  * Notes:
   7808  *      This API is superseded by bcm_vlan_ip_add.
   7809  */
   7810 
   7811 int
   7812 bcm_esw_vlan_ip4_add(int unit, bcm_ip_t ipaddr, bcm_ip_t netmask,
   7813                      bcm_vlan_t vid, int prio)
   7814 {
   7815 #ifdef BCM_XGS3_SWITCH_SUPPORT
   7816     if (SOC_IS_XGS3_SWITCH(unit) && !SOC_IS_XGS3_FABRIC(unit)) {
   7817         bcm_ip6_t ip6addr;
   7818         bcm_ip6_t ip6mask;
   7819         uint8 * ptr;
   7820 
   7821 #ifdef BCM_SCORPION_SUPPORT
   7822         if (SOC_IS_SC_CQ(unit) &&
   7823             !soc_feature(unit, soc_feature_vlan_action)) {
   7824             return BCM_E_UNAVAIL;
   7825         }
   7826 #endif
   7827 
   7828 #ifdef BCM_TRIDENT_SUPPORT
   7829         if (SOC_IS_TD_TT(unit) &&
   7830             !soc_feature(unit, soc_feature_ip_subnet_based_vlan)) {
   7831             return BCM_E_UNAVAIL;
   7832         }
   7833 #endif
   7834 
   7835         /* Construct ipv6 mask/address from ipv4 parameters.
   7836          * Only use the upper 64-bits of ipv6 mask/address.
   7837          */
   7838         ptr = ip6addr;
   7839         sal_memset(ptr, 0, sizeof(ip6addr));
   7840         sal_memcpy(ptr, "\xff\xff\x00\x00", 4);
   7841         _ip4cat(ptr + 4, ipaddr);
   7842 
   7843         ptr = ip6mask;
   7844         sal_memset(ptr, 0, sizeof(ip6mask));
   7845         sal_memcpy(ptr, "\xff\xff\xff\xff", 4);
   7846         _ip4cat(ptr + 4, netmask);
   7847 
   7848         return _xgs3_vlan_ipv6_add(unit, ip6addr, ip6mask, vid, prio);
   7849     }
   7850 #endif
   7851     return BCM_E_UNAVAIL;
   7852 }
   7853 
   7854 /*
   7855  * Function:
   7856  *      bcm_vlan_ip4_delete
   7857  * Purpose:
   7858  *      Delete an IPv4 subnet lookup entry.
   7859  * Parameters:
   7860  *      unit -          device number
   7861  *      ipaddr -        IPv4 address
   7862  *      netmask -       network mask of ipaddr to match
   7863  * Returns:
   7864  *      BCM_E_XXX
   7865  * Notes:
   7866  *      This API is superseded by bcm_vlan_ip_delete.
   7867  */
   7868 
   7869 int
   7870 bcm_esw_vlan_ip4_delete(int unit, bcm_ip_t ipaddr, bcm_ip_t netmask)
   7871 {
   7872 #ifdef BCM_XGS3_SWITCH_SUPPORT
   7873     if (SOC_IS_XGS3_SWITCH(unit) && !SOC_IS_XGS3_FABRIC(unit)) {
   7874         bcm_ip6_t ip6addr;
   7875         bcm_ip6_t ip6mask;
   7876         uint8 * ptr;
   7877 
   7878 #ifdef BCM_SCORPION_SUPPORT
   7879         if (SOC_IS_SC_CQ(unit) &&
   7880             !soc_feature(unit, soc_feature_vlan_action)) {
   7881             return BCM_E_UNAVAIL;
   7882         }
   7883 #endif
   7884 
   7885 #ifdef BCM_TRIDENT_SUPPORT
   7886         if (SOC_IS_TD_TT(unit) &&
   7887             !soc_feature(unit, soc_feature_ip_subnet_based_vlan)) {
   7888             return BCM_E_UNAVAIL;
   7889         }
   7890 #endif
   7891 
   7892         /* Construct ipv6 mask/address from ipv4 parameters */
   7893         ptr = ip6addr;
   7894         sal_memset(ptr, 0, sizeof(ip6addr));
   7895         sal_memcpy(ptr, "\xff\xff\x00\x00", 4);
   7896         _ip4cat(ptr + 4, ipaddr);
   7897 
   7898         ptr = ip6mask;
   7899         sal_memset(ptr, 0, sizeof(ip6mask));
   7900         sal_memcpy(ptr, "\xff\xff\xff\xff", 4);
   7901         _ip4cat(ptr + 4, netmask);
   7902 
   7903         return _xgs3_vlan_ipv6_delete(unit, ip6addr, ip6mask);
   7904     }
   7905 #endif
   7906     return BCM_E_UNAVAIL;
   7907 }
   7908 
   7909 /*
   7910  * Function:
   7911  *      bcm_vlan_ip4_delete_all
   7912  * Purpose:
   7913  *      Delete all IPv4 subnet lookup entries.
   7914  * Parameters:
   7915  *      unit -          device number
   7916  * Returns:
   7917  *      BCM_E_XXX
   7918  * Notes:
   7919  *      This API is superseded by bcm_vlan_ip_delete_all.
   7920  */
   7921 
   7922 int
   7923 bcm_esw_vlan_ip4_delete_all(int unit)
   7924 {
   7925 #ifdef BCM_XGS3_SWITCH_SUPPORT
   7926     if (SOC_IS_XGS3_SWITCH(unit) && !SOC_IS_XGS3_FABRIC(unit)) {
   7927 #ifdef BCM_SCORPION_SUPPORT
   7928         if (SOC_IS_SC_CQ(unit) &&
   7929             !soc_feature(unit, soc_feature_vlan_action)) {
   7930             return BCM_E_UNAVAIL;
   7931         }
   7932 #endif
   7933 
   7934 #ifdef BCM_TRIDENT_SUPPORT
   7935         if (SOC_IS_TD_TT(unit) &&
   7936             !soc_feature(unit, soc_feature_ip_subnet_based_vlan)) {
   7937             return BCM_E_UNAVAIL;
   7938         }
   7939 #endif
   7940 
   7941         return _xgs3_vlan_ipv6_delete_all(unit);
   7942     }
   7943 #endif
   7944     return BCM_E_UNAVAIL;
   7945 }
   7946 
   7947 /*
   7948  * Vlan selection based on IPv6 addresses
   7949  */
   7950 
   7951 /*
   7952  * Function:
   7953  *      _bcm_vlan_ip6_add (internal)
   7954  * Purpose:
   7955  *      Add an IPv6 subnet lookup to select vlan and priority for
   7956  *      untagged packets
   7957  * Parameters:
   7958  *      unit -          device number
   7959  *      ipaddr -        IPv6 address
   7960  *      prefix -        network prefix of ipaddr to match
   7961  *      vlan -          VLAN number to give matching packets
   7962  *      prio -          priority to give matching packets
   7963  * Returns:
   7964  *      BCM_E_XXX
   7965  * Notes:
   7966  *      Valid prefix lengths may be limited to no more than 64
   7967  */
   7968 
   7969 STATIC int
   7970 _bcm_vlan_ip6_add(int unit,
   7971                   bcm_ip6_t ipaddr,
   7972                   int prefix,
   7973                   bcm_vlan_t vlan,
   7974                   int prio)
   7975 {
   7976 #ifdef BCM_XGS3_SWITCH_SUPPORT
   7977     if (SOC_IS_XGS3_SWITCH(unit) && !SOC_IS_XGS3_FABRIC(unit)) {
   7978         bcm_ip6_t mask;
   7979 
   7980         if (prefix > 64) {
   7981             return BCM_E_PARAM;
   7982         }
   7983 
   7984         _ip6_prefix_to_mask(prefix, mask);
   7985         return _xgs3_vlan_ipv6_add(unit, ipaddr, mask, vlan, prio);
   7986     }
   7987 #endif
   7988 
   7989     return BCM_E_UNAVAIL;
   7990 }
   7991 
   7992 /*
   7993  * Function:
   7994  *      _bcm_vlan_ip6_delete (internal)
   7995  * Purpose:
   7996  *      Delete an IPv6 subnet lookup entry
   7997  * Parameters:
   7998  *      unit -          device number
   7999  *      ipaddr -        IPv6 address
   8000  *      prefix -        network prefix of ipaddr to match
   8001  * Returns:
   8002  *      BCM_E_XXX
   8003  */
   8004 
   8005 STATIC int
   8006 _bcm_vlan_ip6_delete(int unit,
   8007                      bcm_ip6_t ipaddr,
   8008                      int prefix)
   8009 {
   8010 #ifdef BCM_XGS3_SWITCH_SUPPORT
   8011     if (SOC_IS_XGS3_SWITCH(unit) && !SOC_IS_XGS3_FABRIC(unit)) {
   8012         bcm_ip6_t mask;
   8013 
   8014         if (prefix > 64) {
   8015             return BCM_E_PARAM;
   8016         }
   8017 
   8018         _ip6_prefix_to_mask(prefix, mask);
   8019         return _xgs3_vlan_ipv6_delete(unit, ipaddr, mask);
   8020     }
   8021 #endif
   8022 
   8023     return BCM_E_UNAVAIL;
   8024 }
   8025 
   8026 /*
   8027  * Function:
   8028  *      _bcm_vlan_ip6_delete_all (internal)
   8029  * Purpose:
   8030  *      Delete all IPv6 subnet lookup entries
   8031  * Parameters:
   8032  *      unit -          device number
   8033  * Returns:
   8034  *      BCM_E_XXX
   8035  */
   8036 
   8037 STATIC int
   8038 _bcm_vlan_ip6_delete_all(int unit)
   8039 {
   8040 #ifdef BCM_XGS3_SWITCH_SUPPORT
   8041     if (SOC_IS_XGS3_SWITCH(unit) && !SOC_IS_XGS3_FABRIC(unit)) {
   8042         return _xgs3_vlan_ipv6_delete_all(unit);
   8043     }
   8044 #endif
   8045 
   8046     return BCM_E_UNAVAIL;
   8047 }
   8048 
   8049 /*
   8050  * Vlan selection based on unified IPv4/IPv6 information structure.
   8051  */
   8052 
   8053 /*
   8054  * Function:
   8055  *      bcm_vlan_ip_add
   8056  * Purpose:
   8057  *      Add a subnet lookup to select vlan and priority for
   8058  *      untagged packets
   8059  * Parameters:
   8060  *      unit -          device number
   8061  *      vlan_ip -       structure specifying IP address and other info
   8062  * Returns:
   8063  *      BCM_E_XXX
   8064  */
   8065 
   8066 int
   8067 bcm_esw_vlan_ip_add(int unit, bcm_vlan_ip_t *vlan_ip)
   8068 {
   8069 #ifdef BCM_TRX_SUPPORT
   8070     if (SOC_IS_TRX(unit)) {
   8071         int rv; 
   8072 
   8073         if (soc_feature(unit, soc_feature_vlan_action)
   8074             && soc_feature(unit, soc_feature_ip_subnet_based_vlan)) {
   8075             bcm_vlan_action_set_t action;
   8076 
   8077             bcm_vlan_action_set_t_init(&action);
   8078             action.new_outer_vlan = vlan_ip->vid;
   8079             action.new_inner_vlan = 0;
   8080             action.priority = vlan_ip->prio;
   8081             action.dt_outer_prio = bcmVlanActionReplace;
   8082             action.ot_outer_prio = bcmVlanActionReplace;
   8083             action.it_outer      = bcmVlanActionAdd;
   8084             action.it_inner_prio = bcmVlanActionNone;
   8085             action.ut_outer      = bcmVlanActionAdd;
   8086 
   8087             soc_mem_lock(unit, VLAN_SUBNETm);
   8088             rv =  _bcm_trx_vlan_ip_action_add(unit, vlan_ip, &action);
   8089             soc_mem_unlock(unit, VLAN_SUBNETm);
   8090 
   8091             return rv;
   8092         } else {
   8093             return BCM_E_UNAVAIL;  /* Latency bypass */
   8094         }
   8095     }
   8096 #endif /* BCM_TRX_SUPPORT */
   8097 
   8098     return (vlan_ip->flags & BCM_VLAN_SUBNET_IP6)
   8099         ? _bcm_vlan_ip6_add(unit, vlan_ip->ip6, vlan_ip->prefix,
   8100                 vlan_ip->vid, vlan_ip->prio)
   8101         : bcm_esw_vlan_ip4_add(unit, vlan_ip->ip4, vlan_ip->mask,
   8102                 vlan_ip->vid, vlan_ip->prio);
   8103 }
   8104 
   8105 /*
   8106  * Function:
   8107  *      bcm_vlan_ip_delete
   8108  * Purpose:
   8109  *      Delete a subnet lookup entry.
   8110  * Parameters:
   8111  *      unit -          device number
   8112  *      vlan_ip -       structure specifying IP address and other info
   8113  * Returns:
   8114  *      BCM_E_XXX
   8115  */
   8116 
   8117 int
   8118 bcm_esw_vlan_ip_delete(int unit, bcm_vlan_ip_t *vlan_ip)
   8119 {
   8120 #ifdef BCM_TRX_SUPPORT
   8121     if (SOC_IS_TRX(unit)) {
   8122         int rv;
   8123 
   8124         if (soc_feature(unit, soc_feature_vlan_action)
   8125             && soc_feature(unit, soc_feature_ip_subnet_based_vlan)) {
   8126             soc_mem_lock(unit, VLAN_SUBNETm);
   8127             rv = _bcm_trx_vlan_ip_delete(unit, vlan_ip);
   8128             soc_mem_unlock(unit, VLAN_SUBNETm);
   8129 
   8130             return rv;
   8131         } else {
   8132             return BCM_E_UNAVAIL;  /* Latency bypass */
   8133         }
   8134     }
   8135 #endif /* BCM_TRX_SUPPORT */
   8136 
   8137     return (vlan_ip->flags & BCM_VLAN_SUBNET_IP6)
   8138         ? _bcm_vlan_ip6_delete(unit, vlan_ip->ip6, vlan_ip->prefix)
   8139         : bcm_esw_vlan_ip4_delete(unit, vlan_ip->ip4, vlan_ip->mask);
   8140 }
   8141 
   8142 /*
   8143  * Function:
   8144  *      bcm_vlan_ip_delete_all
   8145  * Purpose:
   8146  *      Delete all subnet lookup entries.
   8147  * Parameters:
   8148  *      unit -          device number
   8149  * Returns:
   8150  *      BCM_E_XXX
   8151  */
   8152 
   8153 int
   8154 bcm_esw_vlan_ip_delete_all(int unit)
   8155 {
   8156     int rv;
   8157 
   8158 #ifdef BCM_TRX_SUPPORT
   8159     if (SOC_IS_TRX(unit)) {
   8160         if (soc_feature(unit, soc_feature_vlan_action)
   8161             && soc_feature(unit, soc_feature_ip_subnet_based_vlan)) {
   8162             soc_mem_lock(unit, VLAN_SUBNETm);
   8163             rv = _bcm_trx_vlan_ip_delete_all(unit);
   8164             soc_mem_unlock(unit, VLAN_SUBNETm);
   8165 
   8166             return rv;
   8167         } else {
   8168             return BCM_E_UNAVAIL;  /* Latency bypass */
   8169         }
   8170     }
   8171 #endif /* BCM_TRX_SUPPORT */
   8172 
   8173     if ((rv = _bcm_vlan_ip6_delete_all(unit)) == BCM_E_UNAVAIL) {
   8174         rv = BCM_E_NONE;
   8175     }
   8176     if (rv == BCM_E_NONE) {
   8177         rv = bcm_esw_vlan_ip4_delete_all(unit);
   8178     }
   8179 
   8180     return rv;
   8181 }
   8182 
   8183 /*
   8184  * Function:
   8185  *      bcm_vlan_ip_action_add
   8186  * Purpose:
   8187  *      Add a subnet lookup to select vlan action for untagged packets
   8188  * Parameters:
   8189  *      unit    -   device number
   8190  *      vlan_ip -   structure specifying IP address and other info
   8191  *      action  -   structure VLAN tag actions
   8192  * Returns:
   8193  *      BCM_E_XXX
   8194  */
   8195 
   8196 int
   8197 bcm_esw_vlan_ip_action_add(int unit, bcm_vlan_ip_t *vlan_ip,
   8198                            bcm_vlan_action_set_t *action)
   8199 {
   8200 #ifdef BCM_TRX_SUPPORT
   8201     int rv;
   8202         
   8203     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)
   8204         && soc_feature(unit, soc_feature_ip_subnet_based_vlan)) {
   8205         soc_mem_lock(unit, VLAN_SUBNETm);
   8206         rv = _bcm_trx_vlan_ip_action_add(unit, vlan_ip, action);
   8207         soc_mem_unlock(unit, VLAN_SUBNETm);
   8208 
   8209         return rv;
   8210     }
   8211 #endif /* BCM_TRX_SUPPORT */
   8212 
   8213     return BCM_E_UNAVAIL;
   8214 }
   8215 
   8216 /*
   8217  * Function:
   8218  *      bcm_vlan_ip_action_get
   8219  * Purpose:
   8220  *      Get an action for subnet 
   8221  * Parameters:
   8222  *      unit    -   (IN) device number
   8223  *      vlan_ip -   (IN) structure specifying IP address and other info
   8224  *      action  -   (OUT) structure VLAN tag actions
   8225  * Returns:
   8226  *      BCM_E_XXX
   8227  */
   8228 
   8229 int
   8230 bcm_esw_vlan_ip_action_get(int unit, bcm_vlan_ip_t *vlan_ip,
   8231                            bcm_vlan_action_set_t *action)
   8232 {
   8233 #ifdef BCM_TRX_SUPPORT
   8234     int rv; 
   8235 
   8236     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)
   8237         && soc_feature(unit, soc_feature_ip_subnet_based_vlan)) {
   8238 
   8239         bcm_vlan_action_set_t_init(action);
   8240         soc_mem_lock(unit, VLAN_SUBNETm);
   8241         rv = _bcm_trx_vlan_ip_action_get(unit, vlan_ip, action);
   8242         soc_mem_unlock(unit, VLAN_SUBNETm);
   8243 
   8244         return rv;
   8245     }
   8246 #endif /* BCM_TRX_SUPPORT */
   8247 
   8248     return BCM_E_UNAVAIL;
   8249 }
   8250 
   8251 /*
   8252  * Function:
   8253  *      bcm_esw_vlan_ip_action_delete
   8254  * Purpose:
   8255  *      Delete an action for subnet 
   8256  * Parameters:
   8257  *      unit    -   (IN) device number
   8258  *      vlan_ip -   (IN) structure specifying IP address and other info
   8259  * Returns:
   8260  *      BCM_E_XXX
   8261  */
   8262 
   8263 int
   8264 bcm_esw_vlan_ip_action_delete(int unit, bcm_vlan_ip_t *vlan_ip)
   8265 {
   8266 #ifdef BCM_TRX_SUPPORT
   8267     int rv; 
   8268 
   8269     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)
   8270         && soc_feature(unit, soc_feature_ip_subnet_based_vlan)) {
   8271         soc_mem_lock(unit, VLAN_SUBNETm);
   8272         rv = _bcm_trx_vlan_ip_delete(unit, vlan_ip);
   8273         soc_mem_unlock(unit, VLAN_SUBNETm);
   8274 
   8275         return rv;
   8276     }
   8277 #endif /* BCM_TRX_SUPPORT */
   8278 
   8279     return BCM_E_UNAVAIL;
   8280 }
   8281 
   8282 /*
   8283  * Function:
   8284  *      bcm_esw_vlan_ip_action_delete_all
   8285  * Purpose:
   8286  *      Delete all actions for all subnets
   8287  * Parameters:
   8288  *      unit    -   (IN) device number
   8289  * Returns:
   8290  *      BCM_E_XXX
   8291  */
   8292 
   8293 int
   8294 bcm_esw_vlan_ip_action_delete_all(int unit)
   8295 {
   8296 #ifdef BCM_TRX_SUPPORT
   8297     int rv; 
   8298 
   8299     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)
   8300         && soc_feature(unit, soc_feature_ip_subnet_based_vlan)) {
   8301         soc_mem_lock(unit, VLAN_SUBNETm);
   8302         rv = _bcm_trx_vlan_ip_delete_all(unit);
   8303         soc_mem_unlock(unit, VLAN_SUBNETm);
   8304 
   8305         return rv;
   8306     }
   8307 #endif /* BCM_TRX_SUPPORT */
   8308 
   8309     return BCM_E_UNAVAIL;
   8310 }
   8311 /*
   8312  * Function:
   8313  *      bcm_esw_vlan_ip_action_traverse
   8314  * Purpose:
   8315  *      Delete all actions for all subnets
   8316  * Parameters:
   8317  *      unit    -   (IN) device number
   8318  *      cb      -   (IN) call back function 
   8319  *      user_data - (IN) a pointer to user data
   8320  * Returns:
   8321  *      BCM_E_XXX
   8322  */
   8323 int
   8324 bcm_esw_vlan_ip_action_traverse(int unit, bcm_vlan_ip_action_traverse_cb cb, 
   8325                                 void *user_data)
   8326 {
   8327 #ifdef BCM_TRX_SUPPORT
   8328     int rv;
   8329 
   8330     if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_vlan_action)
   8331         && soc_feature(unit, soc_feature_ip_subnet_based_vlan)) {
   8332         soc_mem_lock(unit, VLAN_SUBNETm);
   8333         rv = _bcm_trx_vlan_ip_action_traverse(unit, cb, user_data);
   8334         soc_mem_unlock(unit, VLAN_SUBNETm);
   8335 
   8336         return rv;
   8337     }
   8338 #endif /* BCM_TRX_SUPPORT */
   8339 
   8340     return BCM_E_UNAVAIL;
   8341 }
   8342 
   8343 /*
   8344  * IMPLEMENTATION NOTES
   8345  *
   8346  * bcm_vlan_ip4_* should be implemented in FB/ER as adding
   8347  * entries to the VLAN_SUBNET tables with:
   8348  *      VLAN_SUBNET.IP_ADDR = 0xFFFF0000 <ip4_addr>
   8349  *      VLAN_SUBNET.MASK = 0xFFFFFFFF <ip4_netmask>
   8350  *      VLAN_SUBNET.VALID = 1
   8351  * The VLAN_SUBNET entries must be sorted in order from
   8352  * longest prefix match to shortest prefix match.
   8353  */
   8354 
   8355 /*
   8356  * Function:
   8357  *     bcm_vlan_control_set
   8358  *
   8359  * Purpose:
   8360  *     Set miscellaneous VLAN-specific chip options
   8361  *
   8362  * Parameters:
   8363  *     unit - StrataSwitch PCI device unit number (driver internal).
   8364  *     type - A value from bcm_vlan_control_t enumeration list
   8365  *     arg  - state whose meaning is dependent on 'type'
   8366  *
   8367  * Returns:
   8368  *     BCM_E_NONE     - Success
   8369  *     BCM_E_INTERNAL - Chip access failure.
   8370  *     BCM_E_UNAVAIL  - type not supported on unit
   8371  */
   8372 
   8373 int
   8374 bcm_esw_vlan_control_set(int unit, bcm_vlan_control_t type, int arg)
   8375 {
   8376     bcm_pbmp_t e_pbmp;
   8377 
   8378 #if defined(BCM_HGPROXY_COE_SUPPORT)
   8379     int i;
   8380     bcm_gport_t gport;
   8381 #endif /* BCM_HGPROXY_COE_SUPPORT */
   8382 
   8383 #ifdef BCM_TOMAHAWK3_SUPPORT
   8384     if (SOC_IS_TOMAHAWK3(unit)) {
   8385         return bcm_tomahawk3_vlan_control_set(unit, type, arg);
   8386     }
   8387 #endif
   8388 
   8389     LOG_VERBOSE(BSL_LS_BCM_VLAN,
   8390                 (BSL_META_U(unit,
   8391                             "VLAN %d: control set: type %d, arg %d\n"),
   8392                  unit, type, arg));
   8393 
   8394     BCM_PBMP_CLEAR(e_pbmp);
   8395     BCM_PBMP_ASSIGN(e_pbmp, PBMP_E_ALL(unit));
   8396 #ifdef BCM_KATANA2_SUPPORT
   8397     if (soc_feature(unit, soc_feature_linkphy_coe) ||
   8398         soc_feature(unit, soc_feature_subtag_coe)) {
   8399         _bcm_kt2_subport_pbmp_update (unit, &e_pbmp);
   8400     }
   8401     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
   8402         BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &e_pbmp));
   8403     }
   8404 #endif
   8405 
   8406 #ifdef BCM_XGS3_SWITCH_SUPPORT
   8407     if (SOC_IS_XGS3_SWITCH(unit) && (!SOC_IS_XGS3_FABRIC(unit) ||
   8408         SOC_IS_TOMAHAWK2(unit))) {
   8409         bcm_port_t  port;
   8410         uint32      vlan_ctrl;
   8411         uint32      data;
   8412         int         oval;
   8413 
   8414         PBMP_E_ITER(unit, port) {
   8415             break;
   8416         }
   8417 
   8418         switch (type) {
   8419         case bcmVlanDropUnknown:
   8420             return bcm_esw_switch_control_set(unit,
   8421                                               bcmSwitchUnknownVlanToCpu,
   8422                                               arg ? 0 : 1);
   8423 
   8424         case bcmVlanShared:
   8425             if (!SOC_REG_FIELD_VALID(unit, EGR_CONFIGr, USE_LEARN_VIDf) ||
   8426                 !SOC_REG_FIELD_VALID(unit, VLAN_CTRLr, USE_LEARN_VIDf)) {
   8427                 return BCM_E_UNAVAIL;
   8428             }
   8429             arg = (arg ? 1 : 0);
   8430             SOC_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &vlan_ctrl));
   8431             data = vlan_ctrl;
   8432             soc_reg_field_set(unit, VLAN_CTRLr, &vlan_ctrl,
   8433                               USE_LEARN_VIDf, arg);
   8434             if (data != vlan_ctrl) {
   8435                 SOC_IF_ERROR_RETURN(WRITE_VLAN_CTRLr(unit, vlan_ctrl));
   8436                 if (SOC_IS_FBX(unit)) {
   8437                     SOC_IF_ERROR_RETURN
   8438                         (soc_reg_field32_modify(unit, EGR_CONFIGr, port,
   8439                                                 USE_LEARN_VIDf, arg));
   8440                 }
   8441             }
   8442             return BCM_E_NONE;
   8443         case bcmVlanSharedID:
   8444             if (!SOC_REG_FIELD_VALID(unit, EGR_CONFIGr, LEARN_VIDf) ||
   8445                 !SOC_REG_FIELD_VALID(unit, VLAN_CTRLr, LEARN_VIDf)) {
   8446                 return BCM_E_UNAVAIL;
   8447             }
   8448             SOC_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &vlan_ctrl));
   8449             data = vlan_ctrl;
   8450             soc_reg_field_set(unit, VLAN_CTRLr, &vlan_ctrl,
   8451                               LEARN_VIDf, arg);
   8452             if (data != vlan_ctrl) {
   8453                 SOC_IF_ERROR_RETURN(WRITE_VLAN_CTRLr(unit, vlan_ctrl));
   8454                 if (SOC_IS_FBX(unit)) {
   8455                     SOC_IF_ERROR_RETURN
   8456                         (soc_reg_field32_modify(unit, EGR_CONFIGr, port,
   8457                                                 LEARN_VIDf, arg));
   8458                 }
   8459             }
   8460             return BCM_E_NONE;
   8461         case bcmVlanPreferIP4:
   8462             arg = (arg ? 1 : 0);
   8463             SOC_IF_ERROR_RETURN
   8464                 (_bcm_esw_port_config_get(unit, port,
   8465                                           _bcmPortVlanPrecedence, &oval));
   8466             if (arg != oval) {
   8467                 PBMP_ITER(e_pbmp, port) {
   8468                     SOC_IF_ERROR_RETURN
   8469                         (_bcm_esw_port_config_set(unit, port,
   8470                                               _bcmPortVlanPrecedence, arg));
   8471                 }
   8472 #if defined(BCM_HGPROXY_COE_SUPPORT)
   8473                 BCM_HGPROXY_SUBTAG_COE_PORT_ITER(i, gport) {
   8474                     SOC_IF_ERROR_RETURN
   8475                         (_bcm_esw_port_config_set(unit, gport,
   8476                                                   _bcmPortVlanPrecedence, arg));
   8477                 }
   8478 #endif /* BCM_HGPROXY_COE_SUPPORT */
   8479             }
   8480             return BCM_E_NONE;
   8481 
   8482         case bcmVlanPreferMAC:
   8483             if (soc_feature(unit, soc_feature_mac_based_vlan)) {
   8484                 arg = (arg ? 0 : 1);
   8485                 SOC_IF_ERROR_RETURN
   8486                     (_bcm_esw_port_config_get(unit, port,
   8487                                               _bcmPortVlanPrecedence, &oval));
   8488                 if (arg != oval) {
   8489                     PBMP_ITER(e_pbmp, port) {
   8490                         SOC_IF_ERROR_RETURN
   8491                             (_bcm_esw_port_config_set(unit, port,
   8492                                                   _bcmPortVlanPrecedence, arg));
   8493                     }
   8494 #if defined(BCM_HGPROXY_COE_SUPPORT)
   8495                     BCM_HGPROXY_SUBTAG_COE_PORT_ITER(i, gport) {
   8496                         SOC_IF_ERROR_RETURN
   8497                             (_bcm_esw_port_config_set(unit, gport,
   8498                                                       _bcmPortVlanPrecedence,
   8499                                                       arg));
   8500                     }
   8501 #endif /* BCM_HGPROXY_COE_SUPPORT */
   8502 
   8503                 }
   8504                 return BCM_E_NONE;
   8505             }
   8506             return BCM_E_UNAVAIL;
   8507 
   8508         case bcmVlanTranslate:
   8509             if (soc_feature(unit, soc_feature_vlan_translation)) {
   8510                 arg = (arg ? 1 : 0);
   8511                 SOC_IF_ERROR_RETURN
   8512                     (_bcm_esw_port_config_get(unit, port,
   8513                                               _bcmPortVlanTranslate, &oval));
   8514                 if (arg != oval) {
   8515                     PBMP_ITER(e_pbmp, port) {
   8516 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   8517                         if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
   8518                             if (soc_feature(unit, soc_feature_egr_all_profile)) {
   8519                                 BCM_IF_ERROR_RETURN
   8520                                     (bcm_esw_port_egr_lport_field_set(unit, port,
   8521                                     EGR_VLAN_CONTROL_1m, VT_ENABLEf, arg));
   8522                             } else {
   8523                             egr_vlan_control_1_entry_t entry;
   8524                             SOC_IF_ERROR_RETURN(
   8525                                         READ_EGR_VLAN_CONTROL_1m(unit,
   8526                                         MEM_BLOCK_ANY, port, &entry));
   8527                                 soc_EGR_VLAN_CONTROL_1m_field32_set(unit,
   8528                                         &entry, VT_ENABLEf, arg);
   8529                             SOC_IF_ERROR_RETURN(
   8530                                         WRITE_EGR_VLAN_CONTROL_1m(unit,
   8531                                         MEM_BLOCK_ANY, port, &entry));
   8532                             }
   8533                         } else
   8534 #endif
   8535                         {
   8536                             SOC_IF_ERROR_RETURN
   8537                                 (soc_reg_field32_modify(unit, EGR_VLAN_CONTROL_1r,
   8538                                                         port, VT_ENABLEf, arg));
   8539                         }
   8540                         SOC_IF_ERROR_RETURN
   8541                             (_bcm_esw_port_config_set(unit, port,
   8542                                                       _bcmPortVlanTranslate, arg));
   8543                     }
   8544 #if defined(BCM_HGPROXY_COE_SUPPORT)
   8545                     BCM_HGPROXY_SUBTAG_COE_PORT_ITER(i, gport) {
   8546                         SOC_IF_ERROR_RETURN
   8547                             (_bcm_esw_port_config_set(unit, gport,
   8548                                                       _bcmPortVlanTranslate,
   8549                                                       arg));
   8550                     }
   8551 #endif /* BCM_HGPROXY_COE_SUPPORT */
   8552                 }
   8553                 return BCM_E_NONE;
   8554             }
   8555             return BCM_E_UNAVAIL;
   8556 
   8557         case bcmVlanPreferEgressTranslate:
   8558             arg = (arg ? 1 : 0);
   8559 #ifdef BCM_TRX_SUPPORT
   8560             if (SOC_IS_TRX(unit)) {
   8561                 SOC_IF_ERROR_RETURN
   8562                     (soc_reg_field32_modify(unit,
   8563                     SOC_IS_TRIDENT3X(unit) ? EGR_CONFIG_1_64r : EGR_CONFIG_1r,
   8564                     port, DISABLE_VT_IF_IFP_CHANGE_VLANf, arg));
   8565                 return BCM_E_NONE;
   8566             }
   8567 #endif
   8568             return BCM_E_UNAVAIL;
   8569         default:
   8570             return BCM_E_UNAVAIL;
   8571         }
   8572     }
   8573 #endif /* BCM_XGS3_SWITCH_SUPPORT */
   8574 
   8575 #ifdef BCM_XGS12_SWITCH_SUPPORT
   8576     if (SOC_IS_XGS12_SWITCH(unit)) {
   8577         bcm_port_t          port; 
   8578         uint64              r64, o64;
   8579         switch (type) {
   8580         case bcmVlanDropUnknown:
   8581             PBMP_E_ITER(unit, port) {
   8582                 SOC_IF_ERROR_RETURN(READ_CPU_CONTROLr(unit, port, &r64));
   8583                 o64 = r64;
   8584                 soc_reg64_field32_set(unit, CPU_CONTROLr, &r64,
   8585                                       UVLAN_TOCPUf, arg ? 0 : 1);
   8586                 if (COMPILER_64_NE(r64, o64)) {
   8587                     SOC_IF_ERROR_RETURN(WRITE_CPU_CONTROLr(unit, port, r64));
   8588                 }
   8589             }
   8590             return BCM_E_NONE;
   8591         case bcmVlanShared:
   8592             PBMP_E_ITER(unit, port) {
   8593                 SOC_IF_ERROR_RETURN(READ_VLAN_CONTROLr(unit, port, &r64));
   8594                 o64 = r64;
   8595                 soc_reg64_field32_set(unit, VLAN_CONTROLr, &r64,
   8596                                       USE_LEARN_VIDf, arg ? 1 : 0);
   8597                 if (COMPILER_64_NE(r64, o64)) {
   8598                     SOC_IF_ERROR_RETURN(WRITE_VLAN_CONTROLr(unit, port, r64));
   8599                 }
   8600             }
   8601             return BCM_E_NONE;
   8602         case bcmVlanSharedID:
   8603             PBMP_E_ITER(unit, port) {
   8604                 SOC_IF_ERROR_RETURN(READ_VLAN_CONTROLr(unit, port, &r64));
   8605                 o64 = r64;
   8606                 soc_reg64_field32_set(unit, VLAN_CONTROLr, &r64,
   8607                                       LEARN_VIDf, arg & 0xfff);
   8608                 if (COMPILER_64_NE(r64, o64)) {
   8609                     SOC_IF_ERROR_RETURN(WRITE_VLAN_CONTROLr(unit, port, r64));
   8610                 }
   8611             }
   8612             return BCM_E_NONE;
   8613         default:
   8614             break;
   8615         }
   8616     }
   8617 #endif /* BCM_XGS12_SWITCH_SUPPORT */
   8618     return BCM_E_UNAVAIL;
   8619 }
   8620 
   8621 /*
   8622  * Function:
   8623  *     bcm_vlan_control_get
   8624  *
   8625  * Purpose:
   8626  *     Get miscellaneous VLAN-specific chip options
   8627  *
   8628  * Parameters:
   8629  *     unit - StrataSwitch PCI device unit number (driver internal).
   8630  *     type - A value from bcm_vlan_control_t enumeration list
   8631  *     arg  - (OUT) state whose meaning is dependent on 'type'
   8632  *
   8633  * Returns:
   8634  *     BCM_E_NONE     - Success
   8635  *     BCM_E_PARAM    - arg points to NULL
   8636  *     BCM_E_INTERNAL - Chip access failure.
   8637  *     BCM_E_UNAVAIL  - type not supported on unit
   8638  */
   8639 
   8640 int
   8641 bcm_esw_vlan_control_get(int unit, bcm_vlan_control_t type, int *arg)
   8642 {
   8643 #ifdef BCM_TOMAHAWK3_SUPPORT
   8644     if (SOC_IS_TOMAHAWK3(unit)) {
   8645         return bcm_tomahawk3_vlan_control_get(unit, type, arg);
   8646     }
   8647 #endif
   8648 
   8649     if (arg == 0) {
   8650         return BCM_E_PARAM;
   8651     }
   8652 
   8653 #ifdef BCM_XGS3_SWITCH_SUPPORT
   8654     if (SOC_IS_XGS3_SWITCH(unit) && (!SOC_IS_XGS3_FABRIC(unit) ||
   8655         SOC_IS_TOMAHAWK2(unit))) {
   8656         int                 port;
   8657         uint32              vlan_ctrl;
   8658 
   8659         PBMP_E_ITER(unit, port) {
   8660             break;
   8661         }
   8662         switch (type) {
   8663 
   8664         case bcmVlanDropUnknown:
   8665             {
   8666                 int ret_val;
   8667                 ret_val = bcm_esw_switch_control_get(unit,
   8668                                                   bcmSwitchUnknownVlanToCpu,
   8669                                                   arg);
   8670                 if (ret_val == BCM_E_NONE) {
   8671                     *arg = (*arg) ? 0 : 1;
   8672                 }
   8673                 return ret_val;
   8674             }
   8675         case bcmVlanShared:
   8676             if (!SOC_REG_FIELD_VALID(unit, EGR_CONFIGr, USE_LEARN_VIDf) ||
   8677                 !SOC_REG_FIELD_VALID(unit, VLAN_CTRLr, USE_LEARN_VIDf)) {
   8678                 return BCM_E_UNAVAIL;
   8679             }
   8680             SOC_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &vlan_ctrl));
   8681             *arg = soc_reg_field_get(unit, VLAN_CTRLr,
   8682                                      vlan_ctrl, USE_LEARN_VIDf);
   8683             return BCM_E_NONE;
   8684 
   8685         case bcmVlanSharedID:
   8686             if (!SOC_REG_FIELD_VALID(unit, EGR_CONFIGr, LEARN_VIDf) ||
   8687                 !SOC_REG_FIELD_VALID(unit, VLAN_CTRLr, LEARN_VIDf)) {
   8688                 return BCM_E_UNAVAIL;
   8689             }
   8690             SOC_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &vlan_ctrl));
   8691             *arg = soc_reg_field_get(unit, VLAN_CTRLr,
   8692                                      vlan_ctrl, LEARN_VIDf);
   8693             return BCM_E_NONE;
   8694 
   8695         case bcmVlanPreferIP4:
   8696            return (_bcm_esw_port_config_get(unit, port,
   8697                                             _bcmPortVlanPrecedence, arg));
   8698         case bcmVlanPreferMAC:
   8699             SOC_IF_ERROR_RETURN
   8700                 (_bcm_esw_port_config_get(unit, port,
   8701                                           _bcmPortVlanPrecedence, arg));
   8702             *arg = !*arg;
   8703             return BCM_E_NONE;
   8704         case bcmVlanTranslate:
   8705             if (soc_feature(unit, soc_feature_vlan_translation)) {
   8706                 return (_bcm_esw_port_config_get(unit, port,
   8707                                                  _bcmPortVlanTranslate, arg));
   8708             } else {
   8709                 return BCM_E_UNAVAIL;
   8710             }
   8711         case bcmVlanPreferEgressTranslate:
   8712 #ifdef BCM_TRX_SUPPORT
   8713             if (SOC_IS_TRIDENT3X(unit)) {
   8714                 uint64  rval64;
   8715                 COMPILER_64_ZERO(rval64);
   8716                 SOC_IF_ERROR_RETURN(soc_reg_get(unit, EGR_CONFIG_1_64r,
   8717                                     REG_PORT_ANY, 0, &rval64));
   8718                 *arg = soc_reg64_field32_get(unit, EGR_CONFIG_1_64r, rval64,
   8719                             DISABLE_VT_IF_IFP_CHANGE_VLANf);
   8720                 return BCM_E_NONE;
   8721             } else if (SOC_IS_TRX(unit)) {
   8722                 uint32 egr_cfg;
   8723                 SOC_IF_ERROR_RETURN(READ_EGR_CONFIG_1r(unit, &egr_cfg));
   8724                 *arg = soc_reg_field_get(unit, EGR_CONFIG_1r, egr_cfg, 
   8725                                          DISABLE_VT_IF_IFP_CHANGE_VLANf);
   8726                 return BCM_E_NONE;
   8727             }
   8728 #endif
   8729             return BCM_E_UNAVAIL;
   8730         default:
   8731             return BCM_E_UNAVAIL;
   8732         }
   8733     }
   8734 #endif /* BCM_XGS3_SWITCH_SUPPORT */
   8735 
   8736 #ifdef BCM_XGS12_SWITCH_SUPPORT
   8737     if (SOC_IS_XGS12_SWITCH(unit)) {
   8738         int                 port;
   8739         uint64              r64;
   8740         switch (type) {
   8741         case bcmVlanDropUnknown:
   8742             COMPILER_64_ZERO(r64);
   8743             PBMP_E_ITER(unit, port) {
   8744                 SOC_IF_ERROR_RETURN(READ_CPU_CONTROLr(unit, port, &r64));
   8745                 break;
   8746             }
   8747             *arg = !soc_reg64_field32_get(unit, CPU_CONTROLr, r64,
   8748                                           UVLAN_TOCPUf);
   8749             return BCM_E_NONE;
   8750         case bcmVlanShared:
   8751             COMPILER_64_ZERO(r64);
   8752             PBMP_E_ITER(unit, port) {
   8753                 SOC_IF_ERROR_RETURN(READ_VLAN_CONTROLr(unit, port, &r64));
   8754                 break;
   8755             }
   8756             *arg = soc_reg64_field32_get(unit, VLAN_CONTROLr, r64,
   8757                                          USE_LEARN_VIDf);
   8758             return BCM_E_NONE;
   8759         case bcmVlanSharedID:
   8760             COMPILER_64_ZERO(r64);
   8761             PBMP_E_ITER(unit, port) {
   8762                 SOC_IF_ERROR_RETURN(READ_VLAN_CONTROLr(unit, port, &r64));
   8763                 break;
   8764             }
   8765             *arg = soc_reg64_field32_get(unit, VLAN_CONTROLr, r64,
   8766                                          LEARN_VIDf);
   8767             return BCM_E_NONE;
   8768         default:
   8769             return BCM_E_UNAVAIL;
   8770         }
   8771     }
   8772 #endif /* BCM_XGS12_SWITCH_SUPPORT */
   8773 
   8774     return BCM_E_UNAVAIL;
   8775 }
   8776 
   8777 /*
   8778  * Function:
   8779  *      bcm_esw_vlan_control_port_proxy_validate
   8780  * Description:
   8781  *      Checks that vlan port control is valid for a PROXY GPORT.
   8782  *      Resolves port to expected port value for the given port control type.
   8783  * Parameters:
   8784  *      unit      - (IN) Device number
   8785  *      port      - (IN) Port to resolve
   8786  *      type      - (IN) Vlan control type
   8787  *      port_out  - (OUT) Returns port (gport or BCM format) that
   8788  *                  is expected for corresponding vlan control type.
   8789  * Return Value:
   8790  *      BCM_E_XXX
   8791  */
   8792 STATIC int
   8793 bcm_esw_vlan_control_port_proxy_validate(int unit, bcm_port_t port,
   8794                                          bcm_vlan_control_port_t type,
   8795                                          bcm_port_t *port_out)
   8796 {
   8797     int rv = BCM_E_PORT;
   8798     int support = FALSE;
   8799 
   8800     if (!soc_feature(unit, soc_feature_proxy_port_property)) {
   8801         return BCM_E_PORT;
   8802     }
   8803 
   8804     switch(type) {
   8805     case bcmVlanTranslateIngressEnable:
   8806     case bcmVlanPortTranslateKeyFirst:
   8807     case bcmVlanPortTranslateKeySecond: 
   8808         support = TRUE;
   8809         break;
   8810     default:
   8811         support = FALSE;
   8812         break;
   8813     }
   8814 
   8815     if (support) {
   8816         *port_out = port;
   8817         rv = BCM_E_NONE;
   8818     }
   8819 
   8820     return rv;
   8821 }
   8822 
   8823 /*
   8824  * Function:
   8825  *      bcm_esw_vlan_control_port_niv_validate
   8826  * Description:
   8827  *      Checks that vlan port control is valid for a NIV GPORT.
   8828  *      Resolves port to expected port value for the given port control type.
   8829  * Parameters:
   8830  *      unit      - (IN) Device number
   8831  *      port      - (IN) Port to resolve
   8832  *      type      - (IN) Vlan control type
   8833  *      port_out  - (OUT) Returns port (gport or BCM format) that
   8834  *                  is expected for corresponding vlan control type.
   8835  * Return Value:
   8836  *      BCM_E_XXX
   8837  */
   8838 STATIC int
   8839 bcm_esw_vlan_control_port_niv_validate(int unit, bcm_port_t port,
   8840                                        bcm_vlan_control_port_t type,
   8841                                        bcm_port_t *port_out)
   8842 {
   8843 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
   8844     int rv = BCM_E_PORT;
   8845     int support = FALSE;
   8846 
   8847     if (!soc_feature(unit, soc_feature_niv)) {
   8848         return BCM_E_PORT;
   8849     }
   8850 
   8851     switch(type) {
   8852     case bcmVlanPortTranslateKeyFirst:
   8853         support = TRUE;
   8854         break;
   8855     default:
   8856         support = FALSE;
   8857         break;
   8858     }
   8859 
   8860     if (support) {
   8861         *port_out = port;
   8862         rv = BCM_E_NONE;
   8863     }
   8864 
   8865     return rv;
   8866 #else
   8867     return BCM_E_PORT;
   8868 #endif
   8869 }
   8870 
   8871 /*
   8872  * Function:
   8873  *      bcm_esw_vlan_control_port_flow_validate
   8874  * Description:
   8875  *      Checks that vlan port control is valid for a FLOW GPORT.
   8876  *      Resolves port to expected port value for the given port control type.
   8877  * Parameters:
   8878  *      unit      - (IN) Device number
   8879  *      port      - (IN) Port to resolve
   8880  *      type      - (IN) Vlan control type
   8881  *      port_out  - (OUT) Returns port (gport or BCM format) that
   8882  *                  is expected for corresponding vlan control type.
   8883  * Return Value:
   8884  *      BCM_E_XXX
   8885  */
   8886 STATIC int
   8887 bcm_esw_vlan_control_port_flow_validate(int unit, bcm_port_t port,
   8888                                        bcm_vlan_control_port_t type,
   8889                                        bcm_port_t *port_out)
   8890 {
   8891 #if defined(BCM_TRIDENT3_SUPPORT) && defined(INCLUDE_L3)
   8892     int rv = BCM_E_PORT;
   8893     int support = FALSE;
   8894 
   8895     if (!soc_feature(unit, soc_feature_flex_flow)) {
   8896         return BCM_E_PORT;
   8897     }
   8898 
   8899     switch(type) {
   8900     case bcmVlanPortTranslateEgressKey:
   8901     case bcmVlanPortUseInnerPri:
   8902         support = TRUE;
   8903         break;
   8904     default:
   8905         support = FALSE;
   8906         break;
   8907     }
   8908 
   8909     if (support) {
   8910         *port_out = port;
   8911         rv = BCM_E_NONE;
   8912     }
   8913 
   8914     return rv;
   8915 #else
   8916     return BCM_E_PORT;
   8917 #endif
   8918 }
   8919 
   8920 #if defined(BCM_TRX_SUPPORT) 
   8921 /*
   8922  * Function:
   8923  *      bcm_esw_vlan_control_port_niv_resolve
   8924  * Description:
   8925  *      Resolve NIV GPORT to a BCM local physical port.
   8926  * Parameters:
   8927  *      unit      - (IN) Device number
   8928  *      port      - (IN) Port to resolve
   8929  *      port_out  - (OUT) Returns BCM local physical port
   8930  * Return Value:
   8931  *      BCM_E_XXX
   8932  */
   8933 STATIC int
   8934 bcm_esw_vlan_control_port_niv_resolve(int unit, bcm_port_t port,
   8935                                       bcm_port_t *port_out)
   8936 {
   8937 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
   8938     bcm_niv_port_t niv_port;
   8939     bcm_module_t modid;
   8940     bcm_port_t local_port;
   8941     bcm_trunk_t trunk_id;
   8942     int gport_id;
   8943     int is_local;
   8944     bcm_niv_egress_t niv_egress;
   8945     int              rv = BCM_E_NONE;
   8946     bcm_gport_t      gport;
   8947     int              count;
   8948 
   8949     bcm_niv_port_t_init(&niv_port);
   8950     niv_port.niv_port_id = port;
   8951 
   8952     BCM_IF_ERROR_RETURN(bcm_esw_niv_port_get(unit, &niv_port));
   8953     if (niv_port.flags & BCM_NIV_PORT_MATCH_NONE) {
   8954         bcm_niv_egress_t_init(&niv_egress);
   8955         rv = bcm_trident_niv_egress_get(unit, niv_port.niv_port_id,
   8956                                         1, &niv_egress, &count);
   8957         if (BCM_FAILURE(rv)) {
   8958             return BCM_E_PARAM;
   8959         }
   8960         
   8961         if (niv_egress.flags & BCM_NIV_EGRESS_MULTICAST) {
   8962             return BCM_E_PARAM;
   8963         } else {
   8964             gport = niv_egress.port;
   8965         }
   8966     } else {
   8967         gport = niv_port.port;
   8968     }
   8969 
   8970     BCM_IF_ERROR_RETURN
   8971         (_bcm_esw_gport_resolve(unit, gport, 
   8972                                 &modid, &local_port,
   8973                                 &trunk_id, &gport_id));
   8974 
   8975     BCM_IF_ERROR_RETURN(_bcm_esw_modid_is_local(unit, modid, &is_local));
   8976     if (!is_local) {
   8977         return BCM_E_PORT;
   8978 
   8979     }
   8980 
   8981     *port_out = local_port;
   8982 
   8983     return BCM_E_NONE;
   8984 #else
   8985     return BCM_E_PORT;
   8986 #endif
   8987 }
   8988 #endif /*BCM_TRX_SUPPORT*/
   8989 /*
   8990  * Function:
   8991  *      bcm_esw_vlan_control_port_validate
   8992  * Description:
   8993  *      Checks that port is valid and that control is supported
   8994  *      for the given port type.  Resolves port to expected
   8995  *      port value for the given vlan control type.
   8996  * Parameters:
   8997  *      unit      - (IN) Device number
   8998  *      port      - (IN) Port to resolve
   8999  *      type      - (IN) Vlan control type
   9000  *      port_out  - (OUT) Returns port (gport or BCM format) that
   9001  *                  is expected for corresponding vlan control type.
   9002  * Return Value:
   9003  *      BCM_E_XXX
   9004  */
   9005 STATIC int
   9006 bcm_esw_vlan_control_port_validate(int unit, bcm_port_t port,
   9007                                    bcm_vlan_control_port_t type,
   9008                                    bcm_port_t *port_out)
   9009 {
   9010     bcm_module_t  modid;
   9011     bcm_port_t  port_id;
   9012     bcm_trunk_t  tgid;
   9013     int  id;
   9014 #if defined(BCM_KATANA2_SUPPORT)
   9015     int my_modid = 0, pp_port;
   9016     int min_subport = SOC_INFO(unit).pp_port_index_min;
   9017     int max_subport = SOC_INFO(unit).pp_port_index_max;
   9018 #endif
   9019 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_HGPROXY_COE_SUPPORT)
   9020     int is_local_subport = FALSE;
   9021 #endif
   9022 
   9023     if (BCM_GPORT_IS_SET(port)) {
   9024         if (BCM_GPORT_IS_PROXY(port)) {
   9025             BCM_IF_ERROR_RETURN
   9026                 (bcm_esw_vlan_control_port_proxy_validate(unit, port,
   9027                                                           type, port_out));
   9028         } else if (BCM_GPORT_IS_NIV_PORT(port)) {
   9029             BCM_IF_ERROR_RETURN
   9030                 (bcm_esw_vlan_control_port_niv_validate(unit, port,
   9031                                                         type, port_out));
   9032         } else if (BCM_GPORT_IS_FLOW_PORT(port)) {
   9033             BCM_IF_ERROR_RETURN
   9034                 (bcm_esw_vlan_control_port_flow_validate(unit, port,
   9035                                                           type, port_out));
   9036         } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
   9037 
   9038 #if defined(BCM_HGPROXY_COE_SUPPORT)
   9039         if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   9040             BCM_GPORT_IS_SET(port) &&
   9041             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   9042 
   9043             if(_bcm_xgs5_subport_coe_gport_local(unit, port)) {
   9044                 is_local_subport = TRUE;
   9045             }
   9046 
   9047             if (is_local_subport == FALSE) {
   9048                 return BCM_E_PORT;
   9049             }
   9050 
   9051             /*For HGPROXY_COE, subport is needed for configuring
   9052              *port and lport tables.
   9053              */
   9054             *port_out = port;
   9055 
   9056         } else 
   9057 #endif
   9058 #if defined(BCM_KATANA2_SUPPORT)
   9059             if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port)) {
   9060                 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
   9061                     &modid, &port_id, &tgid, &id));
   9062                     pp_port = BCM_GPORT_SUBPORT_PORT_GET(port);
   9063                 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
   9064                 if ((_bcm_kt2_mod_is_coe_mod_check(unit, modid) == BCM_E_NONE) ||
   9065                     (soc_feature(unit, soc_feature_general_cascade) &&
   9066                      SOC_PBMP_MEMBER(SOC_INFO(unit).general_pp_port_pbm, pp_port))) {
   9067 #if defined BCM_METROLITE_SUPPORT
   9068                     if (soc_feature(unit, soc_feature_discontinuous_pp_port)) {
   9069                         if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) {
   9070                             is_local_subport = 1;
   9071                             *port_out = pp_port;
   9072                         }
   9073                     } else
   9074 #endif
   9075                     {
   9076                         if ((pp_port >= min_subport) &&
   9077                             (pp_port <= max_subport)) {
   9078                             is_local_subport = 1;
   9079                             *port_out = pp_port;
   9080                         }
   9081                     }
   9082                 }
   9083                 if (is_local_subport == 0) {
   9084                     return BCM_E_PORT;
   9085                 }
   9086             } else
   9087 #endif
   9088             {
   9089                 return BCM_E_PORT;
   9090             }
   9091         } else {
   9092             /* Other GPORT types */
   9093             if (BCM_SUCCESS(_bcm_vlan_control_trust_gport(type))) {
   9094                 *port_out = port;
   9095             } else {
   9096                 BCM_IF_ERROR_RETURN
   9097                     (_bcm_esw_gport_resolve(unit, port, &modid, &port_id,
   9098                                             &tgid, &id));
   9099                 if ((id != -1) || (tgid != -1)) {
   9100                     return BCM_E_PORT;
   9101                 }
   9102                 *port_out = port_id;
   9103             }
   9104         }
   9105 
   9106     } else {
   9107 
   9108 #ifdef BCM_KATANA2_SUPPORT
   9109         if ((soc_feature(unit, soc_feature_linkphy_coe) &&
   9110              BCM_PBMP_MEMBER(SOC_INFO(unit).linkphy_pp_port_pbm, port)) ||
   9111             (soc_feature(unit, soc_feature_subtag_coe) &&
   9112              BCM_PBMP_MEMBER(SOC_INFO(unit).subtag_pp_port_pbm, port))) {
   9113         } else
   9114 #endif
   9115         if (!SOC_PORT_VALID(unit, port)) {
   9116             return BCM_E_PORT;
   9117         }
   9118         *port_out = port;
   9119     }
   9120 
   9121     return BCM_E_NONE;
   9122 }
   9123 
   9124 STATIC int
   9125 _bcm_vlan_control_port_set(int unit, int port,
   9126                            bcm_vlan_control_port_t type, int arg)
   9127 {
   9128 #if defined(BCM_FIREBOLT_SUPPORT)
   9129     if (SOC_IS_FBX(unit)) {
   9130         uint32 data;
   9131         uint32 evc;
   9132         soc_reg_t egr_register;
   9133         int key_type_value;
   9134 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9135         soc_field_t field = VT_ENABLEf;
   9136         soc_mem_t egr_mem;
   9137         egr_mem = EGR_VLAN_CONTROL_1m;
   9138 #endif
   9139         egr_register = EGR_VLAN_CONTROL_1r;
   9140 
   9141         switch (type) {
   9142         case bcmVlanPortPreferIP4:
   9143             arg = (arg ? 1 : 0);
   9144             return (_bcm_esw_port_config_set(unit, port,
   9145                                              _bcmPortVlanPrecedence, arg));
   9146 
   9147         case bcmVlanPortPreferMAC:
   9148             arg = (arg ? 0 : 1);
   9149             return (_bcm_esw_port_config_set(unit, port,
   9150                                              _bcmPortVlanPrecedence, arg));
   9151 
   9152         case bcmVlanTranslateIngressEnable:
   9153             if (soc_feature(unit, soc_feature_vlan_translation)) {
   9154                 arg = (arg ? 1 : 0);
   9155                 return (_bcm_esw_port_config_set(unit, port,
   9156                                                  _bcmPortVlanTranslate, arg));
   9157             }
   9158             return BCM_E_UNAVAIL;
   9159 
   9160         case bcmVlanTranslateIngressMissDrop:
   9161             if (soc_feature(unit, soc_feature_vlan_translation)) {
   9162                 arg = (arg ? 1 : 0);
   9163                 return (_bcm_esw_port_config_set(unit, port,
   9164                                                 _bcmPortVTMissDrop, arg));
   9165             }
   9166             return BCM_E_UNAVAIL;
   9167 
   9168         case bcmVlanTranslateEgressEnable:
   9169             if (soc_feature(unit, soc_feature_vlan_translation)) {
   9170                 arg = (arg ? 1 : 0);
   9171 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9172                 if (SOC_MEM_IS_VALID(unit, egr_mem)) {
   9173                     egr_vlan_control_1_entry_t entry;
   9174                     if (soc_feature(unit, soc_feature_egr_all_profile)
   9175 #if defined(BCM_HGPROXY_COE_SUPPORT)
   9176                         || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   9177                         BCM_GPORT_IS_SET(port) &&
   9178                             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))
   9179 #endif
   9180                         ) {
   9181                         SOC_IF_ERROR_RETURN(
   9182                             bcm_esw_port_egr_lport_field_set(unit, port,
   9183                             EGR_VLAN_CONTROL_1m, VT_ENABLEf, arg));
   9184                         return BCM_E_NONE;
   9185                     }
   9186                     SOC_IF_ERROR_RETURN
   9187                             (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, port, &entry));
   9188                     data = soc_mem_field32_get(unit, egr_mem, &entry, VT_ENABLEf);
   9189                     if (data != arg) {
   9190                         soc_mem_field32_set(unit, egr_mem, &entry, VT_ENABLEf, arg);
   9191                         return (soc_mem_write(unit, egr_mem, MEM_BLOCK_ANY, port, &entry));
   9192                     }
   9193                 } else
   9194 #endif
   9195                 {
   9196                     SOC_IF_ERROR_RETURN
   9197                         (soc_reg32_get(unit, egr_register, port, 0, &evc));
   9198                     data = evc;
   9199                     soc_reg_field_set(unit, egr_register, &evc, VT_ENABLEf, arg);
   9200                     if (evc != data) {
   9201                         return (soc_reg32_set(unit, egr_register, port, 0, evc));
   9202                     }
   9203                 }
   9204                 return BCM_E_NONE;
   9205             }
   9206             return BCM_E_UNAVAIL;
   9207 
   9208         case bcmVlanTranslateEgressMissDrop:
   9209             if (soc_feature(unit, soc_feature_vlan_translation)) {
   9210                 arg = (arg ? 1 : 0);
   9211 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9212                 if (SOC_MEM_IS_VALID(unit, egr_mem)) {
   9213                     egr_vlan_control_1_entry_t entry;
   9214                     if (soc_feature(unit, soc_feature_egr_all_profile)
   9215 #if defined(BCM_HGPROXY_COE_SUPPORT)
   9216                         || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   9217                         BCM_GPORT_IS_SET(port) &&
   9218                             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))
   9219 #endif
   9220                         ) {
   9221                         SOC_IF_ERROR_RETURN(
   9222                             bcm_esw_port_egr_lport_field_set(unit, port,
   9223                             EGR_VLAN_CONTROL_1m, VT_MISS_DROPf, arg));
   9224                         return BCM_E_NONE;
   9225                     }
   9226                     SOC_IF_ERROR_RETURN
   9227                             (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, port, &entry));
   9228                     data = soc_mem_field32_get(unit, egr_mem, &entry, VT_MISS_DROPf);
   9229                     if (data != arg) {
   9230                         soc_mem_field32_set(unit, egr_mem, &entry, VT_MISS_DROPf, arg);
   9231                         return (soc_mem_write(unit, egr_mem, MEM_BLOCK_ANY, port, &entry));
   9232                     }
   9233                 } else
   9234 #endif
   9235                 {
   9236                     SOC_IF_ERROR_RETURN
   9237                         (soc_reg32_get(unit, egr_register, port, 0, &evc));
   9238                     data = evc;
   9239                     soc_reg_field_set(unit, egr_register, &evc, VT_MISS_DROPf, arg);
   9240                     if (evc != data) {
   9241                         return (soc_reg32_set(unit, egr_register, port, 0, evc));
   9242                     }
   9243                 }
   9244                 return BCM_E_NONE;
   9245             }
   9246             return BCM_E_UNAVAIL;
   9247 
   9248         case bcmVlanTranslateEgressMissUntaggedDrop:
   9249             if ((soc_feature(unit, soc_feature_untagged_vt_miss)) &&
   9250                 (soc_feature(unit,soc_feature_vlan_translation))) {
   9251                 arg = (arg ? 1 : 0);
   9252 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9253                 if (SOC_MEM_IS_VALID(unit, egr_mem)) {
   9254                     egr_vlan_control_1_entry_t entry;
   9255                     if (soc_feature(unit, soc_feature_egr_all_profile)
   9256 #if defined(BCM_HGPROXY_COE_SUPPORT)
   9257                         || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   9258                         BCM_GPORT_IS_SET(port) &&
   9259                             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))
   9260 #endif
   9261                         ) {
   9262                         SOC_IF_ERROR_RETURN(
   9263                             bcm_esw_port_egr_lport_field_set(unit, port,
   9264                             EGR_VLAN_CONTROL_1m, VT_MISS_UT_DROPf, arg));
   9265                         return BCM_E_NONE;
   9266                     }
   9267                     SOC_IF_ERROR_RETURN
   9268                             (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, port, &entry));
   9269                     data = soc_mem_field32_get(unit, egr_mem, &entry, VT_MISS_UT_DROPf);
   9270                     if (data != arg) {
   9271                         soc_mem_field32_set(unit, egr_mem, &entry, VT_MISS_UT_DROPf, arg);
   9272                         SOC_IF_ERROR_RETURN
   9273                             (soc_mem_write(unit, egr_mem, MEM_BLOCK_ANY, port, &entry));
   9274                     }
   9275                 } else
   9276 #endif
   9277                 {
   9278                     SOC_IF_ERROR_RETURN
   9279                         (soc_reg32_get(unit, egr_register, port, 0, &evc));
   9280                     data = evc;
   9281                     soc_reg_field_set(unit, egr_register, &evc, VT_MISS_UT_DROPf,
   9282                                       arg);
   9283                     if (evc != data) {
   9284                         SOC_IF_ERROR_RETURN
   9285                             (soc_reg32_set(unit, egr_register, port, 0, evc));
   9286                     }
   9287                 }
   9288                 return BCM_E_NONE;
   9289             }
   9290             return BCM_E_UNAVAIL;
   9291 
   9292         case bcmVlanTranslateEgressMissUntag:
   9293 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) || \
   9294             defined(BCM_RAVEN_SUPPORT)
   9295 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9296             if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
   9297                 egr_vlan_control_1_entry_t entry;
   9298                 if (SOC_MEM_FIELD_VALID(unit, egr_mem, VT_MISS_UNTAGf)) {
   9299                     arg = (arg ? 1 : 0);
   9300                     if (soc_feature(unit, soc_feature_egr_all_profile)
   9301 #if defined(BCM_HGPROXY_COE_SUPPORT)
   9302                         || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   9303                         BCM_GPORT_IS_SET(port) &&
   9304                             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))
   9305 #endif
   9306                         ) {
   9307                         SOC_IF_ERROR_RETURN(
   9308                             bcm_esw_port_egr_lport_field_set(unit, port,
   9309                             EGR_VLAN_CONTROL_1m, VT_MISS_UNTAGf, arg));
   9310                         if (SOC_IS_TRIDENT3X(unit)) {
   9311                             SOC_IF_ERROR_RETURN(_bcm_esw_egr_port_tab_set(unit,
   9312                                      port,VXLT_CTRL_IDf, arg));
   9313                         }
   9314                         return BCM_E_NONE;
   9315                     }
   9316                     SOC_IF_ERROR_RETURN(soc_mem_read(unit, egr_mem,
   9317                                     MEM_BLOCK_ANY, port, &entry));
   9318                     soc_mem_field32_set(unit, egr_mem, &entry,
   9319                                             VT_MISS_UNTAGf, arg);
   9320                     return soc_mem_write(unit, EGR_VLAN_CONTROL_1m,
   9321                                         MEM_BLOCK_ANY, port, &entry);
   9322                 }
   9323             } else
   9324 #endif
   9325             {
   9326                 if (SOC_REG_FIELD_VALID(unit, egr_register, VT_MISS_UNTAGf)) {
   9327                     arg = (arg ? 1 : 0);
   9328                     return soc_reg_field32_modify(unit, egr_register, port,
   9329                                                   VT_MISS_UNTAGf, arg);
   9330                 }
   9331             }
   9332 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRIUMPH_SUPPORT || BCM_RAPTOR_SUPPORT */
   9333             return BCM_E_UNAVAIL;
   9334 
   9335         case bcmVlanLookupMACEnable:
   9336             arg = (arg ? 1 : 0);
   9337             return (_bcm_esw_port_config_set(unit, port,
   9338                                              _bcmPortLookupMACEnable, arg));
   9339 
   9340         case bcmVlanLookupIPEnable:
   9341             arg = (arg ? 1 : 0);
   9342             return (_bcm_esw_port_config_set(unit, port,
   9343                                              _bcmPortLookupIPEnable, arg));
   9344 
   9345         case bcmVlanPortUseInnerPri:
   9346             arg = (arg ? 1 : 0);
   9347 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
   9348             if (BCM_GPORT_IS_MIM_PORT(port) || BCM_GPORT_IS_MPLS_PORT(port) ||
   9349                 BCM_GPORT_IS_VXLAN_PORT(port)) {
   9350                 return (_bcm_tr2_svp_field_set(unit, port, 
   9351                                                USE_INNER_PRIf, arg));
   9352             }
   9353 #endif
   9354 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
   9355  || defined(BCM_RAVEN_SUPPORT)
   9356             if (SOC_IS_FIREBOLT2(unit) || SOC_IS_TRX(unit) ||
   9357                 SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) {
   9358                 if (BCM_GPORT_IS_SET(port)) {
   9359                 BCM_IF_ERROR_RETURN(
   9360                     bcm_esw_port_local_get(unit, port, &port));
   9361                 }
   9362                 return (_bcm_esw_port_config_set(unit, port,
   9363                                                  _bcmPortUseInnerPri, arg));
   9364             }
   9365 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
   9366             return BCM_E_UNAVAIL;
   9367 
   9368         case bcmVlanPortUseOuterPri:
   9369             arg = (arg ? 1 : 0);
   9370 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
   9371             if (BCM_GPORT_IS_MPLS_PORT(port) || BCM_GPORT_IS_MIM_PORT(port)) {
   9372                 int rv = BCM_E_NONE;
   9373                 rv = _bcm_tr2_svp_field_set(unit, port,
   9374                                             TRUST_OUTER_DOT1Pf, arg);
   9375                 if (rv == BCM_E_UNAVAIL) {
   9376                     return BCM_E_PORT;
   9377                 } else {
   9378                     return rv;
   9379                 }
   9380             }
   9381 #endif
   9382 #if defined(BCM_TRX_SUPPORT)
   9383             if (SOC_IS_TRX(unit)) {
   9384                 if (BCM_GPORT_IS_SET(port)) {
   9385                 BCM_IF_ERROR_RETURN(
   9386                     bcm_esw_port_local_get(unit, port, &port));
   9387                 }
   9388                 return (_bcm_esw_port_config_set(unit, port,
   9389                                                  _bcmPortUseOuterPri, arg));
   9390             }
   9391 #endif /* BCM_TRX_SUPPORT */
   9392             return BCM_E_UNAVAIL;
   9393 
   9394         case bcmVlanPortVerifyOuterTpid:
   9395 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAPTOR_SUPPORT) \
   9396  || defined(BCM_TRX_SUPPORT)
   9397             if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) ||
   9398                 SOC_IS_TRX(unit) || SOC_IS_HAWKEYE(unit)) {
   9399                 arg = (arg ? 1 : 0);
   9400                 return (_bcm_esw_port_config_set(unit, port,
   9401                                                  _bcmPortVerifyOuterTpid, arg));
   9402             }
   9403 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAPTOR_SUPPORT || BCM_TRX_SUPPORT */
   9404             return BCM_E_UNAVAIL;
   9405 
   9406         case bcmVlanPortOuterTpidSelect:
   9407 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \
   9408  || defined(BCM_TRX_SUPPORT)
   9409             if ((SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || 
   9410                 SOC_IS_TRX(unit) || SOC_IS_HAWKEYE(unit)) &&
   9411                 !SOC_IS_SHADOW(unit)) {
   9412                 if (arg != BCM_PORT_OUTER_TPID &&
   9413                     arg != BCM_VLAN_OUTER_TPID) {
   9414                     return BCM_E_PARAM;
   9415                 }
   9416 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9417                 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
   9418                     egr_vlan_control_1_entry_t entry;
   9419                     soc_field_t tpid_sel_f = OUTER_TPID_VALIDf;
   9420                     if (SOC_MEM_FIELD_VALID(unit, EGR_VLAN_CONTROL_1m,
   9421                                             OUTER_TPID_SELf)) {
   9422                         tpid_sel_f = OUTER_TPID_SELf;
   9423                     }
   9424                     if (soc_feature(unit, soc_feature_egr_all_profile)
   9425 #if defined(BCM_HGPROXY_COE_SUPPORT)
   9426                         || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   9427                         BCM_GPORT_IS_SET(port) &&
   9428                             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))
   9429 #endif
   9430                         ) {
   9431                         SOC_IF_ERROR_RETURN(
   9432                             bcm_esw_port_egr_lport_field_set(unit, port,
   9433                             EGR_VLAN_CONTROL_1m, tpid_sel_f, arg));
   9434                         return BCM_E_NONE;
   9435                     }
   9436                     SOC_IF_ERROR_RETURN(
   9437                             READ_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, 
   9438                             &entry));
   9439                     data = soc_EGR_VLAN_CONTROL_1m_field32_get(unit, &entry,
   9440                                                                tpid_sel_f);
   9441                     if (arg != data) {
   9442                         soc_EGR_VLAN_CONTROL_1m_field32_set(unit, &entry,
   9443                                                             tpid_sel_f, arg);
   9444                         SOC_IF_ERROR_RETURN(
   9445                                 WRITE_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, 
   9446                                 port, &entry));
   9447                     }
   9448                 } else
   9449 #endif
   9450                 {
   9451                     SOC_IF_ERROR_RETURN
   9452                         (READ_EGR_VLAN_CONTROL_1r(unit, port, &evc));
   9453                     data = evc;
   9454                     soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &evc,
   9455                                           OUTER_TPID_SELf, arg);
   9456                     if (evc != data) {
   9457                         SOC_IF_ERROR_RETURN
   9458                             (WRITE_EGR_VLAN_CONTROL_1r(unit, port, evc));
   9459                     }
   9460                 }
   9461                 return BCM_E_NONE;
   9462             }
   9463 
   9464 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
   9465             return BCM_E_UNAVAIL;
   9466 
   9467         case bcmVlanPortTranslateKeyFirst:
   9468         case bcmVlanPortTranslateKeySecond:
   9469 #if defined(BCM_TRX_SUPPORT) 
   9470             if (SOC_IS_TRX(unit)) {
   9471                 _bcm_port_config_t vt_key_type;
   9472                 _bcm_port_config_t vt_key_port;
   9473                 int rv, key_type = 0, use_port = 0;
   9474                 switch (arg) {
   9475                     case bcmVlanTranslateKeyPortDouble:
   9476                         use_port = 1;
   9477                         /* fall through */
   9478                     case bcmVlanTranslateKeyDouble:
   9479                         key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID;
   9480                         break;
   9481                     case bcmVlanTranslateKeyPortOuterTag:
   9482                         use_port = 1;
   9483                         /* fall through */
   9484                     case bcmVlanTranslateKeyOuterTag:
   9485                         key_type = VLXLT_HASH_KEY_TYPE_OTAG;
   9486                         break;
   9487                     case bcmVlanTranslateKeyPortInnerTag:
   9488                         use_port = 1;
   9489                         /* fall through */
   9490                     case bcmVlanTranslateKeyInnerTag:
   9491                         key_type = VLXLT_HASH_KEY_TYPE_ITAG;
   9492                         break;
   9493                     case bcmVlanTranslateKeyPortOuter:
   9494                         use_port = 1;
   9495                         /* fall through */
   9496                     case bcmVlanTranslateKeyOuter:
   9497                         key_type = VLXLT_HASH_KEY_TYPE_OVID;
   9498                         break;
   9499                     case bcmVlanTranslateKeyPortInner:
   9500                         use_port = 1;
   9501                         /* fall through */
   9502                     case bcmVlanTranslateKeyInner:
   9503                         key_type = VLXLT_HASH_KEY_TYPE_IVID;
   9504                         break;
   9505                     case bcmVlanTranslateKeyPortOuterPri:
   9506                         use_port = 1;
   9507                         /* fall through */
   9508                     case bcmVlanTranslateKeyOuterPri:
   9509                         key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI;
   9510                         break;
   9511                     case bcmVlanTranslateKeyPortPonTunnel:
   9512                         use_port = 1;
   9513                         key_type = VLXLT_HASH_KEY_TYPE_LLVID;
   9514                         break;
   9515                     case bcmVlanTranslateKeyPortPonTunnelOuter:
   9516                         use_port = 1;
   9517                         key_type = VLXLT_HASH_KEY_TYPE_LLVID_OVID;
   9518                         break;
   9519                     case bcmVlanTranslateKeyPortPonTunnelInner:
   9520                         key_type = VLXLT_HASK_KEY_TYPE_LLVID_IVID;
   9521                         use_port = 1;
   9522                         break;
   9523                     case bcmVlanTranslateKeyPortCapwapPayloadDouble:
   9524                         use_port = 1;
   9525                         /* fall through */
   9526                     case bcmVlanTranslateKeyCapwapPayloadDouble:
   9527                         key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID;
   9528                         break;
   9529                     case bcmVlanTranslateKeyPortCapwapPayloadOuter:
   9530                         use_port = 1;
   9531                         /* fall through */
   9532                     case bcmVlanTranslateKeyCapwapPayloadOuter:
   9533                         key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID;
   9534                         break;
   9535                     case bcmVlanTranslateKeyPortCapwapPayloadInner:
   9536                         use_port = 1;
   9537                         /* fall through */
   9538                     case bcmVlanTranslateKeyCapwapPayloadInner:
   9539                         key_type =VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID;
   9540                         break;
   9541                     case bcmVlanTranslateKeyPortCapwapPayloadOuterTag:
   9542                         use_port = 1;
   9543                         /* fall through */
   9544                     case bcmVlanTranslateKeyCapwapPayloadOuterTag:
   9545                         key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG;
   9546                         break;
   9547                     case bcmVlanTranslateKeyPortCapwapPayloadInnerTag:
   9548                         use_port = 1;
   9549                         /* fall through */
   9550                     case bcmVlanTranslateKeyCapwapPayloadInnerTag:
   9551                         key_type = VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG;
   9552                         break;
   9553                     case bcmVlanTranslateKeyPortVxlanVnid:
   9554                         use_port = 1;
   9555                         /* fall through */
   9556                     case bcmVlanTranslateKeyVxlanVnid:
   9557                         key_type = VLXLT_HASH_KEY_TYPE_VNID;
   9558                         break;
   9559 #if defined(BCM_TRIDENT2_SUPPORT)
   9560                     case bcmVlanTranslateKeyPortGroupDouble:
   9561                         use_port = 3; /* port_group */
   9562                         key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID;
   9563                         break;
   9564                     case bcmVlanTranslateKeyPortGroupOuterTag:
   9565                         use_port = 3; /* port_group */
   9566                         key_type = VLXLT_HASH_KEY_TYPE_OTAG;
   9567                         break;
   9568                     case bcmVlanTranslateKeyPortGroupInnerTag:
   9569                         use_port = 3; /* port_group */
   9570                         key_type = VLXLT_HASH_KEY_TYPE_ITAG;
   9571                         break;
   9572                     case bcmVlanTranslateKeyPortGroupOuter:
   9573                         use_port = 3; /* port_group */
   9574                         key_type = VLXLT_HASH_KEY_TYPE_OVID;
   9575                         break;
   9576                     case bcmVlanTranslateKeyPortGroupInner:
   9577                         use_port = 3; /* port_group */
   9578                         key_type = VLXLT_HASH_KEY_TYPE_IVID;
   9579                         break;
   9580                     case bcmVlanTranslateKeyPortGroupOuterPri:
   9581                         use_port = 3; /* port_group */
   9582                         key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI;
   9583                         break;
   9584 #endif /* BCM_TRIDENT2_SUPPORT */
   9585                     case bcmVlanTranslateKeyMacPort:
   9586                         use_port = 1; /* Port */
   9587                         key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT;
   9588                         break;
   9589                     case bcmVlanTranslateKeyMacVirtualPort:
   9590                         use_port = 2; /* Virtual Port */
   9591                         key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT;
   9592                         break;
   9593                     case bcmVlanTranslateKeyMacPortGroup:
   9594                         use_port = 3; /* Port Group */
   9595                         key_type = VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT;
   9596                         break;
   9597                     default:
   9598                         return BCM_E_PARAM;
   9599                 }
   9600 
   9601                 if (BCM_GPORT_IS_NIV_PORT(port)) {
   9602                     switch (arg) {
   9603                     case bcmVlanTranslateKeyPortOuterTag:
   9604                         key_type = VLXLT_HASH_KEY_TYPE_VIF_OTAG;
   9605                         break;
   9606     
   9607                     case bcmVlanTranslateKeyPortInnerTag:
   9608                         key_type = VLXLT_HASH_KEY_TYPE_VIF_ITAG;
   9609                         break;
   9610     
   9611                     case bcmVlanTranslateKeyPortOuter:
   9612                         key_type = VLXLT_HASH_KEY_TYPE_VIF_VLAN;
   9613                         break;
   9614     
   9615                     case bcmVlanTranslateKeyPortInner:
   9616                         key_type = VLXLT_HASH_KEY_TYPE_VIF_CVLAN;
   9617                         break;
   9618     
   9619                     default:
   9620                         return BCM_E_PARAM;
   9621                     }
   9622 
   9623                     BCM_IF_ERROR_RETURN
   9624                         (bcm_esw_vlan_control_port_niv_resolve(unit,
   9625                                                                port, &port));
   9626                     use_port = 1;
   9627                 }
   9628 
   9629                 if ((use_port == 3) &&
   9630                     !(soc_feature(unit, soc_feature_port_group_for_ivxlt))) {
   9631                     return BCM_E_UNAVAIL;
   9632                 }
   9633 
   9634                 if (type == bcmVlanPortTranslateKeyFirst) {
   9635                     vt_key_type = _bcmPortVTKeyTypeFirst;
   9636                     vt_key_port = _bcmPortVTKeyPortFirst;
   9637                 } else {
   9638                     vt_key_type = _bcmPortVTKeyTypeSecond;
   9639                     vt_key_port = _bcmPortVTKeyPortSecond;
   9640                 }
   9641                 BCM_IF_ERROR_RETURN
   9642                     (_bcm_esw_pt_vtkey_type_value_get(unit,
   9643                              key_type,&key_type_value));
   9644 
   9645                 rv = _bcm_esw_port_config_set(unit, port,
   9646                                               vt_key_type, 
   9647                                               key_type_value);
   9648                 if (rv < 0) {
   9649                     return rv;
   9650                 }
   9651                 return (_bcm_esw_port_config_set(unit, port,
   9652                                                  vt_key_port, 
   9653                                                  use_port));
   9654             } 
   9655 #endif /* BCM_TRX_SUPPORT */
   9656             return BCM_E_UNAVAIL;
   9657 
   9658 #if defined(BCM_KATANA2_SUPPORT)
   9659         case bcmVlanPortOamUseXlatedInnerVlan:
   9660             if (SOC_IS_KATANA2(unit) && (soc_feature(unit, soc_feature_oam))) {
   9661                 arg = (arg ? 1 : 0);
   9662                 return (_bcm_esw_port_config_set(unit, port,
   9663                                           _bcmPortOamUseXlatedInnerVlan, arg));
   9664             } 
   9665             return BCM_E_UNAVAIL;
   9666             break;
   9667 #endif /* BCM_KATANA2_SUPPORT */
   9668 
   9669         case bcmVlanPortTranslateEgressKey:
   9670         case bcmVlanPortTranslateEgressKeyFirst:
   9671         case bcmVlanPortTranslateEgressKeySecond:
   9672             if ((arg < bcmVlanTranslateEgressKeyInvalid) || 
   9673                     (arg >= bcmVlanTranslateEgressKeyCount)) {
   9674                 return BCM_E_PARAM;
   9675             }
   9676 
   9677 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   9678             if (bcmVlanPortTranslateEgressKeySecond == type) {
   9679                 if (soc_feature(unit, soc_feature_egr_vlan_xlate_second_lookup)) {
   9680                     field = VT2_ENABLEf;
   9681                 } else {
   9682                     return BCM_E_UNAVAIL;
   9683                 }
   9684             }
   9685 
   9686             if (soc_feature(unit, soc_feature_egr_vlan_xlate_key_on_dvp)) {
   9687                 if (BCM_GPORT_IS_VXLAN_PORT(port) || BCM_GPORT_IS_MIM_PORT(port)
   9688                      || BCM_GPORT_IS_MPLS_PORT(port) || BCM_GPORT_IS_L2GRE_PORT(port)) {
   9689                     if (bcmVlanPortTranslateEgressKeySecond == type) {
   9690                         /* Second EVxlate lookup is not supported with VPs */
   9691                         return BCM_E_UNAVAIL;
   9692                     }
   9693 
   9694                     BCM_IF_ERROR_RETURN
   9695                         (_bcm_esw_dvp_vtkey_type_value_get(unit, arg,
   9696                                                            &key_type_value));
   9697                     return (bcm_td2p_dvp_vlan_xlate_key_set(unit, port,
   9698                                                                   key_type_value));
   9699                 } else if (BCM_GPORT_IS_FLOW_PORT(port)) {
   9700                     int rv = BCM_E_UNAVAIL;
   9701 #ifdef BCM_TRIDENT3_SUPPORT
   9702                     if (soc_feature(unit,soc_feature_flex_flow)) {
   9703                         rv = bcmi_esw_flow_dvp_vlan_xlate_key_set(unit, 
   9704                                      port, arg);
   9705                     }
   9706 #endif
   9707                     return rv;
   9708                 }
   9709             }
   9710 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */  
   9711 
   9712             BCM_IF_ERROR_RETURN
   9713                 (_bcm_esw_egr_vtkey_type_value_get(unit, arg,
   9714                                                    &key_type_value));
   9715 
   9716 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9717             if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
   9718                 egr_vlan_control_1_entry_t entry;
   9719                     if (soc_feature(unit, soc_feature_egr_all_profile)
   9720 #if defined(BCM_HGPROXY_COE_SUPPORT)
   9721                         || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   9722                         BCM_GPORT_IS_SET(port) &&
   9723                             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))
   9724 #endif
   9725                         ) {
   9726                     SOC_IF_ERROR_RETURN(
   9727                             bcm_esw_port_egr_lport_field_set(unit, port,
   9728                             EGR_VLAN_CONTROL_1m, field, key_type_value));
   9729                     return BCM_E_NONE;
   9730                 }
   9731                 if (BCM_GPORT_IS_LOCAL(port)) {
   9732                     port = BCM_GPORT_LOCAL_GET(port);
   9733                 }
   9734                 if (!SOC_PORT_VALID(unit, port)) {
   9735                     return BCM_E_PORT;
   9736                 }
   9737 
   9738                 SOC_IF_ERROR_RETURN
   9739                     (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, port, &entry));
   9740                 data = soc_mem_field32_get(unit, egr_mem, &entry, field);
   9741 
   9742                 if (data != key_type_value) {
   9743                     soc_mem_field32_set(unit, egr_mem, &entry, field, key_type_value);
   9744                     return (soc_mem_write(unit, egr_mem, MEM_BLOCK_ANY, port, &entry));
   9745                 }
   9746                 return BCM_E_NONE;
   9747             } else 
   9748 #endif
   9749             {
   9750                 /* 
   9751                  * We reach here for devices where EGR_VLAN_CONTROL_1 is a register;
   9752                  * There's nothing to set for them as VT_ENABLEf in the register 
   9753                  * would have been programmed through bcmVlanTranslateEgressEnable
   9754                  */
   9755                 return BCM_E_NONE;
   9756             }
   9757         default:
   9758             return BCM_E_UNAVAIL;
   9759         }
   9760     }
   9761 #endif /* BCM_FIREBOLT_SUPPORT */
   9762     return BCM_E_UNAVAIL;
   9763 }
   9764 
   9765 int
   9766 bcm_esw_vlan_control_port_set(int unit, bcm_port_t port,
   9767                               bcm_vlan_control_port_t type, int arg)
   9768 {
   9769     bcm_pbmp_t temp_pbmp;
   9770 #if defined(BCM_HGPROXY_COE_SUPPORT)
   9771     int i;
   9772     bcm_gport_t gport;
   9773 #endif /* BCM_HGPROXY_COE_SUPPORT */
   9774 
   9775 #ifdef BCM_TOMAHAWK3_SUPPORT
   9776     if (SOC_IS_TOMAHAWK3(unit)) {
   9777         return bcm_tomahawk3_vlan_control_port_set(unit, port, type, arg);
   9778     }
   9779 #endif
   9780 
   9781     if (port == -1) {
   9782         BCM_PBMP_CLEAR(temp_pbmp);
   9783         BCM_PBMP_ASSIGN(temp_pbmp, PBMP_E_ALL(unit));
   9784 
   9785 #ifdef BCM_KATANA2_SUPPORT
   9786         if (soc_feature(unit, soc_feature_linkphy_coe) ||
   9787             soc_feature(unit, soc_feature_subtag_coe)) {
   9788             _bcm_kt2_subport_pbmp_update (unit, &temp_pbmp);
   9789         }
   9790         if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
   9791             BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &temp_pbmp));
   9792         }
   9793 #endif
   9794 
   9795         PBMP_ITER(temp_pbmp, port) {
   9796             BCM_IF_ERROR_RETURN
   9797                 (_bcm_vlan_control_port_set(unit, port, type, arg));
   9798         }
   9799 
   9800 #if defined(BCM_HGPROXY_COE_SUPPORT)
   9801         BCM_HGPROXY_SUBTAG_COE_PORT_ITER(i, gport) {
   9802             BCM_IF_ERROR_RETURN
   9803                 (_bcm_vlan_control_port_set(unit, gport, type, arg));
   9804         }
   9805 #endif /* BCM_HGPROXY_COE_SUPPORT */
   9806     } else {
   9807         BCM_IF_ERROR_RETURN
   9808             (bcm_esw_vlan_control_port_validate(unit, port, type, &port));
   9809         return _bcm_vlan_control_port_set(unit, port, type, arg);
   9810     }
   9811 
   9812     return BCM_E_NONE;
   9813 }
   9814 
   9815 int
   9816 bcm_esw_vlan_control_port_get(int unit, bcm_port_t port,
   9817                               bcm_vlan_control_port_t type, int * arg)
   9818 {
   9819 #ifdef BCM_TOMAHAWK3_SUPPORT
   9820     if (SOC_IS_TOMAHAWK3(unit)) {
   9821         return bcm_tomahawk3_vlan_control_port_get(unit, port, type, arg);
   9822     }
   9823 #endif
   9824 
   9825     if (arg == 0) {
   9826         return BCM_E_PARAM;
   9827     }
   9828 
   9829     BCM_IF_ERROR_RETURN
   9830         (bcm_esw_vlan_control_port_validate(unit, port, type, &port));
   9831 
   9832 #if defined(BCM_FIREBOLT_SUPPORT)
   9833     if (SOC_IS_FBX(unit)) {
   9834         uint32 evc;
   9835         soc_reg_t egr_register;
   9836         int key_type_value;
   9837 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9838         soc_field_t field = VT_ENABLEf;
   9839         soc_mem_t egr_mem;
   9840         egr_mem = EGR_VLAN_CONTROL_1m;
   9841 #endif
   9842         egr_register = EGR_VLAN_CONTROL_1r;
   9843 
   9844         switch (type) {
   9845         case bcmVlanPortPreferIP4:
   9846             return _bcm_esw_port_config_get(unit, port, _bcmPortVlanPrecedence,
   9847                                             arg);
   9848 
   9849         case bcmVlanPortPreferMAC:
   9850             SOC_IF_ERROR_RETURN
   9851                 (_bcm_esw_port_config_get(unit, port, _bcmPortVlanPrecedence,
   9852                                             arg));
   9853             *arg = !*arg;
   9854             return BCM_E_NONE;
   9855 
   9856         case bcmVlanTranslateIngressEnable:
   9857             if (soc_feature(unit, soc_feature_vlan_translation)) {
   9858                 return (_bcm_esw_port_config_get(unit, port,
   9859                                                  _bcmPortVlanTranslate, arg));
   9860             }
   9861             return BCM_E_UNAVAIL;
   9862 
   9863         case bcmVlanTranslateIngressMissDrop:
   9864             if (soc_feature(unit, soc_feature_vlan_translation)) {
   9865                 return (_bcm_esw_port_config_get(unit, port,
   9866                                                  _bcmPortVTMissDrop, arg));
   9867             }
   9868             return BCM_E_UNAVAIL;
   9869 
   9870         case bcmVlanTranslateEgressEnable:
   9871             if (soc_feature(unit, soc_feature_vlan_translation)) {
   9872 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9873                 if (SOC_MEM_IS_VALID(unit, egr_mem)) {
   9874                     egr_vlan_control_1_entry_t entry;
   9875                     if (soc_feature(unit, soc_feature_egr_all_profile)
   9876 #if defined(BCM_HGPROXY_COE_SUPPORT)
   9877                         || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   9878                         BCM_GPORT_IS_SET(port) &&
   9879                             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))
   9880 #endif
   9881                         ) {
   9882                         SOC_IF_ERROR_RETURN(
   9883                             bcm_esw_port_egr_lport_field_get(unit, port,
   9884                             EGR_VLAN_CONTROL_1m, VT_ENABLEf, (uint32 *)arg));
   9885                         return BCM_E_NONE;
   9886                     }
   9887                     SOC_IF_ERROR_RETURN
   9888                             (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, port, &entry));
   9889                     *arg = soc_mem_field32_get(unit, egr_mem, &entry, VT_ENABLEf);
   9890                 } else
   9891 #endif
   9892                 {
   9893                     SOC_IF_ERROR_RETURN
   9894                             (soc_reg32_get(unit, egr_register, port, 0, &evc));
   9895                     *arg = soc_reg_field_get(unit, egr_register, evc, VT_ENABLEf);
   9896                 }
   9897                 return BCM_E_NONE;
   9898             }
   9899             return BCM_E_UNAVAIL;
   9900 
   9901         case bcmVlanTranslateEgressMissDrop:
   9902             if (soc_feature(unit, soc_feature_vlan_translation)) {
   9903 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9904                 if (SOC_MEM_IS_VALID(unit, egr_mem)) {
   9905                     egr_vlan_control_1_entry_t entry;
   9906                     if (soc_feature(unit, soc_feature_egr_all_profile)
   9907 #if defined(BCM_HGPROXY_COE_SUPPORT)
   9908                         || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   9909                         BCM_GPORT_IS_SET(port) &&
   9910                             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))
   9911 #endif
   9912                         ) {
   9913                         SOC_IF_ERROR_RETURN(
   9914                             bcm_esw_port_egr_lport_field_get(unit, port,
   9915                             EGR_VLAN_CONTROL_1m, VT_MISS_DROPf, (uint32 *)arg));
   9916                         return BCM_E_NONE;
   9917                     }
   9918                     SOC_IF_ERROR_RETURN
   9919                             (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, port, &entry));
   9920                     *arg = soc_mem_field32_get(unit, egr_mem, &entry, VT_MISS_DROPf);
   9921                 } else
   9922 #endif
   9923                 {
   9924                     SOC_IF_ERROR_RETURN
   9925                             (soc_reg32_get(unit, egr_register, port, 0, &evc));
   9926                     *arg = soc_reg_field_get(unit, egr_register, evc,
   9927                                                          VT_MISS_DROPf);
   9928                 }
   9929                 return BCM_E_NONE;
   9930             }
   9931             return BCM_E_UNAVAIL;
   9932 
   9933         case bcmVlanTranslateEgressMissUntaggedDrop:
   9934             if ((soc_feature(unit, soc_feature_untagged_vt_miss)) &&
   9935                 (soc_feature(unit,soc_feature_vlan_translation))) {
   9936 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9937                 if (SOC_MEM_IS_VALID(unit, egr_mem)) {
   9938                     egr_vlan_control_1_entry_t entry;
   9939                     if (soc_feature(unit, soc_feature_egr_all_profile)
   9940 #if defined(BCM_HGPROXY_COE_SUPPORT)
   9941                         || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   9942                         BCM_GPORT_IS_SET(port) &&
   9943                             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))
   9944 #endif
   9945                         ) {
   9946                         SOC_IF_ERROR_RETURN(
   9947                             bcm_esw_port_egr_lport_field_get(unit, port,
   9948                             EGR_VLAN_CONTROL_1m,
   9949                                             VT_MISS_UT_DROPf, (uint32 *)arg));
   9950                         return BCM_E_NONE;
   9951                     }
   9952                     SOC_IF_ERROR_RETURN
   9953                             (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, port, &entry));
   9954                     *arg = soc_mem_field32_get(unit, egr_mem, &entry, VT_MISS_UT_DROPf);
   9955                 } else
   9956 #endif
   9957                 {
   9958                     SOC_IF_ERROR_RETURN
   9959                             (soc_reg32_get(unit, egr_register, port, 0, &evc));
   9960                     *arg = soc_reg_field_get(unit, egr_register, evc, VT_MISS_UT_DROPf);
   9961                 }
   9962                 return BCM_E_NONE;
   9963             }
   9964             return BCM_E_UNAVAIL;
   9965 
   9966         case bcmVlanTranslateEgressMissUntag:
   9967 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) || \
   9968             defined(BCM_RAVEN_SUPPORT)
   9969 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   9970             if (SOC_MEM_IS_VALID(unit, egr_mem)) {
   9971                 egr_vlan_control_1_entry_t entry;
   9972                 if (SOC_MEM_FIELD_VALID(unit, egr_mem, VT_MISS_UNTAGf)) {
   9973                     if (soc_feature(unit, soc_feature_egr_all_profile)
   9974 #if defined(BCM_HGPROXY_COE_SUPPORT)
   9975                         || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   9976                         BCM_GPORT_IS_SET(port) &&
   9977                             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))
   9978 #endif
   9979                         ) {
   9980                         SOC_IF_ERROR_RETURN(
   9981                             bcm_esw_port_egr_lport_field_get(unit, port,
   9982                             EGR_VLAN_CONTROL_1m,
   9983                                             VT_MISS_UNTAGf, (uint32 *)arg));
   9984                         return BCM_E_NONE;
   9985                     }
   9986                     SOC_IF_ERROR_RETURN
   9987                             (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, port, &entry));
   9988                     *arg = soc_mem_field32_get(unit, egr_mem, &entry, VT_MISS_UNTAGf);
   9989                     return BCM_E_NONE; 
   9990                 }
   9991             } else
   9992 #endif
   9993             {
   9994                 if (SOC_REG_FIELD_VALID(unit, egr_register, VT_MISS_UNTAGf)) {
   9995                     SOC_IF_ERROR_RETURN
   9996                         (soc_reg32_get(unit, egr_register, port, 0, &evc));
   9997                     *arg = soc_reg_field_get(unit, egr_register, evc,
   9998                                              VT_MISS_UNTAGf);
   9999                     return BCM_E_NONE; 
  10000                 }
  10001             }
  10002 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
  10003             return BCM_E_UNAVAIL;
  10004 
  10005         case bcmVlanLookupMACEnable:
  10006             return _bcm_esw_port_config_get(unit, port,
  10007                                             _bcmPortLookupMACEnable, arg);
  10008         case bcmVlanLookupIPEnable:
  10009             return _bcm_esw_port_config_get(unit, port,
  10010                                             _bcmPortLookupIPEnable, arg);
  10011         case bcmVlanPortUseInnerPri:
  10012 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  10013             if (BCM_GPORT_IS_MIM_PORT(port) || BCM_GPORT_IS_MPLS_PORT(port) ||
  10014                 BCM_GPORT_IS_VXLAN_PORT(port)) {
  10015                 return (_bcm_tr2_svp_field_get(unit, port, 
  10016                                                USE_INNER_PRIf, arg));
  10017             }
  10018 #endif
  10019 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
  10020  || defined(BCM_RAVEN_SUPPORT)
  10021             if (SOC_IS_FIREBOLT2(unit) || SOC_IS_TRX(unit) ||
  10022                 SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit) ||
  10023                 SOC_IS_HURRICANEX(unit)) {
  10024                 if (BCM_GPORT_IS_SET(port)) {
  10025                 BCM_IF_ERROR_RETURN(
  10026                     bcm_esw_port_local_get(unit, port, &port));
  10027                 }
  10028                 return (_bcm_esw_port_config_get(unit, port,
  10029                                                 _bcmPortUseInnerPri, arg));
  10030             }
  10031 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
  10032             return BCM_E_UNAVAIL;
  10033         case bcmVlanPortUseOuterPri:
  10034 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  10035             if (BCM_GPORT_IS_MPLS_PORT(port) || BCM_GPORT_IS_MIM_PORT(port)) {
  10036                 return (_bcm_tr2_svp_field_get(unit, port, 
  10037                                                TRUST_OUTER_DOT1Pf, arg));
  10038             }
  10039 #endif
  10040 #if defined(BCM_TRX_SUPPORT)
  10041             if (SOC_IS_TRX(unit)) {
  10042                 if (BCM_GPORT_IS_SET(port)) {
  10043                 BCM_IF_ERROR_RETURN(
  10044                     bcm_esw_port_local_get(unit, port, &port));
  10045                 }
  10046                 return (_bcm_esw_port_config_get(unit, port,
  10047                                                 _bcmPortUseOuterPri, arg));
  10048             }
  10049 #endif /* BCM_TRX_SUPPORT */
  10050             return BCM_E_UNAVAIL;
  10051         case bcmVlanPortVerifyOuterTpid:
  10052 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAPTOR_SUPPORT) \
  10053  || defined(BCM_TRX_SUPPORT)
  10054             if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) ||
  10055                 SOC_IS_TRX(unit) || SOC_IS_HAWKEYE(unit) ||
  10056                 SOC_IS_HURRICANEX(unit)) {
  10057                 return (_bcm_esw_port_config_get(unit, port,
  10058                                                 _bcmPortVerifyOuterTpid, arg));
  10059             }
  10060 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAPTOR_SUPPORT || BCM_TRX_SUPPORT */
  10061             return BCM_E_UNAVAIL;
  10062         case bcmVlanPortOuterTpidSelect:
  10063 
  10064 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \
  10065  || defined(BCM_TRX_SUPPORT)
  10066             if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) ||
  10067                 SOC_IS_TRX(unit) || SOC_IS_HAWKEYE(unit) ||
  10068                 SOC_IS_HURRICANEX(unit)) {
  10069 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  10070                 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
  10071                     egr_vlan_control_1_entry_t entry;
  10072                     soc_field_t tpid_sel_f = OUTER_TPID_VALIDf;
  10073                     if (SOC_MEM_FIELD_VALID(unit, EGR_VLAN_CONTROL_1m,
  10074                                             OUTER_TPID_SELf)) {
  10075                         tpid_sel_f = OUTER_TPID_SELf;
  10076                     }
  10077                     if (soc_feature(unit, soc_feature_egr_all_profile)
  10078 #if defined(BCM_HGPROXY_COE_SUPPORT)
  10079                         || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  10080                         BCM_GPORT_IS_SET(port) &&
  10081                             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))
  10082 #endif
  10083                         ) {
  10084                         SOC_IF_ERROR_RETURN(
  10085                             bcm_esw_port_egr_lport_field_get(unit, port,
  10086                             EGR_VLAN_CONTROL_1m,
  10087                             tpid_sel_f, (uint32 *)arg));
  10088                         return BCM_E_NONE;
  10089                     }
  10090                     SOC_IF_ERROR_RETURN(
  10091                             READ_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, &entry));
  10092                     *arg = soc_EGR_VLAN_CONTROL_1m_field32_get(unit, &entry,
  10093                                                                tpid_sel_f);
  10094                 } else
  10095 #endif
  10096                 {
  10097                     SOC_IF_ERROR_RETURN
  10098                         (READ_EGR_VLAN_CONTROL_1r(unit, port, &evc));
  10099                     *arg = soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r,
  10100                                              evc, OUTER_TPID_SELf);
  10101                 }
  10102                 return BCM_E_NONE;
  10103             }
  10104 
  10105 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
  10106             return BCM_E_UNAVAIL;
  10107         case bcmVlanPortTranslateKeyFirst:
  10108         case bcmVlanPortTranslateKeySecond:
  10109 #if defined(BCM_TRX_SUPPORT)
  10110             if (SOC_IS_TRX(unit)) {
  10111                 _bcm_port_config_t vt_key_type;
  10112                 _bcm_port_config_t vt_key_port;
  10113                 int key_type = 0, use_port = 0;
  10114                 int key_type_value;
  10115 
  10116                 if (type == bcmVlanPortTranslateKeyFirst) {
  10117                     vt_key_type = _bcmPortVTKeyTypeFirst;
  10118                     vt_key_port = _bcmPortVTKeyPortFirst;
  10119                 } else {
  10120                     vt_key_type = _bcmPortVTKeyTypeSecond;
  10121                     vt_key_port = _bcmPortVTKeyPortSecond;
  10122                 }
  10123 
  10124                 if (BCM_GPORT_IS_NIV_PORT(port)) {
  10125                     BCM_IF_ERROR_RETURN
  10126                         (bcm_esw_vlan_control_port_niv_resolve(unit, port,
  10127                                                                &port));
  10128                 }
  10129 
  10130                 BCM_IF_ERROR_RETURN
  10131                     (_bcm_esw_port_config_get(unit, port,
  10132                                               vt_key_type, 
  10133                                               &key_type_value));
  10134 
  10135                 BCM_IF_ERROR_RETURN
  10136                     (_bcm_esw_pt_vtkey_type_get(unit,
  10137                              key_type_value,&key_type));
  10138 
  10139                 BCM_IF_ERROR_RETURN
  10140                     (_bcm_esw_port_config_get(unit, port,
  10141                                               vt_key_port, 
  10142                                               &use_port));
  10143                 switch (key_type) {
  10144                 case VLXLT_HASH_KEY_TYPE_IVID_OVID:
  10145                     if (use_port == 3) {
  10146                         *arg = bcmVlanTranslateKeyPortGroupDouble;
  10147                     } else {
  10148                         *arg = (use_port) ? bcmVlanTranslateKeyPortDouble :
  10149                                             bcmVlanTranslateKeyDouble;
  10150                     }
  10151                     break;
  10152                 case VLXLT_HASH_KEY_TYPE_OTAG:
  10153                     if (use_port == 3) {
  10154                         *arg = bcmVlanTranslateKeyPortGroupOuterTag;
  10155                     } else {
  10156                         *arg = (use_port) ? bcmVlanTranslateKeyPortOuterTag :
  10157                                             bcmVlanTranslateKeyOuterTag;
  10158                     }
  10159                     break;
  10160                 case VLXLT_HASH_KEY_TYPE_ITAG:
  10161                     if (use_port == 3) {
  10162                         *arg = bcmVlanTranslateKeyPortGroupInnerTag;
  10163                     } else {
  10164                         *arg = (use_port) ? bcmVlanTranslateKeyPortInnerTag :
  10165                                             bcmVlanTranslateKeyInnerTag;
  10166                     }
  10167                     break;
  10168                 case VLXLT_HASH_KEY_TYPE_OVID:
  10169                     if (use_port == 3) {
  10170                         *arg = bcmVlanTranslateKeyPortGroupOuter;
  10171                     } else {
  10172                         *arg = (use_port) ? bcmVlanTranslateKeyPortOuter :
  10173                                             bcmVlanTranslateKeyOuter;
  10174                     }
  10175                     break;
  10176                 case VLXLT_HASH_KEY_TYPE_IVID:
  10177                     if (use_port == 3) {
  10178                         *arg = bcmVlanTranslateKeyPortGroupInner;
  10179                     } else {
  10180                         *arg = (use_port) ? bcmVlanTranslateKeyPortInner :
  10181                                             bcmVlanTranslateKeyInner;
  10182                     }
  10183                     break;
  10184                 case VLXLT_HASH_KEY_TYPE_PRI_CFI:
  10185                     if (use_port == 3) {
  10186                         *arg = bcmVlanTranslateKeyPortGroupOuterPri;
  10187                     } else {
  10188                         *arg = (use_port) ? bcmVlanTranslateKeyPortOuterPri :
  10189                                             bcmVlanTranslateKeyOuterPri;
  10190                     }
  10191                     break;
  10192                 case VLXLT_HASH_KEY_TYPE_VIF_OTAG:
  10193                     *arg = (use_port) ? bcmVlanTranslateKeyPortOuterTag :
  10194                                         bcmVlanTranslateKeyOuterTag;
  10195                     break;
  10196                 case VLXLT_HASH_KEY_TYPE_VIF_ITAG:
  10197                     *arg = (use_port) ? bcmVlanTranslateKeyPortInnerTag :
  10198                                         bcmVlanTranslateKeyInnerTag;
  10199                     break;
  10200                 case VLXLT_HASH_KEY_TYPE_VIF_VLAN:
  10201                     *arg = (use_port) ? bcmVlanTranslateKeyPortOuter:
  10202                                         bcmVlanTranslateKeyOuter;
  10203                     break;
  10204                 case VLXLT_HASH_KEY_TYPE_VIF_CVLAN:
  10205                     *arg = (use_port) ? bcmVlanTranslateKeyPortInner:
  10206                                         bcmVlanTranslateKeyInner;
  10207                     break;
  10208                 case VLXLT_HASH_KEY_TYPE_LLVID:
  10209                     *arg = (use_port) ? bcmVlanTranslateKeyPortPonTunnel:
  10210                                         bcmVlanTranslateKeyInvalid;
  10211                     break;
  10212                 case VLXLT_HASH_KEY_TYPE_LLVID_OVID:
  10213                     *arg = (use_port) ? bcmVlanTranslateKeyPortPonTunnelOuter:
  10214                                         bcmVlanTranslateKeyInvalid;
  10215                     break;
  10216                 case VLXLT_HASK_KEY_TYPE_LLVID_IVID:
  10217                     *arg = (use_port) ? bcmVlanTranslateKeyPortPonTunnelOuter:
  10218                                         bcmVlanTranslateKeyPortPonTunnelInner;
  10219                     break;
  10220                 case VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID:
  10221                     *arg = (use_port) ? bcmVlanTranslateKeyPortCapwapPayloadDouble:
  10222                                         bcmVlanTranslateKeyCapwapPayloadDouble;
  10223                     break;
  10224                 case VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG:
  10225                     *arg = (use_port) ? bcmVlanTranslateKeyPortCapwapPayloadOuterTag:
  10226                                         bcmVlanTranslateKeyCapwapPayloadOuterTag;
  10227                     break;
  10228                 case VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG:
  10229                     *arg = (use_port) ? bcmVlanTranslateKeyPortCapwapPayloadInnerTag:
  10230                                         bcmVlanTranslateKeyCapwapPayloadInnerTag;
  10231                     break;
  10232                 case VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID:
  10233                     *arg = (use_port) ? bcmVlanTranslateKeyPortCapwapPayloadOuter:
  10234                                         bcmVlanTranslateKeyCapwapPayloadOuter;
  10235                     break;
  10236                 case VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID:
  10237                     *arg = (use_port) ? bcmVlanTranslateKeyPortCapwapPayloadInner:
  10238                                         bcmVlanTranslateKeyCapwapPayloadInner;
  10239                     break;
  10240                 case VLXLT_HASH_KEY_TYPE_VNID:
  10241                     *arg = (use_port) ? bcmVlanTranslateKeyPortVxlanVnid:
  10242                                         bcmVlanTranslateKeyVxlanVnid;
  10243                     break;
  10244                 case VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT:
  10245                     if (use_port == 1) {
  10246                         *arg = bcmVlanTranslateKeyMacPort;
  10247                     } else if (use_port == 2) {
  10248                         *arg = bcmVlanTranslateKeyMacVirtualPort;
  10249                     } else if (use_port == 3) {
  10250                         *arg = bcmVlanTranslateKeyMacPortGroup;
  10251                     }
  10252                     break;
  10253                 default:
  10254                     *arg = bcmVlanTranslateKeyInvalid;
  10255                     break;
  10256                 }
  10257                 return BCM_E_NONE;
  10258             } 
  10259 #endif /* BCM_TRX_SUPPORT */
  10260             return BCM_E_UNAVAIL;
  10261 #if defined(BCM_KATANA2_SUPPORT)
  10262         case bcmVlanPortOamUseXlatedInnerVlan:
  10263             if (SOC_IS_KATANA2(unit) && (soc_feature(unit, soc_feature_oam))) {
  10264                 return (_bcm_esw_port_config_get(unit, port,
  10265                                           _bcmPortOamUseXlatedInnerVlan, arg));
  10266             } 
  10267             return BCM_E_UNAVAIL;
  10268             break;
  10269 #endif /* BCM_KATANA2_SUPPORT */  
  10270         case bcmVlanPortTranslateEgressKey:
  10271         case bcmVlanPortTranslateEgressKeyFirst:
  10272         case bcmVlanPortTranslateEgressKeySecond:
  10273 
  10274 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
  10275             if (bcmVlanPortTranslateEgressKeySecond == type) {
  10276                 if (soc_feature(unit, soc_feature_egr_vlan_xlate_second_lookup)) {
  10277                     field = VT2_ENABLEf;
  10278                 } else {
  10279                     return BCM_E_UNAVAIL;
  10280                 }
  10281             }
  10282 
  10283             if (soc_feature(unit, soc_feature_egr_vlan_xlate_key_on_dvp)) {
  10284                 int key_type_value;
  10285 
  10286                 if (BCM_GPORT_IS_VXLAN_PORT(port) || BCM_GPORT_IS_MIM_PORT(port)
  10287                     || BCM_GPORT_IS_MPLS_PORT(port) || BCM_GPORT_IS_L2GRE_PORT(port)) {
  10288                     if (bcmVlanPortTranslateEgressKeySecond == type) {
  10289                         /* Second EVxlate lookup is not supported with VPs */
  10290                         return BCM_E_UNAVAIL;
  10291                     }
  10292                     BCM_IF_ERROR_RETURN
  10293                         (bcm_td2p_dvp_vlan_xlate_key_get(unit, port, 
  10294                                                          &key_type_value));  
  10295                     return (_bcm_esw_dvp_vtkey_type_get(unit, 
  10296                                               key_type_value, arg));
  10297                 } else if (BCM_GPORT_IS_FLOW_PORT(port)) {
  10298                     int rv = BCM_E_UNAVAIL;
  10299 #ifdef BCM_TRIDENT3_SUPPORT
  10300                     if (soc_feature(unit,soc_feature_flex_flow)) {
  10301                         rv = bcmi_esw_flow_dvp_vlan_xlate_key_get(unit,
  10302                                      port, arg);
  10303                     }
  10304 #endif
  10305                    return rv;
  10306                 }
  10307             }
  10308 #endif /* BCM_TRIDENT2PLUS_SUPPORT &&  INCLUDE_L3 */  
  10309 
  10310             if (soc_feature(unit, soc_feature_vlan_translation)) {
  10311 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  10312                 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
  10313                     egr_vlan_control_1_entry_t entry;
  10314                     if (soc_feature(unit, soc_feature_egr_all_profile)
  10315 #if defined(BCM_HGPROXY_COE_SUPPORT)
  10316                         || (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  10317                             BCM_GPORT_IS_SET(port) &&
  10318                             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))
  10319 #endif
  10320                         ) {
  10321                         SOC_IF_ERROR_RETURN(
  10322                                 bcm_esw_port_egr_lport_field_get(unit, port,
  10323                                 EGR_VLAN_CONTROL_1m,
  10324                                     field, (uint32 *)(&key_type_value)));
  10325                     } else {
  10326                         if (BCM_GPORT_IS_LOCAL(port)) { 
  10327                             port = BCM_GPORT_LOCAL_GET(port);
  10328                         }
  10329                         if (!SOC_PORT_VALID(unit, port)) {
  10330                             return BCM_E_PORT;
  10331                         }
  10332 
  10333                         SOC_IF_ERROR_RETURN
  10334                             (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, port, &entry));
  10335                         key_type_value = soc_mem_field32_get(unit, egr_mem, &entry, field);
  10336                     }
  10337                 } else
  10338 #endif
  10339                 {
  10340                     if (BCM_GPORT_IS_LOCAL(port)) { 
  10341                         port = BCM_GPORT_LOCAL_GET(port);
  10342                     }
  10343                     if (!SOC_PORT_VALID(unit, port)) {
  10344                         return BCM_E_PORT;
  10345                     }
  10346 
  10347                     SOC_IF_ERROR_RETURN
  10348                         (soc_reg32_get(unit, egr_register, port, 0, &evc));
  10349                     key_type_value = soc_reg_field_get(unit, egr_register, evc, VT_ENABLEf);
  10350                 }
  10351                 return (_bcm_esw_egr_vtkey_type_get(unit, key_type_value, arg));
  10352             }
  10353             return BCM_E_UNAVAIL;
  10354 
  10355         default:
  10356             return BCM_E_UNAVAIL;
  10357         }
  10358     }
  10359 #endif /* BCM_FIREBOLT_SUPPORT */
  10360     return BCM_E_UNAVAIL;
  10361 }
  10362 
  10363 #if defined(BCM_XGS_SWITCH_SUPPORT)
  10364 /****************************************************************
  10365  *
  10366  * Stack port updating of VLAN tables
  10367  */
  10368 
  10369 /* Boolean: returns TRUE if bitmap changed. */
  10370 STATIC int
  10371 _stk_vlan_bitmap_update(int unit, bcm_pbmp_t remove_ports,
  10372                         bcm_pbmp_t old_ports, bcm_pbmp_t *new_ports)
  10373 {
  10374     SOC_PBMP_ASSIGN(*new_ports, old_ports);
  10375     SOC_PBMP_OR(*new_ports, SOC_PBMP_STACK_CURRENT(unit));
  10376     SOC_PBMP_REMOVE(*new_ports, remove_ports);
  10377 
  10378     return SOC_PBMP_NEQ(*new_ports, old_ports);
  10379 }
  10380 
  10381 STATIC void
  10382 _xgs_vlan_bitmap_get(int unit, vlan_tab_entry_t *vt, bcm_pbmp_t *ports)
  10383 {
  10384     SOC_PBMP_CLEAR(*ports);
  10385 
  10386 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  10387     if (SOC_IS_XGS3_SWITCH(unit)) {
  10388         soc_mem_pbmp_field_get(unit, VLAN_TABLE(unit), vt, PORT_BITMAPf, ports);
  10389     }
  10390 #endif
  10391 }
  10392 
  10393 STATIC void
  10394 _xgs_vlan_bitmap_set(int unit, vlan_tab_entry_t *vt, bcm_pbmp_t ports)
  10395 {
  10396 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  10397     if (SOC_IS_XGS3_SWITCH(unit)) {
  10398         soc_mem_pbmp_field_set(unit, VLAN_TABLE(unit), vt, PORT_BITMAPf, &ports);
  10399     }
  10400 #endif
  10401 }
  10402 #ifdef BCM_TRIUMPH3_SUPPORT
  10403 STATIC void
  10404 _xgs_vlan_ing_bitmap_get(int unit, vlan_tab_entry_t *vt, bcm_pbmp_t *ports)
  10405 {
  10406     SOC_PBMP_CLEAR(*ports);
  10407 
  10408 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  10409     if (SOC_IS_XGS3_SWITCH(unit)) {
  10410         if (SOC_MEM_FIELD_VALID(unit, VLAN_TABLE(unit), ING_PORT_BITMAPf)) {
  10411             soc_mem_pbmp_field_get(unit, VLAN_TABLE(unit), vt, ING_PORT_BITMAPf,
  10412                                    ports);
  10413         }
  10414     }
  10415 #endif
  10416 }
  10417 
  10418 STATIC void
  10419 _xgs_vlan_ing_bitmap_set(int unit, vlan_tab_entry_t *vt, bcm_pbmp_t ports)
  10420 {
  10421 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  10422     if (SOC_IS_XGS3_SWITCH(unit)) {
  10423         if (SOC_MEM_FIELD_VALID(unit, VLAN_TABLE(unit), ING_PORT_BITMAPf)) {
  10424             soc_mem_pbmp_field_set(unit, VLAN_TABLE(unit), vt, ING_PORT_BITMAPf,
  10425                                    &ports);
  10426         } 
  10427     }
  10428 #endif
  10429 }
  10430 #endif /*BCM_TRIUMPH3_SUPPORT*/
  10431 #endif /* BCM_XGS_SWITCH_SUPPORT */
  10432 
  10433 STATIC int
  10434 _xgs_vlan_stk_update(int unit, int vid, bcm_pbmp_t add_ports,
  10435                      bcm_pbmp_t remove_ports)
  10436 {
  10437 #if defined(BCM_XGS_SWITCH_SUPPORT)
  10438 
  10439     vlan_tab_entry_t vt;
  10440     bcm_pbmp_t old_ports, new_ports;
  10441     int pbmp_update=0;
  10442 #ifdef BCM_TRIUMPH3_SUPPORT
  10443     int ing_pbmp_update=0;
  10444     bcm_pbmp_t old_ing_ports, new_ing_ports;
  10445 #endif /* BCM_TRIUMPH3_SUPPORT*/
  10446 
  10447     /* Read in table entry.  Assume valid as given VID */
  10448     SOC_IF_ERROR_RETURN(soc_mem_read(unit, VLAN_TABLE(unit), MEM_BLOCK_ANY, vid, &vt));
  10449 
  10450     _xgs_vlan_bitmap_get(unit, &vt, &old_ports);
  10451 
  10452     /* See if changed */
  10453     pbmp_update =
  10454             _stk_vlan_bitmap_update(unit, remove_ports, old_ports, &new_ports);
  10455     if (pbmp_update) {
  10456         _xgs_vlan_bitmap_set(unit, &vt, new_ports);
  10457     }
  10458 
  10459 #ifdef BCM_TRIUMPH3_SUPPORT
  10460     if (SOC_IS_TRIUMPH3(unit)) {
  10461         _xgs_vlan_ing_bitmap_get(unit, &vt, &old_ing_ports);
  10462         ing_pbmp_update = _stk_vlan_bitmap_update(unit, remove_ports, old_ing_ports, &new_ing_ports);
  10463         if (ing_pbmp_update) {
  10464            _xgs_vlan_ing_bitmap_set(unit, &vt, new_ing_ports);
  10465         }
  10466     }
  10467 
  10468     if (pbmp_update || ing_pbmp_update)
  10469 #else
  10470     if (pbmp_update)
  10471 #endif
  10472     {
  10473         SOC_IF_ERROR_RETURN(soc_mem_write(unit, VLAN_TABLE(unit), MEM_BLOCK_ANY, vid, &vt));
  10474     }
  10475 
  10476     /* FIREBOLT has an EGR VLAN table;
  10477        in general, this should match VLAN_TAB */
  10478     if (SOC_IS_FBX(unit) && soc_feature(unit, soc_feature_egr_vlan_check) ) {
  10479 #if defined(BCM_FIREBOLT_SUPPORT)
  10480         egr_vlan_entry_t evt;
  10481         bcm_pbmp_t old_ports, new_ports;
  10482 
  10483         /* Read in EGR_VLAN table entry.  */
  10484         SOC_IF_ERROR_RETURN(READ_EGR_VLANm(unit, MEM_BLOCK_ANY, vid, &evt));
  10485 
  10486         if (_bcm_vlan_valid_check(unit, EGR_VLANm, (void *) &evt, 
  10487                                   vid) == BCM_E_NONE) {
  10488             soc_mem_pbmp_field_get(unit, EGR_VLANm, &evt, PORT_BITMAPf,
  10489                                    &old_ports);
  10490 
  10491             /* See if changed */
  10492             if (_stk_vlan_bitmap_update(unit, remove_ports,
  10493                                         old_ports, &new_ports)) {
  10494                 soc_mem_pbmp_field_set(unit, EGR_VLANm, &evt, PORT_BITMAPf,
  10495                                        &new_ports);
  10496                 SOC_IF_ERROR_RETURN(WRITE_EGR_VLANm(unit, MEM_BLOCK_ANY,
  10497                                                     vid, &evt));
  10498             }
  10499         }
  10500 #endif /* BCM_FIREBOLT_SUPPORT */
  10501     }
  10502 
  10503 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
  10504     if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
  10505         BCM_IF_ERROR_RETURN(
  10506             bcm_td2p_vlan_vfi_mbrship_port_set(unit, vid, TRUE,
  10507                                                TRUE, add_ports));
  10508         BCM_IF_ERROR_RETURN(
  10509             bcm_td2p_vlan_vfi_mbrship_port_set(unit, vid, TRUE,
  10510                                                FALSE, remove_ports));
  10511         if (pbmp_update) {
  10512             BCM_IF_ERROR_RETURN(
  10513                     bcm_td2p_vlan_vfi_mbrship_port_set(unit, vid, FALSE,
  10514                                                        TRUE, add_ports));
  10515             BCM_IF_ERROR_RETURN(
  10516                     bcm_td2p_vlan_vfi_mbrship_port_set(unit, vid, FALSE,
  10517                                                        FALSE, remove_ports));
  10518         }
  10519     }
  10520 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  10521 
  10522 #endif /* BCM_XGS_SWITCH_SUPPORT */
  10523 
  10524     return BCM_E_NONE;
  10525 }
  10526 
  10527 STATIC int
  10528 _esw_vlan_stk_update(int unit, int vid, bcm_pbmp_t add_ports,
  10529                      bcm_pbmp_t remove_ports)
  10530 {
  10531     LOG_VERBOSE(BSL_LS_BCM_VLAN,
  10532                 (BSL_META_U(unit,
  10533                             "VLAN %d: stk update internal: vid %d, add 0x%x, "
  10534                              "rmv 0x%x\n"), unit, vid,
  10535                  SOC_PBMP_WORD_GET(add_ports, 0),
  10536                  SOC_PBMP_WORD_GET(remove_ports, 0)));
  10537 
  10538     if (SOC_IS_XGS_SWITCH(unit)) {
  10539         return _xgs_vlan_stk_update(unit, vid, add_ports, remove_ports);
  10540     }
  10541 
  10542     return BCM_E_NONE;  /* Ignore where not supported. */
  10543 }
  10544 
  10545 STATIC void
  10546 _vlan_mem_lock(int unit)
  10547 {
  10548 #ifdef  BCM_XGS12_SWITCH_SUPPORT
  10549     if (SOC_IS_XGS12_SWITCH(unit)) {
  10550         soc_mem_lock(unit, VLAN_TABm);
  10551     }
  10552 #endif
  10553 
  10554 #ifdef  BCM_XGS3_SWITCH_SUPPORT
  10555     if (SOC_IS_XGS3_SWITCH(unit)) {
  10556         soc_mem_lock(unit, VLAN_TABm);
  10557         soc_mem_lock(unit, EGR_VLANm);
  10558     }
  10559 #endif
  10560 }
  10561 
  10562 STATIC void
  10563 _vlan_mem_unlock(int unit)
  10564 {
  10565 #ifdef  BCM_XGS12_SWITCH_SUPPORT
  10566     if (SOC_IS_XGS12_SWITCH(unit)) {
  10567         soc_mem_unlock(unit, VLAN_TABm);
  10568     }
  10569 #endif
  10570 
  10571 #ifdef  BCM_XGS3_SWITCH_SUPPORT
  10572     if (SOC_IS_XGS3_SWITCH(unit)) {
  10573         soc_mem_unlock(unit, EGR_VLANm);
  10574         soc_mem_unlock(unit, VLAN_TABm);
  10575     }
  10576 #endif
  10577 }
  10578 
  10579 
  10580 
  10581 int
  10582 _bcm_esw_vlan_untag_update(int unit, bcm_port_t port, int untag)
  10583 {
  10584     int rv = BCM_E_NONE;
  10585     bcm_pbmp_t port_pbmp, port_ubmp, vlan_pbmp, vlan_ubmp, vlan_ing_pbmp;
  10586     int vid;
  10587 
  10588     if (!soc_feature(unit, soc_feature_xport_convertible) && !SOC_IS_RAVEN(unit)) {
  10589         return BCM_E_NONE;
  10590     }
  10591 
  10592     SOC_PBMP_CLEAR(port_pbmp);
  10593     SOC_PBMP_CLEAR(port_ubmp);
  10594 
  10595     SOC_PBMP_PORT_SET(port_pbmp, port);
  10596     if (!untag) {
  10597         SOC_PBMP_PORT_SET(port_ubmp, port);
  10598     }
  10599 
  10600     _vlan_mem_lock(unit);
  10601     vid = vlan_info[unit].defl;
  10602     rv = mbcm_driver[unit]->mbcm_vlan_port_get
  10603         (unit, vid, &vlan_pbmp, &vlan_ubmp, &vlan_ing_pbmp);
  10604 
  10605     if (rv >= 0) {
  10606         if (untag || SOC_PBMP_MEMBER(vlan_pbmp, port)) {
  10607             /* port_pbmp is a mask for the other two arguments */
  10608             BCM_PBMP_AND(vlan_ing_pbmp, port_pbmp);
  10609             rv = mbcm_driver[unit]->mbcm_vlan_port_add
  10610                 (unit, vid, port_pbmp, port_ubmp, vlan_ing_pbmp);
  10611         }
  10612     }
  10613     _vlan_mem_unlock(unit);
  10614 
  10615     return rv;
  10616 }
  10617 
  10618 
  10619 
  10620 int
  10621 _bcm_esw_vlan_stk_update(int unit, uint32 flags)
  10622 {
  10623     int rv = BCM_E_NONE;
  10624 
  10625     if (vlan_info[unit].vlan_auto_stack) {
  10626         bcm_pbmp_t add_ports, remove_ports;
  10627         int vid;
  10628         int vlan_count = 0;
  10629 
  10630         LOG_VERBOSE(BSL_LS_BCM_VLAN,
  10631                     (BSL_META_U(unit,
  10632                                 "VLAN %d: stk_update: flags 0x%x\n"),
  10633                      unit, flags));
  10634 
  10635         /*
  10636          * Force all stack ports in all VLANs and assume BLOCK registers
  10637          * take care of DLFs and BCast; remove ports no longer stacking.
  10638          */
  10639         SOC_PBMP_ASSIGN(add_ports, SOC_PBMP_STACK_CURRENT(unit));
  10640 
  10641         SOC_PBMP_ASSIGN(remove_ports, SOC_PBMP_STACK_PREVIOUS(unit));
  10642         SOC_PBMP_REMOVE(remove_ports, SOC_PBMP_STACK_CURRENT(unit));
  10643 
  10644         _vlan_mem_lock(unit);
  10645 
  10646         for (vid = BCM_VLAN_MIN;vid < BCM_VLAN_COUNT; vid++) {
  10647             if (0 == _BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vid)) {
  10648                 continue;
  10649             }
  10650             vlan_count++;
  10651             rv = _esw_vlan_stk_update(unit, vid, add_ports, remove_ports);
  10652             if (BCM_FAILURE(rv)) {
  10653                 break;
  10654             }
  10655             if (vlan_info[unit].count == vlan_count) {
  10656                 break;
  10657             }
  10658         }
  10659         _vlan_mem_unlock(unit);
  10660     }
  10661     return rv;
  10662 }
  10663 
  10664 
  10665 /*
  10666  * Function:
  10667  *      bcm_vlan_mcast_flood_set
  10668  * Purpose:
  10669  *      Set the VLAN Multicast flood mode (aka PFM - port filter mode)
  10670  * Parameters:
  10671  *      unit - StrataSwitch PCI device unit number (driver internal).
  10672  *      vid  - VLAN to change the flood setting on.
  10673  *      mode - Multicast flood mode
  10674  * Returns:
  10675  *      BCM_E_NONE - Success.
  10676  *      BCM_E_XXX
  10677  * Notes:
  10678  *      Available on XGS3 only.
  10679  */
  10680 int
  10681 bcm_esw_vlan_mcast_flood_set(int unit,
  10682                              bcm_vlan_t vlan,
  10683                              bcm_vlan_mcast_flood_t mode)
  10684 {
  10685     int rv = BCM_E_UNAVAIL;
  10686 
  10687 #ifdef BCM_XGS3_SWITCH_SUPPORT
  10688     if (soc_feature(unit, soc_feature_vlan_mc_flood_ctrl)) {
  10689         CHECK_INIT(unit);
  10690 #if defined(BCM_TRIUMPH_SUPPORT) && defined(BCM_MPLS_SUPPORT) && \
  10691     defined(INCLUDE_L3)
  10692         if (_BCM_MPLS_VPN_IS_VPLS(vlan)) {
  10693             if (soc_feature(unit, soc_feature_vfi_mc_flood_ctrl)) {
  10694                 return bcm_tr_mpls_mcast_flood_set(unit, vlan, mode);
  10695             } else {
  10696                 return rv;
  10697             }
  10698         } 
  10699 #endif
  10700         VLAN_CHK_ID(unit, vlan);
  10701 
  10702         if (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vlan)) {
  10703             rv = _bcm_xgs3_vlan_mcast_flood_set(unit, vlan, mode);
  10704         } else {
  10705             rv = BCM_E_PARAM;
  10706         }
  10707     }
  10708 #endif
  10709     return rv;
  10710 }
  10711 
  10712 /*
  10713  * Function:
  10714  *      bcm_vlan_mcast_flood_get
  10715  * Purpose:
  10716  *      Get the VLAN Multicast flood mode (aka PFM - port filter mode)
  10717  * Parameters:
  10718  *      unit - StrataSwitch PCI device unit number (driver internal).
  10719  *      vid  - VLAN to get the flood setting for.
  10720  *      mode - Multicast flood mode
  10721  * Returns:
  10722  *      BCM_E_NONE - Success.
  10723  *      BCM_E_XXX
  10724  * Notes:
  10725  *      Available on XGS3 only.
  10726  */
  10727 int
  10728 bcm_esw_vlan_mcast_flood_get(int unit,
  10729                              bcm_vlan_t vlan,
  10730                              bcm_vlan_mcast_flood_t *mode)
  10731 {
  10732    int rv = BCM_E_UNAVAIL;
  10733 #ifdef BCM_XGS3_SWITCH_SUPPORT
  10734     if (soc_feature(unit, soc_feature_vlan_mc_flood_ctrl)) {
  10735         CHECK_INIT(unit);
  10736 #if defined(BCM_TRIUMPH_SUPPORT) && defined(BCM_MPLS_SUPPORT) && \
  10737     defined(INCLUDE_L3)
  10738         if (_BCM_MPLS_VPN_IS_VPLS(vlan)) {
  10739             if (soc_feature(unit, soc_feature_vfi_mc_flood_ctrl)) {
  10740                 return bcm_tr_mpls_mcast_flood_get(unit, vlan, mode);
  10741             } else {
  10742                 return rv;
  10743             }
  10744         } 
  10745 #endif
  10746         VLAN_CHK_ID(unit, vlan);
  10747         if (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vlan)) {
  10748             rv = _bcm_xgs3_vlan_mcast_flood_get(unit, vlan, mode);
  10749         } else {
  10750             rv = BCM_E_PARAM;
  10751         }
  10752     }
  10753 #endif
  10754     return rv;
  10755 }
  10756 
  10757 
  10758 /*
  10759  * Function:
  10760  *      bcm_esw_vlan_block_set
  10761  * Purpose:
  10762  *      Set per VLAN configuration.
  10763  * Parameters:
  10764  *      unit    - (IN) BCM device number.
  10765  *      vid     - (IN) VLAN to get the flood setting for.
  10766  *      block   - (IN) VLAN block structure
  10767  * Returns:
  10768  *      BCM_E_NONE - Success.
  10769  *      BCM_E_XXX
  10770  * Notes:
  10771  */
  10772 int
  10773 bcm_esw_vlan_block_set(int unit, bcm_vlan_t vid, bcm_vlan_block_t *block)
  10774 {
  10775     int rv = BCM_E_UNAVAIL;
  10776 
  10777 #ifdef BCM_TRX_SUPPORT
  10778     CHECK_INIT(unit);
  10779 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
  10780     if (soc_feature(unit, soc_feature_vfi_combo_profile) &&
  10781         _BCM_VPN_VFI_IS_SET(vid)) {
  10782         int vfi = 0;
  10783         bcm_vpn_t vpn_min = 0;
  10784         int num_vfi = soc_mem_index_count(unit, VFIm);
  10785 
  10786         _BCM_VPN_SET(vpn_min, _BCM_VPN_TYPE_VFI, 0);
  10787         if ((vid > (vpn_min+num_vfi-1)) || (vid < vpn_min)) {
  10788             return (BCM_E_PARAM);
  10789         }
  10790 
  10791         _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vid);
  10792         if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeAny)) {
  10793             return BCM_E_NOT_FOUND;
  10794         }
  10795 
  10796         rv = bcmi_td2p_vlan_block_set(unit, vid, block);
  10797     } else
  10798 #endif
  10799     {
  10800     VLAN_CHK_ID(unit, vid);
  10801 
  10802     if (SOC_MEM_IS_VALID(unit, VLAN_PROFILE_2m))  {
  10803         if (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vid)) {
  10804             BCM_LOCK(unit);
  10805             rv = _bcm_trx_vlan_block_set(unit, vid, block);
  10806             BCM_UNLOCK(unit);
  10807         } else {
  10808             rv = BCM_E_PARAM;
  10809         }
  10810     }
  10811     }
  10812 #endif /* BCM_TRX_SUPPORT */
  10813     return rv;
  10814 }
  10815 
  10816 /*
  10817  * Function:
  10818  *      bcm_esw_vlan_block_get
  10819  * Purpose:
  10820  *      Get per VLAN block configuration.
  10821  * Parameters:
  10822  *      unit    - (IN) BCM device number.
  10823  *      vid     - (IN) VLAN to get the flood setting for.
  10824  *      control - (OUT) VLAN control structure
  10825  * Returns:
  10826  *      BCM_E_NONE - Success.
  10827  *      BCM_E_XXX
  10828  * Notes:
  10829  */
  10830 int
  10831 bcm_esw_vlan_block_get(int unit, bcm_vlan_t vid, bcm_vlan_block_t *block)
  10832 {
  10833     int rv = BCM_E_UNAVAIL;
  10834 
  10835     if (NULL == block) {
  10836         return (BCM_E_PARAM);
  10837     }
  10838 
  10839 #ifdef BCM_TRX_SUPPORT
  10840     CHECK_INIT(unit);
  10841 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
  10842     if (soc_feature(unit, soc_feature_vfi_combo_profile) &&
  10843         _BCM_VPN_VFI_IS_SET(vid)) {
  10844         int vfi = 0;
  10845         bcm_vpn_t vpn_min = 0;
  10846         int num_vfi = soc_mem_index_count(unit, VFIm);
  10847 
  10848         _BCM_VPN_SET(vpn_min, _BCM_VPN_TYPE_VFI, 0);
  10849         if ((vid > (vpn_min+num_vfi-1)) || (vid < vpn_min)) {
  10850             return (BCM_E_PARAM);
  10851         }
  10852 
  10853         _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vid);
  10854         if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeAny)) {
  10855             return BCM_E_NOT_FOUND;
  10856         }
  10857 
  10858         rv = bcmi_td2p_vlan_block_get(unit, vid, block);
  10859     } else
  10860 #endif
  10861     {
  10862     VLAN_CHK_ID(unit, vid);
  10863     if (SOC_MEM_IS_VALID(unit, VLAN_PROFILE_2m)) {
  10864         if (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vid)) {
  10865             BCM_LOCK(unit);
  10866             rv = _bcm_trx_vlan_block_get(unit, vid, block);
  10867             BCM_UNLOCK(unit);
  10868         } else {
  10869             rv = BCM_E_PARAM;
  10870         }
  10871     }
  10872     }
  10873 #endif /* BCM_TRX_SUPPORT */
  10874     return rv;
  10875 }
  10876 
  10877 /*
  10878  * Function:
  10879  *      bcm_esw_vlan_control_vlan_selective_set
  10880  * Purpose:
  10881  *      Set per VLAN configuration.
  10882  * Parameters:
  10883  *      unit    - (IN) StrataSwitch PCI device unit number (driver internal).
  10884  *      vid     - (IN) VLAN to get the flood setting for.
  10885  *      valid_fields - (IN) Valid fields for VLAN control structure, BCM_VLAN_CONTROL_VLAN_XXX_MASK.
  10886  *      control - (IN) VLAN control structure
  10887  * Returns:
  10888  *      BCM_E_NONE - Success.
  10889  *      BCM_E_XXX
  10890  * Notes:
  10891  */
  10892 int
  10893 bcm_esw_vlan_control_vlan_selective_set(int unit, bcm_vlan_t vlan,
  10894                               uint32 valid_fields, bcm_vlan_control_vlan_t *control)
  10895 {
  10896     int rv = BCM_E_UNAVAIL;
  10897 
  10898 #ifdef BCM_TOMAHAWK3_SUPPORT
  10899     if (SOC_IS_TOMAHAWK3(unit)) {
  10900         return bcm_tomahawk3_vlan_control_vlan_selective_set(unit,
  10901                                                              vlan,
  10902                                                              valid_fields,
  10903                                                              control);
  10904     }
  10905 #endif
  10906 
  10907     if (NULL == control) {
  10908         return (BCM_E_PARAM);
  10909     }
  10910 
  10911 #ifdef BCM_XGS3_SWITCH_SUPPORT
  10912 #if (defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || \
  10913      defined(BCM_GREYHOUND2_SUPPORT)) && defined(INCLUDE_L3)
  10914     if (_BCM_VPN_VFI_IS_SET(vlan)) {
  10915         int vfi = 0;
  10916         bcm_vpn_t vpn_min = 0;
  10917         int max_vfi = soc_mem_index_max(unit, VFIm);
  10918 
  10919         _BCM_VPN_SET(vpn_min, _BCM_VPN_TYPE_VFI, 0);
  10920         if ((vlan > (vpn_min + max_vfi)) || (vlan < vpn_min)) {
  10921             return (BCM_E_PARAM);
  10922         }
  10923 
  10924         _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vlan);
  10925 #ifdef BCM_GREYHOUND2_SUPPORT
  10926         if (soc_feature(unit, soc_feature_vxlan_lite_riot)) {
  10927             if (!bcmi_gh2_vxlan_vfi_used_get(unit, vfi)) {
  10928                 return BCM_E_NOT_FOUND;
  10929             }
  10930         } else
  10931 #endif /* BCM_GREYHOUND2_SUPPORT */
  10932         if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeAny)) {
  10933             return BCM_E_NOT_FOUND;
  10934         }
  10935     } else
  10936 #endif /* TRIDENT2PLUS || TOMAHAWK || GREYHOUND2 */
  10937     {
  10938         VLAN_CHK_ID(unit, vlan);
  10939     }
  10940 
  10941     if ((control->vrf > SOC_VRF_MAX(unit))) {
  10942         return (BCM_E_PARAM);
  10943     }
  10944 
  10945     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  10946         BCM_LOCK(unit);
  10947         rv = _bcm_xgs3_vlan_control_vlan_set(unit, vlan, valid_fields, control);
  10948         BCM_UNLOCK(unit);
  10949     }
  10950 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  10951 
  10952     return rv;
  10953 }
  10954 
  10955 /*
  10956  * Function:
  10957  *      bcm_esw_vlan_control_vlan_selective_get
  10958  * Purpose:
  10959  *      Get per VLAN configuration.
  10960  * Parameters:
  10961  *      unit     - (IN) StrataSwitch PCI device unit number (driver internal).
  10962  *      vid      - (IN) VLAN to get the flood setting for.
  10963  *      valid_fields - (IN) Valid fields for VLAN control structure, BCM_VLAN_CONTROL_VLAN_XXX_MASK.
  10964  *      control  - (OUT) VLAN control structure
  10965  * Returns:
  10966  *      BCM_E_NONE - Success.
  10967  *      BCM_E_XXX
  10968  * Notes:
  10969  */
  10970 int
  10971 bcm_esw_vlan_control_vlan_selective_get(int unit, bcm_vlan_t vlan,
  10972                               uint32 valid_fields, bcm_vlan_control_vlan_t *control)
  10973 {
  10974     int rv = BCM_E_UNAVAIL;
  10975 
  10976 #ifdef BCM_TOMAHAWK3_SUPPORT
  10977     if (SOC_IS_TOMAHAWK3(unit)) {
  10978         return bcm_tomahawk3_vlan_control_vlan_selective_get(unit,
  10979                                                              vlan,
  10980                                                              valid_fields,
  10981                                                              control);
  10982     }
  10983 #endif
  10984 
  10985     if (NULL == control) {
  10986         return (BCM_E_PARAM);
  10987     }
  10988 
  10989 #ifdef BCM_XGS3_SWITCH_SUPPORT
  10990 #if (defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || \
  10991      defined(BCM_GREYHOUND2_SUPPORT)) && defined(INCLUDE_L3)
  10992     if (_BCM_VPN_VFI_IS_SET(vlan)) {
  10993         int vfi = 0;
  10994         bcm_vpn_t vpn_min = 0;
  10995         int max_vfi = soc_mem_index_max(unit, VFIm);
  10996 
  10997         _BCM_VPN_SET(vpn_min, _BCM_VPN_TYPE_VFI, 0);
  10998         if ((vlan > (vpn_min + max_vfi)) || (vlan < vpn_min)) {
  10999             return (BCM_E_PARAM);
  11000         }
  11001 
  11002         _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vlan);
  11003 #ifdef BCM_GREYHOUND2_SUPPORT
  11004         if (soc_feature(unit, soc_feature_vxlan_lite_riot)) {
  11005             if (!bcmi_gh2_vxlan_vfi_used_get(unit, vfi)) {
  11006                 return BCM_E_NOT_FOUND;
  11007             }
  11008         } else
  11009 #endif /* BCM_GREYHOUND2_SUPPORT */
  11010         if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeAny)) {
  11011             return BCM_E_NOT_FOUND;
  11012         }
  11013     } else
  11014 #endif /* TRIDENT2PLUS || TOMAHAWK || GREYHOUND2 */
  11015     {
  11016         VLAN_CHK_ID(unit, vlan);
  11017     }
  11018 
  11019     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  11020         BCM_LOCK(unit);
  11021         rv = _bcm_xgs3_vlan_control_vlan_get(unit, vlan, valid_fields, control);
  11022         BCM_UNLOCK(unit);
  11023     }
  11024 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  11025 
  11026     return rv;
  11027 }
  11028 
  11029 /*
  11030  * Function:
  11031  *      bcm_esw_vlan_control_vlan_set
  11032  * Purpose:
  11033  *      Set per VLAN configuration.
  11034  * Parameters:
  11035  *      unit    - (IN) StrataSwitch PCI device unit number (driver internal).
  11036  *      vid     - (IN) VLAN to get the flood setting for.
  11037  *      control - (IN) VLAN control structure
  11038  * Returns:
  11039  *      BCM_E_NONE - Success.
  11040  *      BCM_E_XXX
  11041  * Notes:
  11042  */
  11043 int
  11044 bcm_esw_vlan_control_vlan_set(int unit, bcm_vlan_t vid,
  11045 /* coverity[pass_by_value] */
  11046                               bcm_vlan_control_vlan_t control)
  11047 {
  11048     int rv = BCM_E_UNAVAIL;
  11049 
  11050 #ifdef BCM_XGS3_SWITCH_SUPPORT
  11051 #ifdef BCM_TOMAHAWK3_SUPPORT
  11052     if (SOC_IS_TOMAHAWK3(unit)) {
  11053         return bcm_tomahawk3_vlan_control_vlan_set(unit, vid, control);
  11054     }
  11055 #endif
  11056     CHECK_INIT(unit);
  11057 
  11058     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  11059         uint32 valid_fields = BCM_VLAN_CONTROL_VLAN_ALL_MASK;
  11060 
  11061         /* API semantic validation */
  11062         if (!_BCM_VPN_VFI_IS_SET(vid)) {
  11063             VLAN_CHK_ID(unit, vid);
  11064         }
  11065         if (control.vrf > SOC_VRF_MAX(unit)) {
  11066             return (BCM_E_PARAM);
  11067         }
  11068 
  11069         /*
  11070          * On some devices not all fields are supported
  11071          * Raven does not support Forwarding database support.
  11072          */
  11073         if (soc_feature(unit, soc_feature_forwarding_db_no_support)) {
  11074            if (control.forwarding_vlan) {
  11075                return BCM_E_UNAVAIL;
  11076            }
  11077            valid_fields &= ~BCM_VLAN_CONTROL_VLAN_FORWARDING_VLAN_MASK;
  11078         }
  11079         /* 
  11080          * some device can't support VLAN based VRF due to L3_IIFm can't 
  11081          * be indexed by VID.
  11082          */
  11083         if (soc_feature(unit, soc_feature_no_vlan_vrf)) {
  11084             if (control.vrf != 0) {
  11085                 return BCM_E_UNAVAIL;
  11086             }
  11087             valid_fields &= ~BCM_VLAN_CONTROL_VLAN_VRF_MASK;
  11088         }
  11089         rv = bcm_esw_vlan_control_vlan_selective_set(
  11090                         unit, vid, valid_fields, &control);
  11091     }
  11092 
  11093 #if defined(BCM_BRADLEY_SUPPORT)
  11094     else if (SOC_IS_HB_GW(unit)) {
  11095         bcm_vlan_control_vlan_t vctrl;
  11096         vlan_tab_entry_t vt;
  11097 
  11098         /* Check for unsupported parameters */
  11099         sal_memset(&vctrl, 0, sizeof(vctrl));
  11100         if (control.forwarding_vlan > BCM_VLAN_MAX) {
  11101             return BCM_E_PARAM;
  11102         }
  11103         vctrl.forwarding_vlan = control.forwarding_vlan;
  11104         if (sal_memcmp(&vctrl, &control, sizeof(vctrl)) != 0) {
  11105             return BCM_E_PARAM;
  11106         }
  11107 
  11108         soc_mem_lock(unit, VLAN_TABm);
  11109         rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, vid, &vt);
  11110         if (BCM_SUCCESS(rv)) {
  11111             soc_mem_field32_set(unit, VLAN_TABm, &vt, FID_IDf,
  11112                                 control.forwarding_vlan);
  11113             rv = soc_mem_write(unit, VLAN_TABm, MEM_BLOCK_ANY, vid, &vt);
  11114         }
  11115         soc_mem_unlock(unit, VLAN_TABm);
  11116     }
  11117 #endif /* BCM_BRADLEY_SUPPORT */
  11118 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  11119     return rv;
  11120 }
  11121 
  11122 /*
  11123  * Function:
  11124  *      bcm_esw_vlan_control_vlan_get
  11125  * Purpose:
  11126  *      Get per VLAN configuration.
  11127  * Parameters:
  11128  *      unit    - (IN) StrataSwitch PCI device unit number (driver internal).
  11129  *      vid     - (IN) VLAN to get the flood setting for.
  11130  *      control - (OUT) VLAN control structure
  11131  * Returns:
  11132  *      BCM_E_NONE - Success.
  11133  *      BCM_E_XXX
  11134  * Notes:
  11135  */
  11136 int
  11137 bcm_esw_vlan_control_vlan_get(int unit, bcm_vlan_t vid,
  11138                               bcm_vlan_control_vlan_t *control)
  11139 {
  11140     int rv = BCM_E_UNAVAIL;
  11141 
  11142 #ifdef BCM_TOMAHAWK3_SUPPORT
  11143     if (SOC_IS_TOMAHAWK3(unit)) {
  11144         return bcm_tomahawk3_vlan_control_vlan_get(unit, vid, control);
  11145     }
  11146 #endif
  11147 
  11148     if (NULL == control) {
  11149         return (BCM_E_PARAM);
  11150     }
  11151 
  11152 #ifdef BCM_XGS3_SWITCH_SUPPORT
  11153     CHECK_INIT(unit);
  11154 
  11155     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  11156         uint32 valid_fields = BCM_VLAN_CONTROL_VLAN_ALL_MASK;
  11157 
  11158         /* 
  11159          * some device can't support VLAN based VRF due to L3_IIFm can't 
  11160          * be indexed by VID
  11161          */
  11162         if (soc_feature(unit, soc_feature_no_vlan_vrf)) {
  11163             valid_fields &= ~BCM_VLAN_CONTROL_VLAN_VRF_MASK;
  11164         }
  11165         rv = bcm_esw_vlan_control_vlan_selective_get(unit, vid, valid_fields,
  11166                                                      control);
  11167     }
  11168 #if defined(BCM_BRADLEY_SUPPORT)
  11169     else if (SOC_IS_HB_GW(unit)) {
  11170         vlan_tab_entry_t vt;
  11171 
  11172         soc_mem_lock(unit, VLAN_TABm);
  11173         rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, vid, &vt);
  11174         if (BCM_SUCCESS(rv)) {
  11175             control->forwarding_vlan = soc_mem_field32_get(unit, VLAN_TABm,
  11176                                                            &vt, FID_IDf);
  11177             if (!SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VRF_IDf)) {
  11178                control->vrf = 0;
  11179             }
  11180         }
  11181         soc_mem_unlock(unit, VLAN_TABm);
  11182     }
  11183 #endif /* BCM_TRX_SUPPORT || BCM_BRADLEY_SUPPORT */
  11184 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  11185     return rv;
  11186 }
  11187 
  11188 /*
  11189  *   Function
  11190  *      bcm_esw_vlan_vector_flags_set
  11191  *   Purpose
  11192  *      Set a one or more VLAN control vlan flags on a vlan_vector on this unit
  11193  *   Parameters
  11194  *      (in) int unit = unit number
  11195  *      (in) bcm_vlan_vector_t vlan_vector = Vlan vector for values to be set
  11196  *      (in) uint32 flags_mask
  11197  *      (in) uint32 flags_value
  11198  *   Returns
  11199  *      bcm_error_t = BCM_E_NONE if successful
  11200  *                    BCM_E_* appropriately if not
  11201  *   Notes
  11202  */
  11203 int
  11204 bcm_esw_vlan_vector_flags_set(int unit,
  11205                               bcm_vlan_vector_t vlan_vector,
  11206                               uint32 flags_mask,
  11207                               uint32 flags_value)
  11208 {
  11209     int rv;
  11210 
  11211     bcm_vlan_t              vid;
  11212     bcm_vlan_control_vlan_t control;
  11213 
  11214 #ifdef BCM_TOMAHAWK3_SUPPORT
  11215     if (SOC_IS_TOMAHAWK3(unit)) {
  11216         return bcm_tomahawk3_vlan_vector_flags_set(unit, vlan_vector,
  11217                                                    flags_mask, flags_value);
  11218     }
  11219 #endif
  11220 
  11221     /* non-supported vector flags */
  11222     if (flags_mask & (BCM_VLAN_USE_FABRIC_DISTRIBUTION | BCM_VLAN_COSQ_ENABLE)) {
  11223         return BCM_E_PARAM;
  11224     }
  11225 
  11226     /* Optimistically assume success from here */
  11227     rv = BCM_E_NONE;
  11228 
  11229     for (vid = BCM_VLAN_MIN + 1; vid < BCM_VLAN_MAX; vid++) {
  11230 
  11231        if (BCM_VLAN_VEC_GET(vlan_vector, vid)) {
  11232 
  11233           rv = bcm_esw_vlan_control_vlan_get(unit, vid, &control);
  11234 
  11235           control.flags = (~flags_mask & control.flags) | (flags_mask & flags_value);
  11236 
  11237           if (BCM_SUCCESS(rv)) {
  11238               rv = bcm_esw_vlan_control_vlan_set(unit, vid, control);
  11239           }
  11240        }
  11241     }
  11242     return rv;
  11243 }
  11244 
  11245 /*
  11246  * Function:
  11247  *      bcm_vlan_cross_connect_add
  11248  * Purpose:
  11249  *      Add a VLAN cross connect entry
  11250  * Parameters:
  11251  *      unit       - Device unit number
  11252  *      outer_vlan - Outer vlan ID
  11253  *      inner_vlan - Inner vlan ID
  11254  *      port_1     - First port in the cross-connect
  11255  *      port_2     - Second port in the cross-connect
  11256  * Returns:
  11257  *      BCM_E_NONE - Success.
  11258  *      BCM_E_XXX
  11259  */
  11260 int
  11261 bcm_esw_vlan_cross_connect_add(int unit, 
  11262                                bcm_vlan_t outer_vlan, bcm_vlan_t inner_vlan,
  11263                                bcm_gport_t port_1, bcm_gport_t port_2)
  11264 {
  11265 #ifdef BCM_TOMAHAWK3_SUPPORT
  11266     if (SOC_IS_TOMAHAWK3(unit)) {
  11267         return bcm_tomahawk3_vlan_cross_connect_add(
  11268                     unit, outer_vlan, inner_vlan, port_1, port_2);
  11269     }
  11270 #endif
  11271 #ifdef BCM_TRX_SUPPORT
  11272     
  11273     if ((port_1 == BCM_GPORT_INVALID) || (port_2 == BCM_GPORT_INVALID)) {
  11274         return BCM_E_PORT;
  11275     }
  11276 #ifdef BCM_TRIUMPH3_SUPPORT
  11277     if (SOC_IS_TRIUMPH3(unit)) {
  11278         return bcm_tr3_l2_cross_connect_add(unit, outer_vlan, inner_vlan,
  11279                                            port_1, port_2);
  11280     }
  11281 #endif
  11282     if (SOC_IS_TRX(unit)) {
  11283         return bcm_tr_l2_cross_connect_add(unit, outer_vlan, inner_vlan,
  11284                                            port_1, port_2);
  11285     }
  11286 #endif
  11287     return BCM_E_UNAVAIL;
  11288 }
  11289 
  11290 /*
  11291  * Function:
  11292  *      bcm_vlan_cross_connect_delete
  11293  * Purpose:
  11294  *      Delete a VLAN cross connect entry
  11295  * Parameters:
  11296  *      unit       - Device unit number
  11297  *      outer_vlan - Outer vlan ID
  11298  *      inner_vlan - Inner vlan ID
  11299  * Returns:
  11300  *      BCM_E_NONE - Success.
  11301  *      BCM_E_XXX
  11302  */
  11303 int
  11304 bcm_esw_vlan_cross_connect_delete(int unit,
  11305                                   bcm_vlan_t outer_vlan, 
  11306                                   bcm_vlan_t inner_vlan)
  11307 {
  11308 #ifdef BCM_TOMAHAWK3_SUPPORT
  11309     if (SOC_IS_TOMAHAWK3(unit)) {
  11310         return bcm_tomahawk3_vlan_cross_connect_delete(
  11311                                 unit, outer_vlan, inner_vlan);
  11312     }
  11313 #endif
  11314 #ifdef BCM_TRX_SUPPORT
  11315 #ifdef BCM_TRIUMPH3_SUPPORT
  11316     if (SOC_IS_TRIUMPH3(unit)) {
  11317         return bcm_tr3_l2_cross_connect_delete(unit, outer_vlan, inner_vlan);
  11318     }
  11319 #endif
  11320     if (SOC_IS_TRX(unit)) {
  11321         return bcm_tr_l2_cross_connect_delete(unit, outer_vlan, inner_vlan);
  11322     }
  11323 #endif
  11324     return BCM_E_UNAVAIL;
  11325 }
  11326 
  11327 /*
  11328  * Function:
  11329  *      bcm_vlan_cross_connect_delete_all
  11330  * Purpose:
  11331  *      Delete all VLAN cross connect entries
  11332  * Parameters:
  11333  *      unit       - Device unit number
  11334  * Returns:
  11335  *      BCM_E_NONE - Success.
  11336  *      BCM_E_XXX
  11337  */
  11338 int
  11339 bcm_esw_vlan_cross_connect_delete_all(int unit)
  11340 {
  11341 #ifdef BCM_TOMAHAWK3_SUPPORT
  11342     if (SOC_IS_TOMAHAWK3(unit)) {
  11343         return bcm_tomahawk3_vlan_cross_connect_delete_all(unit);
  11344     }
  11345 #endif
  11346 #ifdef BCM_TRIUMPH3_SUPPORT
  11347     if (SOC_IS_TRIUMPH3(unit)) {
  11348         return bcm_tr3_l2_cross_connect_delete_all(unit); 
  11349     }
  11350 #endif
  11351 #ifdef BCM_TRX_SUPPORT
  11352     if (SOC_IS_TRX(unit)) {
  11353         return bcm_tr_l2_cross_connect_delete_all(unit);
  11354     }
  11355 #endif
  11356     return BCM_E_UNAVAIL;
  11357 }
  11358 
  11359 /*
  11360  * Function:
  11361  *      bcm_vlan_cross_connect_traverse
  11362  * Purpose:
  11363  *      Walks through the valid cross connect entries and calls 
  11364  *      the user supplied callback function for each entry.
  11365  * Parameters:
  11366  *      unit       - (IN) bcm device.
  11367  *      trav_fn    - (IN) Callback function.
  11368  *      user_data  - (IN) User data to be passed to callback function.
  11369  * Returns:
  11370  *      BCM_E_NONE - Success.
  11371  *      BCM_E_XXX
  11372  */
  11373 int
  11374 bcm_esw_vlan_cross_connect_traverse(int unit,
  11375                                     bcm_vlan_cross_connect_traverse_cb cb,
  11376                                     void *user_data)
  11377 {
  11378 #ifdef BCM_TOMAHAWK3_SUPPORT
  11379     if (SOC_IS_TOMAHAWK3(unit)) {
  11380         return bcm_tomahawk3_vlan_cross_connect_traverse(unit, cb, user_data);
  11381     }
  11382 #endif
  11383 #ifdef BCM_TRX_SUPPORT
  11384 #ifdef BCM_TRIUMPH3_SUPPORT
  11385     if (SOC_IS_TRIUMPH3(unit)) {
  11386         return bcm_tr3_l2_cross_connect_traverse(unit, cb, user_data);
  11387     }
  11388 #endif
  11389     if (SOC_IS_TRX(unit)) {
  11390         return bcm_tr_l2_cross_connect_traverse(unit, cb, user_data);
  11391     }
  11392 #endif
  11393     return BCM_E_UNAVAIL;
  11394 }
  11395 
  11396 #if defined(BCM_TRIUMPH2_SUPPORT)
  11397 STATIC int
  11398 _bcm_xgs3_vlan_table_hw_fs_set(int unit, bcm_vlan_t vid,
  11399                                int fs_idx, int table)
  11400 {
  11401     vlan_tab_entry_t    vt;
  11402     int                 rv;
  11403 
  11404     /* Upper layer already checks that vid is valid */
  11405     soc_mem_lock(unit, table);
  11406 
  11407     rv = soc_mem_read(unit, table, MEM_BLOCK_ANY, (int) vid, &vt);
  11408 
  11409     if (BCM_SUCCESS(rv) && !soc_mem_field32_get(unit, table, &vt, VALIDf)) {
  11410         rv = BCM_E_NOT_FOUND;
  11411     }
  11412 
  11413     if (BCM_SUCCESS(rv)) {
  11414         soc_mem_field32_set(unit, table, &vt, SERVICE_CTR_IDXf, fs_idx);
  11415 
  11416         rv = soc_mem_write(unit, table, MEM_BLOCK_ALL, (int) vid, &vt);
  11417     }
  11418 
  11419     soc_mem_unlock(unit, table);
  11420 
  11421     return rv;
  11422 }
  11423 
  11424 int
  11425 _bcm_esw_vlan_flex_stat_index_set(int unit, bcm_vlan_t vlan, int fs_idx,
  11426                                    uint32 flags)
  11427 {
  11428     int rv = BCM_E_NONE;
  11429     int rv1= BCM_E_NONE;
  11430 
  11431     BCM_LOCK(unit); /* To access the VLAN existence bitmap */
  11432     if (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vlan)) {
  11433         if (flags & _BCM_FLEX_STAT_HW_INGRESS) {
  11434             rv = _bcm_xgs3_vlan_table_hw_fs_set(unit, vlan, fs_idx, VLAN_TABm);
  11435         }
  11436         if (flags & _BCM_FLEX_STAT_HW_EGRESS) {
  11437             rv1 = _bcm_xgs3_vlan_table_hw_fs_set(unit, vlan,
  11438                                                 fs_idx, EGR_VLANm);
  11439         }
  11440     } else {
  11441         rv = BCM_E_NOT_FOUND;
  11442     }
  11443     BCM_UNLOCK(unit);
  11444     if (BCM_SUCCESS(rv1)) {
  11445         return rv;
  11446     } else {
  11447         return rv1;
  11448     }
  11449 }
  11450 
  11451 STATIC int
  11452 _bcm_esw_vlan_stat_param_verify(int unit, bcm_vlan_t vlan, bcm_cos_t cos)
  11453 {
  11454 #if defined(INCLUDE_L3)
  11455     int vfi;
  11456     int rv = BCM_E_NOT_FOUND;
  11457 #endif /* INCLUDE_L3 */
  11458 
  11459 #if defined(INCLUDE_L3)
  11460     /* 
  11461      * Is it a VPN? Both VPLS and VPN have the same VLAN encoding hence looping
  11462      * in booth the MIM and VPLS tables
  11463      */
  11464     if (_BCM_VPN_IS_VPLS(vlan)) {
  11465 #if defined(BCM_TOMAHAWK3_SUPPORT)
  11466         if (SOC_IS_TOMAHAWK3(unit)) {
  11467             rv = BCM_E_UNAVAIL;
  11468         } else
  11469 #endif
  11470          if (soc_feature(unit, soc_feature_mpls)) {
  11471              _BCM_MPLS_VPN_GET(vfi, _BCM_MPLS_VPN_TYPE_VPLS, vlan);
  11472              if (_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeMpls)) {
  11473                  rv = BCM_E_NONE;
  11474              }
  11475          } else {
  11476            rv = BCM_E_UNAVAIL;
  11477          }
  11478          BCM_IF_ERROR_RETURN (rv);
  11479     } else if ((_BCM_VPN_IS_MIM(vlan))) {
  11480          if ((rv != BCM_E_NONE) && (soc_feature(unit, soc_feature_mim))) {
  11481              _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, vlan);
  11482              if (_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeMim)) {
  11483                  rv =  BCM_E_NONE;
  11484              }
  11485          } else {
  11486            rv = BCM_E_UNAVAIL;
  11487          }
  11488          BCM_IF_ERROR_RETURN (rv);
  11489          
  11490     } else
  11491 #endif /* INCLUDE_L3 */
  11492     {
  11493         VLAN_CHK_ID(unit, vlan);
  11494     }
  11495     if (cos != BCM_COS_INVALID) {
  11496         return BCM_E_PARAM;
  11497     }
  11498     return BCM_E_NONE;
  11499 }
  11500 
  11501 STATIC int
  11502 _bcm_esw_vlan_stat_param_valid(int unit, bcm_vlan_t vlan, bcm_cos_t cos)
  11503 {
  11504     CHECK_INIT(unit);
  11505     if (!soc_feature(unit, soc_feature_gport_service_counters)) {
  11506         return BCM_E_UNAVAIL;
  11507     }
  11508     return _bcm_esw_vlan_stat_param_verify(unit,vlan,cos);
  11509 }
  11510 
  11511 typedef _bcm_flex_stat_t (*_bcm_vlan_stat_to_flex_stat_f)(bcm_vlan_stat_t
  11512                                                           stat);
  11513 
  11514 STATIC _bcm_flex_stat_t
  11515 _bcm_esw_vlan_stat_to_flex_stat(bcm_vlan_stat_t stat)
  11516 {
  11517     _bcm_flex_stat_t flex_stat;
  11518 
  11519     switch (stat) {
  11520     case bcmVlanStatIngressPackets:
  11521         flex_stat = _bcmFlexStatIngressPackets;
  11522         break;
  11523     case bcmVlanStatIngressBytes:
  11524         flex_stat = _bcmFlexStatIngressBytes;
  11525         break;
  11526     case bcmVlanStatEgressPackets:
  11527         flex_stat = _bcmFlexStatEgressPackets;
  11528         break;
  11529     case bcmVlanStatEgressBytes:
  11530         flex_stat = _bcmFlexStatEgressBytes;
  11531         break;
  11532     default:
  11533         flex_stat = _bcmFlexStatNum;
  11534     }
  11535 
  11536     return flex_stat;
  11537 }
  11538 
  11539 /* Requires "idx" variable */
  11540 #define BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr) \
  11541     for (idx = 0; idx < nstat; idx++) { \
  11542         if (NULL == value_arr + idx) { \
  11543             return (BCM_E_PARAM); \
  11544         } \
  11545     }
  11546 
  11547 STATIC int
  11548 _bcm_vlan_stat_array_convert(int unit, int nstat, bcm_vlan_stat_t *stat_arr, 
  11549                              _bcm_flex_stat_t *fs_arr,
  11550                              _bcm_vlan_stat_to_flex_stat_f vs2fs_f)
  11551 {
  11552     int idx;
  11553 
  11554     if ((nstat <= 0) || (nstat > _bcmFlexStatNum)) {
  11555         return BCM_E_PARAM;
  11556     }
  11557 
  11558     if (NULL == stat_arr) {
  11559         return (BCM_E_PARAM);
  11560     }
  11561 
  11562     for (idx = 0; idx < nstat; idx++) {
  11563         fs_arr[idx] = (*vs2fs_f)(stat_arr[idx]);
  11564     }
  11565     return BCM_E_NONE;
  11566 }
  11567 
  11568 #endif /* BCM_TRIUMPH2_SUPPORT */
  11569 
  11570 /*
  11571  * Function:
  11572  *      bcm_esw_vlan_stat_enable_set
  11573  * Purpose:
  11574  *      Enable/disable collection of statistics on the indicated VLAN.
  11575  * Parameters:
  11576  *      unit - (IN) Unit number.
  11577  *      vlan - (IN) VLAN Id.
  11578  *      enable - (IN) Non-zero to enable counter collection, zero to disable.
  11579  * Returns:
  11580  *      BCM_E_XXX
  11581  * Notes:
  11582  */
  11583 int 
  11584 bcm_esw_vlan_stat_enable_set(int unit, bcm_vlan_t vlan, int enable)
  11585 {
  11586 #if defined(BCM_TRIUMPH2_SUPPORT)
  11587 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  11588     uint32                     num_of_tables=0;
  11589     uint32                     num_stat_counter_ids=0;
  11590     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  11591     bcm_stat_object_t          object=bcmStatObjectIngPort;
  11592     uint32                     stat_counter_id[
  11593                                        BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]={0};
  11594     uint32                     num_entries=0;
  11595     int                        index=0;
  11596 
  11597 #endif
  11598  if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  11599     BCM_IF_ERROR_RETURN
  11600         (_bcm_esw_vlan_stat_param_valid(unit, vlan, BCM_COS_INVALID));
  11601     return _bcm_esw_flex_stat_enable_set(unit, _bcmFlexStatTypeService,
  11602                              _bcm_esw_vlan_flex_stat_hw_index_set,
  11603                                          NULL, vlan, enable,0);
  11604  }
  11605 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  11606     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_stat_get_table_info(
  11607                         unit,vlan,&num_of_tables,&table_info[0]));
  11608     if (enable ) {
  11609         for(index=0;index < num_of_tables ;index++) {
  11610             if(table_info[index].direction == bcmStatFlexDirectionIngress) {
  11611                BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_ingress_object(
  11612                                    unit,table_info[index].table,
  11613                                    table_info[index].index,NULL,&object));
  11614             } else {
  11615                 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_egress_object(
  11616                                     unit,table_info[index].table,
  11617                                     table_info[index].index,NULL,&object));
  11618             }
  11619             BCM_IF_ERROR_RETURN(bcm_esw_stat_group_create(
  11620                                 unit,object,bcmStatGroupModeSingle,
  11621                                 &stat_counter_id[table_info[index].direction],
  11622                                 &num_entries));
  11623             BCM_IF_ERROR_RETURN(bcm_esw_vlan_stat_attach(
  11624                                 unit,vlan,
  11625                                 stat_counter_id[table_info[index].direction]));
  11626         }
  11627         return BCM_E_NONE;
  11628     } else {
  11629         BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_counter_id(
  11630                             unit, num_of_tables,&table_info[0],
  11631                             &num_stat_counter_ids,&stat_counter_id[0]));
  11632         if ((stat_counter_id[bcmStatFlexDirectionIngress] == 0) &&
  11633             (stat_counter_id[bcmStatFlexDirectionEgress] == 0)) {
  11634              return BCM_E_PARAM;
  11635         }
  11636         BCM_IF_ERROR_RETURN(bcm_esw_vlan_stat_detach(unit,vlan));
  11637         if (stat_counter_id[bcmStatFlexDirectionIngress] != 0) {
  11638             BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy(
  11639                                 unit,
  11640                                 stat_counter_id[bcmStatFlexDirectionIngress]));
  11641         }
  11642         if (stat_counter_id[bcmStatFlexDirectionEgress] != 0) {
  11643             BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy(
  11644                                 unit,
  11645                                 stat_counter_id[bcmStatFlexDirectionEgress]));
  11646         }
  11647         return BCM_E_NONE;
  11648     }
  11649 #else
  11650     return BCM_E_UNAVAIL;
  11651 #endif
  11652 #else
  11653     return BCM_E_UNAVAIL;
  11654 #endif
  11655 }
  11656 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  11657 /*
  11658  * Function:
  11659  *      _bcm_esw_vlan_stat_get_table_info
  11660  * Description:
  11661  *      Provides relevant flex table information(table-name,index with
  11662  *      direction)  for given vlan.
  11663  *
  11664  * Parameters:
  11665  *      unit             - (IN) unit number
  11666  *      vlan             - (IN) VLAN Id.
  11667  *      num_of_tables    - (OUT) Number of flex counter tables
  11668  *      table_info       - (OUT) Flex counter tables information
  11669  *
  11670  * Return Value:
  11671  *      BCM_E_XXX
  11672  * Notes:
  11673  */
  11674 STATIC
  11675 bcm_error_t _bcm_esw_vlan_stat_get_table_info(
  11676             int                        unit,
  11677             bcm_vlan_t                 vlan,
  11678             uint32                     *num_of_tables,
  11679             bcm_stat_flex_table_info_t *table_info)
  11680 {
  11681 #if defined(INCLUDE_L3)
  11682     uint32 vfi=0;
  11683     bcm_error_t rv = BCM_E_NOT_FOUND;
  11684 #endif
  11685     (*num_of_tables) = 0;
  11686     if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  11687         return BCM_E_UNAVAIL;
  11688     }
  11689 
  11690     BCM_IF_ERROR_RETURN (_bcm_esw_vlan_stat_param_verify(
  11691                          unit, vlan, BCM_COS_INVALID));
  11692     if ((_BCM_MPLS_VPN_IS_SET(vlan)) || (_BCM_MIM_VPN_IS_SET(vlan))) {
  11693 #if defined(INCLUDE_L3)
  11694 #if defined(BCM_TOMAHAWK3_SUPPORT)
  11695         if (SOC_IS_TOMAHAWK3(unit)) {
  11696             return BCM_E_UNAVAIL;
  11697         }
  11698 #endif
  11699         /* since the VLAN encoding is same for MIM and MPLS looping in both */
  11700         if (soc_feature(unit, soc_feature_mpls)) {
  11701             _BCM_MPLS_VPN_GET(vfi, _BCM_MPLS_VPN_TYPE_VPLS, vlan);
  11702             if ((_bcm_vfi_used_get(unit,vfi,_bcmVfiTypeMpls))) {
  11703                 table_info[*num_of_tables].table=VFIm;
  11704                 table_info[*num_of_tables].index=vfi;
  11705                 table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress;
  11706                 (*num_of_tables)++;
  11707                 table_info[*num_of_tables].table=EGR_VFIm;
  11708                 table_info[*num_of_tables].index=vfi;
  11709                 table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress;
  11710                 (*num_of_tables)++;
  11711                 rv = BCM_E_NONE;
  11712             }
  11713         }
  11714         if ((rv == BCM_E_NOT_FOUND) && (soc_feature(unit, soc_feature_mim))) {
  11715             _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, vlan);
  11716             if ((_bcm_vfi_used_get(unit,vfi,_bcmVfiTypeMim))) {
  11717                  table_info[*num_of_tables].table=VFIm;
  11718                  table_info[*num_of_tables].index=vfi;
  11719                  table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress;
  11720                  (*num_of_tables)++;
  11721                  table_info[*num_of_tables].table=EGR_VFIm;
  11722                  table_info[*num_of_tables].index=vfi;
  11723                  table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress;
  11724                  (*num_of_tables)++;
  11725                  rv = BCM_E_NONE;
  11726             }
  11727         }
  11728         return rv;
  11729 #else
  11730                return BCM_E_UNAVAIL;
  11731 #endif
  11732     } else {
  11733         if (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vlan)) {
  11734             table_info[*num_of_tables].table=VLAN_TABm;
  11735             table_info[*num_of_tables].index=vlan;
  11736             table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress;
  11737             (*num_of_tables)++;
  11738 #if defined(BCM_TOMAHAWK_SUPPORT)
  11739             if (SOC_MEM_IS_VALID(unit, EGR_VLANm))
  11740 #endif
  11741             {
  11742                 table_info[*num_of_tables].table=EGR_VLANm;
  11743                 table_info[*num_of_tables].index=vlan;
  11744                 table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress;
  11745                 (*num_of_tables)++;
  11746             }
  11747             return BCM_E_NONE;
  11748         }
  11749         return BCM_E_NOT_FOUND;
  11750     }
  11751     /* Must not hit */
  11752     return BCM_E_NOT_FOUND;
  11753 }
  11754 #endif
  11755 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  11756 /*
  11757  * Function:
  11758  *      _bcm_esw_vlan_stat_attach
  11759  * Description:
  11760  *      Attach counter entries to the given vlan
  11761  *
  11762  * Parameters:
  11763  *      unit             - (IN) unit number
  11764  *      vlan             - (IN) VLAN Id.
  11765  *      stat_counter_id  - (IN) Stat Counter ID.
  11766  *
  11767  * Return Value:
  11768  *      BCM_E_XXX
  11769  * Notes:
  11770  */
  11771 STATIC bcm_error_t _bcm_esw_vlan_stat_attach(
  11772             int            unit,
  11773             bcm_vlan_t    vlan,
  11774             uint32      stat_counter_id)
  11775 {
  11776     soc_mem_t                  table=0;
  11777     bcm_stat_flex_direction_t  direction=bcmStatFlexDirectionIngress;
  11778     uint32                     pool_number=0;
  11779     uint32                     base_index=0;
  11780     bcm_stat_flex_mode_t       offset_mode=0;
  11781     bcm_stat_object_t          object=bcmStatObjectIngPort;
  11782     bcm_stat_group_mode_t      group_mode= bcmStatGroupModeSingle;
  11783     uint32                     count=0;
  11784     uint32                     actual_num_tables=0;
  11785     uint32                     num_of_tables=0;
  11786     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  11787 
  11788     _bcm_esw_stat_get_counter_id_info(
  11789                   unit, stat_counter_id,
  11790                   &group_mode,&object,&offset_mode,&pool_number,&base_index);
  11791     BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit,object,&direction));
  11792     BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit,group_mode));
  11793     BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_table_info(
  11794                         unit,object,1,&actual_num_tables,&table,&direction));
  11795 
  11796     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_stat_get_table_info(
  11797                         unit, vlan,&num_of_tables,&table_info[0]));
  11798     for (count=0; count < num_of_tables ; count++) {
  11799          if ((table_info[count].direction == direction) &&
  11800              (table_info[count].table == table)) {
  11801               if (direction == bcmStatFlexDirectionIngress) {
  11802                   return _bcm_esw_stat_flex_attach_ingress_table_counters(
  11803                          unit,table_info[count].table,table_info[count].index,
  11804                          offset_mode, base_index, pool_number);
  11805               } else {
  11806                   return _bcm_esw_stat_flex_attach_egress_table_counters(
  11807                          unit,table_info[count].table,table_info[count].index,
  11808                          0, offset_mode,base_index,pool_number);
  11809               } 
  11810          }
  11811     }
  11812     return BCM_E_NOT_FOUND;
  11813 }
  11814 #endif
  11815 
  11816 /*
  11817  * Function:
  11818  *      bcm_esw_vlan_stat_attach
  11819  * Description:
  11820  *      Attach counter entries to the given vlan
  11821  *
  11822  * Parameters:
  11823  *      unit             - (IN) unit number
  11824  *      vlan             - (IN) VLAN Id.
  11825  *      stat_counter_id  - (IN) Stat Counter ID.
  11826  *
  11827  * Return Value:
  11828  *      BCM_E_XXX
  11829  * Notes:
  11830  */
  11831 int bcm_esw_vlan_stat_attach(
  11832             int         unit,
  11833             bcm_vlan_t  vlan,
  11834             uint32      stat_counter_id)
  11835 {
  11836 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  11837     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  11838         return _bcm_esw_vlan_stat_attach(unit,vlan,stat_counter_id);
  11839     } else
  11840 #endif
  11841 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  11842     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  11843         _bcm_flex_stat_type_t fs_type;
  11844         uint32 fs_inx;
  11845         uint32 flag;
  11846 
  11847         fs_type = _BCM_FLEX_STAT_TYPE(stat_counter_id);
  11848         fs_inx  = _BCM_FLEX_STAT_COUNT_INX(stat_counter_id);
  11849 
  11850         if (!((fs_type == _bcmFlexStatTypeService ||
  11851             fs_type == _bcmFlexStatTypeEgressService) && fs_inx)) {
  11852             return BCM_E_PARAM;
  11853         }
  11854         BCM_IF_ERROR_RETURN
  11855             (_bcm_esw_vlan_stat_param_valid(unit, vlan, BCM_COS_INVALID));
  11856 
  11857         flag = fs_type==_bcmFlexStatTypeService? _BCM_FLEX_STAT_HW_INGRESS:
  11858                          _BCM_FLEX_STAT_HW_EGRESS;
  11859         return _bcm_esw_flex_stat_enable_set(unit, fs_type,
  11860                              _bcm_esw_vlan_flex_stat_hw_index_set,
  11861                                       INT_TO_PTR(flag),
  11862                                       vlan, TRUE,fs_inx);
  11863     } else
  11864 #endif
  11865     {
  11866         return BCM_E_UNAVAIL;
  11867     }
  11868 }
  11869 
  11870 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  11871 /*
  11872  * Function:
  11873  *      _bcm_esw_vlan_stat_detach
  11874  * Description:
  11875  *      Detach counter entries to the given GPORT
  11876  *
  11877  * Parameters:
  11878  *      unit             - (IN) unit number
  11879  *      vlan             - (IN) VLAN Id.
  11880  *
  11881  * Return Value:
  11882  *      BCM_E_XXX
  11883  * Notes:
  11884  */
  11885 STATIC bcm_error_t _bcm_esw_vlan_stat_detach(
  11886             int            unit,
  11887             bcm_vlan_t    vlan)
  11888 {
  11889     uint32                     count=0;
  11890     uint32                     num_of_tables=0;
  11891     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  11892     bcm_error_t                rv = BCM_E_NONE;
  11893     bcm_error_t                err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE};
  11894 
  11895     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_stat_get_table_info(
  11896                         unit, vlan,&num_of_tables,&table_info[0]));
  11897 
  11898     for (count=0; count < num_of_tables ; count++) {
  11899          if (table_info[count].direction == bcmStatFlexDirectionIngress) {
  11900              rv = _bcm_esw_stat_flex_detach_ingress_table_counters(
  11901                         unit, table_info[count].table, table_info[count].index);
  11902              if (BCM_E_NONE != rv &&
  11903                 BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) {
  11904                 err_code[bcmStatFlexDirectionIngress] = rv;
  11905              }
  11906          } else {
  11907              rv = _bcm_esw_stat_flex_detach_egress_table_counters(
  11908                         unit, 0, table_info[count].table, table_info[count].index);
  11909 
  11910              if (BCM_E_NONE != rv &&
  11911                 BCM_E_NONE == err_code[bcmStatFlexDirectionEgress]) {
  11912                 err_code[bcmStatFlexDirectionEgress] = rv;
  11913              }
  11914          }
  11915     }
  11916     
  11917     BCM_STAT_FLEX_DETACH_RETURN(err_code)
  11918 }
  11919 
  11920 /*
  11921  * Function:
  11922  *      _bcm_esw_vlan_stat_detach_with_id
  11923  * Description:
  11924  *      Detach counter entries to the given vlan with a given stat counter id
  11925  *
  11926  * Parameters:
  11927  *      unit             - (IN) unit number
  11928  *      vlan             - (IN) VLAN Id
  11929  *      stat_counter_id  - (IN) Stat Counter ID. 
  11930  *
  11931  * Return Value:
  11932  *      BCM_E_XXX
  11933  * Notes:
  11934  */
  11935 STATIC bcm_error_t _bcm_esw_vlan_stat_detach_with_id(
  11936             int	        unit,
  11937             bcm_vlan_t  vlan,
  11938             uint32      stat_counter_id)
  11939 {
  11940     uint32                     count=0;
  11941     uint32                     num_of_tables=0;
  11942     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  11943     bcm_error_t                rv = BCM_E_NONE;
  11944     bcm_error_t                err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE};
  11945     bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress;
  11946     uint32                    pool_number=0;
  11947     uint32                    base_index=0;
  11948     bcm_stat_flex_mode_t      offset_mode=0;
  11949     bcm_stat_object_t         object=bcmStatObjectIngPort;
  11950     bcm_stat_group_mode_t     group_mode= bcmStatGroupModeSingle;
  11951     uint32                     actual_num_tables=0;
  11952     soc_mem_t                 table=0;
  11953     
  11954     
  11955     _bcm_esw_stat_get_counter_id_info(
  11956                   unit, stat_counter_id,
  11957                   &group_mode,&object,&offset_mode,&pool_number,&base_index);
  11958     BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit,object,&direction));
  11959     BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit,group_mode));
  11960     BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_table_info(
  11961                         unit,object,1,&actual_num_tables,&table,&direction));
  11962 
  11963     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_stat_get_table_info(
  11964                         unit, vlan,&num_of_tables,&table_info[0]));
  11965 
  11966     for (count=0; count < num_of_tables ; count++) {
  11967         if((table_info[count].direction == direction) &&
  11968              (table_info[count].table == table)) {
  11969             if(direction == bcmStatFlexDirectionIngress) {
  11970                 rv = _bcm_esw_stat_flex_detach_ingress_table_counters(
  11971                            unit, table_info[count].table, table_info[count].index);
  11972                 if (BCM_E_NONE != rv &&
  11973                     BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) {
  11974                     err_code[bcmStatFlexDirectionIngress] = rv;
  11975                 }
  11976             } else {
  11977                 rv = _bcm_esw_stat_flex_detach_egress_table_counters(
  11978                            unit, 0, table_info[count].table, table_info[count].index);
  11979                 if (BCM_E_NONE != rv &&
  11980                     BCM_E_NONE == err_code[bcmStatFlexDirectionEgress]) {
  11981                     err_code[bcmStatFlexDirectionEgress] = rv;
  11982                 }
  11983             }
  11984         }
  11985     }
  11986     
  11987     BCM_STAT_FLEX_DETACH_RETURN(err_code)
  11988 }
  11989 #endif
  11990 
  11991 /*
  11992  * Function:
  11993  *      bcm_esw_vlan_stat_detach
  11994  * Description:
  11995  *      Detach counter entries to the given GPORT
  11996  *
  11997  * Parameters:
  11998  *      unit             - (IN) unit number
  11999  *      vlan             - (IN) VLAN Id.
  12000  *
  12001  * Return Value:
  12002  *      BCM_E_XXX
  12003  * Notes:
  12004  */
  12005 int bcm_esw_vlan_stat_detach(
  12006             int         unit,
  12007             bcm_vlan_t  vlan)
  12008 {
  12009 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12010     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  12011         return _bcm_esw_vlan_stat_detach(unit,vlan);
  12012     } else
  12013 #endif
  12014 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  12015     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  12016         uint32 flag;
  12017         int rv;
  12018 
  12019         BCM_IF_ERROR_RETURN
  12020             (_bcm_esw_vlan_stat_param_valid(unit, vlan, BCM_COS_INVALID));
  12021 
  12022         flag = _BCM_FLEX_STAT_HW_INGRESS;
  12023         rv = _bcm_esw_flex_stat_enable_set(unit, _bcmFlexStatTypeService,
  12024                              _bcm_esw_vlan_flex_stat_hw_index_set,
  12025                                       INT_TO_PTR(flag),
  12026                                       vlan, FALSE, 1);
  12027         flag = _BCM_FLEX_STAT_HW_EGRESS;
  12028         rv = _bcm_esw_flex_stat_enable_set(unit,_bcmFlexStatTypeEgressService,
  12029                              _bcm_esw_vlan_flex_stat_hw_index_set,
  12030                                       INT_TO_PTR(flag),
  12031                                       vlan, FALSE, 1);
  12032         return rv;
  12033     } else
  12034 #endif
  12035     {
  12036         return BCM_E_UNAVAIL;
  12037     }
  12038 }
  12039 
  12040 /*
  12041  * Function:
  12042  *      bcm_esw_vlan_stat_detach_with_id
  12043  * Description:
  12044  *      Detach counter entries to the given vlan with a given stat counter id
  12045  *
  12046  * Parameters:
  12047  *      unit             - (IN) unit number
  12048  *      vlan             - (IN) VLAN Id
  12049  *      stat_counter_id  - (IN) Stat Counter ID. 
  12050  *
  12051  * Return Value:
  12052  *      BCM_E_XXX
  12053  * Notes:
  12054  */
  12055 bcm_error_t bcm_esw_vlan_stat_detach_with_id(
  12056             int         unit,
  12057             bcm_vlan_t  vlan,
  12058             uint32      stat_counter_id)
  12059 {
  12060 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12061     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  12062         return _bcm_esw_vlan_stat_detach_with_id(unit, vlan, stat_counter_id);
  12063     } else
  12064 #endif
  12065     {
  12066         return BCM_E_UNAVAIL;
  12067     }
  12068 }
  12069 
  12070 
  12071 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12072 /*
  12073  * Function:
  12074  *      _bcm_esw_vlan_stat_counter_get
  12075  * Description:
  12076  *      retrieve set of counter statistic values for the given vlan
  12077  *      if sync_mode is set, sync the sw accumulated count
  12078  *      with hw count value first, else return sw count.  
  12079  *
  12080  * Parameters:
  12081  *      unit             - (IN) unit number
  12082  *      sync_mode        - (IN) hwcount is to be synced to sw count 
  12083  *      vlan             - (IN) VLAN ID
  12084  *      stat             - (IN) Type of the counter to retrieve
  12085  *                              I.e. ingress/egress byte/packet)
  12086  *      num_entries      - (IN) Number of counter Entries
  12087  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  12088  *      counter_values   - (OUT) Pointer to counter values
  12089  *
  12090  * Return Value:
  12091  *      BCM_E_XXX
  12092  * Notes:
  12093  */
  12094 STATIC bcm_error_t _bcm_esw_vlan_stat_counter_get( 
  12095             int              unit, 
  12096             int              sync_mode, 
  12097             bcm_vlan_t       vlan, 
  12098             bcm_vlan_stat_t  stat,
  12099             uint32           num_entries,
  12100             uint32           *counter_indexes,
  12101             bcm_stat_value_t *counter_values)
  12102 {
  12103     uint32                     table_count=0;
  12104     uint32                     index_count=0;
  12105     uint32                     num_of_tables=0;
  12106     bcm_stat_flex_direction_t  direction=bcmStatFlexDirectionIngress;
  12107     uint32                     byte_flag=0;
  12108     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  12109 
  12110     if ((NULL == counter_indexes) || (NULL == counter_values)) {
  12111         return BCM_E_PARAM;
  12112     }
  12113 
  12114     switch(stat) {
  12115     case bcmVlanStatIngressPackets:
  12116     case bcmVlanStatEgressPackets:
  12117          byte_flag=0;
  12118          break;
  12119     case bcmVlanStatIngressBytes:
  12120     case bcmVlanStatEgressBytes:
  12121          byte_flag=1;
  12122          break;
  12123     default:
  12124          return BCM_E_PARAM;
  12125     }
  12126     if ((stat == bcmVlanStatIngressPackets) ||
  12127         (stat == bcmVlanStatIngressBytes)) {
  12128          direction = bcmStatFlexDirectionIngress;
  12129     } else {
  12130          direction = bcmStatFlexDirectionEgress;
  12131     }
  12132     
  12133     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_stat_get_table_info(
  12134                         unit, vlan,&num_of_tables,&table_info[0]));
  12135 
  12136     for (table_count=0; table_count < num_of_tables ; table_count++) {
  12137          if (table_info[table_count].direction == direction) {
  12138              for (index_count=0; index_count < num_entries ; index_count++) {
  12139                   BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_get(
  12140                                       unit, sync_mode,
  12141                                       table_info[table_count].index,
  12142                                       table_info[table_count].table,
  12143                                       0,
  12144                                       byte_flag,
  12145                                       counter_indexes[index_count],
  12146                                       &counter_values[index_count]));
  12147              }
  12148          }
  12149     }
  12150     return BCM_E_NONE;
  12151 }
  12152 #endif
  12153 
  12154 /*
  12155  * Function:
  12156  *      _bcm_esw_vlan_flex_stat_counter_get
  12157  * Description:  
  12158  *      retrieve set of counter statistic values for the given vlan
  12159  *      if sync_mode is set, sync the sw accumulated count
  12160  *      with hw count value first, else return sw count.  
  12161  *
  12162  * Parameters:
  12163  *      unit             - (IN) unit number
  12164  *      sync_mode        - (IN) hwcount is to be synced to sw count 
  12165  *      vlan             - (IN) VLAN ID
  12166  *      stat             - (IN) Type of the counter to retrieve  
  12167  *                              I.e. ingress/egress byte/packet)
  12168  *      num_entries      - (IN) Number of counter Entries
  12169  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  12170  *      counter_values   - (OUT) Pointer to counter values
  12171  *
  12172  * Return Value:
  12173  *      BCM_E_XXX
  12174  * Notes:
  12175  */
  12176 int  
  12177 _bcm_esw_vlan_flex_stat_counter_get(int              unit,
  12178                                     int              sync_mode,
  12179                                     bcm_vlan_t       vlan,
  12180                                     bcm_vlan_stat_t  stat,
  12181                                     uint32           num_entries,
  12182                                     uint32           *counter_indexes,
  12183                                     bcm_stat_value_t *counter_values)
  12184 {
  12185 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12186     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  12187         return _bcm_esw_vlan_stat_counter_get(unit, sync_mode, vlan, stat,
  12188                       num_entries, counter_indexes, counter_values);
  12189     } else
  12190 #endif
  12191 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  12192     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  12193         uint64 val;
  12194         int rv = BCM_E_NONE;
  12195 
  12196         rv =  _bcm_esw_flex_stat_get(unit, 0,
  12197                ((stat == bcmVlanStatIngressPackets) ||
  12198                 (stat == bcmVlanStatIngressBytes)) ?
  12199                  _bcmFlexStatTypeService:_bcmFlexStatTypeEgressService,
  12200                 vlan,
  12201                 _bcm_esw_vlan_stat_to_flex_stat(stat), &val);
  12202 
  12203         if ((stat == bcmVlanStatIngressPackets) ||
  12204             (stat == bcmVlanStatEgressPackets)) {
  12205             counter_values->packets = COMPILER_64_LO(val);
  12206         } else {
  12207             COMPILER_64_SET(counter_values->bytes,
  12208                       COMPILER_64_HI(val),
  12209                       COMPILER_64_LO(val));
  12210         }
  12211         return rv;
  12212 
  12213     } else
  12214 #endif
  12215     {
  12216         return BCM_E_UNAVAIL;
  12217     }
  12218 }
  12219 /*
  12220  * Function:
  12221  *      bcm_esw_vlan_stat_counter_get
  12222  * Description:  
  12223  *      retrieve set of counter statistic values for the given vlan
  12224  *
  12225  * Parameters:
  12226  *      unit             - (IN) unit number
  12227  *      vlan             - (IN) VLAN ID
  12228  *      stat             - (IN) Type of the counter to retrieve  
  12229  *                              I.e. ingress/egress byte/packet)
  12230  *      num_entries      - (IN) Number of counter Entries
  12231  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  12232  *      counter_values   - (OUT) Pointer to counter values
  12233  *
  12234  * Return Value:
  12235  *      BCM_E_XXX
  12236  * Notes:
  12237  */
  12238 int 
  12239 bcm_esw_vlan_stat_counter_get(int              unit,
  12240                               bcm_vlan_t       vlan,
  12241                               bcm_vlan_stat_t  stat,
  12242                               uint32           num_entries,
  12243                               uint32           *counter_indexes,
  12244                               bcm_stat_value_t *counter_values)
  12245 {
  12246     return _bcm_esw_vlan_flex_stat_counter_get(unit, 0, vlan, stat, num_entries,
  12247                                                counter_indexes, counter_values);
  12248 }
  12249 
  12250 
  12251 /*
  12252  * Function:
  12253  *      bcm_esw_vlan_stat_counter_sync_get
  12254  * Description:  
  12255  *      retrieve set of counter statistic values for the given vlan
  12256  *      sw accumulated counters synced with hw count.
  12257  *
  12258  * Parameters:
  12259  *      unit             - (IN) unit number
  12260  *      vlan             - (IN) VLAN ID
  12261  *      stat             - (IN) Type of the counter to retrieve  
  12262  *                              I.e. ingress/egress byte/packet)
  12263  *      num_entries      - (IN) Number of counter Entries
  12264  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  12265  *      counter_values   - (OUT) Pointer to counter values
  12266  *
  12267  * Return Value:
  12268  *      BCM_E_XXX
  12269  * Notes:
  12270  */
  12271 int 
  12272 bcm_esw_vlan_stat_counter_sync_get(int              unit,
  12273                                    bcm_vlan_t       vlan,
  12274                                    bcm_vlan_stat_t  stat,
  12275                                    uint32           num_entries,
  12276                                    uint32           *counter_indexes,
  12277                                    bcm_stat_value_t *counter_values)
  12278 {
  12279     return _bcm_esw_vlan_flex_stat_counter_get(unit, 1, vlan, stat, num_entries,
  12280                                                counter_indexes, counter_values);
  12281 }
  12282 
  12283 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12284 /*
  12285  * Function:
  12286  *      _bcm_esw_vlan_stat_counter_set
  12287  * Description:
  12288  *      set counter statistic values for the given VLAN
  12289  *
  12290  * Parameters:
  12291  *      unit             - (IN) unit number
  12292  *      port             - (IN) VLAN ID
  12293  *      stat             - (IN) Type of the counter to retrieve
  12294  *                              I.e. ingress/egress byte/packet)
  12295  *      num_entries      - (IN) Number of counter Entries
  12296  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  12297  *      counter_values   - (IN) Pointer to counter values
  12298  *
  12299  * Return Value:
  12300  *      BCM_E_XXX
  12301  * Notes:
  12302  */
  12303 STATIC bcm_error_t _bcm_esw_vlan_stat_counter_set( 
  12304             int                 unit, 
  12305             bcm_vlan_t       vlan,
  12306             bcm_vlan_stat_t  stat,
  12307             uint32           num_entries,
  12308             uint32           *counter_indexes,
  12309             bcm_stat_value_t *counter_values)
  12310 {
  12311     uint32                     table_count=0;
  12312     uint32                     index_count=0;
  12313     uint32                     num_of_tables=0;
  12314     bcm_stat_flex_direction_t  direction=bcmStatFlexDirectionIngress;
  12315     uint32                     byte_flag=0;
  12316     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  12317 
  12318     if ((NULL == counter_indexes) || (NULL == counter_values)) {
  12319         return BCM_E_PARAM;
  12320     }
  12321 
  12322     switch(stat) {
  12323     case bcmVlanStatIngressPackets:
  12324     case bcmVlanStatEgressPackets:
  12325          byte_flag=0;
  12326          break;
  12327     case bcmVlanStatIngressBytes:
  12328     case bcmVlanStatEgressBytes:
  12329          byte_flag=1;
  12330          break;
  12331     default:
  12332          return BCM_E_PARAM;
  12333     }
  12334     if ((stat == bcmVlanStatIngressPackets) ||
  12335         (stat == bcmVlanStatIngressBytes)) {
  12336          direction = bcmStatFlexDirectionIngress;
  12337     } else {
  12338          direction = bcmStatFlexDirectionEgress;
  12339     }
  12340     
  12341     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_stat_get_table_info(
  12342                         unit, vlan,&num_of_tables,&table_info[0]));
  12343 
  12344     for (table_count=0; table_count < num_of_tables ; table_count++) {
  12345          if (table_info[table_count].direction == direction) {
  12346              for (index_count=0; index_count < num_entries ; index_count++) {
  12347                   BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_set(
  12348                                      unit,
  12349                                      table_info[table_count].index,
  12350                                      table_info[table_count].table,
  12351                                      0,
  12352                                      byte_flag,
  12353                                      counter_indexes[index_count],
  12354                                      &counter_values[index_count]));
  12355              }
  12356          }
  12357     }
  12358     return BCM_E_NONE;
  12359 }
  12360 #endif
  12361 
  12362 /*
  12363  * Function:
  12364  *      bcm_esw_vlan_stat_counter_set
  12365  * Description:
  12366  *      set counter statistic values for the given VLAN
  12367  *
  12368  * Parameters:
  12369  *      unit             - (IN) unit number
  12370  *      port             - (IN) VLAN ID
  12371  *      stat             - (IN) Type of the counter to retrieve
  12372  *                              I.e. ingress/egress byte/packet)
  12373  *      num_entries      - (IN) Number of counter Entries
  12374  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  12375  *      counter_values   - (IN) Pointer to counter values
  12376  *
  12377  * Return Value:
  12378  *      BCM_E_XXX
  12379  * Notes:
  12380  */
  12381 int bcm_esw_vlan_stat_counter_set(
  12382             int              unit,
  12383             bcm_vlan_t       vlan,
  12384             bcm_vlan_stat_t  stat,
  12385             uint32           num_entries,
  12386             uint32           *counter_indexes,
  12387             bcm_stat_value_t *counter_values)
  12388 {
  12389 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12390     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  12391         return _bcm_esw_vlan_stat_counter_set(unit,vlan,stat,
  12392                       num_entries,counter_indexes,counter_values);
  12393     } else
  12394 #endif
  12395 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  12396     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  12397         uint64 val;
  12398         int rv = BCM_E_NONE;
  12399 
  12400         if ((stat == bcmVlanStatIngressPackets) ||
  12401             (stat == bcmVlanStatEgressPackets)) {
  12402             COMPILER_64_SET(val,0,counter_values->packets);
  12403         } else {
  12404             COMPILER_64_SET(val,
  12405                       COMPILER_64_HI(counter_values->bytes),
  12406                       COMPILER_64_LO(counter_values->bytes));
  12407         }
  12408         rv =  _bcm_esw_flex_stat_set(unit,
  12409                ((stat == bcmVlanStatIngressPackets) ||
  12410                 (stat == bcmVlanStatIngressBytes)) ?
  12411                  _bcmFlexStatTypeService:_bcmFlexStatTypeEgressService,
  12412                 vlan,
  12413                 _bcm_esw_vlan_stat_to_flex_stat(stat), val);
  12414 
  12415         return rv;
  12416 
  12417     } else
  12418 #endif
  12419     {
  12420         return BCM_E_UNAVAIL;
  12421     }
  12422 }
  12423 
  12424 /*
  12425  * Function:
  12426  *      bcm_esw_vlan_stat_id_get
  12427  * Description:
  12428  *      Get stat counter id associated with given vlan
  12429  *
  12430  * Parameters:
  12431  *      unit             - (IN) unit number
  12432  *      vlan             - (IN) VLAN ID
  12433  *      stat             - (IN) Type of the counter to retrieve
  12434  *                              I.e. ingress/egress byte/packet)
  12435  *      Stat_counter_id  - (OUT) Stat Counter ID
  12436  *
  12437  * Return Value:
  12438  *      BCM_E_XXX
  12439  * Notes:
  12440  */
  12441 int bcm_esw_vlan_stat_id_get(
  12442             int              unit,
  12443             bcm_vlan_t       vlan,
  12444             bcm_vlan_stat_t  stat,
  12445             uint32           *stat_counter_id)
  12446 {
  12447 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12448     bcm_stat_flex_direction_t  direction=bcmStatFlexDirectionIngress;
  12449     uint32                     num_of_tables=0;
  12450     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  12451     uint32                     index=0;
  12452     uint32                     num_stat_counter_ids=0;
  12453 
  12454     if ((stat == bcmVlanStatIngressPackets) ||
  12455         (stat == bcmVlanStatIngressBytes)) {
  12456          direction = bcmStatFlexDirectionIngress;
  12457     } else {
  12458          direction = bcmStatFlexDirectionEgress;
  12459     }
  12460     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_stat_get_table_info(
  12461                         unit,vlan,&num_of_tables,&table_info[0]));
  12462     for (index=0; index < num_of_tables ; index++) {
  12463          if (table_info[index].direction == direction)
  12464              return _bcm_esw_stat_flex_get_counter_id(
  12465                                   unit, 1, &table_info[index],
  12466                                   &num_stat_counter_ids,stat_counter_id);
  12467     }
  12468     return BCM_E_NOT_FOUND;
  12469 #else
  12470     return BCM_E_UNAVAIL;
  12471 #endif
  12472 }
  12473 
  12474 
  12475 
  12476 /*
  12477  * Function:
  12478  *      _bcm_esw_vlan_stat_get
  12479  * Purpose:
  12480  *      Extract per-VLAN statistics from the chip.
  12481  *      if sync_mode is set, sync the sw accumulated count
  12482  *      with hw count value first, else return sw count.
  12483  * 
  12484  * Parameters:
  12485  *      unit      - (IN) Unit number.
  12486  *      sync_mode - (IN) hwcount is to be synced to sw count
  12487  *      vlan      - (IN) VLAN Id.
  12488  *      cos       - (IN) COS or priority
  12489  *      stat      - (IN) Type of the counter to retrieve.
  12490  *      val       - (OUT) Pointer to a counter value.
  12491  * Returns:
  12492  *      BCM_E_XXX
  12493  * Notes:
  12494  */
  12495 int 
  12496 _bcm_esw_vlan_stat_get(int unit, int sync_mode, 
  12497                        bcm_vlan_t vlan, bcm_cos_t cos, 
  12498                        bcm_vlan_stat_t stat, uint64 *val)
  12499 {
  12500 #if defined(BCM_TRIUMPH2_SUPPORT)
  12501 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12502     uint32           counter_indexes=0;
  12503     bcm_stat_value_t counter_values={0};
  12504 #endif
  12505 
  12506   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  12507     BCM_IF_ERROR_RETURN
  12508         (_bcm_esw_vlan_stat_param_valid(unit, vlan, cos));
  12509     return _bcm_esw_flex_stat_get(unit, sync_mode, 
  12510                                   _bcmFlexStatTypeService, vlan,
  12511                                   _bcm_esw_vlan_stat_to_flex_stat(stat),
  12512                                   val);
  12513   }
  12514 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12515     BCM_IF_ERROR_RETURN (_bcm_esw_vlan_stat_param_verify(
  12516                          unit, vlan, cos));
  12517     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_flex_stat_counter_get(unit, sync_mode, 
  12518                                                             vlan, stat, 1, 
  12519                                                             &counter_indexes, 
  12520                                                             &counter_values));
  12521     if ((stat == bcmVlanStatIngressPackets) ||
  12522         (stat == bcmVlanStatEgressPackets)) {
  12523          COMPILER_64_SET(*val,
  12524                          COMPILER_64_HI(counter_values.packets64),
  12525                          COMPILER_64_LO(counter_values.packets64));
  12526     } else {
  12527          COMPILER_64_SET(*val,
  12528                          COMPILER_64_HI(counter_values.bytes),
  12529                          COMPILER_64_LO(counter_values.bytes));
  12530     }
  12531     return BCM_E_NONE;
  12532 #else
  12533     return BCM_E_UNAVAIL;
  12534 #endif
  12535 #else
  12536     return BCM_E_UNAVAIL;
  12537 #endif
  12538 }
  12539 
  12540 
  12541 /*
  12542  * Function:
  12543  *      bcm_esw_vlan_stat_get
  12544  * Purpose:
  12545  *      Extract per-VLAN statistics from the chip.
  12546  * Parameters:
  12547  *      unit - (IN) Unit number.
  12548  *      vlan - (IN) VLAN Id.
  12549  *      cos - (IN) COS or priority
  12550  *      stat - (IN) Type of the counter to retrieve.
  12551  *      val - (OUT) Pointer to a counter value.
  12552  * Returns:
  12553  *      BCM_E_XXX
  12554  * Notes:
  12555  */
  12556 int 
  12557 bcm_esw_vlan_stat_get(int unit, bcm_vlan_t vlan, bcm_cos_t cos, 
  12558                       bcm_vlan_stat_t stat, uint64 *val)
  12559 {
  12560     int rv = BCM_E_NONE;
  12561 
  12562     rv = _bcm_esw_vlan_stat_get(unit, 0, vlan, cos, stat, val);
  12563 
  12564     return rv;
  12565 }
  12566 
  12567 
  12568 /*
  12569  * Function:
  12570  *      bcm_esw_vlan_stat_sync_get
  12571  * Purpose:
  12572  *      Extract per-VLAN statistics from the chip.
  12573  *      sw accumulated counters synced with hw count.
  12574  *
  12575  * Parameters:
  12576  *      unit - (IN) Unit number.
  12577  *      vlan - (IN) VLAN Id.
  12578  *      cos - (IN) COS or priority
  12579  *      stat - (IN) Type of the counter to retrieve.
  12580  *      val - (OUT) Pointer to a counter value.
  12581  * Returns:
  12582  *      BCM_E_XXX
  12583  * Notes:
  12584  */
  12585 int 
  12586 bcm_esw_vlan_stat_sync_get(int unit, bcm_vlan_t vlan, bcm_cos_t cos, 
  12587                            bcm_vlan_stat_t stat, uint64 *val)
  12588 {
  12589     int rv = BCM_E_NONE;
  12590 
  12591     rv = _bcm_esw_vlan_stat_get(unit, 1, vlan, cos, stat, val);
  12592 
  12593     return rv;
  12594 }
  12595 
  12596 /*
  12597  * Function:
  12598  *      _bcm_esw_vlan_stat_get32
  12599  * Purpose:
  12600  *      Extract per-VLAN statistics from the chip.
  12601  *      if sync_mode is set, sync the sw accumulated count
  12602  *      with hw count value first, else return sw count.
  12603  *
  12604  * Parameters:
  12605  *      unit      - (IN) Unit number.
  12606  *      sync_mode - (IN) hwcount is to be synced to sw count
  12607  *      vlan      - (IN) VLAN Id.
  12608  *      cos       - (IN) COS or priority
  12609  *      stat      - (IN) Type of the counter to retrieve.
  12610  *      val       - (OUT) Pointer to a counter value.
  12611  * Returns:
  12612  *      BCM_E_XXX
  12613  * Notes:
  12614  */
  12615 int 
  12616 _bcm_esw_vlan_stat_get32(int unit, int sync_mode, 
  12617                          bcm_vlan_t vlan, bcm_cos_t cos, 
  12618                          bcm_vlan_stat_t stat, uint32 *val)
  12619 {
  12620 #if defined(BCM_TRIUMPH2_SUPPORT)
  12621 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12622     uint32           counter_indexes=0;
  12623     bcm_stat_value_t counter_values={0};
  12624 #endif
  12625  if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  12626     BCM_IF_ERROR_RETURN
  12627         (_bcm_esw_vlan_stat_param_valid(unit, vlan, cos));
  12628     return _bcm_esw_flex_stat_get32(unit, sync_mode, 
  12629                                     _bcmFlexStatTypeService, vlan,
  12630                                     _bcm_esw_vlan_stat_to_flex_stat(stat), val);
  12631   }
  12632 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12633     BCM_IF_ERROR_RETURN (_bcm_esw_vlan_stat_param_verify(
  12634                          unit, vlan, cos));
  12635     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_flex_stat_counter_get(unit, sync_mode, 
  12636                                                             vlan, stat, 1, 
  12637                                                             &counter_indexes, 
  12638                                                             &counter_values));
  12639     if ((stat == bcmVlanStatIngressPackets) ||
  12640         (stat == bcmVlanStatEgressPackets)) {
  12641          *val = counter_values.packets;
  12642     } else {
  12643          /* Ignoring Hi bytes value */
  12644          *val = COMPILER_64_LO(counter_values.bytes);
  12645     }
  12646     return BCM_E_NONE;
  12647 #else
  12648     return BCM_E_UNAVAIL;
  12649 #endif
  12650 #else
  12651     return BCM_E_UNAVAIL;
  12652 #endif
  12653 }
  12654 
  12655 /*
  12656  * Function:
  12657  *      bcm_esw_vlan_stat_get32
  12658  * Purpose:
  12659  *      Extract per-VLAN statistics from the chip.
  12660  * Parameters:
  12661  *      unit - (IN) Unit number.
  12662  *      vlan - (IN) VLAN Id.
  12663  *      cos - (IN) COS or priority
  12664  *      stat - (IN) Type of the counter to retrieve.
  12665  *      val - (OUT) Pointer to a counter value.
  12666  * Returns:
  12667  *      BCM_E_XXX
  12668  * Notes:
  12669  */
  12670 int 
  12671 bcm_esw_vlan_stat_get32(int unit, bcm_vlan_t vlan, bcm_cos_t cos, 
  12672                         bcm_vlan_stat_t stat, uint32 *val)
  12673 {
  12674     int rv = BCM_E_NONE;
  12675 
  12676     rv = _bcm_esw_vlan_stat_get32(unit, 0, vlan, cos, stat, val);
  12677 
  12678     return rv;
  12679 }
  12680 
  12681 /*
  12682  * Function:
  12683  *      bcm_esw_vlan_stat_sync_get32
  12684  * Purpose:
  12685  *      Extract per-VLAN statistics from the chip.
  12686  *      sw accumulated counters synced with hw count.
  12687  *
  12688  * Parameters:
  12689  *      unit - (IN) Unit number.
  12690  *      vlan - (IN) VLAN Id.
  12691  *      cos - (IN) COS or priority
  12692  *      stat - (IN) Type of the counter to retrieve.
  12693  *      val - (OUT) Pointer to a counter value.
  12694  * Returns:
  12695  *      BCM_E_XXX
  12696  * Notes:
  12697  */
  12698 int 
  12699 bcm_esw_vlan_stat_sync_get32(int unit, bcm_vlan_t vlan, bcm_cos_t cos, 
  12700                              bcm_vlan_stat_t stat, uint32 *val)
  12701 {
  12702     int rv = BCM_E_NONE;
  12703 
  12704     rv = _bcm_esw_vlan_stat_get32(unit, 1, vlan, cos, stat, val);
  12705 
  12706     return rv;
  12707 }
  12708 
  12709 /*
  12710  * Function:
  12711  *      bcm_esw_vlan_stat_set
  12712  * Purpose:
  12713  *      Set the specified statistic to the indicated value for the
  12714  *      specified VLAN.
  12715  * Parameters:
  12716  *      unit - (IN) Unit number.
  12717  *      vlan - (IN) VLAN Id.
  12718  *      cos - (IN) COS or priority
  12719  *      stat - (IN) Type of the counter to set.
  12720  *      val - (IN) New counter value.
  12721  * Returns:
  12722  *      BCM_E_XXX
  12723  * Notes:
  12724  */
  12725 int 
  12726 bcm_esw_vlan_stat_set(int unit, bcm_vlan_t vlan, bcm_cos_t cos, 
  12727                       bcm_vlan_stat_t stat, uint64 val)
  12728 {
  12729 #if defined(BCM_TRIUMPH2_SUPPORT)
  12730 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12731     uint32           counter_indexes=0;
  12732     bcm_stat_value_t counter_values={0};
  12733 #endif
  12734   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  12735     BCM_IF_ERROR_RETURN
  12736         (_bcm_esw_vlan_stat_param_valid(unit, vlan, cos));
  12737     return _bcm_esw_flex_stat_set(unit, _bcmFlexStatTypeService, vlan,
  12738                            _bcm_esw_vlan_stat_to_flex_stat(stat), val);
  12739   }
  12740 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12741     if ((stat == bcmVlanStatIngressPackets) ||
  12742         (stat == bcmVlanStatEgressPackets)) {
  12743          counter_values.packets = COMPILER_64_LO(val);
  12744     } else {
  12745          COMPILER_64_SET(counter_values.bytes,
  12746                          COMPILER_64_HI(val),
  12747                          COMPILER_64_LO(val));
  12748     }
  12749     BCM_IF_ERROR_RETURN (_bcm_esw_vlan_stat_param_verify(
  12750                          unit, vlan, cos));
  12751     BCM_IF_ERROR_RETURN(bcm_esw_vlan_stat_counter_set(
  12752                         unit,vlan, stat, 1, &counter_indexes, &counter_values));
  12753     return BCM_E_NONE;
  12754 #else
  12755     return BCM_E_UNAVAIL;
  12756 #endif
  12757 #else
  12758     return BCM_E_UNAVAIL;
  12759 #endif
  12760 }
  12761 
  12762 /*
  12763  * Function:
  12764  *      bcm_esw_vlan_stat_set32
  12765  * Purpose:
  12766  *      Set the specified statistic to the indicated value for the
  12767  *      specified VLAN.
  12768  * Parameters:
  12769  *      unit - (IN) Unit number.
  12770  *      vlan - (IN) VLAN Id.
  12771  *      cos - (IN) COS or priority
  12772  *      stat - (IN) Type of the counter to set.
  12773  *      val - (IN) New counter value.
  12774  * Returns:
  12775  *      BCM_E_XXX
  12776  * Notes:
  12777  */
  12778 int 
  12779 bcm_esw_vlan_stat_set32(int unit, bcm_vlan_t vlan, bcm_cos_t cos, 
  12780                         bcm_vlan_stat_t stat, uint32 val)
  12781 {
  12782 #if defined(BCM_TRIUMPH2_SUPPORT)
  12783 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12784     uint32           counter_indexes=0;
  12785     bcm_stat_value_t counter_values={0};
  12786 #endif
  12787 
  12788   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  12789     BCM_IF_ERROR_RETURN
  12790         (_bcm_esw_vlan_stat_param_valid(unit, vlan, cos));
  12791     return _bcm_esw_flex_stat_set32(unit, _bcmFlexStatTypeService, vlan,
  12792                            _bcm_esw_vlan_stat_to_flex_stat(stat), val);
  12793   }
  12794 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12795     if ((stat == bcmVlanStatIngressPackets) ||
  12796         (stat == bcmVlanStatEgressPackets)) {
  12797          counter_values.packets = val;
  12798     } else {
  12799          /* Ignoring high value */
  12800          COMPILER_64_SET(counter_values.bytes,0,val);
  12801     }
  12802     BCM_IF_ERROR_RETURN (_bcm_esw_vlan_stat_param_verify(
  12803                          unit, vlan, cos));
  12804     BCM_IF_ERROR_RETURN(bcm_esw_vlan_stat_counter_set(
  12805                         unit,vlan, stat, 1, &counter_indexes, &counter_values));
  12806     return BCM_E_NONE;
  12807 #else
  12808     return BCM_E_UNAVAIL;
  12809 #endif
  12810 #else
  12811     return BCM_E_UNAVAIL;
  12812 #endif
  12813 }
  12814 
  12815 /*
  12816  * Function:
  12817  *      bcm_esw_vlan_stat_multi_get
  12818  * Purpose:
  12819  *      Get 64-bit counter value for multiple VLAN statistic types.
  12820  * Parameters:
  12821  *      unit - (IN) Unit number.
  12822  *      vlan - (IN) VLAN Id.
  12823  *      cos - (IN) COS or priority
  12824  *      nstat - (IN) Number of elements in stat array
  12825  *      stat_arr - (IN) Collected statistics descriptors array
  12826  *      value_arr - (OUT) Collected counters values
  12827  * Returns:
  12828  *      BCM_E_XXX
  12829  * Notes:
  12830  */
  12831 int 
  12832 bcm_esw_vlan_stat_multi_get(int unit, bcm_vlan_t vlan, bcm_cos_t cos, 
  12833                             int nstat, bcm_vlan_stat_t *stat_arr, 
  12834                             uint64 *value_arr)
  12835 {
  12836 #if defined(BCM_TRIUMPH2_SUPPORT)
  12837     _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */
  12838     int idx;
  12839 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12840     uint32           counter_indexes=0;
  12841     bcm_stat_value_t counter_values={0};
  12842 #endif
  12843 
  12844   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  12845     BCM_IF_ERROR_RETURN
  12846         (_bcm_esw_vlan_stat_param_valid(unit, vlan, cos));
  12847     BCM_IF_ERROR_RETURN
  12848         (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr, fs_arr,
  12849                                       &_bcm_esw_vlan_stat_to_flex_stat));
  12850     BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr);
  12851 
  12852     return _bcm_esw_flex_stat_multi_get(unit, _bcmFlexStatTypeService, vlan,
  12853                                         nstat, fs_arr, value_arr);
  12854   }
  12855 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12856     BCM_IF_ERROR_RETURN (_bcm_esw_vlan_stat_param_verify(
  12857                          unit, vlan, cos));
  12858     for (idx=0;idx < nstat ; idx ++) {
  12859          BCM_IF_ERROR_RETURN(bcm_esw_vlan_stat_counter_get(
  12860                       unit, vlan, stat_arr[idx], 1, 
  12861                       &counter_indexes, &counter_values));
  12862          if ((stat_arr[idx] == bcmVlanStatIngressPackets) ||
  12863              (stat_arr[idx] == bcmVlanStatEgressPackets)) {
  12864               COMPILER_64_SET(value_arr[idx],
  12865                               COMPILER_64_HI(counter_values.packets64),
  12866                               COMPILER_64_LO(counter_values.packets64));
  12867          } else {
  12868               COMPILER_64_SET(value_arr[idx],
  12869                               COMPILER_64_HI(counter_values.bytes),
  12870                               COMPILER_64_LO(counter_values.bytes));
  12871          }
  12872     }
  12873     return BCM_E_NONE;
  12874 #else
  12875     return BCM_E_UNAVAIL;
  12876 #endif
  12877 
  12878 #else
  12879     return BCM_E_UNAVAIL;
  12880 #endif
  12881 }
  12882 
  12883 /*
  12884  * Function:
  12885  *      bcm_esw_vlan_stat_multi_get32
  12886  * Purpose:
  12887  *      Get lower 32-bit counter value for multiple VLAN statistic
  12888  *      types.
  12889  * Parameters:
  12890  *      unit - (IN) Unit number.
  12891  *      vlan - (IN) VLAN Id.
  12892  *      cos - (IN) COS or priority
  12893  *      nstat - (IN) Number of elements in stat array
  12894  *      stat_arr - (IN) Collected statistics descriptors array
  12895  *      value_arr - (OUT) Collected counters values
  12896  * Returns:
  12897  *      BCM_E_XXX
  12898  * Notes:
  12899  */
  12900 int 
  12901 bcm_esw_vlan_stat_multi_get32(int unit, bcm_vlan_t vlan, bcm_cos_t cos, 
  12902                               int nstat,  bcm_vlan_stat_t *stat_arr, 
  12903                               uint32 *value_arr)
  12904 {
  12905 #if defined(BCM_TRIUMPH2_SUPPORT)
  12906     _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */
  12907     int idx;
  12908 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12909     uint32           counter_indexes=0;
  12910     bcm_stat_value_t counter_values={0};
  12911 #endif
  12912 
  12913   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  12914     BCM_IF_ERROR_RETURN
  12915         (_bcm_esw_vlan_stat_param_valid(unit, vlan, cos));
  12916     BCM_IF_ERROR_RETURN
  12917         (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr, fs_arr,
  12918                                       &_bcm_esw_vlan_stat_to_flex_stat));
  12919     BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr);
  12920 
  12921     return _bcm_esw_flex_stat_multi_get32(unit, _bcmFlexStatTypeService, vlan,
  12922                                           nstat, fs_arr, value_arr);
  12923   }
  12924 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12925     BCM_IF_ERROR_RETURN (_bcm_esw_vlan_stat_param_verify(
  12926                          unit, vlan, cos));
  12927     for (idx=0;idx < nstat ; idx ++) {
  12928          BCM_IF_ERROR_RETURN(bcm_esw_vlan_stat_counter_get(
  12929                              unit, vlan, stat_arr[idx], 1, 
  12930                              &counter_indexes, &counter_values));
  12931          if ((stat_arr[idx] == bcmVlanStatIngressPackets) ||
  12932              (stat_arr[idx] == bcmVlanStatEgressPackets)) {
  12933               value_arr[idx] = counter_values.packets;
  12934          } else {
  12935               value_arr[idx] = COMPILER_64_LO(counter_values.bytes);
  12936          }
  12937     }
  12938     return BCM_E_NONE;
  12939 #else
  12940     return BCM_E_UNAVAIL;
  12941 #endif
  12942 #else
  12943     return BCM_E_UNAVAIL;
  12944 #endif
  12945 }
  12946 
  12947 /*
  12948  * Function:
  12949  *      bcm_esw_vlan_stat_multi_set
  12950  * Purpose:
  12951  *      Set 64-bit counter value for multiple VLAN statistic types.
  12952  * Parameters:
  12953  *      unit - (IN) Unit number.
  12954  *      vlan - (IN) VLAN Id.
  12955  *      cos - (IN) COS or priority
  12956  *      nstat - (IN) Number of elements in stat array
  12957  *      stat_arr - (IN) New statistics descriptors array
  12958  *      value_arr - (IN) New counters values
  12959  * Returns:
  12960  *      BCM_E_XXX
  12961  * Notes:
  12962  */
  12963 int 
  12964 bcm_esw_vlan_stat_multi_set(int unit, bcm_vlan_t vlan, bcm_cos_t cos, 
  12965                             int nstat, bcm_vlan_stat_t *stat_arr, 
  12966                             uint64 *value_arr)
  12967 {
  12968 #if defined(BCM_TRIUMPH2_SUPPORT)
  12969     _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */
  12970     int idx;
  12971 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12972     uint32           counter_indexes=0;
  12973     bcm_stat_value_t counter_values={0};
  12974 #endif
  12975 
  12976   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  12977     BCM_IF_ERROR_RETURN
  12978         (_bcm_esw_vlan_stat_param_valid(unit, vlan, cos));
  12979     BCM_IF_ERROR_RETURN
  12980         (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr, fs_arr,
  12981                                       &_bcm_esw_vlan_stat_to_flex_stat));
  12982     BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr);
  12983 
  12984     return _bcm_esw_flex_stat_multi_set(unit, _bcmFlexStatTypeService, vlan,
  12985                                         nstat, fs_arr, value_arr);
  12986   }
  12987 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  12988     BCM_IF_ERROR_RETURN (_bcm_esw_vlan_stat_param_verify(
  12989                          unit, vlan, cos));
  12990     for (idx=0;idx < nstat ; idx ++) {
  12991          if ((stat_arr[idx] == bcmVlanStatIngressPackets) ||
  12992              (stat_arr[idx] == bcmVlanStatEgressPackets)) {
  12993               counter_values.packets = COMPILER_64_LO(value_arr[idx]);
  12994          } else {
  12995               COMPILER_64_SET(counter_values.bytes,
  12996                               COMPILER_64_HI(value_arr[idx]),
  12997                               COMPILER_64_LO(value_arr[idx]));
  12998          }
  12999          BCM_IF_ERROR_RETURN(bcm_esw_vlan_stat_counter_set(
  13000                              unit, vlan, stat_arr[idx], 1, 
  13001                              &counter_indexes, &counter_values));
  13002     }
  13003     return BCM_E_NONE;
  13004 #else
  13005     return BCM_E_UNAVAIL;
  13006 #endif
  13007 
  13008 #else
  13009     return BCM_E_UNAVAIL;
  13010 #endif
  13011 }
  13012 
  13013 /*
  13014  * Function:
  13015  *      bcm_esw_vlan_stat_multi_set32
  13016  * Purpose:
  13017  *      Set lower 32-bit counter value for multiple VLAN statistic
  13018  *      types.
  13019  * Parameters:
  13020  *      unit - (IN) Unit number.
  13021  *      vlan - (IN) VLAN Id.
  13022  *      cos - (IN) COS or priority
  13023  *      nstat - (IN) Number of elements in stat array
  13024  *      stat_arr - (IN) New statistics descriptors array
  13025  *      value_arr - (IN) New counters values
  13026  * Returns:
  13027  *      BCM_E_XXX
  13028  * Notes:
  13029  */
  13030 int 
  13031 bcm_esw_vlan_stat_multi_set32(int unit, bcm_vlan_t vlan, bcm_cos_t cos, 
  13032                               int nstat, bcm_vlan_stat_t *stat_arr, 
  13033                               uint32 *value_arr)
  13034 {
  13035 #if defined(BCM_TRIUMPH2_SUPPORT)
  13036     _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */
  13037     int idx;
  13038 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  13039     uint32           counter_indexes=0;
  13040     bcm_stat_value_t counter_values={0};
  13041 #endif
  13042 
  13043   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  13044     BCM_IF_ERROR_RETURN
  13045         (_bcm_esw_vlan_stat_param_valid(unit, vlan, cos));
  13046     BCM_IF_ERROR_RETURN
  13047         (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr, fs_arr,
  13048                                       &_bcm_esw_vlan_stat_to_flex_stat));
  13049     BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr);
  13050 
  13051     return _bcm_esw_flex_stat_multi_set32(unit, _bcmFlexStatTypeService,
  13052                                           vlan, nstat, fs_arr, value_arr);
  13053   }
  13054 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  13055     BCM_IF_ERROR_RETURN (_bcm_esw_vlan_stat_param_verify(
  13056                          unit, vlan, cos));
  13057     for (idx=0;idx < nstat ; idx ++) {
  13058          if ((stat_arr[idx] == bcmVlanStatIngressPackets) ||
  13059              (stat_arr[idx] == bcmVlanStatEgressPackets)) {
  13060               counter_values.packets = value_arr[idx];
  13061          } else {
  13062               COMPILER_64_SET(counter_values.bytes,0,value_arr[idx]);
  13063          }
  13064          BCM_IF_ERROR_RETURN(bcm_esw_vlan_stat_counter_set(
  13065                              unit, vlan, stat_arr[idx], 1, 
  13066                              &counter_indexes, &counter_values));
  13067     }
  13068     return BCM_E_NONE;
  13069 #else
  13070     return BCM_E_UNAVAIL;
  13071 #endif
  13072 
  13073 #else
  13074     return BCM_E_UNAVAIL;
  13075 #endif
  13076 }
  13077 
  13078 #if defined(BCM_TRIUMPH2_SUPPORT)
  13079 STATIC int
  13080 _bcm_esw_vlan_translate_flex_stat_hw_index_set(int unit,
  13081                                      _bcm_flex_stat_handle_t handle,
  13082                                                int fs_idx, void *cookie)
  13083 {
  13084     vlan_xlate_entry_t  vent, res_vent;
  13085     int rv, idx;
  13086     soc_mem_t mem = VLAN_XLATEm;
  13087     
  13088     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
  13089         mem = VLAN_XLATE_1_DOUBLEm;
  13090     }
  13091     _BCM_FLEX_STAT_HANDLE_COPY(vent, handle);
  13092 
  13093     soc_mem_lock(unit, mem);
  13094     rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, &idx,
  13095                          &vent, &res_vent, 0);
  13096     if (BCM_SUCCESS(rv)) {
  13097         soc_mem_field32_set(unit, mem, &res_vent,
  13098                             VINTF_CTR_IDXf, fs_idx);
  13099         if (SOC_MEM_FIELD_VALID(unit, mem, USE_VINTF_CTR_IDXf)) {
  13100             soc_mem_field32_set(unit, mem, &res_vent,
  13101                                 USE_VINTF_CTR_IDXf, fs_idx > 0 ? 1 : 0);
  13102         }
  13103         rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, &res_vent);
  13104         if (BCM_SUCCESS(rv)) {
  13105             /* We found it already, but didn't overwrite it?  The mem lock
  13106              * must have failed.  Not good. */
  13107             return BCM_E_INTERNAL;
  13108         } else if (BCM_E_EXISTS == rv) {
  13109             rv = BCM_E_NONE;
  13110         } /* Else retain failing rv value */
  13111     }
  13112     soc_mem_unlock(unit, mem);
  13113     return rv;
  13114 }
  13115 
  13116 STATIC _bcm_flex_stat_t
  13117 _bcm_esw_vlan_translate_stat_to_flex_stat(bcm_vlan_stat_t stat)
  13118 {
  13119     _bcm_flex_stat_t flex_stat;
  13120 
  13121     switch (stat) {
  13122     case bcmVlanStatIngressPackets:
  13123         flex_stat = _bcmFlexStatIngressPackets;
  13124         break;
  13125     case bcmVlanStatIngressBytes:
  13126         flex_stat = _bcmFlexStatIngressBytes;
  13127         break;
  13128     /* No egress stats for ingress translations */
  13129     default:
  13130         flex_stat = _bcmFlexStatNum;
  13131     }
  13132 
  13133     return flex_stat;
  13134 }
  13135 
  13136 STATIC int
  13137 _bcm_esw_vlan_translate_stat_param_valid(int unit, bcm_gport_t port,
  13138                                          bcm_vlan_translate_key_t key_type,
  13139                                          bcm_vlan_t outer_vlan,
  13140                                          bcm_vlan_t inner_vlan,
  13141                                          _bcm_flex_stat_handle_t *vxlt_fsh)
  13142 {
  13143     vlan_xlate_entry_t vent;
  13144 
  13145     CHECK_INIT(unit);
  13146 
  13147     if (!soc_feature(unit, soc_feature_gport_service_counters)) {
  13148         return BCM_E_UNAVAIL;
  13149     }
  13150 
  13151     sal_memset(&vent, 0, sizeof(vlan_xlate_entry_t));
  13152     BCM_IF_ERROR_RETURN
  13153         (_bcm_trx_vlan_translate_entry_assemble(unit, &vent,
  13154                                                 port, key_type,
  13155                                                 inner_vlan, outer_vlan));
  13156 
  13157     /* Fill handle for VTS info */
  13158     _BCM_FLEX_STAT_HANDLE_CLEAR(*vxlt_fsh);
  13159     /* This next step is a bit abusive, but we don't have an accessor
  13160      * which captures the full key description in the VLAN_XLATE table. */
  13161     _BCM_FLEX_STAT_HANDLE_COPY(*vxlt_fsh, vent);
  13162 
  13163     return BCM_E_NONE;
  13164 }
  13165 
  13166 #endif /* BCM_TRIUMPH2_SUPPORT */
  13167 
  13168 /*
  13169  * Function:
  13170  *      bcm_esw_vlan_translate_stat_enable_set
  13171  * Purpose:
  13172  *      Enable/disable collection of statistics on the indicated
  13173  *      ingress VLAN translation.
  13174  * Parameters:
  13175  *      unit - (IN) Unit number.
  13176  *      port - (IN) Generic port
  13177  *      key_type - (IN) Key Type : bcmVlanTranslateKey*
  13178  *      outer_vlan - (IN) Packet outer VLAN ID
  13179  *      inner_vlan - (IN) Packet inner VLAN ID
  13180  *      enable - (IN) Non-zero to enable counter collection, zero to disable.
  13181  * Returns:
  13182  *      BCM_E_xxx
  13183  * Notes:
  13184  */
  13185 int 
  13186 bcm_esw_vlan_translate_stat_enable_set(int unit, bcm_gport_t port,
  13187                                        bcm_vlan_translate_key_t key_type,
  13188                                        bcm_vlan_t outer_vlan,
  13189                                        bcm_vlan_t inner_vlan,
  13190                                        int enable)
  13191 {
  13192 #if defined(BCM_TRIUMPH2_SUPPORT)|| defined(BCM_TRIDENT_SUPPORT)
  13193     _bcm_flex_stat_handle_t vxlt_fsh;
  13194 #endif    
  13195 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  13196     uint32                     num_of_tables=0;
  13197     uint32                     num_stat_counter_ids=0;
  13198     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  13199     bcm_stat_object_t          object=bcmStatObjectIngPort;
  13200     uint32                     stat_counter_id[
  13201                                        BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]={0};
  13202     uint32                     num_entries=0;
  13203     int                        index=0;
  13204 #endif
  13205 
  13206 #ifdef BCM_TOMAHAWK3_SUPPORT
  13207     if (SOC_IS_TOMAHAWK3(unit)) {
  13208         return BCM_E_UNAVAIL;
  13209     }
  13210 #endif
  13211 
  13212 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  13213     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  13214         BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_stat_get_table_info(
  13215                         unit,port,key_type,
  13216                         outer_vlan,inner_vlan,
  13217                         &num_of_tables,&table_info[0]));
  13218         if (enable ) {
  13219             for(index=0;index < num_of_tables ;index++) {
  13220                 if(table_info[index].direction == bcmStatFlexDirectionIngress) {
  13221                    BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_ingress_object(
  13222                                        unit,table_info[index].table,
  13223                                        table_info[index].index,NULL,&object));
  13224                 } else {
  13225                     BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_egress_object(
  13226                                         unit,table_info[index].table,
  13227                                         table_info[index].index,NULL,&object));
  13228                 }
  13229                 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_create(
  13230                                     unit,object,bcmStatGroupModeSingle,
  13231                                     &stat_counter_id[table_info[index].direction],
  13232                                     &num_entries));
  13233                 BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_stat_attach(
  13234                                     unit,port,key_type,outer_vlan,inner_vlan,
  13235                                     stat_counter_id[table_info[index].direction]));
  13236             }
  13237             return BCM_E_NONE;
  13238         } else {
  13239             BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_counter_id(
  13240                             unit, num_of_tables,&table_info[0],
  13241                             &num_stat_counter_ids,&stat_counter_id[0]));
  13242             if ((stat_counter_id[bcmStatFlexDirectionIngress] == 0) &&
  13243                 (stat_counter_id[bcmStatFlexDirectionEgress] == 0)) {
  13244                  return BCM_E_PARAM;
  13245             }
  13246             BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_stat_detach(
  13247                             unit,port,key_type,outer_vlan,inner_vlan));
  13248             if (stat_counter_id[bcmStatFlexDirectionIngress] != 0) {
  13249                 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy(
  13250                                     unit,
  13251                                     stat_counter_id[bcmStatFlexDirectionIngress]));
  13252             }
  13253             if (stat_counter_id[bcmStatFlexDirectionEgress] != 0) {
  13254                 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy(
  13255                                     unit,
  13256                                     stat_counter_id[bcmStatFlexDirectionEgress]));
  13257             }
  13258             return BCM_E_NONE;
  13259         }
  13260     } else 
  13261 #endif
  13262 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  13263     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  13264             BCM_IF_ERROR_RETURN
  13265                 (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type,
  13266                                                           outer_vlan, inner_vlan,
  13267                                                           &vxlt_fsh));
  13268 
  13269         return _bcm_esw_flex_stat_ext_enable_set(unit, _bcmFlexStatTypeVxlt,
  13270                                  _bcm_esw_vlan_translate_flex_stat_hw_index_set,
  13271                                                  NULL, vxlt_fsh, enable,0);
  13272     } else
  13273 #endif
  13274 #if defined(BCM_HURRICANE3_SUPPORT)
  13275     if (soc_feature(unit, soc_feature_flowcnt)) {
  13276         return _bcm_hr3_vlan_translate_stat_enable_set(unit, port, key_type,
  13277                    outer_vlan, inner_vlan, enable);
  13278 
  13279     } else
  13280 #endif
  13281     {
  13282         return BCM_E_UNAVAIL;
  13283     }
  13284 }    
  13285 
  13286 #if defined(BCM_TRIUMPH3_SUPPORT)
  13287 static 
  13288 bcm_error_t _bcm_esw_vlan_translate_convert_common_fields(
  13289             int         unit,
  13290             soc_mem_t   from_table,
  13291             soc_mem_t   to_table,
  13292             soc_field_t view_field,
  13293             char        *view_name,
  13294             void        *from_entry,
  13295             void        *to_entry)
  13296 {
  13297    soc_mem_info_t   *memp_from;
  13298    uint32           key_type=0;
  13299    int              f=0;
  13300 #if !defined(SOC_NO_NAMES)
  13301    soc_mem_info_t   *memp_to;
  13302    uint32           fval[SOC_MAX_MEM_FIELD_WORDS];
  13303    soc_field_info_t *fieldp_to;
  13304    soc_field_info_t *fieldp_from;
  13305 #endif /* !SOC_NO_NAMES */
  13306 
  13307    char             view_name_with_colon[64];
  13308 
  13309    /* sal_memset(to_entry, 0, sizeof(vlan_xlate_extd_entry_t)); */
  13310    memp_from = &SOC_MEM_INFO(unit, from_table);
  13311    key_type= soc_mem_field32_get(unit, from_table,
  13312                                  (uint32 *)from_entry , view_field);
  13313    if (sal_strcmp(memp_from->views[key_type],view_name) != 0) {
  13314        return BCM_E_PARAM;
  13315    }
  13316    sal_memset(to_entry, 0, soc_mem_entry_bytes(unit,to_table));
  13317    sal_sprintf(view_name_with_colon,"%s:",view_name);
  13318    for (f = memp_from->nFields - 1; f >= 0; f--) {
  13319 #if !defined(SOC_NO_NAMES)
  13320         memp_to = &SOC_MEM_INFO(unit, to_table);
  13321         fieldp_from = &memp_from->fields[f];
  13322         /* LOG_CLI((BSL_META_U(unit,
  13323                                ":%d:%s: ==>"), f,soc_fieldnames[fieldp_from->field])); */
  13324         if ((strstr(soc_fieldnames[fieldp_from->field],
  13325                     view_name_with_colon) != NULL) ||
  13326             (strstr(soc_fieldnames[fieldp_from->field], ":") == NULL)) {
  13327              if (soc_mem_field_valid(unit,
  13328                                      to_table,fieldp_from->field)) {
  13329                  SOC_FIND_FIELD(fieldp_from->field,
  13330                                 memp_to->fields,
  13331                                 memp_to->nFields,
  13332                                 fieldp_to);
  13333                  if (fieldp_to->len < fieldp_from->len) {
  13334                     LOG_CLI((BSL_META_U(unit,
  13335                                         "Warning:%d:%s: Mismatch in length %d:%d ==>"), 
  13336                              f,soc_fieldnames[fieldp_from->field],
  13337                              fieldp_from->len,fieldp_to->len)); 
  13338                  } else if (fieldp_to->len > fieldp_from->len) {
  13339                      sal_memset(fval,0,((fieldp_to->len-1) >> 5)+1);
  13340                      LOG_CLI((BSL_META_U(unit,
  13341                                          "Warning:%d:%s: More lengthy field %d:%d==>"), 
  13342                               f,soc_fieldnames[fieldp_from->field],
  13343                               fieldp_from->len,fieldp_to->len)); 
  13344                  }
  13345                  soc_mem_field_get(unit, from_table,
  13346                                    (uint32 *)from_entry ,
  13347                                    fieldp_from->field,fval);
  13348                  soc_mem_field_set(unit,to_table,
  13349                                    (uint32 *)to_entry ,
  13350                                    fieldp_from->field, fval);
  13351                  /* LOG_CLI((BSL_META_U(unit,
  13352                                         "Matched \n"))); */
  13353              } else {
  13354                  /* LOG_CLI((BSL_META_U(unit,
  13355                                         "Not Matched \n"))); */
  13356              }
  13357         } else {
  13358             /* LOG_CLI((BSL_META_U(unit,
  13359                                    "Skipped \n"))); */
  13360         }
  13361 #endif /* !SOC_NO_NAMES */
  13362    }
  13363    return BCM_E_NONE;
  13364 }
  13365 static 
  13366 bcm_error_t _bcm_esw_vlan_translate_convert_to_extd_entry(
  13367             int                     unit,
  13368             vlan_xlate_entry_t      *vlan_xlate_entry,
  13369             vlan_xlate_extd_entry_t *vlan_xlate_extd_entry)
  13370 {
  13371    uint32 key_type=0;
  13372    uint32 fval[SOC_MAX_MEM_FIELD_WORDS];
  13373    uint32 new_key_type=0;
  13374 
  13375    BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_convert_common_fields(
  13376                        unit, 
  13377                        VLAN_XLATEm, VLAN_XLATE_EXTDm,KEY_TYPEf,"XLATE",
  13378                        (void *)vlan_xlate_entry,
  13379                        (void *)vlan_xlate_extd_entry));
  13380 
  13381    /* Take care about special fields */
  13382    soc_mem_field_get(unit, VLAN_XLATEm,
  13383                      (uint32 *)vlan_xlate_entry , VALIDf,fval);
  13384    soc_mem_field_set(unit, VLAN_XLATE_EXTDm,
  13385                      (uint32 *)vlan_xlate_extd_entry, VALID_0f, fval);
  13386    soc_mem_field_set(unit, VLAN_XLATE_EXTDm,
  13387                      (uint32 *)vlan_xlate_extd_entry, VALID_1f, fval);
  13388    fval[0] = 0;
  13389    fval[1] = 0;
  13390    soc_mem_field_get(unit,VLAN_XLATEm,(uint32 *)vlan_xlate_entry,KEYf,fval);
  13391    soc_mem_field_set(unit,VLAN_XLATE_EXTDm,(uint32 *)vlan_xlate_extd_entry,
  13392                      XLATE__KEY_0f, fval); /* Default KEY_0f */
  13393 
  13394    soc_mem_field_get(unit, VLAN_XLATEm, (uint32 *)vlan_xlate_entry , 
  13395                      KEY_TYPEf,&key_type);
  13396    new_key_type=key_type+1;
  13397    soc_mem_field_set(unit,VLAN_XLATE_EXTDm,(uint32 *)vlan_xlate_extd_entry,
  13398                        KEY_TYPE_0f, &new_key_type);
  13399    soc_mem_field_set(unit,VLAN_XLATE_EXTDm,(uint32 *)vlan_xlate_extd_entry,
  13400                        KEY_TYPE_1f, &new_key_type);
  13401 
  13402    fval[0] = 0;
  13403    fval[1] = 0;
  13404    soc_mem_field_get(unit, VLAN_XLATEm,(uint32 *)vlan_xlate_entry, DATAf,fval);
  13405    soc_mem_field_set(unit, VLAN_XLATE_EXTDm, 
  13406                      (uint32 *)vlan_xlate_extd_entry, XLATE__DATA_0f, fval);
  13407    return BCM_E_NONE;
  13408 }
  13409 static 
  13410 bcm_error_t _bcm_esw_vlan_translate_convert_to_regular_entry(
  13411             int                     unit,
  13412             vlan_xlate_extd_entry_t *vlan_xlate_extd_entry,
  13413             vlan_xlate_entry_t      *vlan_xlate_entry)
  13414 {
  13415    uint32 key_type=0;
  13416    uint32 fval[SOC_MAX_MEM_FIELD_WORDS];
  13417    uint32 new_key_type=0;
  13418 
  13419    BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_convert_common_fields(
  13420                        unit, 
  13421                        VLAN_XLATE_EXTDm, VLAN_XLATEm,KEY_TYPE_0f,"XLATE",
  13422                        (void *)vlan_xlate_extd_entry,
  13423                        (void *)vlan_xlate_entry));
  13424    /* Take care about special fields */
  13425 
  13426    fval[0] = 0;
  13427    fval[1] = 0;
  13428    soc_mem_field_get(unit, VLAN_XLATE_EXTDm,
  13429                      (uint32 *)vlan_xlate_extd_entry , VALID_0f,fval);
  13430    soc_mem_field_set(unit, VLAN_XLATEm,(uint32 *)vlan_xlate_entry,
  13431                      VALIDf, fval);
  13432 
  13433    fval[0] = 0;
  13434    fval[1] = 0;
  13435    soc_mem_field_get(unit, VLAN_XLATE_EXTDm,
  13436                      (uint32 *)vlan_xlate_extd_entry , XLATE__KEY_0f,fval);
  13437    soc_mem_field_set(unit, VLAN_XLATEm,(uint32 *)vlan_xlate_entry,
  13438                      KEYf, fval);
  13439 
  13440    soc_mem_field_get(unit,VLAN_XLATE_EXTDm, (uint32 *)vlan_xlate_extd_entry,
  13441                      KEY_TYPE_0f, &key_type);
  13442    new_key_type = key_type - 1;
  13443    soc_mem_field_set(unit, VLAN_XLATEm, (uint32 *)vlan_xlate_entry ,
  13444                      KEY_TYPEf, &new_key_type);
  13445 
  13446    fval[0] = 0;
  13447    fval[1] = 0;
  13448    soc_mem_field_get(unit, VLAN_XLATE_EXTDm, (uint32 *)vlan_xlate_extd_entry, 
  13449                      XLATE__DATA_0f,fval);
  13450    fval[1] &= 0x3f;
  13451    soc_mem_field_set(unit, VLAN_XLATEm, (uint32 *)vlan_xlate_entry, DATAf,fval);
  13452 
  13453    return BCM_E_NONE;
  13454 }
  13455 #endif
  13456 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  13457 /*
  13458  * Function:
  13459  *      _bcm_esw_vlan_translate_stat_get_table_info
  13460  * Description:
  13461  *      Provides relevant flex table information(table-name,index with
  13462  *      direction)  for given ingress vlan translation
  13463  *
  13464  * Parameters:
  13465  *      unit             - (IN) unit number
  13466  *      port             - (IN) Generic port
  13467  *      key_type         - (IN) Key Type : bcmVlanTranslateKey*
  13468  *      outer_vlan       - (IN) Packet outer VLAN ID
  13469  *      inner_vlan       - (IN) Packet inner VLAN ID
  13470  *      num_of_tables    - (OUT) Number of flex counter tables
  13471  *      table_info       - (OUT) Flex counter tables information
  13472  *
  13473  * Return Value:
  13474  *      BCM_E_XXX
  13475  * Notes:
  13476  */
  13477 static bcm_error_t _bcm_esw_vlan_translate_stat_get_table_info(
  13478                    int                        unit, 
  13479                    bcm_gport_t                port,
  13480                    bcm_vlan_translate_key_t   key_type,
  13481                    bcm_vlan_t                 outer_vlan,
  13482                    bcm_vlan_t                 inner_vlan,
  13483                    uint32                     *num_of_tables,
  13484                    bcm_stat_flex_table_info_t *table_info)
  13485 {
  13486     bcm_error_t        rv=BCM_E_NONE;
  13487     uint32             vent[SOC_MAX_MEM_FIELD_WORDS];
  13488     uint32             vlan_xlate_entry[SOC_MAX_MEM_FIELD_WORDS];
  13489 
  13490     int                index=0;
  13491 #if defined(BCM_TRIUMPH3_SUPPORT)
  13492     vlan_xlate_extd_entry_t vlan_xlate_extd_entry={{0}};
  13493 #endif
  13494     soc_mem_t               mem = VLAN_XLATEm;
  13495 
  13496     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
  13497         mem = VLAN_XLATE_1_DOUBLEm;
  13498     }
  13499 
  13500     (*num_of_tables) = 0;
  13501 
  13502     if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  13503         return BCM_E_UNAVAIL;
  13504     }
  13505     sal_memset(vent, 0, sizeof(vent));
  13506     sal_memset(vlan_xlate_entry, 0, sizeof(vlan_xlate_entry));
  13507     BCM_IF_ERROR_RETURN (_bcm_trx_vlan_translate_entry_assemble(
  13508                          unit, vent, port, key_type, inner_vlan,outer_vlan));
  13509     soc_mem_lock(unit, mem);
  13510     rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL,&index,vent,
  13511                         vlan_xlate_entry,0);
  13512     soc_mem_unlock(unit, mem);
  13513     if (SOC_IS_KATANAX(unit)) {
  13514     if (BCM_SUCCESS(rv)) {
  13515         table_info[*num_of_tables].table=mem;
  13516         table_info[*num_of_tables].index=index;
  13517         table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress;
  13518         (*num_of_tables)++;
  13519     }
  13520 #if defined(BCM_TRIUMPH3_SUPPORT)
  13521     } else if SOC_IS_TD2_TT2(unit) {
  13522         if (BCM_SUCCESS(rv)) {
  13523             table_info[*num_of_tables].table=mem;
  13524             table_info[*num_of_tables].index=index;
  13525             table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress;
  13526             (*num_of_tables)++;
  13527         }
  13528     } else if SOC_IS_TRIUMPH3(unit) {
  13529         if (BCM_SUCCESS(rv)) {
  13530             BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_convert_to_extd_entry(
  13531                                 unit, (void *)vlan_xlate_entry,
  13532                                 &vlan_xlate_extd_entry));
  13533             BCM_IF_ERROR_RETURN(soc_mem_delete(
  13534                                 unit, VLAN_XLATEm, MEM_BLOCK_ANY,
  13535                                 (void *)vlan_xlate_entry));
  13536             BCM_IF_ERROR_RETURN(soc_mem_insert(
  13537                                 unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ALL,
  13538                                 (void *)&vlan_xlate_extd_entry));
  13539         } else {
  13540            /* Possibly entry has already been moved to VLAN_XLATE_EXTD table */
  13541            BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_convert_to_extd_entry(
  13542                                unit, (void *)vent, &vlan_xlate_extd_entry));
  13543         }
  13544         BCM_IF_ERROR_RETURN(soc_mem_search(unit, VLAN_XLATE_EXTDm, 
  13545                             MEM_BLOCK_ALL,&index,
  13546                             (void *)&vlan_xlate_extd_entry,
  13547                             (void *)&vlan_xlate_extd_entry,0));
  13548         table_info[*num_of_tables].table=VLAN_XLATE_EXTDm;
  13549         table_info[*num_of_tables].index=index;
  13550         table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress;
  13551         (*num_of_tables)++;
  13552         return BCM_E_NONE;
  13553 #endif
  13554     } 
  13555     return rv;
  13556 }
  13557 #endif
  13558 
  13559 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  13560 /*
  13561  * Function:
  13562  *      _bcm_esw_vlan_translate_stat_attach
  13563  * Description:
  13564  *      attach counters entries for the given ingress vlan translation table.
  13565  *
  13566  * Parameters:
  13567  *      unit             - (IN) unit number
  13568  *      Port             - (IN) GPORT (global port) identifier  
  13569  *      key_type         - (IN) VLAN translation key type  
  13570  *      outer_vlan       - (IN) Outer VLAN ID or tag  
  13571  *      inner_vlan       - (IN) Inner VLAN ID or tag  
  13572  *      Stat_counter_id  - (IN) Stat Counter ID.                   
  13573  *
  13574  * Return Value:
  13575  *      BCM_E_XXX
  13576  * Notes:
  13577  */
  13578 STATIC bcm_error_t _bcm_esw_vlan_translate_stat_attach(
  13579             int                      unit,
  13580             bcm_gport_t              port,
  13581             bcm_vlan_translate_key_t key_type,
  13582             bcm_vlan_t               outer_vlan,
  13583             bcm_vlan_t               inner_vlan,
  13584             uint32                   stat_counter_id)
  13585 {
  13586     soc_mem_t                  table=0;
  13587     bcm_stat_flex_direction_t  direction=bcmStatFlexDirectionIngress;
  13588     uint32                     pool_number=0;
  13589     uint32                     base_index=0;
  13590     bcm_stat_flex_mode_t       offset_mode=0;
  13591     bcm_stat_object_t          object=bcmStatObjectIngPort;
  13592     bcm_stat_group_mode_t      group_mode= bcmStatGroupModeSingle;
  13593     uint32                     count=0;
  13594     uint32                     actual_num_tables=0;
  13595     uint32                     num_of_tables=0;
  13596     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  13597 
  13598     _bcm_esw_stat_get_counter_id_info(
  13599                   unit, stat_counter_id,
  13600                   &group_mode,&object,&offset_mode,&pool_number,&base_index);
  13601     BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit,object,&direction));
  13602     BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit,group_mode));
  13603     BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_table_info(
  13604                         unit,object,1,&actual_num_tables,&table,&direction));
  13605     /* When key_type is bcmVlanTranslateKeyPortOuter, 
  13606        outer_vlan should be old vlan_id.Inner Vlan value is discarded */
  13607     /* When key_type is bcmVlanTranslateKeyPortInn, 
  13608        inner_vlan should be old vlan_id.Outer vlan value is discarded */
  13609     /*
  13610     if (key_type == bcmVlanTranslateKeyPortOuter) {
  13611         BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_stat_get_table_info(
  13612                             unit, port,key_type,inner_vlan,0,
  13613                             &num_of_tables,&table_info[0]));
  13614     } else if(key_type ==  bcmVlanTranslateKeyPortInner) {
  13615         BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_stat_get_table_info(
  13616                             unit, port,key_type,0,inner_vlan,
  13617                             &num_of_tables,&table_info[0]));
  13618     } else {
  13619           return BCM_E_PARAM;
  13620     }
  13621     */
  13622     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_stat_get_table_info(
  13623                             unit, port,key_type,outer_vlan,inner_vlan,
  13624                             &num_of_tables,&table_info[0]));
  13625     for (count=0; count < num_of_tables ; count++) {
  13626          if ((table_info[count].direction == direction) &&
  13627              (table_info[count].table == table) ) {
  13628               if (direction == bcmStatFlexDirectionIngress) {
  13629                   return _bcm_esw_stat_flex_attach_ingress_table_counters(
  13630                         unit, table_info[count].table, table_info[count].index,
  13631                         offset_mode, base_index, pool_number);
  13632               } else {
  13633                   return _bcm_esw_stat_flex_attach_egress_table_counters(
  13634                          unit, table_info[count].table, table_info[count].index,
  13635                          0, offset_mode, base_index, pool_number);
  13636               } 
  13637          }
  13638     }
  13639     return BCM_E_NOT_FOUND;
  13640 }
  13641 #endif
  13642 
  13643 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  13644 /*
  13645  * Function:
  13646  *      _tr2_vlan_translate_stat_attach
  13647  * Description:
  13648  *      attach counters entries for the given ingress vlan translation table.
  13649  *
  13650  * Parameters:
  13651  *      unit             - (IN) unit number
  13652  *      Port             - (IN) GPORT (global port) identifier
  13653  *      key_type         - (IN) VLAN translation key type
  13654  *      outer_vlan       - (IN) Outer VLAN ID or tag
  13655  *      inner_vlan       - (IN) Inner VLAN ID or tag
  13656  *      Stat_counter_id  - (IN) Stat Counter ID.
  13657  *
  13658  * Return Value:
  13659  *      BCM_E_XXX
  13660  * Notes:
  13661  */
  13662 STATIC bcm_error_t _tr2_vlan_translate_stat_attach(
  13663             int                      unit,
  13664             bcm_gport_t              port,
  13665             bcm_vlan_translate_key_t key_type,
  13666             bcm_vlan_t               outer_vlan,
  13667             bcm_vlan_t               inner_vlan,
  13668             uint32                   stat_counter_id,
  13669             int                      attached)
  13670 {
  13671 
  13672     _bcm_flex_stat_type_t fs_type;
  13673     uint32 fs_inx;
  13674     _bcm_flex_stat_handle_t vxlt_fsh;
  13675 
  13676     fs_type = _BCM_FLEX_STAT_TYPE(stat_counter_id);
  13677     fs_inx  = _BCM_FLEX_STAT_COUNT_INX(stat_counter_id);
  13678 
  13679     if (!((fs_type == _bcmFlexStatTypeVxlt) && fs_inx)) {
  13680         return BCM_E_PARAM;
  13681     }
  13682     BCM_IF_ERROR_RETURN
  13683         (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type,
  13684                                               outer_vlan, inner_vlan,
  13685                                                   &vxlt_fsh));
  13686     
  13687     return _bcm_esw_flex_stat_ext_enable_set(unit, fs_type,
  13688                              _bcm_esw_vlan_translate_flex_stat_hw_index_set,
  13689                              INT_TO_PTR(_BCM_FLEX_STAT_HW_INGRESS), 
  13690                              vxlt_fsh, attached,
  13691                              fs_inx);
  13692 }
  13693 #endif
  13694 
  13695 /*
  13696  * Function:
  13697  *      bcm_esw_vlan_translate_stat_attach
  13698  * Description:
  13699  *      attach counters entries for the given ingress vlan translation table.
  13700  *
  13701  * Parameters:
  13702  *      unit             - (IN) unit number
  13703  *      Port             - (IN) GPORT (global port) identifier
  13704  *      key_type         - (IN) VLAN translation key type
  13705  *      outer_vlan       - (IN) Outer VLAN ID or tag
  13706  *      inner_vlan       - (IN) Inner VLAN ID or tag
  13707  *      Stat_counter_id  - (IN) Stat Counter ID.
  13708  *
  13709  * Return Value:
  13710  *      BCM_E_XXX
  13711  * Notes:
  13712  */
  13713 int bcm_esw_vlan_translate_stat_attach(
  13714             int                      unit,
  13715             bcm_gport_t              port,
  13716             bcm_vlan_translate_key_t key_type,
  13717             bcm_vlan_t               outer_vlan,
  13718             bcm_vlan_t               inner_vlan,
  13719             uint32                   stat_counter_id)
  13720 {
  13721 #ifdef BCM_TOMAHAWK3_SUPPORT
  13722     if (SOC_IS_TOMAHAWK3(unit)) {
  13723         return BCM_E_UNAVAIL;
  13724     }
  13725 #endif
  13726 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  13727     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  13728         return _bcm_esw_vlan_translate_stat_attach(unit,port,
  13729                key_type,outer_vlan,inner_vlan,stat_counter_id);
  13730     } else
  13731 #endif
  13732 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  13733     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  13734         return _tr2_vlan_translate_stat_attach(unit,port,key_type,
  13735                    outer_vlan,inner_vlan,stat_counter_id,TRUE);
  13736     } else
  13737 #endif
  13738 #if defined(BCM_HURRICANE3_SUPPORT)
  13739     if (soc_feature(unit, soc_feature_flowcnt)) {
  13740         return _bcm_hr3_vlan_translate_stat_attach(unit,port,key_type,
  13741                    outer_vlan,inner_vlan,stat_counter_id);
  13742     } else
  13743 #endif
  13744     {
  13745         return BCM_E_UNAVAIL;
  13746     }
  13747 
  13748 }
  13749 
  13750 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  13751 /*
  13752  * Function:
  13753  *      _bcm_esw_vlan_translate_stat_detach
  13754  * Description:
  13755  *      Detach counters entries for the given ingress vlan translation table.
  13756  *
  13757  * Parameters:
  13758  *      unit             - (IN) unit number
  13759  *      Port             - (IN) GPORT (global port) identifier  
  13760  *      key_type         - (IN) VLAN translation key type  
  13761  *      outer_vlan       - (IN) Outer VLAN ID or tag  
  13762  *      inner_vlan       - (IN) Inner VLAN ID or tag  
  13763  *
  13764  * Return Value:
  13765  *      BCM_E_XXX
  13766  * Notes:
  13767  */
  13768 STATIC bcm_error_t _bcm_esw_vlan_translate_stat_detach(
  13769             int                      unit,
  13770             bcm_gport_t              port,
  13771             bcm_vlan_translate_key_t key_type,
  13772             bcm_vlan_t               outer_vlan,
  13773             bcm_vlan_t               inner_vlan)
  13774 {
  13775     uint32                     count=0;
  13776     uint32                     num_of_tables=0;
  13777     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  13778     bcm_error_t                rv = BCM_E_NONE;
  13779     bcm_error_t                err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE};
  13780 #if defined(BCM_TRIUMPH3_SUPPORT)
  13781     vlan_xlate_entry_t         vlan_xlate_entry={{0}};
  13782     vlan_xlate_extd_entry_t    vlan_xlate_extd_entry={{0}};
  13783 #endif
  13784 
  13785     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_stat_get_table_info(
  13786                         unit, port,key_type,outer_vlan,inner_vlan,
  13787                         &num_of_tables,&table_info[0]));
  13788 
  13789     for (count=0; count < num_of_tables ; count++) {
  13790          if (table_info[count].direction == bcmStatFlexDirectionIngress) {
  13791              rv = _bcm_esw_stat_flex_detach_ingress_table_counters(
  13792                          unit, table_info[count].table,table_info[count].index);
  13793 #if defined(BCM_TRIUMPH3_SUPPORT)
  13794              if (SOC_IS_TRIUMPH3(unit)) {
  13795                  BCM_IF_ERROR_RETURN(soc_mem_read(
  13796                                      unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ANY,
  13797                                      table_info[count].index,
  13798                                      (void *)&vlan_xlate_extd_entry));
  13799                  if (soc_mem_field32_get(unit,VLAN_XLATE_EXTDm,
  13800                                          (uint32 *)&vlan_xlate_extd_entry,
  13801                                          XLATE__SVC_METER_INDEXf) == 0) {
  13802                      BCM_IF_ERROR_RETURN(
  13803                         _bcm_esw_vlan_translate_convert_to_regular_entry(
  13804                          unit,&vlan_xlate_extd_entry,&vlan_xlate_entry));
  13805                      BCM_IF_ERROR_RETURN(soc_mem_delete(
  13806                                          unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ANY,
  13807                                          (void *)&vlan_xlate_extd_entry));
  13808                      BCM_IF_ERROR_RETURN(soc_mem_insert(
  13809                                          unit, VLAN_XLATEm, MEM_BLOCK_ALL,
  13810                                          (void *)&vlan_xlate_entry));
  13811                  }
  13812              }
  13813 #endif
  13814              if (BCM_E_NONE != rv &&
  13815                 BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) {
  13816                 err_code[bcmStatFlexDirectionIngress] = rv;
  13817              }
  13818          } else {
  13819              rv = _bcm_esw_stat_flex_detach_egress_table_counters(
  13820                         unit, 0, table_info[count].table,table_info[count].index);
  13821              if (BCM_E_NONE != rv &&
  13822                 BCM_E_NONE == err_code[bcmStatFlexDirectionEgress]) {
  13823                 err_code[bcmStatFlexDirectionEgress] = rv;
  13824              }
  13825          }
  13826     }
  13827     
  13828     BCM_STAT_FLEX_DETACH_RETURN(err_code)
  13829 }
  13830 #endif
  13831 
  13832 /*
  13833  * Function:
  13834  *      bcm_esw_vlan_translate_stat_detach
  13835  * Description:
  13836  *      Detach counters entries for the given ingress vlan translation table.
  13837  *
  13838  * Parameters:
  13839  *      unit             - (IN) unit number
  13840  *      Port             - (IN) GPORT (global port) identifier
  13841  *      key_type         - (IN) VLAN translation key type
  13842  *      outer_vlan       - (IN) Outer VLAN ID or tag
  13843  *      inner_vlan       - (IN) Inner VLAN ID or tag
  13844  *
  13845  * Return Value:
  13846  *      BCM_E_XXX
  13847  * Notes:
  13848  */
  13849 int bcm_esw_vlan_translate_stat_detach(
  13850             int                      unit,
  13851             bcm_gport_t              port,
  13852             bcm_vlan_translate_key_t key_type,
  13853             bcm_vlan_t               outer_vlan,
  13854             bcm_vlan_t               inner_vlan)
  13855 {
  13856 #ifdef BCM_TOMAHAWK3_SUPPORT
  13857     if (SOC_IS_TOMAHAWK3(unit)) {
  13858         return BCM_E_UNAVAIL;
  13859     }
  13860 #endif
  13861 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  13862     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  13863         return _bcm_esw_vlan_translate_stat_detach(unit,port,
  13864                key_type,outer_vlan,inner_vlan);
  13865     } else
  13866 #endif
  13867 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  13868     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  13869         return _tr2_vlan_translate_stat_attach(unit,port,key_type,
  13870                    outer_vlan,inner_vlan,
  13871                    _BCM_FLEX_STAT_COUNT_ID(_bcmFlexStatTypeVxlt,1),FALSE);
  13872     } else
  13873 #endif
  13874 #if defined(BCM_HURRICANE3_SUPPORT)
  13875     if (soc_feature(unit, soc_feature_flowcnt)) {
  13876         return _bcm_hr3_vlan_translate_stat_detach(unit,port,key_type,
  13877                    outer_vlan,inner_vlan);
  13878     } else
  13879 #endif 
  13880     {
  13881         return BCM_E_UNAVAIL;
  13882     }
  13883 }
  13884 
  13885 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  13886 /*
  13887  * Function:
  13888  *      _bcm_esw_vlan_translate_stat_counter_get
  13889  * Description:
  13890  *      Get counter values from ingress vlan translation table
  13891  *      if sync_mode is set, sync the sw accumulated count
  13892  *      with hw count value first, else return sw count.  
  13893  *
  13894  * Parameters:
  13895  *      unit             - (IN) unit number
  13896  *      sync_mode        - (IN) hwcount is to be synced to sw count 
  13897  *      Port             - (IN) GPORT (global port) identifier  
  13898  *      key_type         - (IN) VLAN translation key type  
  13899  *      outer_vlan       - (IN) Outer VLAN ID or tag  
  13900  *      inner_vlan       - (IN) Inner VLAN ID or tag  
  13901  *      stat             - (IN) Type of the counter to retrieve
  13902  *                              I.e. ingress/egress byte/packet)
  13903  *      num_entries      - (IN) Number of counter Entries
  13904  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  13905  *      counter_values   - (OUT) Pointer to counter values
  13906  *
  13907  * Return Value:
  13908  *      BCM_E_XXX
  13909  * Notes:
  13910  */
  13911 STATIC bcm_error_t _bcm_esw_vlan_translate_stat_counter_get(
  13912             int                      unit,
  13913             int                      sync_mode,
  13914             bcm_gport_t              port,
  13915             bcm_vlan_translate_key_t key_type,
  13916             bcm_vlan_t               outer_vlan,
  13917             bcm_vlan_t               inner_vlan,
  13918             bcm_vlan_stat_t          stat,
  13919             uint32                   num_entries,
  13920             uint32                   *counter_indexes,
  13921             bcm_stat_value_t         *counter_values)
  13922 {
  13923     uint32                          table_count=0;
  13924     uint32                          index_count=0;
  13925     uint32                          num_of_tables=0;
  13926     bcm_stat_flex_direction_t       direction=bcmStatFlexDirectionIngress;
  13927     uint32                          byte_flag=0;
  13928     bcm_stat_flex_table_info_t      table_info[
  13929                                     BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  13930 
  13931     if ((stat == bcmVlanStatIngressPackets) ||
  13932         (stat == bcmVlanStatIngressBytes)) {
  13933          direction = bcmStatFlexDirectionIngress;
  13934     } else {
  13935          direction = bcmStatFlexDirectionEgress;
  13936     }
  13937     if ((stat == bcmVlanStatIngressPackets) ||
  13938         (stat == bcmVlanStatEgressPackets)) {
  13939         byte_flag=0;
  13940     } else {
  13941         byte_flag=1;
  13942     }
  13943     
  13944     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_stat_get_table_info(
  13945                         unit, port,key_type,outer_vlan,inner_vlan,
  13946                         &num_of_tables,&table_info[0]));
  13947 
  13948     for (table_count=0; table_count < num_of_tables ; table_count++) {
  13949         if (table_info[table_count].direction == direction) {
  13950             for (index_count=0; index_count < num_entries ; index_count++) {
  13951                  BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_get(
  13952                                      unit, sync_mode, 
  13953                                      table_info[table_count].index,
  13954                                      table_info[table_count].table, 0,
  13955                                      byte_flag,
  13956                                      counter_indexes[index_count],
  13957                                      &counter_values[index_count]));
  13958             }
  13959         }
  13960     }
  13961     return BCM_E_NONE;
  13962 }
  13963 #endif
  13964 
  13965 /*
  13966  * Function:
  13967  *      _bcm_esw_vlan_xslate_stat_counter_get
  13968  * Description:
  13969  *      Get counter values from ingress vlan translation table
  13970  *      if sync_mode is set, sync the sw accumulated count
  13971  *      with hw count value first, else return sw count.  
  13972  *
  13973  * Parameters:
  13974  *      unit             - (IN) unit number
  13975  *      sync_mode        - (IN) hwcount is to be synced to sw count 
  13976  *      Port             - (IN) GPORT (global port) identifier
  13977  *      key_type         - (IN) VLAN translation key type
  13978  *      outer_vlan       - (IN) Outer VLAN ID or tag
  13979  *      inner_vlan       - (IN) Inner VLAN ID or tag
  13980  *      stat             - (IN) Type of the counter to retrieve
  13981  *                              I.e. ingress/egress byte/packet)
  13982  *      num_entries      - (IN) Number of counter Entries
  13983  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  13984  *      counter_values   - (OUT) Pointer to counter values
  13985  *
  13986  * Return Value:
  13987  *      BCM_E_XXX
  13988  * Notes:
  13989  */
  13990 int  
  13991 bcm_esw_vlan_xslate_stat_counter_get(int                      unit,
  13992                                      int                      sync_mode,
  13993                                      bcm_gport_t              port,
  13994                                      bcm_vlan_translate_key_t key_type,
  13995                                      bcm_vlan_t               outer_vlan,
  13996                                      bcm_vlan_t               inner_vlan,
  13997                                      bcm_vlan_stat_t          stat,
  13998                                      uint32                   num_entries,
  13999                                      uint32                   *counter_indexes,
  14000                                      bcm_stat_value_t         *counter_values)
  14001 {
  14002 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  14003     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  14004         return _bcm_esw_vlan_translate_stat_counter_get(unit, sync_mode, 
  14005                                                         port, key_type,
  14006                                                         outer_vlan, inner_vlan,
  14007                                                         stat,num_entries,
  14008                                                         counter_indexes,
  14009                                                         counter_values);
  14010     } else
  14011 #endif
  14012 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  14013     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  14014         uint64 val;
  14015         _bcm_flex_stat_handle_t vxlt_fsh;
  14016         int rv = BCM_E_NONE;
  14017 
  14018         BCM_IF_ERROR_RETURN
  14019             (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type,
  14020                                                   outer_vlan, inner_vlan,
  14021                                                   &vxlt_fsh));
  14022         rv =  _bcm_esw_flex_stat_ext_get(unit, 0, _bcmFlexStatTypeVxlt,
  14023                 vxlt_fsh, _bcm_esw_vlan_translate_stat_to_flex_stat(stat), 
  14024                 &val);
  14025 
  14026         if (stat == bcmVlanStatIngressPackets) {
  14027             counter_values->packets = COMPILER_64_LO(val);
  14028         } else {
  14029             COMPILER_64_SET(counter_values->bytes,
  14030                       COMPILER_64_HI(val),
  14031                       COMPILER_64_LO(val));
  14032         }
  14033         return rv;
  14034 
  14035     } else
  14036 #endif
  14037 #if defined(BCM_HURRICANE3_SUPPORT)
  14038     if (soc_feature(unit, soc_feature_flowcnt)) {
  14039         return _bcm_hr3_vlan_translate_stat_counter_get(unit, sync_mode, 
  14040                                                         port, key_type,
  14041                                                         outer_vlan, inner_vlan,
  14042                                                         stat,num_entries,
  14043                                                         counter_indexes,
  14044                                                         counter_values);
  14045     } else
  14046 #endif
  14047     {
  14048         return BCM_E_UNAVAIL;
  14049     }
  14050 }
  14051 
  14052 
  14053 /*
  14054  * Function:
  14055  *      bcm_esw_vlan_translate_stat_counter_get
  14056  * Description:
  14057  *      Get   counter values from ingress vlan translation table
  14058  *
  14059  * Parameters:
  14060  *      unit             - (IN) unit number
  14061  *      Port             - (IN) GPORT (global port) identifier
  14062  *      key_type         - (IN) VLAN translation key type
  14063  *      outer_vlan       - (IN) Outer VLAN ID or tag
  14064  *      inner_vlan       - (IN) Inner VLAN ID or tag
  14065  *      stat             - (IN) Type of the counter to retrieve
  14066  *                              I.e. ingress/egress byte/packet)
  14067  *      num_entries      - (IN) Number of counter Entries
  14068  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  14069  *      counter_values   - (OUT) Pointer to counter values
  14070  *
  14071  * Return Value:
  14072  *      BCM_E_XXX
  14073  * Notes:
  14074  */
  14075 int  bcm_esw_vlan_translate_stat_counter_get(
  14076             int                      unit,
  14077             bcm_gport_t              port,
  14078             bcm_vlan_translate_key_t key_type,
  14079             bcm_vlan_t               outer_vlan,
  14080             bcm_vlan_t               inner_vlan,
  14081             bcm_vlan_stat_t          stat,
  14082             uint32                   num_entries,
  14083             uint32                   *counter_indexes,
  14084             bcm_stat_value_t         *counter_values)
  14085 {
  14086 #ifdef BCM_TOMAHAWK3_SUPPORT
  14087     if (SOC_IS_TOMAHAWK3(unit)) {
  14088         return BCM_E_UNAVAIL;
  14089     }
  14090 #endif
  14091     return bcm_esw_vlan_xslate_stat_counter_get(unit, 0,  port, key_type,
  14092                                                 outer_vlan, inner_vlan,
  14093                                                 stat, num_entries,
  14094                                                 counter_indexes,
  14095                                                 counter_values);
  14096 }
  14097 
  14098 
  14099 /*
  14100  * Function:
  14101  *      bcm_esw_vlan_translate_stat_counter_sync_get
  14102  * Description:
  14103  *      Get counter values from ingress vlan translation table
  14104  *      sw accumulated counters synced with hw count.
  14105  *
  14106  * Parameters:
  14107  *      unit             - (IN) unit number
  14108  *      Port             - (IN) GPORT (global port) identifier
  14109  *      key_type         - (IN) VLAN translation key type
  14110  *      outer_vlan       - (IN) Outer VLAN ID or tag
  14111  *      inner_vlan       - (IN) Inner VLAN ID or tag
  14112  *      stat             - (IN) Type of the counter to retrieve
  14113  *                              I.e. ingress/egress byte/packet)
  14114  *      num_entries      - (IN) Number of counter Entries
  14115  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  14116  *      counter_values   - (OUT) Pointer to counter values
  14117  *
  14118  * Return Value:
  14119  *      BCM_E_XXX
  14120  * Notes:
  14121  */
  14122 int bcm_esw_vlan_translate_stat_counter_sync_get(
  14123             int                      unit,
  14124             bcm_gport_t              port,
  14125             bcm_vlan_translate_key_t key_type,
  14126             bcm_vlan_t               outer_vlan,
  14127             bcm_vlan_t               inner_vlan,
  14128             bcm_vlan_stat_t          stat,
  14129             uint32                   num_entries,
  14130             uint32                   *counter_indexes,
  14131             bcm_stat_value_t         *counter_values)
  14132 {
  14133 #ifdef BCM_TOMAHAWK3_SUPPORT
  14134     if (SOC_IS_TOMAHAWK3(unit)) {
  14135         return BCM_E_UNAVAIL;
  14136     }
  14137 #endif
  14138     return bcm_esw_vlan_xslate_stat_counter_get(unit, 1,  port, key_type,
  14139                                                 outer_vlan, inner_vlan,
  14140                                                 stat, num_entries,
  14141                                                 counter_indexes,
  14142                                                 counter_values);
  14143 }
  14144 
  14145 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  14146 /* Function:
  14147  *      _bcm_esw_vlan_translate_stat_counter_set
  14148  * Description:
  14149  *      Set counter values into a ingress vlan translation table
  14150  *
  14151  * Parameters:
  14152  *      unit             - (IN) unit number
  14153  *      Port             - (IN) GPORT (global port) identifier  
  14154  *      key_type         - (IN) VLAN translation key type  
  14155  *      outer_vlan       - (IN) Outer VLAN ID or tag  
  14156  *      inner_vlan       - (IN) Inner VLAN ID or tag  
  14157  *      stat             - (IN) Type of the counter to retrieve
  14158  *                              I.e. ingress/egress byte/packet)
  14159  *      num_entries      - (IN) Number of counter Entries
  14160  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  14161  *      counter_values   - (IN) Pointer to counter values
  14162  *
  14163  * Return Value:
  14164  *      BCM_E_XXX
  14165  * Notes:
  14166  */
  14167 STATIC bcm_error_t _bcm_esw_vlan_translate_stat_counter_set(
  14168             int                      unit,
  14169             bcm_gport_t              port,
  14170             bcm_vlan_translate_key_t key_type,
  14171             bcm_vlan_t               outer_vlan,
  14172             bcm_vlan_t               inner_vlan,
  14173             bcm_vlan_stat_t          stat,
  14174             uint32                   num_entries,
  14175             uint32                   *counter_indexes,
  14176             bcm_stat_value_t         *counter_values)
  14177 {
  14178     uint32                          table_count=0;
  14179     uint32                          index_count=0;
  14180     uint32                          num_of_tables=0;
  14181     bcm_stat_flex_direction_t       direction=bcmStatFlexDirectionIngress;
  14182     uint32                          byte_flag=0;
  14183     bcm_stat_flex_table_info_t      table_info[
  14184                                     BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  14185 
  14186     if ((stat == bcmVlanStatIngressPackets) ||
  14187         (stat == bcmVlanStatIngressBytes)) {
  14188          direction = bcmStatFlexDirectionIngress;
  14189     } else {
  14190          direction = bcmStatFlexDirectionEgress;
  14191     }
  14192     if ((stat == bcmVlanStatIngressPackets) ||
  14193         (stat == bcmVlanStatEgressPackets)) {
  14194         byte_flag=0;
  14195     } else {
  14196         byte_flag=1;
  14197     }
  14198     
  14199     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_stat_get_table_info(
  14200                         unit, port,key_type,outer_vlan,inner_vlan,
  14201                         &num_of_tables,&table_info[0]));
  14202 
  14203     for (table_count=0; table_count < num_of_tables ; table_count++) {
  14204          if (table_info[table_count].direction == direction) {
  14205              for (index_count=0; index_count < num_entries ; index_count++) {
  14206                   BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_set(
  14207                                       unit, table_info[table_count].index,
  14208                                       table_info[table_count].table, 0,
  14209                                       byte_flag,
  14210                                       counter_indexes[index_count],
  14211                                       &counter_values[index_count]));
  14212              }
  14213          }
  14214     }
  14215     return BCM_E_NONE;
  14216 }
  14217 #endif
  14218 
  14219 /* Function:
  14220  *      bcm_esw_vlan_translate_stat_counter_set
  14221  * Description:
  14222  *      Set counter values into a ingress vlan translation table
  14223  *
  14224  * Parameters:
  14225  *      unit             - (IN) unit number
  14226  *      Port             - (IN) GPORT (global port) identifier
  14227  *      key_type         - (IN) VLAN translation key type
  14228  *      outer_vlan       - (IN) Outer VLAN ID or tag
  14229  *      inner_vlan       - (IN) Inner VLAN ID or tag
  14230  *      stat             - (IN) Type of the counter to retrieve
  14231  *                              I.e. ingress/egress byte/packet)
  14232  *      num_entries      - (IN) Number of counter Entries
  14233  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  14234  *      counter_values   - (IN) Pointer to counter values
  14235  *
  14236  * Return Value:
  14237  *      BCM_E_XXX
  14238  * Notes:
  14239  */
  14240 int bcm_esw_vlan_translate_stat_counter_set(
  14241             int                      unit,
  14242             bcm_gport_t              port,
  14243             bcm_vlan_translate_key_t key_type,
  14244             bcm_vlan_t               outer_vlan,
  14245             bcm_vlan_t               inner_vlan,
  14246             bcm_vlan_stat_t          stat,
  14247             uint32                   num_entries,
  14248             uint32                   *counter_indexes,
  14249             bcm_stat_value_t         *counter_values)
  14250 {
  14251 #ifdef BCM_TOMAHAWK3_SUPPORT
  14252     if (SOC_IS_TOMAHAWK3(unit)) {
  14253         return BCM_E_UNAVAIL;
  14254     }
  14255 #endif
  14256 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  14257     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  14258         return _bcm_esw_vlan_translate_stat_counter_set(unit,port,key_type,
  14259                       outer_vlan,inner_vlan,stat,num_entries,
  14260                       counter_indexes,counter_values);
  14261     } else
  14262 #endif
  14263 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  14264     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  14265         uint64 val;
  14266         _bcm_flex_stat_handle_t vxlt_fsh;
  14267         int rv = BCM_E_NONE;
  14268 
  14269         if (stat == bcmVlanStatIngressPackets) {
  14270             COMPILER_64_SET(val,0,counter_values->packets);
  14271         } else {
  14272             COMPILER_64_SET(val,
  14273                       COMPILER_64_HI(counter_values->bytes),
  14274                       COMPILER_64_LO(counter_values->bytes));
  14275         }
  14276         BCM_IF_ERROR_RETURN
  14277             (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type,
  14278                                                   outer_vlan, inner_vlan,
  14279                                                   &vxlt_fsh));
  14280         rv =  _bcm_esw_flex_stat_ext_set(unit, _bcmFlexStatTypeVxlt,
  14281                 vxlt_fsh, _bcm_esw_vlan_translate_stat_to_flex_stat(stat),val);
  14282         return rv;
  14283 
  14284     } else
  14285 #endif
  14286 #if defined(BCM_HURRICANE3_SUPPORT)
  14287     if (soc_feature(unit, soc_feature_flowcnt)) {
  14288         return _bcm_hr3_vlan_translate_stat_counter_set(unit,port,key_type,
  14289                       outer_vlan,inner_vlan,stat,num_entries,
  14290                       counter_indexes,counter_values);
  14291     } else
  14292 #endif
  14293     {
  14294         return BCM_E_UNAVAIL;
  14295     }
  14296 
  14297 }
  14298 
  14299 /*
  14300  * Function:
  14301  *      bcm_esw_vlan_translate_stat_id_get
  14302  * Description:
  14303  *      Get stat counter id associated with given ingress vlan
  14304  *
  14305  * Parameters:
  14306  *      unit             - (IN) unit number
  14307  *      Port             - (IN) GPORT (global port) identifier  
  14308  *      key_type         - (IN) VLAN translation key type  
  14309  *      outer_vlan       - (IN) Outer VLAN ID or tag  
  14310  *      inner_vlan       - (IN) Inner VLAN ID or tag  
  14311  *      stat             - (IN) Type of the counter to retrieve
  14312  *                              I.e. ingress/egress byte/packet)
  14313  *      Stat_counter_id  - (OUT) Stat Counter ID
  14314  * Return Value:
  14315  *      BCM_E_XXX
  14316  * Notes:
  14317  */
  14318 int bcm_esw_vlan_translate_stat_id_get(
  14319             int                      unit,
  14320             bcm_gport_t              port,
  14321             bcm_vlan_translate_key_t key_type,
  14322             bcm_vlan_t               outer_vlan,
  14323             bcm_vlan_t               inner_vlan,
  14324             bcm_vlan_stat_t          stat,
  14325             uint32                   *stat_counter_id)
  14326 {
  14327 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  14328     bcm_stat_flex_direction_t  direction=bcmStatFlexDirectionIngress;
  14329     uint32                     num_of_tables=0;
  14330     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  14331     uint32                     index=0;
  14332     uint32                     num_stat_counter_ids=0;
  14333 #endif
  14334 
  14335 #ifdef BCM_TOMAHAWK3_SUPPORT
  14336     if (SOC_IS_TOMAHAWK3(unit)) {
  14337         return BCM_E_UNAVAIL;
  14338     }
  14339 #endif
  14340 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  14341     if (soc_feature(unit, soc_feature_advanced_flex_counter)) {
  14342         if ((stat == bcmVlanStatIngressPackets) ||
  14343             (stat == bcmVlanStatIngressBytes)) {
  14344              direction = bcmStatFlexDirectionIngress;
  14345         } else {
  14346              direction = bcmStatFlexDirectionEgress;
  14347         }
  14348         BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_stat_get_table_info(
  14349                             unit, port,key_type,outer_vlan,inner_vlan,
  14350                             &num_of_tables,&table_info[0]));
  14351         for (index=0; index < num_of_tables ; index++) {
  14352              if (table_info[index].direction == direction)
  14353                  return _bcm_esw_stat_flex_get_counter_id(
  14354                                       unit, 1, &table_info[index],
  14355                                       &num_stat_counter_ids,stat_counter_id);
  14356         }
  14357         return BCM_E_NOT_FOUND;
  14358     } else
  14359 #endif
  14360 #if defined(BCM_HURRICANE3_SUPPORT)
  14361     if (soc_feature(unit, soc_feature_flowcnt)) {
  14362         return _bcm_hr3_vlan_translate_stat_id_get(unit, port, key_type,
  14363                     outer_vlan, inner_vlan, stat, stat_counter_id);
  14364     } else
  14365 #endif
  14366     {
  14367         return BCM_E_UNAVAIL;
  14368     }
  14369 }
  14370 
  14371 /*
  14372  * Function:
  14373  *      _bcm_esw_vlan_translate_stat_get
  14374  * Purpose:
  14375  *      Extract ingress VLAN translation statistics from the chip.
  14376  *      if sync_mode is set, sync the sw accumulated count
  14377  *      with hw count value first, else return sw count.
  14378  *
  14379  * Parameters:
  14380  *      unit        - (IN) Unit number.
  14381  *      sync_mode   - (IN) Unit number.
  14382  *      port        - (IN) Generic port
  14383  *      key_type    - (IN) Key Type : bcmVlanTranslateKey*
  14384  *      outer_vlan  - (IN) Packet outer VLAN ID
  14385  *      inner_vlan  - (IN) Packet inner VLAN ID
  14386  *      stat        - (IN) Type of the counter to retrieve.
  14387  *      val         - (OUT) Pointer to a counter value.
  14388  * Returns:
  14389  *      BCM_E_xxx
  14390  * Notes:
  14391  */
  14392 int 
  14393 _bcm_esw_vlan_translate_stat_get(int unit, int sync_mode, bcm_gport_t port,
  14394                                  bcm_vlan_translate_key_t key_type,
  14395                                  bcm_vlan_t outer_vlan,
  14396                                  bcm_vlan_t inner_vlan,
  14397                                  bcm_vlan_stat_t stat,
  14398                                  uint64 *val)
  14399 {
  14400 #if defined(BCM_TRIUMPH2_SUPPORT)|| defined(BCM_TRIDENT_SUPPORT)
  14401     _bcm_flex_stat_handle_t vxlt_fsh;
  14402 #endif
  14403 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  14404     defined(BCM_HURRICANE3_SUPPORT)
  14405     uint32           counter_indexes=0;
  14406     bcm_stat_value_t counter_values={0};
  14407 #endif
  14408 
  14409 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  14410     if (soc_feature(unit, soc_feature_gport_service_counters)) {
  14411   
  14412         BCM_IF_ERROR_RETURN
  14413             (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type,
  14414                                                   outer_vlan, inner_vlan,
  14415                                                   &vxlt_fsh));
  14416         return _bcm_esw_flex_stat_ext_get(unit, sync_mode, _bcmFlexStatTypeVxlt,
  14417                                       vxlt_fsh,
  14418                            _bcm_esw_vlan_translate_stat_to_flex_stat(stat),
  14419                                       val);
  14420     } else
  14421 #endif
  14422 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  14423     defined(BCM_HURRICANE3_SUPPORT)
  14424     if (soc_feature(unit, soc_feature_advanced_flex_counter) ||
  14425         soc_feature(unit, soc_feature_flowcnt)) {
  14426         BCM_IF_ERROR_RETURN(
  14427             bcm_esw_vlan_xslate_stat_counter_get(unit, sync_mode, 
  14428                                                  port, key_type,
  14429                                                  outer_vlan,
  14430                                                  inner_vlan, 
  14431                                                  stat, 1, 
  14432                                                  &counter_indexes,
  14433                                                  &counter_values));
  14434 
  14435         if ((stat == bcmVlanStatIngressPackets) ||
  14436             (stat == bcmVlanStatEgressPackets)) {
  14437             COMPILER_64_SET(*val,
  14438                          COMPILER_64_HI(counter_values.packets64),
  14439                          COMPILER_64_LO(counter_values.packets64));
  14440         } else {
  14441             COMPILER_64_SET(*val,
  14442                          COMPILER_64_HI(counter_values.bytes),
  14443                          COMPILER_64_LO(counter_values.bytes));
  14444         }
  14445         return BCM_E_NONE;
  14446     } else
  14447 #endif
  14448     {
  14449         return BCM_E_UNAVAIL;
  14450     }
  14451 }
  14452 
  14453 /*
  14454  * Function:
  14455  *      bcm_esw_vlan_translate_stat_get
  14456  * Purpose:
  14457  *      Extract ingress VLAN translation statistics from the chip.
  14458  * Parameters:
  14459  *      unit - (IN) Unit number.
  14460  *      port - (IN) Generic port
  14461  *      key_type - (IN) Key Type : bcmVlanTranslateKey*
  14462  *      outer_vlan - (IN) Packet outer VLAN ID
  14463  *      inner_vlan - (IN) Packet inner VLAN ID
  14464  *      stat - (IN) Type of the counter to retrieve.
  14465  *      val - (OUT) Pointer to a counter value.
  14466  * Returns:
  14467  *      BCM_E_xxx
  14468  * Notes:
  14469  */
  14470 int 
  14471 bcm_esw_vlan_translate_stat_get(int unit, bcm_gport_t port,
  14472                                 bcm_vlan_translate_key_t key_type,
  14473                                 bcm_vlan_t outer_vlan,
  14474                                 bcm_vlan_t inner_vlan,
  14475                                 bcm_vlan_stat_t stat,
  14476                                 uint64 *val)
  14477 {
  14478     int rv = BCM_E_NONE;
  14479 
  14480 #ifdef BCM_TOMAHAWK3_SUPPORT
  14481     if (SOC_IS_TOMAHAWK3(unit)) {
  14482         return BCM_E_UNAVAIL;
  14483     }
  14484 #endif
  14485 
  14486     rv = _bcm_esw_vlan_translate_stat_get(unit, 0, port, key_type, outer_vlan,
  14487                                           inner_vlan, stat, val);
  14488 
  14489     return rv;
  14490 }
  14491 
  14492 /*
  14493  * Function:
  14494  *      bcm_esw_vlan_translate_stat_sync_get
  14495  * Purpose:
  14496  *      Extract ingress VLAN translation statistics from the chip.
  14497  *      sw accumulated counters synced with hw count.
  14498  *
  14499  * Parameters:
  14500  *      unit - (IN) Unit number.
  14501  *      port - (IN) Generic port
  14502  *      key_type - (IN) Key Type : bcmVlanTranslateKey*
  14503  *      outer_vlan - (IN) Packet outer VLAN ID
  14504  *      inner_vlan - (IN) Packet inner VLAN ID
  14505  *      stat - (IN) Type of the counter to retrieve.
  14506  *      val - (OUT) Pointer to a counter value.
  14507  * Returns:
  14508  *      BCM_E_xxx
  14509  * Notes:
  14510  */
  14511 int 
  14512 bcm_esw_vlan_translate_stat_sync_get(int unit, bcm_gport_t port,
  14513                                      bcm_vlan_translate_key_t key_type,
  14514                                      bcm_vlan_t outer_vlan,
  14515                                      bcm_vlan_t inner_vlan,
  14516                                      bcm_vlan_stat_t stat,
  14517                                      uint64 *val)
  14518 {
  14519     int rv = BCM_E_NONE;
  14520 
  14521 #ifdef BCM_TOMAHAWK3_SUPPORT
  14522     if (SOC_IS_TOMAHAWK3(unit)) {
  14523         return BCM_E_UNAVAIL;
  14524     }
  14525 #endif
  14526 
  14527     rv = _bcm_esw_vlan_translate_stat_get(unit, 1, port, key_type, outer_vlan,
  14528                                           inner_vlan, stat, val);
  14529 
  14530     return rv;
  14531 }
  14532 
  14533 /*
  14534  * Function:
  14535  *      _bcm_esw_vlan_translate_stat_get32
  14536  * Purpose:
  14537  *      Extract ingress VLAN translation statistics from the chip.
  14538  *      if sync_mode is set, sync the sw accumulated count
  14539  *      with hw count value first, else return sw count.
  14540  *
  14541  * Parameters:
  14542  *      unit       - (IN) Unit number.
  14543  *      sync_mode  - (IN) hwcount is to be synced to sw count
  14544  *      port       - (IN) Generic port
  14545  *      key_type   - (IN) Key Type : bcmVlanTranslateKey*
  14546  *      outer_vlan - (IN) Packet outer VLAN ID
  14547  *      inner_vlan - (IN) Packet inner VLAN ID
  14548  *      stat       - (IN) Type of the counter to retrieve.
  14549  *      val        - (OUT) Pointer to a counter value.
  14550  * Returns:
  14551  *      BCM_E_xxx
  14552  * Notes:
  14553  */
  14554 int 
  14555 _bcm_esw_vlan_translate_stat_get32(int unit, int sync_mode, bcm_gport_t port,
  14556                                    bcm_vlan_translate_key_t key_type,
  14557                                    bcm_vlan_t outer_vlan,
  14558                                    bcm_vlan_t inner_vlan,
  14559                                    bcm_vlan_stat_t stat,
  14560                                    uint32 *val)
  14561 {
  14562 #if defined(BCM_TRIUMPH2_SUPPORT)|| defined(BCM_TRIDENT_SUPPORT)
  14563     _bcm_flex_stat_handle_t vxlt_fsh;
  14564 #endif
  14565 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  14566     defined(BCM_HURRICANE3_SUPPORT)
  14567     uint32           counter_indexes=0;
  14568     bcm_stat_value_t counter_values={0};
  14569 #endif
  14570 
  14571 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  14572     if (soc_feature(unit, soc_feature_gport_service_counters)) {        
  14573         BCM_IF_ERROR_RETURN
  14574             (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type,
  14575                                                       outer_vlan, inner_vlan,
  14576                                                       &vxlt_fsh));
  14577         return _bcm_esw_flex_stat_ext_get32(unit, sync_mode, _bcmFlexStatTypeVxlt,
  14578                                         vxlt_fsh,
  14579                            _bcm_esw_vlan_translate_stat_to_flex_stat(stat),
  14580                                          val);
  14581     } else
  14582 #endif        
  14583 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  14584     defined(BCM_HURRICANE3_SUPPORT)
  14585     if (soc_feature(unit, soc_feature_advanced_flex_counter) ||
  14586         soc_feature(unit, soc_feature_flowcnt)) {
  14587         BCM_IF_ERROR_RETURN(bcm_esw_vlan_xslate_stat_counter_get(unit, sync_mode, 
  14588                                                              port, key_type,
  14589                                                              outer_vlan,
  14590                                                              inner_vlan, stat,
  14591                                                              1, 
  14592                                                              &counter_indexes, 
  14593                                                              &counter_values));
  14594         if ((stat == bcmVlanStatIngressPackets) ||
  14595             (stat == bcmVlanStatEgressPackets)) {
  14596              *val = counter_values.packets;
  14597         } else {
  14598              /* Ignoring Hi bytes value */
  14599              *val = COMPILER_64_LO(counter_values.bytes);
  14600         }
  14601         return BCM_E_NONE;
  14602     } else
  14603 #endif
  14604     {
  14605         return BCM_E_UNAVAIL;
  14606     }
  14607 }
  14608 
  14609 /*
  14610  * Function:
  14611  *      bcm_esw_vlan_translate_stat_get32
  14612  * Purpose:
  14613  *      Extract ingress VLAN translation statistics from the chip.
  14614  * Parameters:
  14615  *      unit - (IN) Unit number.
  14616  *      port - (IN) Generic port
  14617  *      key_type - (IN) Key Type : bcmVlanTranslateKey*
  14618  *      outer_vlan - (IN) Packet outer VLAN ID
  14619  *      inner_vlan - (IN) Packet inner VLAN ID
  14620  *      stat - (IN) Type of the counter to retrieve.
  14621  *      val - (OUT) Pointer to a counter value.
  14622  * Returns:
  14623  *      BCM_E_xxx
  14624  * Notes:
  14625  */
  14626 int 
  14627 bcm_esw_vlan_translate_stat_get32(int unit, bcm_gport_t port,
  14628                                   bcm_vlan_translate_key_t key_type,
  14629                                   bcm_vlan_t outer_vlan,
  14630                                   bcm_vlan_t inner_vlan,
  14631                                   bcm_vlan_stat_t stat,
  14632                                   uint32 *val)
  14633 {
  14634     int rv = BCM_E_NONE;
  14635 
  14636 #ifdef BCM_TOMAHAWK3_SUPPORT
  14637     if (SOC_IS_TOMAHAWK3(unit)) {
  14638         return BCM_E_UNAVAIL;
  14639     }
  14640 #endif
  14641 
  14642     rv = _bcm_esw_vlan_translate_stat_get32(unit, 0, port, key_type, outer_vlan,
  14643                                             inner_vlan, stat, val);
  14644     return rv;
  14645 }
  14646 
  14647 /*
  14648  * Function:
  14649  *      bcm_esw_vlan_translate_stat_sync_get32
  14650  * Purpose:
  14651  *      Extract ingress VLAN translation statistics from the chip.
  14652  *      sw accumulated counters synced with hw count.
  14653  *
  14654  * Parameters:
  14655  *      unit - (IN) Unit number.
  14656  *      port - (IN) Generic port
  14657  *      key_type - (IN) Key Type : bcmVlanTranslateKey*
  14658  *      outer_vlan - (IN) Packet outer VLAN ID
  14659  *      inner_vlan - (IN) Packet inner VLAN ID
  14660  *      stat - (IN) Type of the counter to retrieve.
  14661  *      val - (OUT) Pointer to a counter value.
  14662  * Returns:
  14663  *      BCM_E_xxx
  14664  * Notes:
  14665  */
  14666 int 
  14667 bcm_esw_vlan_translate_stat_sync_get32(int unit, bcm_gport_t port,
  14668                                        bcm_vlan_translate_key_t key_type,
  14669                                        bcm_vlan_t outer_vlan,
  14670                                        bcm_vlan_t inner_vlan,
  14671                                        bcm_vlan_stat_t stat,
  14672                                        uint32 *val)
  14673 {
  14674     int rv = BCM_E_NONE;
  14675 
  14676 #ifdef BCM_TOMAHAWK3_SUPPORT
  14677     if (SOC_IS_TOMAHAWK3(unit)) {
  14678         return BCM_E_UNAVAIL;
  14679     }
  14680 #endif
  14681 
  14682     rv = _bcm_esw_vlan_translate_stat_get32(unit, 1, port, key_type, outer_vlan,
  14683                                             inner_vlan, stat, val);
  14684     return rv;
  14685 }
  14686 
  14687 /*
  14688  * Function:
  14689  *      bcm_esw_vlan_translate_stat_set
  14690  * Purpose:
  14691  *      Set the specified statistic to the indicated value for the
  14692  *      specified ingress VLAN translation.
  14693  * Parameters:
  14694  *      unit - (IN) Unit number.
  14695  *      port - (IN) Generic port
  14696  *      key_type - (IN) Key Type : bcmVlanTranslateKey*
  14697  *      outer_vlan - (IN) Packet outer VLAN ID
  14698  *      inner_vlan - (IN) Packet inner VLAN ID
  14699  *      stat - (IN) Type of the counter to set.
  14700  *      val - (IN) New counter value.
  14701  * Returns:
  14702  *      BCM_E_xxx
  14703  * Notes:
  14704  */
  14705 int 
  14706 bcm_esw_vlan_translate_stat_set(int unit, bcm_gport_t port,
  14707                                 bcm_vlan_translate_key_t key_type,
  14708                                 bcm_vlan_t outer_vlan,
  14709                                 bcm_vlan_t inner_vlan,
  14710                                 bcm_vlan_stat_t stat,
  14711                                 uint64 val)
  14712 {
  14713 #if defined(BCM_TRIUMPH2_SUPPORT)
  14714     _bcm_flex_stat_handle_t vxlt_fsh;
  14715 #endif    
  14716 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  14717     defined(BCM_HURRICANE3_SUPPORT)
  14718     uint32           counter_indexes=0;
  14719     bcm_stat_value_t counter_values={0};
  14720 #endif
  14721 
  14722 #ifdef BCM_TOMAHAWK3_SUPPORT
  14723     if (SOC_IS_TOMAHAWK3(unit)) {
  14724         return BCM_E_UNAVAIL;
  14725     }
  14726 #endif
  14727 
  14728 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  14729     if (soc_feature(unit, soc_feature_gport_service_counters)) {
  14730         BCM_IF_ERROR_RETURN
  14731             (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type,
  14732                                                   outer_vlan, inner_vlan,
  14733                                                   &vxlt_fsh));
  14734         return _bcm_esw_flex_stat_ext_set(unit, _bcmFlexStatTypeVxlt,
  14735                                       vxlt_fsh,
  14736                            _bcm_esw_vlan_translate_stat_to_flex_stat(stat), val);
  14737     } else
  14738 #endif    
  14739 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  14740     defined(BCM_HURRICANE3_SUPPORT)
  14741     if (soc_feature(unit, soc_feature_advanced_flex_counter) ||
  14742         soc_feature(unit, soc_feature_flowcnt)) {    
  14743         if ((stat == bcmVlanStatIngressPackets) ||
  14744             (stat == bcmVlanStatEgressPackets)) {
  14745              counter_values.packets = COMPILER_64_LO(val);
  14746         } else {
  14747              COMPILER_64_SET(counter_values.bytes,
  14748                              COMPILER_64_HI(val),
  14749                              COMPILER_64_LO(val));
  14750         }
  14751         BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_stat_counter_set(
  14752                             unit,port,key_type,outer_vlan,inner_vlan,
  14753                             stat, 1, &counter_indexes, &counter_values));
  14754         return BCM_E_NONE;
  14755     } else
  14756 #endif
  14757     {
  14758        return BCM_E_UNAVAIL;
  14759     }
  14760 }
  14761 
  14762 /*
  14763  * Function:
  14764  *      bcm_esw_vlan_translate_stat_set32
  14765  * Purpose:
  14766  *      Set the specified statistic to the indicated value for the
  14767  *      specified ingress VLAN translation.
  14768  * Parameters:
  14769  *      unit - (IN) Unit number.
  14770  *      port - (IN) Generic port
  14771  *      key_type - (IN) Key Type : bcmVlanTranslateKey*
  14772  *      outer_vlan - (IN) Packet outer VLAN ID
  14773  *      inner_vlan - (IN) Packet inner VLAN ID
  14774  *      stat - (IN) Type of the counter to set.
  14775  *      val - (IN) New counter value.
  14776  * Returns:
  14777  *      BCM_E_xxx
  14778  * Notes:
  14779  */
  14780 int 
  14781 bcm_esw_vlan_translate_stat_set32(int unit, bcm_gport_t port,
  14782                                   bcm_vlan_translate_key_t key_type,
  14783                                   bcm_vlan_t outer_vlan,
  14784                                   bcm_vlan_t inner_vlan,
  14785                                   bcm_vlan_stat_t stat,
  14786                                   uint32 val)
  14787 {
  14788 #if defined(BCM_TRIUMPH2_SUPPORT)|| defined(BCM_TRIDENT_SUPPORT)
  14789     _bcm_flex_stat_handle_t vxlt_fsh;
  14790 #endif    
  14791 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  14792     defined(BCM_HURRICANE3_SUPPORT)
  14793     uint32           counter_indexes=0;
  14794     bcm_stat_value_t counter_values={0};
  14795 #endif
  14796 
  14797 #ifdef BCM_TOMAHAWK3_SUPPORT
  14798     if (SOC_IS_TOMAHAWK3(unit)) {
  14799         return BCM_E_UNAVAIL;
  14800     }
  14801 #endif
  14802 
  14803 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  14804     if (soc_feature(unit, soc_feature_gport_service_counters)) {
  14805           
  14806         BCM_IF_ERROR_RETURN
  14807             (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type,
  14808                                                   outer_vlan, inner_vlan,
  14809                                                   &vxlt_fsh));
  14810         return _bcm_esw_flex_stat_ext_set32(unit, _bcmFlexStatTypeVxlt,
  14811                                         vxlt_fsh,
  14812                            _bcm_esw_vlan_translate_stat_to_flex_stat(stat), val);
  14813     } else 
  14814 #endif    
  14815 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  14816     defined(BCM_HURRICANE3_SUPPORT)
  14817     if (soc_feature(unit, soc_feature_advanced_flex_counter) ||
  14818         soc_feature(unit, soc_feature_flowcnt)) {
  14819         if ((stat == bcmVlanStatIngressPackets) ||
  14820             (stat == bcmVlanStatEgressPackets)) {
  14821             counter_values.packets = val;
  14822         } else {
  14823             /* Ignoring high value */
  14824             COMPILER_64_SET(counter_values.bytes,0,val);
  14825         }
  14826         BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_stat_counter_set(
  14827                         unit,port,key_type,outer_vlan,inner_vlan,
  14828                         stat, 1, &counter_indexes, &counter_values));
  14829         return BCM_E_NONE;
  14830     } else
  14831 #endif
  14832     {
  14833         return BCM_E_UNAVAIL;
  14834     }
  14835 }
  14836 
  14837 /*
  14838  * Function:
  14839  *      bcm_esw_vlan_translate_stat_multi_get
  14840  * Purpose:
  14841  *      Get 64-bit counter value for multiple ingress VLAN translation
  14842  *      statistic types.
  14843  * Parameters:
  14844  *      unit - (IN) Unit number.
  14845  *      port - (IN) Generic port
  14846  *      key_type - (IN) Key Type : bcmVlanTranslateKey*
  14847  *      outer_vlan - (IN) Packet outer VLAN ID
  14848  *      inner_vlan - (IN) Packet inner VLAN ID
  14849  *      nstat - (IN) Number of elements in stat array
  14850  *      stat_arr - (IN) Collected statistics descriptors array
  14851  *      value_arr - (OUT) Collected counters values
  14852  * Returns:
  14853  *      BCM_E_xxx
  14854  * Notes:
  14855  */
  14856 int 
  14857 bcm_esw_vlan_translate_stat_multi_get(int unit, bcm_gport_t port,
  14858                                       bcm_vlan_translate_key_t key_type,
  14859                                       bcm_vlan_t outer_vlan,
  14860                                       bcm_vlan_t inner_vlan,
  14861                                       int nstat,
  14862                                       bcm_vlan_stat_t *stat_arr,
  14863                                       uint64 *value_arr)
  14864 {
  14865 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  14866     _bcm_flex_stat_handle_t vxlt_fsh;
  14867     _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */
  14868     int idx;
  14869 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  14870     defined(BCM_HURRICANE3_SUPPORT)
  14871     uint32           counter_indexes=0;
  14872     bcm_stat_value_t counter_values={0};
  14873 #endif
  14874 
  14875 #ifdef BCM_TOMAHAWK3_SUPPORT
  14876     if (SOC_IS_TOMAHAWK3(unit)) {
  14877         return BCM_E_UNAVAIL;
  14878     }
  14879 #endif
  14880 
  14881     if (soc_feature(unit, soc_feature_gport_service_counters)) {
  14882         BCM_IF_ERROR_RETURN
  14883             (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type,
  14884                                                   outer_vlan, inner_vlan,
  14885                                                   &vxlt_fsh));
  14886         BCM_IF_ERROR_RETURN
  14887             (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr,
  14888                    fs_arr, &_bcm_esw_vlan_translate_stat_to_flex_stat));
  14889         BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr);
  14890 
  14891         return _bcm_esw_flex_stat_ext_multi_get(unit, _bcmFlexStatTypeVxlt,
  14892                                             vxlt_fsh,
  14893                                         nstat, fs_arr, value_arr);
  14894     } else 
  14895 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  14896     defined(BCM_HURRICANE3_SUPPORT)
  14897     if (soc_feature(unit, soc_feature_advanced_flex_counter) ||
  14898         soc_feature(unit, soc_feature_flowcnt)) {
  14899         for (idx=0;idx < nstat ; idx ++) {
  14900              BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_stat_counter_get(
  14901                              unit,port,key_type,outer_vlan,inner_vlan,
  14902                              stat_arr[idx],1,&counter_indexes,&counter_values));
  14903             if ((stat_arr[idx] == bcmVlanStatIngressPackets) ||
  14904                 (stat_arr[idx] == bcmVlanStatEgressPackets)) {
  14905                 COMPILER_64_SET(value_arr[idx],
  14906                               COMPILER_64_HI(counter_values.packets64),
  14907                               COMPILER_64_LO(counter_values.packets64));
  14908             } else {
  14909                 COMPILER_64_SET(value_arr[idx],
  14910                               COMPILER_64_HI(counter_values.bytes),
  14911                               COMPILER_64_LO(counter_values.bytes));
  14912             }
  14913         }
  14914         return BCM_E_NONE;
  14915     } else
  14916 #endif
  14917 #endif
  14918     {
  14919         return BCM_E_UNAVAIL;
  14920     }
  14921 }
  14922 
  14923 /*
  14924  * Function:
  14925  *      bcm_esw_vlan_translate_stat_multi_get32
  14926  * Purpose:
  14927  *      Get lower 32-bit counter value for multiple ingress VLAN
  14928  *      translation statistic types.
  14929  * Parameters:
  14930  *      unit - (IN) Unit number.
  14931  *      port - (IN) Generic port
  14932  *      key_type - (IN) Key Type : bcmVlanTranslateKey*
  14933  *      outer_vlan - (IN) Packet outer VLAN ID
  14934  *      inner_vlan - (IN) Packet inner VLAN ID
  14935  *      nstat - (IN) Number of elements in stat array
  14936  *      stat_arr - (IN) Collected statistics descriptors array
  14937  *      value_arr - (OUT) Collected counters values
  14938  * Returns:
  14939  *      BCM_E_xxx
  14940  * Notes:
  14941  */
  14942 int 
  14943 bcm_esw_vlan_translate_stat_multi_get32(int unit, bcm_gport_t port,
  14944                                         bcm_vlan_translate_key_t key_type,
  14945                                         bcm_vlan_t outer_vlan,
  14946                                         bcm_vlan_t inner_vlan,
  14947                                         int nstat,
  14948                                         bcm_vlan_stat_t *stat_arr,
  14949                                         uint32 *value_arr)
  14950 {
  14951 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  14952     _bcm_flex_stat_handle_t vxlt_fsh;
  14953     _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */
  14954     int idx;
  14955 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  14956     defined(BCM_HURRICANE3_SUPPORT)
  14957     uint32           counter_indexes=0;
  14958     bcm_stat_value_t counter_values={0};
  14959 #endif
  14960 
  14961 #ifdef BCM_TOMAHAWK3_SUPPORT
  14962     if (SOC_IS_TOMAHAWK3(unit)) {
  14963         return BCM_E_UNAVAIL;
  14964     }
  14965 #endif
  14966 
  14967     if (soc_feature(unit, soc_feature_gport_service_counters)) {
  14968         BCM_IF_ERROR_RETURN
  14969             (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type,
  14970                                                   outer_vlan, inner_vlan,
  14971                                                   &vxlt_fsh));
  14972         BCM_IF_ERROR_RETURN
  14973             (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr,
  14974                    fs_arr, &_bcm_esw_vlan_translate_stat_to_flex_stat));
  14975         BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr);
  14976 
  14977         return _bcm_esw_flex_stat_ext_multi_get32(unit, _bcmFlexStatTypeVxlt,
  14978                                               vxlt_fsh,
  14979                                         nstat, fs_arr, value_arr);
  14980     } else
  14981 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  14982     defined(BCM_HURRICANE3_SUPPORT)
  14983     if (soc_feature(unit, soc_feature_advanced_flex_counter) ||
  14984         soc_feature(unit, soc_feature_flowcnt)) {
  14985         for (idx=0;idx < nstat ; idx ++) {
  14986              BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_stat_counter_get(
  14987                                  unit,port,key_type,outer_vlan,inner_vlan,
  14988                                  stat_arr[idx],1,&counter_indexes,&counter_values));
  14989              if ((stat_arr[idx] == bcmVlanStatIngressPackets) ||
  14990                  (stat_arr[idx] == bcmVlanStatEgressPackets)) {
  14991                   value_arr[idx] = counter_values.packets;
  14992              } else {
  14993                   value_arr[idx] = COMPILER_64_LO(counter_values.bytes);
  14994              }
  14995         }
  14996         return BCM_E_NONE;
  14997     }
  14998 #endif
  14999 #endif
  15000     {
  15001         return BCM_E_UNAVAIL;
  15002     }
  15003 }
  15004 
  15005 /*
  15006  * Function:
  15007  *      bcm_esw_vlan_translate_stat_multi_set
  15008  * Purpose:
  15009  *      Set 64-bit counter value for multiple ingress VLAN translation
  15010  *      statistic types.
  15011  * Parameters:
  15012  *      unit - (IN) Unit number.
  15013  *      port - (IN) Generic port
  15014  *      key_type - (IN) Key Type : bcmVlanTranslateKey*
  15015  *      outer_vlan - (IN) Packet outer VLAN ID
  15016  *      inner_vlan - (IN) Packet inner VLAN ID
  15017  *      nstat - (IN) Number of elements in stat array
  15018  *      stat_arr - (IN) New statistics descriptors array
  15019  *      value_arr - (IN) New counters values
  15020  * Returns:
  15021  *      BCM_E_xxx
  15022  * Notes:
  15023  */
  15024 int 
  15025 bcm_esw_vlan_translate_stat_multi_set(int unit, bcm_gport_t port,
  15026                                       bcm_vlan_translate_key_t key_type,
  15027                                       bcm_vlan_t outer_vlan,
  15028                                       bcm_vlan_t inner_vlan,
  15029                                       int nstat,
  15030                                       bcm_vlan_stat_t *stat_arr,
  15031                                       uint64 *value_arr)
  15032 {
  15033 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  15034     _bcm_flex_stat_handle_t vxlt_fsh;
  15035     _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */
  15036     int idx;
  15037 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  15038     defined(BCM_HURRICANE3_SUPPORT)
  15039     uint32           counter_indexes=0;
  15040     bcm_stat_value_t counter_values={0};
  15041 #endif
  15042 
  15043 #ifdef BCM_TOMAHAWK3_SUPPORT
  15044     if (SOC_IS_TOMAHAWK3(unit)) {
  15045         return BCM_E_UNAVAIL;
  15046     }
  15047 #endif
  15048 
  15049     if (soc_feature(unit, soc_feature_gport_service_counters)) {      
  15050         BCM_IF_ERROR_RETURN
  15051             (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type,
  15052                                                       outer_vlan, inner_vlan,
  15053                                                       &vxlt_fsh));
  15054         BCM_IF_ERROR_RETURN
  15055             (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr,
  15056                        fs_arr, &_bcm_esw_vlan_translate_stat_to_flex_stat));
  15057         BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr);
  15058     
  15059         return _bcm_esw_flex_stat_ext_multi_set(unit, _bcmFlexStatTypeVxlt,
  15060                                                 vxlt_fsh,
  15061                                             nstat, fs_arr, value_arr);
  15062     } else    
  15063 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  15064     defined(BCM_HURRICANE3_SUPPORT)
  15065     if (soc_feature(unit, soc_feature_advanced_flex_counter) ||
  15066         soc_feature(unit, soc_feature_flowcnt)) {    
  15067         for (idx=0;idx < nstat ; idx ++) {
  15068              if ((stat_arr[idx] == bcmVlanStatIngressPackets) ||
  15069                  (stat_arr[idx] == bcmVlanStatEgressPackets)) {
  15070                   counter_values.packets = COMPILER_64_LO(value_arr[idx]);
  15071              } else {
  15072                   COMPILER_64_SET(counter_values.bytes,
  15073                                   COMPILER_64_HI(value_arr[idx]),
  15074                                   COMPILER_64_LO(value_arr[idx]));
  15075              }
  15076              BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_stat_counter_set(
  15077                                  unit,port,key_type,outer_vlan,inner_vlan,
  15078                                  stat_arr[idx],1,&counter_indexes,&counter_values));
  15079         }
  15080         return BCM_E_NONE;
  15081     } else
  15082 #endif
  15083 #endif
  15084     {
  15085         return BCM_E_UNAVAIL;
  15086     }
  15087 }
  15088 
  15089 /*
  15090  * Function:
  15091  *      bcm_esw_vlan_translate_stat_multi_set32
  15092  * Purpose:
  15093  *      Set lower 32-bit counter value for multiple ingress VLAN
  15094  *      translation statistic types.
  15095  * Parameters:
  15096  *      unit - (IN) Unit number.
  15097  *      port - (IN) Generic port
  15098  *      key_type - (IN) Key Type : bcmVlanTranslateKey*
  15099  *      outer_vlan - (IN) Packet outer VLAN ID
  15100  *      inner_vlan - (IN) Packet inner VLAN ID
  15101  *      nstat - (IN) Number of elements in stat array
  15102  *      stat_arr - (IN) New statistics descriptors array
  15103  *      value_arr - (IN) New counters values
  15104  * Returns:
  15105  *      BCM_E_xxx
  15106  * Notes:
  15107  */
  15108 int 
  15109 bcm_esw_vlan_translate_stat_multi_set32(int unit, bcm_gport_t port, 
  15110                                         bcm_vlan_translate_key_t key_type,
  15111                                         bcm_vlan_t outer_vlan,
  15112                                         bcm_vlan_t inner_vlan,
  15113                                         int nstat,
  15114                                         bcm_vlan_stat_t *stat_arr,
  15115                                         uint32 *value_arr)
  15116 {
  15117 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  15118     _bcm_flex_stat_handle_t vxlt_fsh;
  15119     _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */
  15120     int idx;
  15121 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  15122     defined(BCM_HURRICANE3_SUPPORT)
  15123     uint32           counter_indexes=0;
  15124     bcm_stat_value_t counter_values={0};
  15125 #endif
  15126 
  15127 #ifdef BCM_TOMAHAWK3_SUPPORT
  15128     if (SOC_IS_TOMAHAWK3(unit)) {
  15129         return BCM_E_UNAVAIL;
  15130     }
  15131 #endif
  15132 
  15133     if (soc_feature(unit, soc_feature_gport_service_counters)) {      
  15134         BCM_IF_ERROR_RETURN
  15135             (_bcm_esw_vlan_translate_stat_param_valid(unit, port, key_type,
  15136                                                       outer_vlan, inner_vlan,
  15137                                                       &vxlt_fsh));
  15138         BCM_IF_ERROR_RETURN
  15139             (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr,
  15140                        fs_arr, &_bcm_esw_vlan_translate_stat_to_flex_stat));
  15141         BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr);
  15142     
  15143         return _bcm_esw_flex_stat_ext_multi_set32(unit, _bcmFlexStatTypeVxlt,
  15144                                                   vxlt_fsh,
  15145                                             nstat, fs_arr, value_arr);
  15146     } else
  15147 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  15148     defined(BCM_HURRICANE3_SUPPORT)
  15149     if (soc_feature(unit, soc_feature_advanced_flex_counter) ||
  15150         soc_feature(unit, soc_feature_flowcnt)) {    
  15151         for (idx=0;idx < nstat ; idx ++) {
  15152              if ((stat_arr[idx] == bcmVlanStatIngressPackets) ||
  15153                  (stat_arr[idx] == bcmVlanStatEgressPackets)) {
  15154                   counter_values.packets = value_arr[idx];
  15155              } else {
  15156                   COMPILER_64_SET(counter_values.bytes,0,value_arr[idx]);
  15157              }
  15158              BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_stat_counter_set(
  15159                                  unit,port,key_type,outer_vlan,inner_vlan,
  15160                                  stat_arr[idx],1,&counter_indexes,&counter_values));
  15161         }
  15162         return BCM_E_NONE;
  15163     } else
  15164 #endif
  15165 #endif
  15166     {
  15167         return BCM_E_UNAVAIL;
  15168     }
  15169 }
  15170 
  15171 #if defined(BCM_TRIUMPH2_SUPPORT)
  15172 STATIC int
  15173 _bcm_esw_vlan_translate_egress_flex_stat_hw_index_set(int unit,
  15174                                      _bcm_flex_stat_handle_t handle,
  15175                                                int fs_idx, void *cookie)
  15176 {
  15177     egr_vlan_xlate_entry_t  vent, res_vent;
  15178     int rv, idx;
  15179     
  15180     _BCM_FLEX_STAT_HANDLE_COPY(vent, handle);
  15181 
  15182     soc_mem_lock(unit, EGR_VLAN_XLATEm);
  15183     rv = soc_mem_search(unit, EGR_VLAN_XLATEm, MEM_BLOCK_ALL, &idx, 
  15184                          &vent, &res_vent, 0);
  15185     if (BCM_SUCCESS(rv)) {
  15186         soc_mem_field32_set(unit, EGR_VLAN_XLATEm, &res_vent,
  15187                             VINTF_CTR_IDXf, fs_idx);
  15188         if (SOC_MEM_FIELD_VALID(unit, EGR_VLAN_XLATEm, USE_VINTF_CTR_IDXf)) {
  15189             soc_mem_field32_set(unit, EGR_VLAN_XLATEm, &res_vent,
  15190                                 USE_VINTF_CTR_IDXf, fs_idx > 0 ? 1 : 0);
  15191         }
  15192         rv = soc_mem_insert(unit, EGR_VLAN_XLATEm, MEM_BLOCK_ALL, &res_vent);
  15193         if (BCM_SUCCESS(rv)) {
  15194             /* We found it already, but didn't overwrite it?  The mem lock
  15195              * must have failed.  Not good. */
  15196             return BCM_E_INTERNAL;
  15197         } else if (BCM_E_EXISTS == rv) {
  15198             rv = BCM_E_NONE;
  15199         } /* Else retain failing rv value */
  15200     }
  15201     soc_mem_unlock(unit, EGR_VLAN_XLATEm);
  15202     return rv;
  15203 }
  15204 
  15205 STATIC _bcm_flex_stat_t
  15206 _bcm_esw_vlan_translate_egress_stat_to_flex_stat(bcm_vlan_stat_t stat)
  15207 {
  15208     _bcm_flex_stat_t flex_stat;
  15209 
  15210     /* No ingress stats for egress translations */
  15211     switch (stat) {
  15212     case bcmVlanStatEgressPackets:
  15213         flex_stat = _bcmFlexStatEgressPackets;
  15214         break;
  15215     case bcmVlanStatEgressBytes:
  15216         flex_stat = _bcmFlexStatEgressBytes;
  15217         break;
  15218     default:
  15219         flex_stat = _bcmFlexStatNum;
  15220     }
  15221 
  15222     return flex_stat;
  15223 }
  15224 
  15225 STATIC int
  15226 _bcm_esw_vlan_translate_egress_stat_param_valid(int unit, int port_class, 
  15227                                                 bcm_vlan_t outer_vlan,
  15228                                                 bcm_vlan_t inner_vlan,
  15229                                          _bcm_flex_stat_handle_t *vxlt_fsh)
  15230 {
  15231     egr_vlan_xlate_entry_t  vent;
  15232     bcm_module_t        modid;
  15233     bcm_trunk_t         tgid = -1;
  15234     int                 id = -1; 
  15235 
  15236     CHECK_INIT(unit);
  15237 
  15238     if (!soc_feature(unit, soc_feature_gport_service_counters)) {
  15239         return BCM_E_UNAVAIL;
  15240     }
  15241 
  15242     if (BCM_GPORT_IS_SET(port_class)) {
  15243         if (!BCM_GPORT_IS_TUNNEL(port_class)) {
  15244             BCM_IF_ERROR_RETURN(
  15245                 _bcm_esw_gport_resolve(unit, port_class, &modid, &port_class, 
  15246                                        &tgid, &id));
  15247         }
  15248         if ((-1 != tgid || -1 != id) && !BCM_GPORT_IS_TUNNEL(port_class)) {
  15249             return BCM_E_PORT;
  15250         }
  15251     } else {
  15252         if (!SOC_PORT_CLASS_VALID(unit, port_class)) { 
  15253             return BCM_E_PORT; 
  15254         }
  15255     }
  15256 
  15257     BCM_IF_ERROR_RETURN
  15258         (_bcm_trx_vlan_translate_egress_entry_assemble(unit, &vent,
  15259                                                        port_class,
  15260                                                        outer_vlan,
  15261                                                        inner_vlan));
  15262 
  15263     /* Fill handle for VTS info */
  15264     _BCM_FLEX_STAT_HANDLE_CLEAR(*vxlt_fsh);
  15265     /* This next step is a bit abusive, but we don't have an accessor
  15266      * which captures the full key description in the VLAN_XLATE table. */
  15267     _BCM_FLEX_STAT_HANDLE_COPY(*vxlt_fsh, vent);
  15268 
  15269     return BCM_E_NONE;
  15270 }
  15271 
  15272 #endif /* BCM_TRIUMPH2_SUPPORT */
  15273 
  15274 /*
  15275  * Function:
  15276  *      bcm_esw_vlan_translate_egress_stat_enable_set
  15277  * Purpose:
  15278  *      Enable/disable collection of statistics on the indicated
  15279  *      egress VLAN translation.
  15280  * Parameters:
  15281  *      unit - (IN) Unit number.
  15282  *      port_class - (IN) Group ID of ingress port
  15283  *      outer_vlan - (IN) Packet outer VLAN ID
  15284  *      inner_vlan - (IN) Packet inner VLAN ID
  15285  *      enable - (IN) Non-zero to enable counter collection, zero to disable.
  15286  * Returns:
  15287  *      BCM_E_xxx
  15288  * Notes:
  15289  */
  15290 int 
  15291 bcm_esw_vlan_translate_egress_stat_enable_set(int unit, int port_class, 
  15292                                               bcm_vlan_t outer_vlan,
  15293                                               bcm_vlan_t inner_vlan,
  15294                                               int enable)
  15295 {
  15296 #if defined(BCM_TRIUMPH2_SUPPORT)|| defined(BCM_TRIDENT_SUPPORT)
  15297     _bcm_flex_stat_handle_t vxlt_fsh;
  15298 #endif    
  15299 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  15300     uint32                     num_of_tables=0;
  15301     uint32                     num_stat_counter_ids=0;
  15302     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  15303     bcm_stat_object_t          object=bcmStatObjectIngPort;
  15304     uint32                     stat_counter_id[
  15305                                        BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]={0};
  15306     uint32                     num_entries=0;
  15307     int                        index=0;
  15308 #endif
  15309  
  15310 #ifdef BCM_TOMAHAWK3_SUPPORT
  15311     if (SOC_IS_TOMAHAWK3(unit)) {
  15312         return BCM_E_UNAVAIL;
  15313     }
  15314 #endif
  15315 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  15316     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  15317         BCM_IF_ERROR_RETURN
  15318             (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class,
  15319                                                       outer_vlan, inner_vlan,
  15320                                                       &vxlt_fsh));
  15321         return _bcm_esw_flex_stat_ext_enable_set(unit, _bcmFlexStatTypeVxlt,
  15322                         _bcm_esw_vlan_translate_egress_flex_stat_hw_index_set,
  15323                                                  NULL, vxlt_fsh, enable,0);
  15324     } else
  15325 #endif        
  15326 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  15327     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  15328         BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_egress_stat_get_table_info(
  15329                             unit,port_class,
  15330                             outer_vlan,inner_vlan,
  15331                             &num_of_tables,&table_info[0]));
  15332         if (enable) {
  15333             for(index=0;index < num_of_tables ;index++) {
  15334                 if(table_info[index].direction == bcmStatFlexDirectionIngress) {
  15335                    BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_ingress_object(
  15336                                        unit,table_info[index].table,
  15337                                        table_info[index].index,NULL,&object));
  15338                 } else {
  15339                     BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_egress_object(
  15340                                         unit,table_info[index].table,
  15341                                         table_info[index].index,NULL,&object));
  15342                 }
  15343                 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_create(
  15344                                     unit,object,bcmStatGroupModeSingle,
  15345                                     &stat_counter_id[table_info[index].direction],
  15346                                     &num_entries));
  15347                 BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_egress_stat_attach(
  15348                                     unit,port_class,outer_vlan,inner_vlan,
  15349                                     stat_counter_id[table_info[index].direction]));
  15350             }
  15351             return BCM_E_NONE;
  15352         } else {
  15353             BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_counter_id(
  15354                                 unit, num_of_tables,&table_info[0],
  15355                                 &num_stat_counter_ids,&stat_counter_id[0]));
  15356             if ((stat_counter_id[bcmStatFlexDirectionIngress] == 0) &&
  15357                 (stat_counter_id[bcmStatFlexDirectionEgress] == 0)) {
  15358                  return BCM_E_PARAM;
  15359             }
  15360             BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_egress_stat_detach(
  15361                                 unit,port_class,outer_vlan,inner_vlan));
  15362             if (stat_counter_id[bcmStatFlexDirectionIngress] != 0) {
  15363                 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy(
  15364                                     unit,
  15365                                     stat_counter_id[bcmStatFlexDirectionIngress]));
  15366             }
  15367             if (stat_counter_id[bcmStatFlexDirectionEgress] != 0) {
  15368                 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy(
  15369                                     unit,
  15370                                     stat_counter_id[bcmStatFlexDirectionEgress]));
  15371             }
  15372             return BCM_E_NONE;
  15373         }
  15374     } else
  15375 #endif
  15376 #if defined(BCM_HURRICANE3_SUPPORT)
  15377     if (soc_feature(unit, soc_feature_flowcnt)) {
  15378         return _bcm_hr3_vlan_translate_egress_stat_enable_set(unit, port_class,
  15379                    outer_vlan, inner_vlan, enable);
  15380 
  15381     } else
  15382 #endif
  15383     {
  15384         return BCM_E_UNAVAIL;
  15385     }}
  15386 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  15387 /*
  15388  * Function:
  15389  *      _bcm_esw_vlan_translate_egress_stat_get_table_info
  15390  * Description:
  15391  *      Provides relevant flex table information(table-name,index with
  15392  *      direction)  for given egress vlan translation
  15393  *
  15394  * Parameters:
  15395  *      unit             - (IN) unit number
  15396  *      port_class       - (IN)    Port class 
  15397  *      outer_vlan       - (IN)    Outer VLAN ID 
  15398  *      inner_vlan       - (IN)    Inner VLAN ID  
  15399  *      num_of_tables    - (OUT) Number of flex counter tables
  15400  *      table_info       - (OUT) Flex counter tables information
  15401  *
  15402  * Return Value:
  15403  *      BCM_E_XXX
  15404  * Notes:
  15405  */
  15406 static 
  15407 bcm_error_t _bcm_esw_vlan_translate_egress_stat_get_table_info(
  15408             int                        unit, 
  15409             int                        port_class,
  15410             bcm_vlan_t                 outer_vlan,
  15411             bcm_vlan_t                 inner_vlan,
  15412             uint32                     *num_of_tables,
  15413             bcm_stat_flex_table_info_t *table_info)
  15414 {
  15415     soc_mem_t               mem = EGR_VLAN_XLATEm;
  15416     bcm_error_t            rv=BCM_E_NONE;
  15417     uint32                  vent[SOC_MAX_MEM_FIELD_WORDS];
  15418     uint32                  return_vent[SOC_MAX_MEM_FIELD_WORDS];
  15419     int                    index=0;
  15420     bcm_module_t           modid=0;
  15421     bcm_trunk_t            tgid = -1;
  15422     int                    id = -1;
  15423     int                    handle_modport_gport = 0;
  15424 
  15425     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) {
  15426         mem = EGR_VLAN_XLATE_1_DOUBLEm;
  15427     }
  15428     if (soc_feature(unit, soc_feature_egr_vxlate_supports_dgpp)) {
  15429         handle_modport_gport = 1;
  15430     }
  15431 
  15432     (*num_of_tables) = 0;
  15433 
  15434     if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  15435         return BCM_E_UNAVAIL;
  15436     }
  15437     if (BCM_GPORT_IS_SET(port_class)) {
  15438         if (!BCM_GPORT_IS_TUNNEL(port_class) &&
  15439             !BCM_GPORT_IS_VLAN_PORT(port_class) &&
  15440             !BCM_GPORT_IS_MIM_PORT(port_class) &&
  15441             !BCM_GPORT_IS_NIV_PORT(port_class) &&
  15442             !BCM_GPORT_IS_MPLS_PORT(port_class) &&
  15443             !BCM_GPORT_IS_VXLAN_PORT(port_class) &&
  15444             !BCM_GPORT_IS_EXTENDER_PORT(port_class) &&
  15445             !BCM_GPORT_IS_L2GRE_PORT(port_class) &&
  15446             !(handle_modport_gport &&
  15447               (BCM_GPORT_IS_MODPORT(port_class) ||
  15448               BCM_GPORT_IS_SUBPORT_PORT(port_class)))) {
  15449             BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(
  15450                                 unit, port_class, &modid, 
  15451                                 &port_class,&tgid, &id));
  15452         }
  15453         if ((-1 != tgid || -1 != id) &&
  15454             !BCM_GPORT_IS_TUNNEL(port_class) &&
  15455             !BCM_GPORT_IS_VLAN_PORT(port_class) &&
  15456             !BCM_GPORT_IS_MIM_PORT(port_class) &&
  15457             !BCM_GPORT_IS_NIV_PORT(port_class) &&
  15458             !BCM_GPORT_IS_MPLS_PORT(port_class) &&
  15459             !BCM_GPORT_IS_VXLAN_PORT(port_class) &&
  15460             !BCM_GPORT_IS_EXTENDER_PORT(port_class) &&
  15461             !BCM_GPORT_IS_L2GRE_PORT(port_class) ) {
  15462             return BCM_E_PORT;
  15463         }
  15464     } else  {
  15465         if (!SOC_PORT_CLASS_VALID(unit, port_class)) {
  15466             return BCM_E_PORT;
  15467         }
  15468     }
  15469     sal_memset(vent, 0, sizeof(vent));
  15470     sal_memset(return_vent, 0, sizeof(return_vent));
  15471     BCM_IF_ERROR_RETURN (_bcm_trx_vlan_translate_egress_entry_assemble(
  15472                          unit, vent, port_class, outer_vlan, inner_vlan));
  15473     soc_mem_lock(unit, mem);
  15474     rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, &index, vent, return_vent, 0);
  15475     if (BCM_SUCCESS(rv)) {
  15476         table_info[*num_of_tables].table=mem;
  15477         table_info[*num_of_tables].index=index;
  15478         table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress;
  15479         (*num_of_tables)++;
  15480     }
  15481     soc_mem_unlock(unit, mem);
  15482     return rv;
  15483 }
  15484 #endif
  15485 
  15486 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  15487 /*
  15488  * Function:
  15489  *      _bcm_esw_vlan_translate_egress_stat_attach
  15490  * Description:
  15491  *      Attach counters for the given egress vlan translation table
  15492  *
  15493  * Parameters:
  15494  *      unit             - (IN) unit number
  15495  *      port_class       - (IN)    Port class 
  15496  *      outer_vlan       - (IN)    Outer VLAN ID 
  15497  *      inner_vlan       - (IN)    Inner VLAN ID  
  15498  *      Stat_counter_id  -  (IN) Stat Counter ID.
  15499  *
  15500  * Return Value:
  15501  *      BCM_E_XXX
  15502  * Notes:
  15503  */
  15504 STATIC bcm_error_t _bcm_esw_vlan_translate_egress_stat_attach(
  15505             int        unit,
  15506             int        port_class,
  15507             bcm_vlan_t outer_vlan,
  15508             bcm_vlan_t inner_vlan,
  15509             uint32     stat_counter_id)
  15510 {
  15511     soc_mem_t                  table=0;
  15512     bcm_stat_flex_direction_t  direction=bcmStatFlexDirectionIngress;
  15513     uint32                     pool_number=0;
  15514     uint32                     base_index=0;
  15515     bcm_stat_flex_mode_t       offset_mode=0;
  15516     bcm_stat_object_t          object=bcmStatObjectIngPort;
  15517     bcm_stat_group_mode_t      group_mode= bcmStatGroupModeSingle;
  15518     uint32                     count=0;
  15519     uint32                     actual_num_tables=0;
  15520     uint32                     num_of_tables=0;
  15521     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  15522 
  15523     _bcm_esw_stat_get_counter_id_info(
  15524                   unit, stat_counter_id,
  15525                   &group_mode,&object,&offset_mode,&pool_number,&base_index);
  15526     BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit,object,&direction));
  15527     BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit,group_mode));
  15528     BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_table_info(
  15529                         unit,object,1,&actual_num_tables,&table,&direction));
  15530 
  15531     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_egress_stat_get_table_info(
  15532                         unit, port_class,outer_vlan,inner_vlan,
  15533                         &num_of_tables,&table_info[0]));
  15534     for (count=0; count < num_of_tables ; count++) {
  15535          if ((table_info[count].direction == direction) &&
  15536              (table_info[count].table == table) ) {
  15537               if (direction == bcmStatFlexDirectionIngress) {
  15538                   return _bcm_esw_stat_flex_attach_ingress_table_counters(
  15539                          unit, table_info[count].table, table_info[count].index,
  15540                          offset_mode, base_index, pool_number);
  15541               } else {
  15542                   return _bcm_esw_stat_flex_attach_egress_table_counters(
  15543                          unit, table_info[count].table, table_info[count].index,
  15544                          0, offset_mode, base_index, pool_number);
  15545               } 
  15546          }
  15547     }
  15548     return BCM_E_NOT_FOUND;
  15549 }
  15550 #endif
  15551 
  15552 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  15553 STATIC bcm_error_t _tr2_vlan_translate_egress_stat_attach(
  15554             int        unit,
  15555             int        port_class,
  15556             bcm_vlan_t outer_vlan,
  15557             bcm_vlan_t inner_vlan,
  15558             uint32     stat_counter_id,
  15559             int        attached)
  15560 {
  15561     _bcm_flex_stat_type_t fs_type;
  15562     _bcm_flex_stat_handle_t vxlt_fsh;
  15563     uint32 fs_inx;
  15564 
  15565     fs_type = _BCM_FLEX_STAT_TYPE(stat_counter_id);
  15566     fs_inx  = _BCM_FLEX_STAT_COUNT_INX(stat_counter_id);
  15567 
  15568     if (!((fs_type == _bcmFlexStatTypeEgrVxlt) && fs_inx)) {
  15569         return BCM_E_PARAM;
  15570     }
  15571     BCM_IF_ERROR_RETURN
  15572         (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class,
  15573                                                   outer_vlan, inner_vlan,
  15574                                                   &vxlt_fsh));
  15575     return _bcm_esw_flex_stat_ext_enable_set(unit, _bcmFlexStatTypeEgrVxlt,
  15576                     _bcm_esw_vlan_translate_egress_flex_stat_hw_index_set,
  15577                                         INT_TO_PTR(_BCM_FLEX_STAT_HW_EGRESS),
  15578                                             vxlt_fsh, attached,fs_inx);
  15579 }
  15580 #endif
  15581 
  15582 /*
  15583  * Function:
  15584  *      bcm_esw_vlan_translate_egress_stat_attach
  15585  * Description:
  15586  *      Attach counters for the given egress vlan translation table
  15587  *
  15588  * Parameters:
  15589  *      unit             - (IN) unit number
  15590  *      port_class       - (IN) Port class
  15591  *      outer_vlan       - (IN) Outer VLAN ID
  15592  *      inner_vlan       - (IN) Inner VLAN ID
  15593  *      Stat_counter_id  -  (IN) Stat Counter ID.
  15594  *
  15595  * Return Value:
  15596  *      BCM_E_XXX
  15597  * Notes:
  15598  */
  15599 int bcm_esw_vlan_translate_egress_stat_attach(
  15600             int        unit,
  15601             int        port_class,
  15602             bcm_vlan_t outer_vlan,
  15603             bcm_vlan_t inner_vlan,
  15604             uint32     stat_counter_id)
  15605 {
  15606 #ifdef BCM_TOMAHAWK3_SUPPORT
  15607     if (SOC_IS_TOMAHAWK3(unit)) {
  15608         return BCM_E_UNAVAIL;
  15609     }
  15610 #endif
  15611 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  15612     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  15613         return _bcm_esw_vlan_translate_egress_stat_attach(unit,
  15614                 port_class,outer_vlan,inner_vlan,stat_counter_id);
  15615     } else
  15616 #endif
  15617 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  15618     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  15619         return _tr2_vlan_translate_egress_stat_attach(unit,
  15620                 port_class,outer_vlan,inner_vlan,stat_counter_id,TRUE);
  15621     } else
  15622 #endif
  15623 #if defined(BCM_HURRICANE3_SUPPORT)
  15624     if (soc_feature(unit, soc_feature_flowcnt)) {
  15625         return _bcm_hr3_vlan_translate_egress_stat_attach(unit,
  15626                 port_class,outer_vlan,inner_vlan,stat_counter_id);
  15627     } else
  15628 #endif
  15629     {
  15630         return BCM_E_UNAVAIL;
  15631     }
  15632 }
  15633 
  15634 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  15635 /*
  15636  * Function:
  15637  *      _bcm_esw_vlan_translate_egress_stat_detach
  15638  * Description:
  15639  *      Detach counters for the given egress vlan translation table
  15640  *
  15641  * Parameters:
  15642  *      unit             - (IN) unit number
  15643  *      port_class       - (IN)    Port class 
  15644  *      outer_vlan       - (IN)    Outer VLAN ID 
  15645  *      inner_vlan       - (IN)    Inner VLAN ID  
  15646  *
  15647  * Return Value:
  15648  *      BCM_E_XXX
  15649  * Notes:
  15650  */
  15651 STATIC bcm_error_t _bcm_esw_vlan_translate_egress_stat_detach(
  15652             int unit,
  15653             int port_class,
  15654             bcm_vlan_t outer_vlan,
  15655             bcm_vlan_t inner_vlan)
  15656 {
  15657     uint32                     count=0;
  15658     uint32                     num_of_tables=0;
  15659     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  15660     bcm_error_t                rv = BCM_E_NONE;
  15661     bcm_error_t                err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE};
  15662 
  15663     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_egress_stat_get_table_info(
  15664                         unit, port_class,outer_vlan,inner_vlan,
  15665                         &num_of_tables,&table_info[0]));
  15666 
  15667     for (count=0; count < num_of_tables ; count++) {
  15668          if (table_info[count].direction == bcmStatFlexDirectionIngress) {
  15669              rv = _bcm_esw_stat_flex_detach_ingress_table_counters(
  15670                         unit, table_info[count].table, table_info[count].index);
  15671              if (BCM_E_NONE != rv &&
  15672                 BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) {
  15673                 err_code[bcmStatFlexDirectionIngress] = rv;
  15674              }
  15675          } else {
  15676              rv = _bcm_esw_stat_flex_detach_egress_table_counters(
  15677                         unit, 0, table_info[count].table, table_info[count].index);
  15678              if (BCM_E_NONE != rv &&
  15679                 BCM_E_NONE == err_code[bcmStatFlexDirectionEgress]) {
  15680                 err_code[bcmStatFlexDirectionEgress] = rv;
  15681              }
  15682          }
  15683     }
  15684     
  15685     BCM_STAT_FLEX_DETACH_RETURN(err_code)
  15686 }
  15687 #endif
  15688 
  15689 /*
  15690  * Function:
  15691  *      bcm_esw_vlan_translate_egress_stat_detach
  15692  * Description:
  15693  *      Detach counters for the given egress vlan translation table
  15694  *
  15695  * Parameters:
  15696  *      unit             - (IN) unit number
  15697  *      port_class       - (IN) Port class
  15698  *      outer_vlan       - (IN) Outer VLAN ID
  15699  *      inner_vlan       - (IN) Inner VLAN ID
  15700  *
  15701  * Return Value:
  15702  *      BCM_E_XXX
  15703  * Notes:
  15704  */
  15705 int bcm_esw_vlan_translate_egress_stat_detach(
  15706             int unit,
  15707             int port_class,
  15708             bcm_vlan_t outer_vlan,
  15709             bcm_vlan_t inner_vlan)
  15710 {
  15711 #ifdef BCM_TOMAHAWK3_SUPPORT
  15712     if (SOC_IS_TOMAHAWK3(unit)) {
  15713         return BCM_E_UNAVAIL;
  15714     }
  15715 #endif
  15716 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  15717     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  15718         return _bcm_esw_vlan_translate_egress_stat_detach(unit,
  15719                 port_class,outer_vlan,inner_vlan);
  15720     } else
  15721 #endif
  15722 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  15723     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  15724         return _tr2_vlan_translate_egress_stat_attach(unit,
  15725                 port_class,outer_vlan,inner_vlan,
  15726                 _BCM_FLEX_STAT_COUNT_ID(_bcmFlexStatTypeEgrVxlt,1),FALSE);
  15727     } else
  15728 #endif
  15729 #if defined(BCM_HURRICANE3_SUPPORT)
  15730     if (soc_feature(unit, soc_feature_flowcnt)) {
  15731         return _bcm_hr3_vlan_translate_egress_stat_detach(unit,
  15732                 port_class,outer_vlan,inner_vlan);
  15733     } else
  15734 #endif 
  15735     {
  15736         return BCM_E_UNAVAIL;
  15737     }
  15738 
  15739 }
  15740 
  15741 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  15742 /*
  15743  * Function:
  15744  *      _bcm_esw_vlan_translate_egress_stat_counter_get
  15745  * Description:
  15746  *      Get counter values from egress vlan translation table
  15747  *      if sync_mode is set, sync the sw accumulated count
  15748  *      with hw count value first, else return sw count.  
  15749  *
  15750  * Parameters:
  15751  *      unit             - (IN) unit number
  15752  *      sync_mode        - (IN) hwcount is to be synced to sw count 
  15753  *      port_class       - (IN)    Port class 
  15754  *      outer_vlan       - (IN)    Outer VLAN ID 
  15755  *      inner_vlan       - (IN)    Inner VLAN ID  
  15756  *      stat             - (IN) Type of the counter to retrieve
  15757  *                              I.e. ingress/egress byte/packet)
  15758  *      num_entries      - (IN) Number of counter Entries
  15759  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  15760  *      counter_values   - (OUT) Pointer to counter values
  15761  *
  15762  * Return Value:
  15763  *      BCM_E_XXX
  15764  * Notes:
  15765  */
  15766 STATIC bcm_error_t _bcm_esw_vlan_translate_egress_stat_counter_get(
  15767             int              unit,
  15768             int              sync_mode,
  15769             int              port_class,
  15770             bcm_vlan_t       outer_vlan,
  15771             bcm_vlan_t       inner_vlan,
  15772             bcm_vlan_stat_t  stat,
  15773             uint32           num_entries,
  15774             uint32           *counter_indexes,
  15775             bcm_stat_value_t *counter_values)
  15776 {
  15777     uint32                     table_count=0;
  15778     uint32                     index_count=0;
  15779     uint32                     num_of_tables=0;
  15780     bcm_stat_flex_direction_t  direction=bcmStatFlexDirectionIngress;
  15781     uint32                     byte_flag=0;
  15782     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  15783 
  15784     if ((stat == bcmVlanStatIngressPackets) ||
  15785         (stat == bcmVlanStatIngressBytes)) {
  15786          direction = bcmStatFlexDirectionIngress;
  15787     } else {
  15788          direction = bcmStatFlexDirectionEgress;
  15789     }
  15790     if ((stat == bcmVlanStatIngressPackets) ||
  15791         (stat == bcmVlanStatEgressPackets)) {
  15792         byte_flag=0;
  15793     } else {
  15794         byte_flag=1;
  15795     }
  15796     
  15797     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_egress_stat_get_table_info(
  15798                         unit, port_class,outer_vlan,inner_vlan,
  15799                         &num_of_tables,&table_info[0]));
  15800 
  15801     for (table_count=0; table_count < num_of_tables ; table_count++) {
  15802          if (table_info[table_count].direction == direction) {
  15803              for (index_count=0; index_count < num_entries ; index_count++) {
  15804                   BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_get(
  15805                                       unit, sync_mode, 
  15806                                       table_info[table_count].index,
  15807                                       table_info[table_count].table, 0,
  15808                                       byte_flag,
  15809                                       counter_indexes[index_count],
  15810                                       &counter_values[index_count]));
  15811              }
  15812          }
  15813     }
  15814     return BCM_E_NONE;
  15815 }
  15816 #endif
  15817 
  15818 /*
  15819  * Function:
  15820  *      _bcm_esw_vlan_xslate_egress_stat_counter_get
  15821  * Description:
  15822  *      Get counter values from egress vlan translation table
  15823  *      if sync_mode is set, sync the sw accumulated count
  15824  *      with hw count value first, else return sw count.  
  15825  *
  15826  * Parameters:
  15827  *      unit             - (IN) unit number
  15828  *      sync_mode        - (IN) hwcount is to be synced to sw count 
  15829  *      port_cLass       - (IN) Port class
  15830  *      outer_vlan       - (IN) Outer VLAN ID
  15831  *      inner_vlan       - (IN) Inner VLAN ID
  15832  *      stat             - (IN) Type of the counter to retrieve
  15833  *                              I.e. ingress/egress byte/packet)
  15834  *      num_entries      - (IN) Number of counter Entries
  15835  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  15836  *      counter_values   - (OUT) Pointer to counter values
  15837  *
  15838  * Return Value:
  15839  *      BCM_E_XXX
  15840  * Notes:
  15841  */
  15842 int  
  15843 _bcm_esw_vlan_xslate_egress_stat_counter_get(
  15844                                             int              unit,
  15845                                             int              sync_mode,
  15846                                             int              port_class,
  15847                                             bcm_vlan_t       outer_vlan,
  15848                                             bcm_vlan_t       inner_vlan,
  15849                                             bcm_vlan_stat_t  stat,
  15850                                             uint32           num_entries,
  15851                                             uint32           *counter_indexes,
  15852                                             bcm_stat_value_t *counter_values)
  15853 {
  15854 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  15855     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  15856         return _bcm_esw_vlan_translate_egress_stat_counter_get(unit, sync_mode,
  15857                 port_class,outer_vlan,inner_vlan,stat,
  15858                       num_entries,counter_indexes,counter_values);
  15859     } else
  15860 #endif
  15861 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  15862     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  15863         uint64 val;
  15864         _bcm_flex_stat_handle_t vxlt_fsh;
  15865         int rv = BCM_E_NONE;
  15866 
  15867         BCM_IF_ERROR_RETURN
  15868             (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class,
  15869                                          outer_vlan, inner_vlan, &vxlt_fsh)); 
  15870 
  15871         rv =  _bcm_esw_flex_stat_ext_get(unit, 0, _bcmFlexStatTypeEgrVxlt,
  15872                 vxlt_fsh,
  15873                 _bcm_esw_vlan_translate_egress_stat_to_flex_stat(stat), &val);
  15874 
  15875         if (stat == bcmVlanStatEgressPackets) {
  15876             counter_values->packets = COMPILER_64_LO(val);
  15877         } else {
  15878             COMPILER_64_SET(counter_values->bytes,
  15879                       COMPILER_64_HI(val),
  15880                       COMPILER_64_LO(val));
  15881         }
  15882         return rv;
  15883 
  15884     } else
  15885 #endif
  15886 #if defined(BCM_HURRICANE3_SUPPORT)
  15887     if (soc_feature(unit, soc_feature_flowcnt)) {
  15888         return _bcm_hr3_vlan_translate_egress_stat_counter_get(unit, sync_mode,
  15889                     port_class, outer_vlan, inner_vlan, stat, num_entries,
  15890                     counter_indexes, counter_values);
  15891     } else
  15892 #endif 
  15893     {
  15894         return BCM_E_UNAVAIL;
  15895     }
  15896 }
  15897 
  15898 
  15899 /*
  15900  * Function:
  15901  *      bcm_esw_vlan_translate_egress_stat_counter_get
  15902  * Description:
  15903  *      Get counter values from egress vlan translation table
  15904  *
  15905  * Parameters:
  15906  *      unit             - (IN) unit number
  15907  *      port_class       - (IN) Port class
  15908  *      outer_vlan       - (IN) Outer VLAN ID
  15909  *      inner_vlan       - (IN) Inner VLAN ID
  15910  *      stat             - (IN) Type of the counter to retrieve
  15911  *                              I.e. ingress/egress byte/packet)
  15912  *      num_entries      - (IN) Number of counter Entries
  15913  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  15914  *      counter_values   - (OUT) Pointer to counter values
  15915  *
  15916  * Return Value:
  15917  *      BCM_E_XXX
  15918  * Notes:
  15919  */
  15920 int 
  15921 bcm_esw_vlan_translate_egress_stat_counter_get(
  15922                                               int              unit,
  15923                                               int              port_class,
  15924                                               bcm_vlan_t       outer_vlan,
  15925                                               bcm_vlan_t       inner_vlan,
  15926                                               bcm_vlan_stat_t  stat,
  15927                                               uint32           num_entries,
  15928                                               uint32           *counter_indexes,
  15929                                               bcm_stat_value_t *counter_values)
  15930 {
  15931 #ifdef BCM_TOMAHAWK3_SUPPORT
  15932     if (SOC_IS_TOMAHAWK3(unit)) {
  15933         return BCM_E_UNAVAIL;
  15934     }
  15935 #endif
  15936     return _bcm_esw_vlan_xslate_egress_stat_counter_get(unit, 0, port_class,
  15937                                                      outer_vlan, inner_vlan,
  15938                                                      stat, num_entries,
  15939                                                      counter_indexes,
  15940                                                      counter_values);      
  15941 }
  15942 
  15943 
  15944 /*
  15945  * Function:
  15946  *      bcm_esw_vlan_translate_egress_stat_counter_sync_get
  15947  * Description:
  15948  *      Get counter values from egress vlan translation table
  15949  *      sw accumulated counters synced with hw count.
  15950  *
  15951  * Parameters:
  15952  *      unit             - (IN) unit number
  15953  *      port_class       - (IN) Port class
  15954  *      outer_vlan       - (IN) Outer VLAN ID
  15955  *      inner_vlan       - (IN) Inner VLAN ID
  15956  *      stat             - (IN) Type of the counter to retrieve
  15957  *                              I.e. ingress/egress byte/packet)
  15958  *      num_entries      - (IN) Number of counter Entries
  15959  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  15960  *      counter_values   - (OUT) Pointer to counter values
  15961  *
  15962  * Return Value:
  15963  *      BCM_E_XXX
  15964  * Notes:
  15965  */
  15966 int 
  15967 bcm_esw_vlan_translate_egress_stat_counter_sync_get(
  15968                                             int              unit,
  15969                                             int              port_class,
  15970                                             bcm_vlan_t       outer_vlan,
  15971                                             bcm_vlan_t       inner_vlan,
  15972                                             bcm_vlan_stat_t  stat,
  15973                                             uint32           num_entries,
  15974                                             uint32           *counter_indexes,
  15975                                             bcm_stat_value_t *counter_values)
  15976 {
  15977 #ifdef BCM_TOMAHAWK3_SUPPORT
  15978     if (SOC_IS_TOMAHAWK3(unit)) {
  15979         return BCM_E_UNAVAIL;
  15980     }
  15981 #endif
  15982     return _bcm_esw_vlan_xslate_egress_stat_counter_get(unit, 1, port_class,
  15983                                                      outer_vlan, inner_vlan,
  15984                                                      stat, num_entries,
  15985                                                      counter_indexes,
  15986                                                      counter_values);      
  15987 }
  15988 
  15989 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  15990 /*
  15991  * Function:
  15992  *      _bcm_esw_vlan_translate_egress_stat_counter_set
  15993  * Description:
  15994  *      Set counter values from egress vlan translation table . 
  15995  *
  15996  * Parameters:
  15997  *      unit             - (IN) unit number
  15998  *      port_class       - (IN)    Port class 
  15999  *      outer_vlan       - (IN)    Outer VLAN ID 
  16000  *      inner_vlan       - (IN)    Inner VLAN ID  
  16001  *      stat             - (IN) Type of the counter to retrieve
  16002  *                              I.e. ingress/egress byte/packet)
  16003  *      num_entries      - (IN) Number of counter Entries
  16004  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  16005  *      counter_values   - (IN) Pointer to counter values
  16006  *
  16007  * Return Value:
  16008  *      BCM_E_XXX
  16009  * Notes:
  16010  */
  16011 STATIC bcm_error_t _bcm_esw_vlan_translate_egress_stat_counter_set(
  16012             int              unit,
  16013             int              port_class,
  16014             bcm_vlan_t       outer_vlan,
  16015             bcm_vlan_t       inner_vlan,
  16016             bcm_vlan_stat_t  stat,
  16017             uint32           num_entries,
  16018             uint32           *counter_indexes,
  16019             bcm_stat_value_t *counter_values)
  16020 {
  16021     uint32                     table_count=0;
  16022     uint32                     index_count=0;
  16023     uint32                     num_of_tables=0;
  16024     bcm_stat_flex_direction_t  direction=bcmStatFlexDirectionIngress;
  16025     uint32                     byte_flag=0;
  16026     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  16027 
  16028     if ((stat == bcmVlanStatIngressPackets) ||
  16029         (stat == bcmVlanStatIngressBytes)) {
  16030          direction = bcmStatFlexDirectionIngress;
  16031     } else {
  16032          direction = bcmStatFlexDirectionEgress;
  16033     }
  16034     if ((stat == bcmVlanStatIngressPackets) ||
  16035         (stat == bcmVlanStatEgressPackets)) {
  16036         byte_flag=0;
  16037     } else {
  16038         byte_flag=1;
  16039     }
  16040     
  16041     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_egress_stat_get_table_info(
  16042                         unit, port_class,outer_vlan,inner_vlan,
  16043                         &num_of_tables,&table_info[0]));
  16044 
  16045     for (table_count=0; table_count < num_of_tables ; table_count++) {
  16046          if (table_info[table_count].direction == direction) {
  16047              for (index_count=0; index_count < num_entries ; index_count++) {
  16048                   BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_set(
  16049                                       unit, table_info[table_count].index,
  16050                                       table_info[table_count].table, 0,
  16051                                       byte_flag,
  16052                                       counter_indexes[index_count],
  16053                                       &counter_values[index_count]));
  16054              }
  16055          }
  16056     }
  16057     return BCM_E_NONE;
  16058 }
  16059 #endif
  16060 
  16061 /*
  16062  * Function:
  16063  *      bcm_esw_vlan_translate_egress_stat_counter_set
  16064  * Description:
  16065  *      Set counter values from egress vlan translation table .
  16066  *
  16067  * Parameters:
  16068  *      unit             - (IN) unit number
  16069  *      port_class       - (IN) Port class
  16070  *      outer_vlan       - (IN) Outer VLAN ID
  16071  *      inner_vlan       - (IN) Inner VLAN ID
  16072  *      stat             - (IN) Type of the counter to retrieve
  16073  *                              I.e. ingress/egress byte/packet)
  16074  *      num_entries      - (IN) Number of counter Entries
  16075  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  16076  *      counter_values   - (IN) Pointer to counter values
  16077  *
  16078  * Return Value:
  16079  *      BCM_E_XXX
  16080  * Notes:
  16081  */
  16082 int bcm_esw_vlan_translate_egress_stat_counter_set(
  16083             int              unit,
  16084             int              port_class,
  16085             bcm_vlan_t       outer_vlan,
  16086             bcm_vlan_t       inner_vlan,
  16087             bcm_vlan_stat_t  stat,
  16088             uint32           num_entries,
  16089             uint32           *counter_indexes,
  16090             bcm_stat_value_t *counter_values)
  16091 {
  16092 #ifdef BCM_TOMAHAWK3_SUPPORT
  16093     if (SOC_IS_TOMAHAWK3(unit)) {
  16094         return BCM_E_UNAVAIL;
  16095     }
  16096 #endif
  16097 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  16098     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  16099         return _bcm_esw_vlan_translate_egress_stat_counter_set(unit,
  16100                 port_class,outer_vlan,inner_vlan,stat,
  16101                       num_entries,counter_indexes,counter_values);
  16102     } else
  16103 #endif
  16104 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  16105     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  16106         uint64 val;
  16107         _bcm_flex_stat_handle_t vxlt_fsh;
  16108         int rv = BCM_E_NONE;
  16109 
  16110         BCM_IF_ERROR_RETURN
  16111             (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class,
  16112                                          outer_vlan, inner_vlan, &vxlt_fsh));
  16113         if (stat == bcmVlanStatEgressPackets) {
  16114             COMPILER_64_SET(val,0,counter_values->packets);
  16115         } else {
  16116             COMPILER_64_SET(val,
  16117                       COMPILER_64_HI(counter_values->bytes),
  16118                       COMPILER_64_LO(counter_values->bytes));
  16119         }
  16120 
  16121         rv =  _bcm_esw_flex_stat_ext_set(unit,_bcmFlexStatTypeEgrVxlt,
  16122                 vxlt_fsh,
  16123                 _bcm_esw_vlan_translate_egress_stat_to_flex_stat(stat), val);
  16124 
  16125         return rv;
  16126 
  16127     } else
  16128 #endif
  16129 #if defined(BCM_HURRICANE3_SUPPORT)
  16130     if (soc_feature(unit, soc_feature_flowcnt)) {
  16131         return _bcm_hr3_vlan_translate_egress_stat_counter_set(unit,
  16132                 port_class,outer_vlan,inner_vlan,stat,
  16133                       num_entries,counter_indexes,counter_values);
  16134     } else
  16135 #endif
  16136     {
  16137         return BCM_E_UNAVAIL;
  16138     }
  16139 }
  16140 
  16141 /*
  16142  * Function:
  16143  *      bcm_esw_vlan_translate_egress_stat_id_get
  16144  * Description:
  16145  *      Get stat counter id associated with given egress vlan
  16146  *
  16147  * Parameters:
  16148  *      unit             - (IN) unit number
  16149  *      port_class       - (IN)    Port class 
  16150  *      outer_vlan       - (IN)    Outer VLAN ID 
  16151  *      inner_vlan       - (IN)    Inner VLAN ID  
  16152  *      stat             - (IN) Type of the counter to retrieve
  16153  *                              I.e. ingress/egress byte/packet)
  16154  *      Stat_counter_id  - (OUT) Stat Counter ID
  16155  *
  16156  * Return Value:
  16157  *      BCM_E_XXX
  16158  * Notes:
  16159  */
  16160 int bcm_esw_vlan_translate_egress_stat_id_get(
  16161             int             unit,
  16162             int         port_class,
  16163             bcm_vlan_t         outer_vlan,
  16164             bcm_vlan_t      inner_vlan,
  16165             bcm_vlan_stat_t stat, 
  16166             uint32          *stat_counter_id)
  16167 {
  16168 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  16169     bcm_stat_flex_direction_t  direction=bcmStatFlexDirectionIngress;
  16170     uint32                     num_of_tables=0;
  16171     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  16172     uint32                     index=0;
  16173     uint32                     num_stat_counter_ids=0;
  16174 #endif
  16175 
  16176 #ifdef BCM_TOMAHAWK3_SUPPORT
  16177     if (SOC_IS_TOMAHAWK3(unit)) {
  16178         return BCM_E_UNAVAIL;
  16179     }
  16180 #endif
  16181 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  16182     if (soc_feature(unit, soc_feature_advanced_flex_counter)) {
  16183         if ((stat == bcmVlanStatIngressPackets) ||
  16184             (stat == bcmVlanStatIngressBytes)) {
  16185              direction = bcmStatFlexDirectionIngress;
  16186         } else {
  16187              direction = bcmStatFlexDirectionEgress;
  16188         }
  16189         BCM_IF_ERROR_RETURN(_bcm_esw_vlan_translate_egress_stat_get_table_info(
  16190                             unit, port_class,outer_vlan,inner_vlan,
  16191                             &num_of_tables,&table_info[0]));
  16192     
  16193         for (index=0; index < num_of_tables ; index++) {
  16194              if (table_info[index].direction == direction)
  16195                  return _bcm_esw_stat_flex_get_counter_id(
  16196                                       unit, 1, &table_info[index],
  16197                                       &num_stat_counter_ids,stat_counter_id);
  16198         }
  16199         return BCM_E_NOT_FOUND;
  16200     } else
  16201 #endif
  16202 #if defined(BCM_HURRICANE3_SUPPORT)
  16203     if (soc_feature(unit, soc_feature_flowcnt)) {
  16204         return _bcm_hr3_vlan_translate_egress_stat_id_get(unit, port_class,
  16205                     outer_vlan, inner_vlan, stat, stat_counter_id);
  16206     } else
  16207 #endif 
  16208     {   
  16209         return BCM_E_UNAVAIL;
  16210     }
  16211 }
  16212 
  16213 /*
  16214  * Function:
  16215  *      _bcm_esw_vlan_translate_egress_stat_get
  16216  * Purpose:
  16217  *      Extract egress VLAN translation statistics from the chip.
  16218  *      if sync_mode is set, sync the sw accumulated count
  16219  *      with hw count value first, else return sw count.
  16220  *
  16221  * Parameters:
  16222  *      unit - (IN) Unit number.
  16223  *      sync_mode  - (IN) hwcount is to be synced to sw count
  16224  *      port_class - (IN) Group ID of ingress port
  16225  *      outer_vlan - (IN) Packet outer VLAN ID
  16226  *      inner_vlan - (IN) Packet inner VLAN ID
  16227  *      stat - (IN) Type of the counter to retrieve.
  16228  *      val - (OUT) Pointer to a counter value.
  16229  * Returns:
  16230  *      BCM_E_xxx
  16231  * Notes:
  16232  */
  16233 int 
  16234 _bcm_esw_vlan_translate_egress_stat_get(int unit, int sync_mode, 
  16235                                         int port_class, 
  16236                                         bcm_vlan_t outer_vlan,
  16237                                         bcm_vlan_t inner_vlan,
  16238                                         bcm_vlan_stat_t stat,
  16239                                         uint64 *val)
  16240 {
  16241 #if defined(BCM_TRIUMPH2_SUPPORT)|| defined(BCM_TRIDENT_SUPPORT)
  16242     _bcm_flex_stat_handle_t vxlt_fsh;
  16243 #endif    
  16244 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) ||\
  16245     defined(BCM_HURRICANE3_SUPPORT)
  16246     uint32           counter_indexes=0;
  16247     bcm_stat_value_t counter_values={0};
  16248 #endif
  16249 
  16250 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  16251     if (soc_feature(unit, soc_feature_gport_service_counters)) {
  16252         BCM_IF_ERROR_RETURN
  16253             (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class,
  16254                                                   outer_vlan, inner_vlan,
  16255                                                   &vxlt_fsh));
  16256         return _bcm_esw_flex_stat_ext_get(unit, sync_mode, _bcmFlexStatTypeVxlt,
  16257                                       vxlt_fsh,
  16258                _bcm_esw_vlan_translate_egress_stat_to_flex_stat(stat),
  16259                                       val);
  16260     } else
  16261 #endif        
  16262 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  16263     defined(BCM_HURRICANE3_SUPPORT)
  16264     if (soc_feature(unit, soc_feature_advanced_flex_counter) ||
  16265         soc_feature(unit, soc_feature_flowcnt)) {
  16266         BCM_IF_ERROR_RETURN(
  16267             _bcm_esw_vlan_xslate_egress_stat_counter_get(
  16268                         unit, sync_mode, port_class, outer_vlan, inner_vlan,
  16269                         stat, 1, &counter_indexes, &counter_values));
  16270         if ((stat == bcmVlanStatIngressPackets) ||
  16271             (stat == bcmVlanStatEgressPackets)) {
  16272              COMPILER_64_SET(*val,0,counter_values.packets);
  16273         } else {
  16274              COMPILER_64_SET(*val,
  16275                              COMPILER_64_HI(counter_values.bytes),
  16276                              COMPILER_64_LO(counter_values.bytes));
  16277         }
  16278         return BCM_E_NONE;
  16279     } else 
  16280 #endif
  16281     {
  16282         return BCM_E_UNAVAIL;
  16283     }
  16284 }
  16285 
  16286 /*
  16287  * Function:
  16288  *      bcm_esw_vlan_translate_egress_stat_get
  16289  * Purpose:
  16290  *      Extract egress VLAN translation statistics from the chip.
  16291  * Parameters:
  16292  *      unit - (IN) Unit number.
  16293  *      port_class - (IN) Group ID of ingress port
  16294  *      outer_vlan - (IN) Packet outer VLAN ID
  16295  *      inner_vlan - (IN) Packet inner VLAN ID
  16296  *      stat - (IN) Type of the counter to retrieve.
  16297  *      val - (OUT) Pointer to a counter value.
  16298  * Returns:
  16299  *      BCM_E_xxx
  16300  * Notes:
  16301  */
  16302 int 
  16303 bcm_esw_vlan_translate_egress_stat_get(int unit, int port_class, 
  16304                                        bcm_vlan_t outer_vlan,
  16305                                        bcm_vlan_t inner_vlan,
  16306                                        bcm_vlan_stat_t stat,
  16307                                        uint64 *val)
  16308 {
  16309     int rv = BCM_E_NONE;
  16310 
  16311 #ifdef BCM_TOMAHAWK3_SUPPORT
  16312     if (SOC_IS_TOMAHAWK3(unit)) {
  16313         return BCM_E_UNAVAIL;
  16314     }
  16315 #endif
  16316     rv = _bcm_esw_vlan_translate_egress_stat_get(unit, 0, port_class,
  16317                                                  outer_vlan, inner_vlan,
  16318                                                  stat, val);
  16319     return rv;
  16320 }
  16321 
  16322 /*
  16323  * Function:
  16324  *      bcm_esw_vlan_translate_egress_stat_sync_get
  16325  * Purpose:
  16326  *      Extract egress VLAN translation statistics from the chip.
  16327  *      sw accumulated counters synced with hw count.
  16328  *
  16329  * Parameters:
  16330  *      unit - (IN) Unit number.
  16331  *      port_class - (IN) Group ID of ingress port
  16332  *      outer_vlan - (IN) Packet outer VLAN ID
  16333  *      inner_vlan - (IN) Packet inner VLAN ID
  16334  *      stat - (IN) Type of the counter to retrieve.
  16335  *      val - (OUT) Pointer to a counter value.
  16336  * Returns:
  16337  *      BCM_E_xxx
  16338  * Notes:
  16339  */
  16340 int 
  16341 bcm_esw_vlan_translate_egress_stat_sync_get(int unit, int port_class, 
  16342                                             bcm_vlan_t outer_vlan,
  16343                                             bcm_vlan_t inner_vlan,
  16344                                             bcm_vlan_stat_t stat,
  16345                                             uint64 *val)
  16346 {
  16347     int rv = BCM_E_NONE;
  16348 
  16349 #ifdef BCM_TOMAHAWK3_SUPPORT
  16350     if (SOC_IS_TOMAHAWK3(unit)) {
  16351         return BCM_E_UNAVAIL;
  16352     }
  16353 #endif
  16354     rv = _bcm_esw_vlan_translate_egress_stat_get(unit, 1, port_class,
  16355                                                  outer_vlan, inner_vlan,
  16356                                                  stat, val);
  16357     return rv;
  16358 }
  16359 
  16360 /*
  16361  * Function:
  16362  *      _bcm_esw_vlan_translate_egress_stat_get32
  16363  * Purpose:
  16364  *      Extract egress VLAN translation statistics from the chip.
  16365  *      if sync_mode is set, sync the sw accumulated count
  16366  *      with hw count value first, else return sw count.
  16367  *
  16368  * Parameters:
  16369  *      unit - (IN) Unit number.
  16370  *      sync_mode  - (IN) hwcount is to be synced to sw count
  16371  *      port_class - (IN) Group ID of ingress port
  16372  *      outer_vlan - (IN) Packet outer VLAN ID
  16373  *      inner_vlan - (IN) Packet inner VLAN ID
  16374  *      stat - (IN) Type of the counter to retrieve.
  16375  *      val - (OUT) Pointer to a counter value.
  16376  * Returns:
  16377  *      BCM_E_xxx
  16378  * Notes:
  16379  */
  16380 int 
  16381 _bcm_esw_vlan_translate_egress_stat_get32(int unit, int sync_mode, 
  16382                                           int port_class, 
  16383                                           bcm_vlan_t outer_vlan,
  16384                                           bcm_vlan_t inner_vlan,
  16385                                           bcm_vlan_stat_t stat,
  16386                                           uint32 *val)
  16387 {
  16388 #if defined(BCM_TRIUMPH2_SUPPORT)|| defined(BCM_TRIDENT_SUPPORT)
  16389     _bcm_flex_stat_handle_t vxlt_fsh;
  16390 #endif    
  16391 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  16392     defined(BCM_HURRICANE3_SUPPORT)
  16393     uint32           counter_indexes=0;
  16394     bcm_stat_value_t counter_values={0};
  16395 #endif
  16396 
  16397 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  16398     if (soc_feature(unit, soc_feature_gport_service_counters)) { 
  16399         BCM_IF_ERROR_RETURN
  16400             (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class,
  16401                                                   outer_vlan, inner_vlan,
  16402                                                   &vxlt_fsh));
  16403         return _bcm_esw_flex_stat_ext_get32(unit, sync_mode, 
  16404                     _bcmFlexStatTypeVxlt, vxlt_fsh,
  16405                 _bcm_esw_vlan_translate_egress_stat_to_flex_stat(stat),
  16406                                         val);
  16407     } else
  16408 #endif        
  16409 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  16410     defined(BCM_HURRICANE3_SUPPORT)
  16411     if (soc_feature(unit, soc_feature_advanced_flex_counter) ||
  16412         soc_feature(unit, soc_feature_flowcnt)) {    
  16413         BCM_IF_ERROR_RETURN(_bcm_esw_vlan_xslate_egress_stat_counter_get(
  16414                         unit, sync_mode, port_class, outer_vlan, inner_vlan,
  16415                         stat, 1, &counter_indexes, &counter_values));
  16416         if ((stat == bcmVlanStatIngressPackets) ||
  16417             (stat == bcmVlanStatEgressPackets)) {
  16418              *val = counter_values.packets;
  16419         } else {
  16420              /* Ignoring Hi bytes value */
  16421              *val = COMPILER_64_LO(counter_values.bytes);
  16422         }
  16423         return BCM_E_NONE;
  16424     } else
  16425 #endif
  16426     {
  16427         return BCM_E_UNAVAIL;
  16428     }
  16429 }
  16430 
  16431 
  16432 /*
  16433  * Function:
  16434  *      bcm_esw_vlan_translate_egress_stat_get32
  16435  * Purpose:
  16436  *      Extract egress VLAN translation statistics from the chip.
  16437  * Parameters:
  16438  *      unit - (IN) Unit number.
  16439  *      port_class - (IN) Group ID of ingress port
  16440  *      outer_vlan - (IN) Packet outer VLAN ID
  16441  *      inner_vlan - (IN) Packet inner VLAN ID
  16442  *      stat - (IN) Type of the counter to retrieve.
  16443  *      val - (OUT) Pointer to a counter value.
  16444  * Returns:
  16445  *      BCM_E_xxx
  16446  * Notes:
  16447  */
  16448 int 
  16449 bcm_esw_vlan_translate_egress_stat_get32(int unit, int port_class, 
  16450                                          bcm_vlan_t outer_vlan,
  16451                                          bcm_vlan_t inner_vlan,
  16452                                          bcm_vlan_stat_t stat,
  16453                                          uint32 *val)
  16454 {
  16455     int rv = BCM_E_NONE;
  16456 
  16457 #ifdef BCM_TOMAHAWK3_SUPPORT
  16458     if (SOC_IS_TOMAHAWK3(unit)) {
  16459         return BCM_E_UNAVAIL;
  16460     }
  16461 #endif
  16462     rv = _bcm_esw_vlan_translate_egress_stat_get32(unit, 0, port_class,
  16463                                                    outer_vlan, inner_vlan,
  16464                                                    stat, val);
  16465     return rv;
  16466 }
  16467 
  16468 /*
  16469  * Function:
  16470  *      bcm_esw_vlan_translate_egress_stat_sync_get32
  16471  * Purpose:
  16472  *      Extract egress VLAN translation statistics from the chip.
  16473  *      sw accumulated counters synced with hw count.
  16474  *
  16475  * Parameters:
  16476  *      unit - (IN) Unit number.
  16477  *      port_class - (IN) Group ID of ingress port
  16478  *      outer_vlan - (IN) Packet outer VLAN ID
  16479  *      inner_vlan - (IN) Packet inner VLAN ID
  16480  *      stat - (IN) Type of the counter to retrieve.
  16481  *      val - (OUT) Pointer to a counter value.
  16482  * Returns:
  16483  *      BCM_E_xxx
  16484  * Notes:
  16485  */
  16486 int 
  16487 bcm_esw_vlan_translate_egress_stat_sync_get32(int unit, int port_class,
  16488                                               bcm_vlan_t outer_vlan,
  16489                                               bcm_vlan_t inner_vlan,
  16490                                               bcm_vlan_stat_t stat,
  16491                                               uint32 *val)
  16492 {
  16493     int rv = BCM_E_NONE;
  16494 
  16495 #ifdef BCM_TOMAHAWK3_SUPPORT
  16496     if (SOC_IS_TOMAHAWK3(unit)) {
  16497         return BCM_E_UNAVAIL;
  16498     }
  16499 #endif
  16500     rv = _bcm_esw_vlan_translate_egress_stat_get32(unit, 1, port_class,
  16501                                                    outer_vlan, inner_vlan,
  16502                                                    stat, val);
  16503     return rv;
  16504 }
  16505 
  16506 /*
  16507  * Function:
  16508  *      bcm_esw_vlan_translate_egress_stat_set
  16509  * Purpose:
  16510  *      Set the specified statistic to the indicated value for the
  16511  *      specified egress VLAN translation.
  16512  * Parameters:
  16513  *      unit - (IN) Unit number.
  16514  *      port_class - (IN) Group ID of ingress port
  16515  *      outer_vlan - (IN) Packet outer VLAN ID
  16516  *      inner_vlan - (IN) Packet inner VLAN ID
  16517  *      stat - (IN) Type of the counter to set.
  16518  *      val - (IN) New counter value.
  16519  * Returns:
  16520  *      BCM_E_xxx
  16521  * Notes:
  16522  */
  16523 int 
  16524 bcm_esw_vlan_translate_egress_stat_set(int unit, 
  16525                                        int port_class,
  16526                                        bcm_vlan_t outer_vlan,
  16527                                        bcm_vlan_t inner_vlan,
  16528                                        bcm_vlan_stat_t stat,
  16529                                        uint64 val)
  16530 {
  16531 #if defined(BCM_TRIUMPH2_SUPPORT)|| defined(BCM_TRIDENT_SUPPORT)
  16532     _bcm_flex_stat_handle_t vxlt_fsh;
  16533 #endif    
  16534 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  16535     defined(BCM_HURRICANE3_SUPPORT)
  16536     uint32           counter_indexes=0;
  16537     bcm_stat_value_t counter_values={0};
  16538 #endif
  16539 
  16540 #ifdef BCM_TOMAHAWK3_SUPPORT
  16541     if (SOC_IS_TOMAHAWK3(unit)) {
  16542         return BCM_E_UNAVAIL;
  16543     }
  16544 #endif
  16545 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  16546     if (soc_feature(unit, soc_feature_gport_service_counters)) {
  16547         BCM_IF_ERROR_RETURN
  16548             (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class,
  16549                                                   outer_vlan, inner_vlan,
  16550                                                   &vxlt_fsh));
  16551         return _bcm_esw_flex_stat_ext_set(unit, _bcmFlexStatTypeVxlt,
  16552                                       vxlt_fsh,
  16553                 _bcm_esw_vlan_translate_egress_stat_to_flex_stat(stat),
  16554                                       val);
  16555     } else
  16556 #endif        
  16557 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  16558     defined(BCM_HURRICANE3_SUPPORT)
  16559     if (soc_feature(unit, soc_feature_advanced_flex_counter) ||
  16560         soc_feature(unit, soc_feature_flowcnt)) {
  16561         if ((stat == bcmVlanStatIngressPackets) ||
  16562             (stat == bcmVlanStatEgressPackets)) {
  16563              counter_values.packets = COMPILER_64_LO(val);
  16564         } else {
  16565              COMPILER_64_SET(counter_values.bytes,
  16566                              COMPILER_64_HI(val),
  16567                              COMPILER_64_LO(val));
  16568         }
  16569         BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_egress_stat_counter_set(
  16570                             unit,port_class,outer_vlan,inner_vlan,
  16571                             stat, 1, &counter_indexes, &counter_values));
  16572         return BCM_E_NONE;
  16573     } else
  16574 #endif
  16575     {
  16576         return BCM_E_UNAVAIL;
  16577     }
  16578 }
  16579 
  16580 /*
  16581  * Function:
  16582  *      bcm_esw_vlan_translate_egress_stat_set32
  16583  * Purpose:
  16584  *      Set the specified statistic to the indicated value for the
  16585  *      specified egress VLAN translation.
  16586  * Parameters:
  16587  *      unit - (IN) Unit number.
  16588  *      port_class - (IN) Group ID of ingress port
  16589  *      outer_vlan - (IN) Packet outer VLAN ID
  16590  *      inner_vlan - (IN) Packet inner VLAN ID
  16591  *      stat - (IN) Type of the counter to set.
  16592  *      val - (IN) New counter value.
  16593  * Returns:
  16594  *      BCM_E_xxx
  16595  * Notes:
  16596  */
  16597 int 
  16598 bcm_esw_vlan_translate_egress_stat_set32(int unit, int port_class, 
  16599                                          bcm_vlan_t outer_vlan,
  16600                                          bcm_vlan_t inner_vlan,
  16601                                          bcm_vlan_stat_t stat,
  16602                                          uint32 val)
  16603 {
  16604 #if defined(BCM_TRIUMPH2_SUPPORT)|| defined(BCM_TRIDENT_SUPPORT)
  16605     _bcm_flex_stat_handle_t vxlt_fsh;
  16606 #endif    
  16607 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  16608     defined(BCM_HURRICANE3_SUPPORT)
  16609     uint32           counter_indexes=0;
  16610     bcm_stat_value_t counter_values={0};
  16611 #endif
  16612 
  16613 #ifdef BCM_TOMAHAWK3_SUPPORT
  16614     if (SOC_IS_TOMAHAWK3(unit)) {
  16615         return BCM_E_UNAVAIL;
  16616     }
  16617 #endif
  16618 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  16619     if (soc_feature(unit, soc_feature_gport_service_counters)) {
  16620         BCM_IF_ERROR_RETURN
  16621             (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class,
  16622                                                   outer_vlan, inner_vlan,
  16623                                                   &vxlt_fsh));
  16624         return _bcm_esw_flex_stat_ext_set32(unit, _bcmFlexStatTypeVxlt,
  16625                                         vxlt_fsh,
  16626                 _bcm_esw_vlan_translate_egress_stat_to_flex_stat(stat),
  16627                                         val);
  16628     } else
  16629 #endif        
  16630 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  16631     defined(BCM_HURRICANE3_SUPPORT)
  16632     if (soc_feature(unit, soc_feature_advanced_flex_counter) ||
  16633         soc_feature(unit, soc_feature_flowcnt)) {
  16634         if ((stat == bcmVlanStatIngressPackets) ||
  16635             (stat == bcmVlanStatEgressPackets)) {
  16636             counter_values.packets = val;
  16637         } else {
  16638              /* Ignoring high value */
  16639              COMPILER_64_SET(counter_values.bytes,0,val);
  16640         }
  16641         BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_egress_stat_counter_set(
  16642                             unit,port_class,outer_vlan,inner_vlan,
  16643                             stat, 1, &counter_indexes, &counter_values));
  16644         return BCM_E_NONE;
  16645     } else
  16646 #endif
  16647     {
  16648         return BCM_E_UNAVAIL;
  16649     }
  16650 }
  16651 
  16652 /*
  16653  * Function:
  16654  *      bcm_esw_vlan_translate_egress_stat_multi_get
  16655  * Purpose:
  16656  *      Get 64-bit counter value for multiple egress VLAN translation
  16657  *      statistic types.
  16658  * Parameters:
  16659  *      unit - (IN) Unit number.
  16660  *      port_class - (IN) Group ID of ingress port
  16661  *      outer_vlan - (IN) Packet outer VLAN ID
  16662  *      inner_vlan - (IN) Packet inner VLAN ID
  16663  *      nstat - (IN) Number of elements in stat array
  16664  *      stat_arr - (IN) Collected statistics descriptors array
  16665  *      value_arr - (OUT) Collected counters values
  16666  * Returns:
  16667  *      BCM_E_xxx
  16668  * Notes:
  16669  */
  16670 int 
  16671 bcm_esw_vlan_translate_egress_stat_multi_get(int unit, int port_class, 
  16672                                              bcm_vlan_t outer_vlan,
  16673                                              bcm_vlan_t inner_vlan,
  16674                                              int nstat,
  16675                                              bcm_vlan_stat_t *stat_arr,
  16676                                              uint64 *value_arr)
  16677 {
  16678 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  16679     _bcm_flex_stat_handle_t vxlt_fsh;
  16680     _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */
  16681     int idx;
  16682 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  16683     defined(BCM_HURRICANE3_SUPPORT)
  16684     uint32           counter_indexes=0;
  16685     bcm_stat_value_t counter_values={0};
  16686 #endif
  16687 
  16688 #ifdef BCM_TOMAHAWK3_SUPPORT
  16689     if (SOC_IS_TOMAHAWK3(unit)) {
  16690         return BCM_E_UNAVAIL;
  16691     }
  16692 #endif
  16693     if (soc_feature(unit, soc_feature_gport_service_counters)) {  
  16694         BCM_IF_ERROR_RETURN
  16695             (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class,
  16696                                                       outer_vlan, inner_vlan,
  16697                                                       &vxlt_fsh));
  16698         BCM_IF_ERROR_RETURN
  16699             (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr, fs_arr,
  16700                        &_bcm_esw_vlan_translate_egress_stat_to_flex_stat));
  16701         BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr);
  16702     
  16703         return _bcm_esw_flex_stat_ext_multi_get(unit, _bcmFlexStatTypeVxlt,
  16704                                                 vxlt_fsh,
  16705                                             nstat, fs_arr, value_arr);
  16706     } else
  16707 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  16708     defined(BCM_HURRICANE3_SUPPORT)
  16709     if (soc_feature(unit, soc_feature_advanced_flex_counter) ||
  16710         soc_feature(unit, soc_feature_flowcnt)) {
  16711         for (idx=0;idx < nstat ; idx ++) {
  16712              BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_egress_stat_counter_get(
  16713                                  unit,port_class,outer_vlan,inner_vlan,
  16714                                  stat_arr[idx],1,&counter_indexes,&counter_values));
  16715              if ((stat_arr[idx] == bcmVlanStatIngressPackets) ||
  16716                  (stat_arr[idx] == bcmVlanStatEgressPackets)) {
  16717     
  16718                   COMPILER_64_SET(value_arr[idx],
  16719                                   COMPILER_64_HI(counter_values.packets64),
  16720                                   COMPILER_64_LO(counter_values.packets64));
  16721              } else {
  16722                   COMPILER_64_SET(value_arr[idx],
  16723                                   COMPILER_64_HI(counter_values.bytes),
  16724                                   COMPILER_64_LO(counter_values.bytes));
  16725              }
  16726         }
  16727         return BCM_E_NONE;
  16728     } else
  16729 #endif
  16730 #endif
  16731     {
  16732         return BCM_E_UNAVAIL;
  16733     }
  16734 }
  16735 
  16736 /*
  16737  * Function:
  16738  *      bcm_esw_vlan_translate_egress_stat_multi_get32
  16739  * Purpose:
  16740  *      Get lower 32-bit counter value for multiple egress VLAN
  16741  *      translation statistic types.
  16742  * Parameters:
  16743  *      unit - (IN) Unit number.
  16744  *      port_class - (IN) Group ID of ingress port
  16745  *      outer_vlan - (IN) Packet outer VLAN ID
  16746  *      inner_vlan - (IN) Packet inner VLAN ID
  16747  *      nstat - (IN) Number of elements in stat array
  16748  *      stat_arr - (IN) Collected statistics descriptors array
  16749  *      value_arr - (OUT) Collected counters values
  16750  * Returns:
  16751  *      BCM_E_xxx
  16752  * Notes:
  16753  */
  16754 int 
  16755 bcm_esw_vlan_translate_egress_stat_multi_get32(int unit, int port_class, 
  16756                                                bcm_vlan_t outer_vlan,
  16757                                                bcm_vlan_t inner_vlan,
  16758                                                int nstat,
  16759                                                bcm_vlan_stat_t *stat_arr,
  16760                                                uint32 *value_arr)
  16761 {
  16762 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  16763     _bcm_flex_stat_handle_t vxlt_fsh;
  16764     _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */
  16765     int idx;
  16766 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  16767     defined(BCM_HURRICANE3_SUPPORT)
  16768     uint32           counter_indexes=0;
  16769     bcm_stat_value_t counter_values={0};
  16770 #endif
  16771 
  16772 #ifdef BCM_TOMAHAWK3_SUPPORT
  16773     if (SOC_IS_TOMAHAWK3(unit)) {
  16774         return BCM_E_UNAVAIL;
  16775     }
  16776 #endif
  16777     if (soc_feature(unit, soc_feature_gport_service_counters)) {
  16778   
  16779         BCM_IF_ERROR_RETURN
  16780             (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class,
  16781                                                       outer_vlan, inner_vlan,
  16782                                                       &vxlt_fsh));
  16783         BCM_IF_ERROR_RETURN
  16784             (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr, fs_arr,
  16785                        &_bcm_esw_vlan_translate_egress_stat_to_flex_stat));
  16786         BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr);
  16787         
  16788         return _bcm_esw_flex_stat_ext_multi_get32(unit, _bcmFlexStatTypeVxlt,
  16789                                                   vxlt_fsh,
  16790                                             nstat, fs_arr, value_arr);
  16791     } else
  16792 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  16793     defined(BCM_HURRICANE3_SUPPORT)
  16794     if (soc_feature(unit, soc_feature_advanced_flex_counter) ||
  16795         soc_feature(unit, soc_feature_flowcnt)) {
  16796         for (idx=0;idx < nstat ; idx ++) {
  16797              BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_egress_stat_counter_get(
  16798                                  unit,port_class,outer_vlan,inner_vlan,
  16799                                  stat_arr[idx],1,&counter_indexes,&counter_values));
  16800              if ((stat_arr[idx] == bcmVlanStatIngressPackets) ||
  16801                  (stat_arr[idx] == bcmVlanStatEgressPackets)) {
  16802                   value_arr[idx] = counter_values.packets;
  16803              } else {
  16804                   value_arr[idx] = COMPILER_64_LO(counter_values.bytes);
  16805              }
  16806         }
  16807     return BCM_E_NONE;
  16808     }
  16809 #endif
  16810 #endif
  16811     {
  16812         return BCM_E_UNAVAIL;
  16813     }
  16814 }
  16815 
  16816 /*
  16817  * Function:
  16818  *      bcm_esw_vlan_translate_egress_stat_multi_set
  16819  * Purpose:
  16820  *      Set 64-bit counter value for multiple egress VLAN translation
  16821  *      statistic types.
  16822  * Parameters:
  16823  *      unit - (IN) Unit number.
  16824  *      port_class - (IN) Group ID of ingress port
  16825  *      outer_vlan - (IN) Packet outer VLAN ID
  16826  *      inner_vlan - (IN) Packet inner VLAN ID
  16827  *      nstat - (IN) Number of elements in stat array
  16828  *      stat_arr - (IN) New statistics descriptors array
  16829  *      value_arr - (IN) New counters values
  16830  * Returns:
  16831  *      BCM_E_xxx
  16832  * Notes:
  16833  */
  16834 int 
  16835 bcm_esw_vlan_translate_egress_stat_multi_set(int unit, int port_class, 
  16836                                              bcm_vlan_t outer_vlan,
  16837                                              bcm_vlan_t inner_vlan,
  16838                                              int nstat,
  16839                                              bcm_vlan_stat_t *stat_arr,
  16840                                              uint64 *value_arr)
  16841 {
  16842 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  16843     _bcm_flex_stat_handle_t vxlt_fsh;
  16844     _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */
  16845     int idx;
  16846 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  16847     defined(BCM_HURRICANE3_SUPPORT)
  16848     uint32           counter_indexes=0;
  16849     bcm_stat_value_t counter_values={0};
  16850 #endif
  16851 
  16852 #ifdef BCM_TOMAHAWK3_SUPPORT
  16853     if (SOC_IS_TOMAHAWK3(unit)) {
  16854         return BCM_E_UNAVAIL;
  16855     }
  16856 #endif
  16857 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 
  16858     if (soc_feature(unit, soc_feature_gport_service_counters)) {
  16859         BCM_IF_ERROR_RETURN
  16860             (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class,
  16861                                                       outer_vlan, inner_vlan,
  16862                                                       &vxlt_fsh));
  16863         BCM_IF_ERROR_RETURN
  16864             (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr, fs_arr,
  16865                        &_bcm_esw_vlan_translate_egress_stat_to_flex_stat));
  16866         BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr);
  16867     
  16868         return _bcm_esw_flex_stat_ext_multi_set(unit, _bcmFlexStatTypeVxlt,
  16869                                                 vxlt_fsh,
  16870                                             nstat, fs_arr, value_arr);
  16871     } else
  16872 #endif        
  16873 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  16874     defined(BCM_HURRICANE3_SUPPORT)
  16875     if (soc_feature(unit, soc_feature_advanced_flex_counter) ||
  16876         soc_feature(unit, soc_feature_flowcnt)) {
  16877         for (idx=0;idx < nstat ; idx ++) {
  16878              if ((stat_arr[idx] == bcmVlanStatIngressPackets) ||
  16879                  (stat_arr[idx] == bcmVlanStatEgressPackets)) {
  16880                   counter_values.packets = COMPILER_64_LO(value_arr[idx]);
  16881              } else {
  16882                   COMPILER_64_SET(counter_values.bytes,
  16883                                   COMPILER_64_HI(value_arr[idx]),
  16884                                   COMPILER_64_LO(value_arr[idx]));
  16885              }
  16886              BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_egress_stat_counter_set(
  16887                                  unit,port_class,outer_vlan,inner_vlan,
  16888                                  stat_arr[idx],1,&counter_indexes,&counter_values));
  16889         }
  16890         return BCM_E_NONE;
  16891     } else
  16892 #endif
  16893 #endif
  16894     {
  16895         return BCM_E_UNAVAIL;
  16896     }
  16897 }
  16898 
  16899 /*
  16900  * Function:
  16901  *      bcm_esw_vlan_translate_egress_stat_multi_set32
  16902  * Purpose:
  16903  *      Set lower 32-bit counter value for multiple egress VLAN
  16904  *      translation statistic types.
  16905  * Parameters:
  16906  *      unit - (IN) Unit number.
  16907  *      port_class - (IN) Group ID of ingress port
  16908  *      outer_vlan - (IN) Packet outer VLAN ID
  16909  *      inner_vlan - (IN) Packet inner VLAN ID
  16910  *      nstat - (IN) Number of elements in stat array
  16911  *      stat_arr - (IN) New statistics descriptors array
  16912  *      value_arr - (IN) New counters values
  16913  * Returns:
  16914  *      BCM_E_xxx
  16915  * Notes:
  16916  */
  16917 int 
  16918 bcm_esw_vlan_translate_egress_stat_multi_set32(int unit, int port_class,
  16919                                                bcm_vlan_t outer_vlan,
  16920                                                bcm_vlan_t inner_vlan,
  16921                                                int nstat,
  16922                                                bcm_vlan_stat_t *stat_arr,
  16923                                                uint32 *value_arr)
  16924 {
  16925 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  16926     _bcm_flex_stat_handle_t vxlt_fsh;
  16927     _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */
  16928     int idx;
  16929 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  16930     defined(BCM_HURRICANE3_SUPPORT)
  16931     uint32           counter_indexes=0;
  16932     bcm_stat_value_t counter_values={0};
  16933 #endif
  16934 
  16935 #ifdef BCM_TOMAHAWK3_SUPPORT
  16936     if (SOC_IS_TOMAHAWK3(unit)) {
  16937         return BCM_E_UNAVAIL;
  16938     }
  16939 #endif
  16940     if (soc_feature(unit, soc_feature_gport_service_counters)) {
  16941         BCM_IF_ERROR_RETURN
  16942             (_bcm_esw_vlan_translate_egress_stat_param_valid(unit, port_class,
  16943                                                       outer_vlan, inner_vlan,
  16944                                                       &vxlt_fsh));
  16945         BCM_IF_ERROR_RETURN
  16946             (_bcm_vlan_stat_array_convert(unit, nstat, stat_arr, fs_arr,
  16947                        &_bcm_esw_vlan_translate_egress_stat_to_flex_stat));
  16948         BCM_VLAN_VALUE_ARRAY_VALID(unit, nstat, value_arr);
  16949     
  16950         return _bcm_esw_flex_stat_ext_multi_set32(unit, _bcmFlexStatTypeVxlt,
  16951                                                   vxlt_fsh,
  16952                                             nstat, fs_arr, value_arr);
  16953     } else
  16954 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  16955     defined(BCM_HURRICANE3_SUPPORT)
  16956     if (soc_feature(unit, soc_feature_advanced_flex_counter) ||
  16957         soc_feature(unit, soc_feature_flowcnt)) {
  16958         for (idx=0;idx < nstat ; idx ++) {
  16959              if ((stat_arr[idx] == bcmVlanStatIngressPackets) ||
  16960                  (stat_arr[idx] == bcmVlanStatEgressPackets)) {
  16961                   counter_values.packets = value_arr[idx];
  16962              } else {
  16963                   COMPILER_64_SET(counter_values.bytes,0,value_arr[idx]);
  16964              }
  16965              BCM_IF_ERROR_RETURN(bcm_esw_vlan_translate_egress_stat_counter_set(
  16966                                  unit,port_class,outer_vlan,inner_vlan,
  16967                                  stat_arr[idx],1,&counter_indexes,&counter_values));
  16968         }
  16969         return BCM_E_NONE;
  16970     } else
  16971 #endif
  16972 #endif
  16973     {
  16974         return BCM_E_UNAVAIL;
  16975     }
  16976 }
  16977 
  16978 /*
  16979  * Function:
  16980  *     _bcm_vlan_queue_map_id_check
  16981  * Description:
  16982  *     To check the status of the specified qmid
  16983  * Parameters:
  16984  *     unit            device number
  16985  *     qmid            queue mapping identifier
  16986  * Return:
  16987  *     BCM_E_UNAVAIL   queue mapping feature is not supported for this device
  16988  *     BCM_E_INIT      vlan component is not initialized on this device
  16989  *     BCM_E_BADID     specified qmid is not in valid range
  16990  *     BCM_E_NOT_FOUND spefified qmid is in valid range but not in used
  16991  *     BCM_E_NONE      specified qmid is in used
  16992  */
  16993 STATIC int
  16994 _bcm_vlan_queue_map_id_check(int unit,
  16995                              int qmid)
  16996 {
  16997     int size;
  16998 
  16999     if (!soc_feature(unit, soc_feature_vlan_queue_map)) {
  17000         return BCM_E_UNAVAIL;
  17001     }
  17002 
  17003     CHECK_INIT(unit);
  17004 
  17005     size = 1 << soc_mem_field_length(unit, VLAN_PROFILE_TABm,
  17006                                      PHB2_DOT1P_MAPPING_PTRf);
  17007 
  17008     if (qmid < 0 || qmid >= size) {
  17009         return BCM_E_BADID;
  17010     }
  17011 
  17012     if (!SHR_BITGET(vlan_info[unit].qm_bmp, qmid)) {
  17013         return BCM_E_NOT_FOUND;
  17014     }
  17015 
  17016     return BCM_E_NONE;
  17017 }
  17018 
  17019 /* Create a VLAN queue map entry. */
  17020 int
  17021 bcm_esw_vlan_queue_map_create(int unit,
  17022                               uint32 flags,
  17023                               int *qmid)
  17024 {
  17025     bcm_vlan_info_t *vi;
  17026     int size, bmp_size, free_qmid, i;
  17027     uint32 bits, tag_flags;
  17028     int rv;
  17029 
  17030     if (!soc_feature(unit, soc_feature_vlan_queue_map)) {
  17031         return BCM_E_UNAVAIL;
  17032     }
  17033 
  17034     CHECK_INIT(unit);
  17035 
  17036     vi = &vlan_info[unit];
  17037     size = 1 << soc_mem_field_length(unit, VLAN_PROFILE_TABm,
  17038                                      PHB2_DOT1P_MAPPING_PTRf);
  17039 
  17040     if (flags & BCM_VLAN_QUEUE_MAP_REPLACE) {
  17041         if (!(flags & BCM_VLAN_QUEUE_MAP_WITH_ID)) {
  17042             return BCM_E_PARAM;
  17043         }
  17044         BCM_IF_ERROR_RETURN(_bcm_vlan_queue_map_id_check(unit, *qmid));
  17045     }
  17046     tag_flags = flags & (BCM_VLAN_QUEUE_MAP_INNER_PKT_PRI |
  17047                          BCM_VLAN_QUEUE_MAP_OUTER_PKT_PRI);
  17048     if (tag_flags != BCM_VLAN_QUEUE_MAP_OUTER_PKT_PRI &&
  17049         tag_flags != BCM_VLAN_QUEUE_MAP_INNER_PKT_PRI) {
  17050         return BCM_E_PARAM;
  17051     }
  17052 
  17053     if (!(flags & BCM_VLAN_QUEUE_MAP_REPLACE)) {
  17054         if (flags & BCM_VLAN_QUEUE_MAP_WITH_ID) {
  17055             rv = _bcm_vlan_queue_map_id_check(unit, *qmid);
  17056             /* make sure the id is in the valid range and not taken */
  17057             if (rv != BCM_E_NOT_FOUND) {
  17058                 return BCM_E_PARAM;
  17059             } 
  17060             SHR_BITSET(vi->qm_bmp, *qmid);
  17061         } else {
  17062             free_qmid = size;
  17063             bmp_size = _SHR_BITDCLSIZE(size);
  17064             /* find the index of first zero from qm_bmp */
  17065             for (i = 0; i < bmp_size; i++) {
  17066                 if (vi->qm_bmp[i] == 0xffffffff) {
  17067                     continue;
  17068                 }
  17069                 bits = vi->qm_bmp[i];
  17070                 bits &= (bits << 1) | 0x00000001;
  17071                 bits &= (bits << 2) | 0x00000003;
  17072                 bits &= (bits << 4) | 0x0000000f;
  17073                 bits &= (bits << 8) | 0x000000ff;
  17074                 bits &= (bits << 16) | 0x0000ffff;
  17075                 free_qmid = (i << 5) + _shr_popcount(bits);
  17076                 break;
  17077             }
  17078             if (free_qmid >= size) {
  17079                 return BCM_E_RESOURCE;
  17080             }
  17081             SHR_BITSET(vi->qm_bmp, free_qmid);
  17082             *qmid = free_qmid;
  17083         }
  17084     }
  17085 
  17086     if (flags & BCM_VLAN_QUEUE_MAP_INNER_PKT_PRI) {
  17087         SHR_BITSET(vi->qm_it_bmp, *qmid);
  17088     } else {
  17089         SHR_BITCLR(vi->qm_it_bmp, *qmid);
  17090     }
  17091 
  17092 #ifdef BCM_WARM_BOOT_SUPPORT
  17093     SOC_CONTROL_LOCK(unit);
  17094     SOC_CONTROL(unit)->scache_dirty = 1;
  17095     SOC_CONTROL_UNLOCK(unit);
  17096 #endif
  17097 
  17098     return BCM_E_NONE;
  17099 }
  17100 
  17101 /* Delete a VLAN queue map entry. */
  17102 int
  17103 bcm_esw_vlan_queue_map_destroy(int unit,
  17104                                int qmid)
  17105 {
  17106     int pkt_pri, cfi;
  17107 
  17108     if (!soc_feature(unit, soc_feature_vlan_queue_map)) {
  17109         return BCM_E_UNAVAIL;
  17110     }
  17111     BCM_IF_ERROR_RETURN(_bcm_vlan_queue_map_id_check(unit, qmid));
  17112 
  17113     for (pkt_pri = 0; pkt_pri <=7; pkt_pri++) {
  17114         for (cfi = 0; cfi <= 1; cfi++) {
  17115             BCM_IF_ERROR_RETURN(bcm_esw_vlan_queue_map_set(unit,
  17116                                         qmid, pkt_pri, cfi, 0, 0));
  17117         }
  17118     }
  17119 
  17120     SHR_BITCLR(vlan_info[unit].qm_bmp, qmid);
  17121 
  17122 #ifdef BCM_WARM_BOOT_SUPPORT
  17123     SOC_CONTROL_LOCK(unit);
  17124     SOC_CONTROL(unit)->scache_dirty = 1;
  17125     SOC_CONTROL_UNLOCK(unit);
  17126 #endif
  17127 
  17128     return BCM_E_NONE;
  17129 }
  17130 
  17131 /* Delete all VLAN queue map entries. */
  17132 int
  17133 bcm_esw_vlan_queue_map_destroy_all(int unit)
  17134 {
  17135     int size, qmid;
  17136 
  17137     if (!soc_feature(unit, soc_feature_vlan_queue_map)) {
  17138         return BCM_E_UNAVAIL;
  17139     }
  17140 
  17141     CHECK_INIT(unit);
  17142 
  17143     size = 1 << soc_mem_field_length(unit, VLAN_PROFILE_TABm,
  17144                                      PHB2_DOT1P_MAPPING_PTRf);
  17145 
  17146     for (qmid = 0; qmid < size; qmid++) {
  17147         if (SHR_BITGET(vlan_info[unit].qm_bmp, qmid)) {
  17148             BCM_IF_ERROR_RETURN(bcm_esw_vlan_queue_map_destroy(unit, qmid));
  17149         }
  17150     }
  17151 
  17152 #ifdef BCM_WARM_BOOT_SUPPORT
  17153     SOC_CONTROL_LOCK(unit);
  17154     SOC_CONTROL(unit)->scache_dirty = 1;
  17155     SOC_CONTROL_UNLOCK(unit);
  17156 #endif
  17157 
  17158     return BCM_E_NONE;
  17159 }
  17160 
  17161 /* Set a VLAN queue map entry. */
  17162 int
  17163 bcm_esw_vlan_queue_map_set(int unit,
  17164                            int qmid,
  17165                            int pkt_pri,
  17166                            int cfi,
  17167                            int queue,
  17168                            int color)
  17169 {
  17170     phb2_cos_map_entry_t entry;
  17171     int index;
  17172 
  17173     if (!soc_feature(unit, soc_feature_vlan_queue_map)) {
  17174         return BCM_E_UNAVAIL;
  17175     }
  17176 
  17177     BCM_IF_ERROR_RETURN(_bcm_vlan_queue_map_id_check(unit, qmid));
  17178 
  17179     if (pkt_pri < 0 || pkt_pri > 7 || cfi < 0 || cfi > 1) {
  17180         return BCM_E_PARAM;
  17181     }
  17182 
  17183     if (queue < 0 ||
  17184         queue >= (1 << soc_mem_field_length(unit, PHB2_COS_MAPm, COSf))) {
  17185         return BCM_E_PARAM;
  17186     }
  17187 
  17188     /* For Triumph2 and Enduro, the entry index is:
  17189      * {PHB2_DOT1P_MAPPING_PTR(4-bit), 802.1 priority(3-bit), CFI/DE}.
  17190      * From Trident onward, the index takes format of:
  17191      * {802.1p_priority[2:0], 802.1p_cfi, PHB2_DOT1P_MAPPING_PTR}.
  17192      */
  17193   
  17194 #ifdef BCM_TRIUMPH2_SUPPORT
  17195     if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  17196         SOC_IS_VALKYRIE2(unit)) {
  17197         index = (qmid << 4) | (pkt_pri << 1) | cfi;
  17198     } else
  17199 #endif
  17200 #ifdef BCM_ENDURO_SUPPORT
  17201     if (SOC_IS_ENDURO(unit)) {
  17202         index = (qmid << 4) | (pkt_pri << 1) | cfi;
  17203     } else
  17204 #endif
  17205 #ifdef BCM_HELIX5_SUPPORT
  17206     if (SOC_IS_HELIX5(unit)) {
  17207         index = (pkt_pri << 6) | (cfi << 5) | (qmid << 1); /* Wired */
  17208     } else
  17209 #endif
  17210     {
  17211         index = (pkt_pri << 5) | (cfi << 4) | qmid;
  17212     }
  17213 
  17214     sal_memset(&entry, 0, sizeof(entry));
  17215     soc_mem_field32_set(unit, PHB2_COS_MAPm, &entry, COSf, queue);
  17216 
  17217     if (soc_feature(unit, soc_feature_vlan_multicast_queue_map)) {
  17218         soc_mem_field32_set(unit, PHB2_COS_MAPm, &entry, MC_COS2f, queue);
  17219     }
  17220 
  17221     BCM_IF_ERROR_RETURN(soc_mem_write(unit, PHB2_COS_MAPm, MEM_BLOCK_ANY,
  17222                                       index,
  17223                                       &entry));
  17224 
  17225 #ifdef BCM_HELIX5_SUPPORT
  17226     if (SOC_IS_HELIX5(unit)) {
  17227         index = ((pkt_pri << 6) | (cfi << 5) | (qmid << 1)) + 1; /* Wireless */
  17228         BCM_IF_ERROR_RETURN(soc_mem_write(unit, PHB2_COS_MAPm, MEM_BLOCK_ANY,
  17229                         index, &entry));
  17230     }
  17231 #endif
  17232 
  17233     return BCM_E_NONE;
  17234 }
  17235 
  17236 /* Get a VLAN queue map entry. */
  17237 int
  17238 bcm_esw_vlan_queue_map_get(int unit,
  17239                            int qmid,
  17240                            int pkt_pri,
  17241                            int cfi,
  17242                            int *queue,
  17243                            int *color)
  17244 {
  17245     phb2_cos_map_entry_t entry;
  17246     int index;
  17247 
  17248     if (!soc_feature(unit, soc_feature_vlan_queue_map)) {
  17249         return BCM_E_UNAVAIL;
  17250     }
  17251 
  17252     BCM_IF_ERROR_RETURN(_bcm_vlan_queue_map_id_check(unit, qmid));
  17253 
  17254     if (pkt_pri < 0 || pkt_pri > 7 || cfi < 0 || cfi > 1) {
  17255         return BCM_E_PARAM;
  17256     }
  17257 
  17258     if (queue == NULL || color == NULL) {
  17259         return BCM_E_PARAM;
  17260     }
  17261 
  17262 #ifdef BCM_TRIUMPH2_SUPPORT
  17263     if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  17264         SOC_IS_VALKYRIE2(unit)) {
  17265         index = (qmid << 4) | (pkt_pri << 1) | cfi;
  17266     } else
  17267 #endif
  17268 #ifdef BCM_ENDURO_SUPPORT
  17269     if (SOC_IS_ENDURO(unit)) {
  17270         index = (qmid << 4) | (pkt_pri << 1) | cfi;
  17271     } else
  17272 #endif
  17273 #ifdef BCM_HELIX5_SUPPORT
  17274     if (SOC_IS_HELIX5(unit)) {
  17275         index = (pkt_pri << 6) | (cfi << 5) | (qmid << 1); /* Wired */
  17276     } else
  17277 #endif
  17278     {
  17279         index = (pkt_pri << 5) | (cfi << 4) | qmid;
  17280     }
  17281 
  17282     BCM_IF_ERROR_RETURN(soc_mem_read(unit, PHB2_COS_MAPm, MEM_BLOCK_ANY,
  17283                                      index,
  17284                                      &entry));
  17285     *queue = soc_mem_field32_get(unit, PHB2_COS_MAPm, &entry, COSf);
  17286     *color = 0;
  17287 
  17288     return BCM_E_NONE;
  17289 }
  17290 
  17291 /* Attach a queue map object to a VLAN or VFI. */
  17292 int
  17293 bcm_esw_vlan_queue_map_attach(int unit,
  17294                               bcm_vlan_t vlan,
  17295                               int qmid)
  17296 {
  17297 #ifdef BCM_TRIUMPH2_SUPPORT
  17298     vfi_entry_t vfi_entry;
  17299     int use_inner_tag;
  17300 #endif /* BCM_TRIUMHP2_SUPPORT */
  17301     if (!soc_feature(unit, soc_feature_vlan_queue_map)) {
  17302         return BCM_E_UNAVAIL;
  17303     }
  17304 
  17305     BCM_IF_ERROR_RETURN(_bcm_vlan_queue_map_id_check(unit, qmid));
  17306 
  17307 #ifdef BCM_TRIUMPH2_SUPPORT
  17308     VLAN_CHK_ID(unit, vlan);
  17309 
  17310     use_inner_tag = SHR_BITGET(vlan_info[unit].qm_it_bmp, qmid) ? 1 : 0;
  17311     BCM_IF_ERROR_RETURN
  17312         (_bcm_tr2_vlan_qmid_set(unit, vlan, qmid, use_inner_tag));
  17313 
  17314     if (SOC_MEM_IS_VALID(unit, VFIm)) {
  17315         BCM_IF_ERROR_RETURN(READ_VFIm(unit, MEM_BLOCK_ANY, vlan, &vfi_entry));
  17316         soc_mem_field32_set(unit, VFIm, &vfi_entry, PHB2_DOT1P_MAPPING_PTRf, qmid);
  17317         soc_mem_field32_set(unit, VFIm, &vfi_entry, PHB2_USE_INNER_DOT1Pf,
  17318                             use_inner_tag);
  17319         soc_mem_field32_set(unit, VFIm, &vfi_entry, PHB2_ENABLEf, 1);
  17320         BCM_IF_ERROR_RETURN(WRITE_VFIm(unit, MEM_BLOCK_ANY, vlan, &vfi_entry));
  17321     }
  17322 #endif /* BCM_TRIUMHP2_SUPPORT */
  17323 
  17324     return BCM_E_NONE;
  17325 }
  17326 
  17327 /* Get the queue map object which is attached to a VLAN or VFI. */
  17328 int
  17329 bcm_esw_vlan_queue_map_attach_get(int unit,
  17330                                   bcm_vlan_t vlan,
  17331                                   int *qmid)
  17332 {
  17333 #ifdef BCM_TRIUMPH2_SUPPORT
  17334     int use_inner_tag;
  17335 #endif /* BCM_TRIUMHP2_SUPPORT */
  17336 
  17337     if (!soc_feature(unit, soc_feature_vlan_queue_map)) {
  17338         return BCM_E_UNAVAIL;
  17339     }
  17340 
  17341 #ifdef BCM_TRIUMPH2_SUPPORT
  17342     CHECK_INIT(unit);
  17343 
  17344     VLAN_CHK_ID(unit, vlan);
  17345 
  17346     if (qmid == NULL) {
  17347         return BCM_E_PARAM;
  17348     }
  17349 
  17350     BCM_IF_ERROR_RETURN
  17351         (_bcm_tr2_vlan_qmid_get(unit, vlan, qmid, &use_inner_tag));
  17352 #endif /* BCM_TRIUMHP2_SUPPORT */
  17353 
  17354     return BCM_E_NONE;
  17355 }
  17356 
  17357 /* Detach a queue map object from a VLAN or VFI. */
  17358 int
  17359 bcm_esw_vlan_queue_map_detach(int unit,
  17360                               bcm_vlan_t vlan)
  17361 {
  17362 #ifdef BCM_TRIUMPH2_SUPPORT
  17363     vfi_entry_t vfi_entry;
  17364 #endif /* BCM_TRIUMHP2_SUPPORT */
  17365 
  17366     if (!soc_feature(unit, soc_feature_vlan_queue_map)) {
  17367         return BCM_E_UNAVAIL;
  17368     }
  17369 
  17370 #ifdef BCM_TRIUMPH2_SUPPORT
  17371     CHECK_INIT(unit);
  17372 
  17373     VLAN_CHK_ID(unit, vlan);
  17374 
  17375     BCM_IF_ERROR_RETURN(_bcm_tr2_vlan_qmid_set(unit, vlan, -1, 0));
  17376 
  17377     if (SOC_MEM_IS_VALID(unit, VFIm)) {
  17378         BCM_IF_ERROR_RETURN(READ_VFIm(unit, MEM_BLOCK_ANY, vlan, &vfi_entry));
  17379         soc_mem_field32_set(unit, VFIm, &vfi_entry, PHB2_DOT1P_MAPPING_PTRf, 0);
  17380         soc_mem_field32_set(unit, VFIm, &vfi_entry, PHB2_USE_INNER_DOT1Pf, 0);
  17381         soc_mem_field32_set(unit, VFIm, &vfi_entry, PHB2_ENABLEf, 0);
  17382         BCM_IF_ERROR_RETURN(WRITE_VFIm(unit, MEM_BLOCK_ANY, vlan, &vfi_entry));
  17383     }
  17384 #endif /* BCM_TRIUMHP2_SUPPORT */
  17385 
  17386     return BCM_E_NONE;
  17387 }
  17388 
  17389 /* Detach queue map objects from all VLAN or VFI. */
  17390 int
  17391 bcm_esw_vlan_queue_map_detach_all(int unit)
  17392 {
  17393 #ifdef BCM_TRIUMPH2_SUPPORT
  17394     vfi_entry_t vfi_entry;
  17395     int vlan;
  17396 #endif /* BCM_TRIUMHP2_SUPPORT */
  17397 
  17398     if (!soc_feature(unit, soc_feature_vlan_queue_map)) {
  17399         return BCM_E_UNAVAIL;
  17400     }
  17401 
  17402 #ifdef BCM_TRIUMPH2_SUPPORT
  17403     CHECK_INIT(unit);
  17404 
  17405     for (vlan = BCM_VLAN_MIN; vlan < BCM_VLAN_COUNT; vlan++) {
  17406         if (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vlan)) {
  17407             BCM_IF_ERROR_RETURN(_bcm_tr2_vlan_qmid_set(unit, vlan, -1, 0));
  17408 
  17409             if (!SOC_MEM_IS_VALID(unit, VFIm)) {
  17410                 continue;
  17411             }
  17412 
  17413             BCM_IF_ERROR_RETURN(READ_VFIm(unit, MEM_BLOCK_ANY, vlan,
  17414                                           &vfi_entry));
  17415             soc_mem_field32_set(unit, VFIm, &vfi_entry,
  17416                                 PHB2_DOT1P_MAPPING_PTRf, 0);
  17417             soc_mem_field32_set(unit, VFIm, &vfi_entry,
  17418                                 PHB2_USE_INNER_DOT1Pf, 0);
  17419             soc_mem_field32_set(unit, VFIm, &vfi_entry, PHB2_ENABLEf, 0);
  17420             BCM_IF_ERROR_RETURN(WRITE_VFIm(unit, MEM_BLOCK_ANY, vlan,
  17421                                            &vfi_entry));
  17422         }
  17423     }
  17424 #endif /* BCM_TRIUMHP2_SUPPORT */
  17425 
  17426     return BCM_E_NONE;
  17427 }
  17428 
  17429 /*
  17430  * Function:
  17431  *      bcmi_esw_vlan_vfi_validate
  17432  * Purpose:
  17433  *      Validate a VLAN/VFI
  17434  * Parameters:
  17435  *      unit - StrataSwitch PCI device unit number (driver internal).
  17436  *      vlan_vfi - VLAN/VFI ID to validate.
  17437  * Returns:
  17438  *      BCM_E_NONE - Success.
  17439  *      BCM_E_PARAM - Invalid value.
  17440  */
  17441 int
  17442 bcmi_esw_vlan_vfi_validate(int unit, bcm_vlan_t vlan_vfi)
  17443 {
  17444 
  17445 #if defined(INCLUDE_L3) && defined(BCM_TRX_SUPPORT)
  17446 
  17447     /* For vlan validate range, for vfi ensure that one of the vpn
  17448        types matches */
  17449     if((soc_feature(unit, soc_feature_vlan_vfi_membership)) &&
  17450        _BCM_VPN_VFI_IS_SET(vlan_vfi)) {       
  17451 
  17452         _BCM_VPN_GET(vlan_vfi, _BCM_VPN_TYPE_VFI, vlan_vfi);
  17453         if(_bcm_vfi_used_get(unit, vlan_vfi, _bcmVfiTypeMpls))
  17454             return BCM_E_NONE;
  17455         else if(_bcm_vfi_used_get(unit, vlan_vfi, _bcmVfiTypeMim))
  17456             return BCM_E_NONE;
  17457         else if(_bcm_vfi_used_get(unit, vlan_vfi, _bcmVfiTypeL2Gre))
  17458             return BCM_E_NONE;
  17459         else if(_bcm_vfi_used_get(unit, vlan_vfi, _bcmVfiTypeVxlan))
  17460             return BCM_E_NONE;
  17461         else if(_bcm_vfi_used_get(unit, vlan_vfi, _bcmVfiTypeFlow))
  17462             return BCM_E_NONE;
  17463         else {
  17464             return BCM_E_PARAM;
  17465         }
  17466 #if defined(BCM_TRIUMPH3_SUPPORT)
  17467     } else if ((soc_feature(unit, soc_feature_vlan_vfi)) &&
  17468         _BCM_VPN_VFI_IS_SET(vlan_vfi)) {
  17469         _BCM_VPN_GET(vlan_vfi, _BCM_VPN_TYPE_VFI, vlan_vfi);
  17470         if (_bcm_vfi_used_get(unit, vlan_vfi, _bcmVfiTypeVlan)) {
  17471             return BCM_E_NONE;
  17472         } else {
  17473             return BCM_E_PARAM;
  17474         }
  17475 #endif /* BCM_TRIUMPH3_SUPPORT */
  17476     } else {
  17477         VLAN_CHK_ID(unit, vlan_vfi);
  17478     }
  17479 
  17480 #else
  17481         VLAN_CHK_ID(unit, vlan_vfi);
  17482 #endif
  17483 
  17484     return BCM_E_NONE;
  17485 }
  17486 
  17487 #define MOD_PORT_TO_GLP(unit, modid, port, glp)   \
  17488     do {    \
  17489         if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { \
  17490             glp = ((0xFF & modid) << 7) | (0x7F & port);    \
  17491         } else {    \
  17492             glp = ((0xFF & modid) << 8) | (0xFF & port);    \
  17493         }   \
  17494     } while(0)
  17495 
  17496 /*
  17497  * Function:
  17498  *      bcm_vlan_gport_add
  17499  * Purpose:
  17500  *      Add a Gport to the specified vlan. Adds WLAN/VLAN/NIV/Extender ports to
  17501  *      broadcast, multicast and unknown unicast groups.
  17502  * Parameters:
  17503  *      unit - StrataSwitch PCI device unit number (driver internal).
  17504  *      vlan - VLAN ID to add port to as a member.
  17505  *      port - Gport ID
  17506  *      flags - BCM_VLAN_PORT_XXX
  17507  * Returns:
  17508  *      BCM_E_NONE - Success.
  17509  *      BCM_E_INTERNAL - Chip access failure.
  17510  *      BCM_E_NOT_FOUND - VLAN ID not in use.
  17511  */
  17512 int
  17513 bcm_esw_vlan_gport_add(int unit, bcm_vlan_t vlan, bcm_gport_t port, 
  17514                        int flags)
  17515 {
  17516     int rv = BCM_E_NONE;
  17517 
  17518 #ifdef BCM_TOMAHAWK3_SUPPORT
  17519     if (SOC_IS_TOMAHAWK3(unit)) {
  17520         return bcm_tomahawk3_vlan_gport_add(unit, vlan, port, flags);
  17521     }
  17522 #endif
  17523 
  17524     CHECK_INIT(unit);
  17525 
  17526     /* VxLAN passes in a VFI, hence check VLAN for non-VxLan cases */
  17527     BCM_IF_ERROR_RETURN(bcmi_esw_vlan_vfi_validate(unit, vlan));
  17528     
  17529     if (port == BCM_GPORT_INVALID)
  17530         return BCM_E_PORT;
  17531 
  17532 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  17533     if (soc_feature(unit, soc_feature_wlan) && BCM_GPORT_IS_WLAN_PORT(port)) {
  17534         int i, vp, mc_idx, gport_id, mod_local, group = 0;
  17535         vlan_tab_entry_t vtab;
  17536         bcm_wlan_port_t wlan_port;
  17537         bcm_module_t mod_out;
  17538         bcm_port_t port_out;
  17539         bcm_trunk_t trunk_id;
  17540         bcm_gport_t local_gport;
  17541         bcm_if_t encap_id;
  17542         bcm_pbmp_t vlan_pbmp, vlan_ubmp, pbmp, l3_pbmp;
  17543         soc_field_t group_type[3] = {BC_IDXf, UMC_IDXf, UUC_IDXf};
  17544 
  17545         vp = BCM_GPORT_WLAN_PORT_ID_GET(port);
  17546         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) {
  17547             return BCM_E_NOT_FOUND;
  17548         }
  17549         if (flags != 0) {
  17550             return BCM_E_PARAM;
  17551         }
  17552         sal_memset(&vtab, 0, sizeof(vlan_tab_entry_t));
  17553 
  17554         soc_mem_lock(unit, VLAN_TABm);
  17555 
  17556         if ((rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vlan, 
  17557              &vtab)) < 0) {
  17558             soc_mem_unlock(unit, VLAN_TABm);
  17559             return rv;
  17560         }
  17561         if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VALIDf)) {
  17562             soc_mem_unlock(unit, VLAN_TABm);
  17563             return BCM_E_NOT_FOUND;
  17564         }
  17565 
  17566         /* Get the VP attributes (need physical port) and encap id */
  17567         if ((rv = bcm_esw_wlan_port_get(unit, port, &wlan_port)) < 0) {
  17568             soc_mem_unlock(unit, VLAN_TABm);
  17569             return rv;
  17570         }
  17571 
  17572         /* Enable VP switching on the VLAN */
  17573         if (!SHR_BITGET(vlan_info[unit].vp_mode, vlan) && 
  17574             SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) {
  17575             if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf)) {
  17576                soc_mem_field32_set(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf, 1);
  17577                if ((rv = soc_mem_write(unit, VLAN_TABm, MEM_BLOCK_ALL, (int)vlan, 
  17578                     &vtab)) < 0) {
  17579                    soc_mem_unlock(unit, VLAN_TABm);
  17580                    return rv;
  17581                }
  17582                /* Also need to copy the physical port members to the L2_BITMAP of
  17583                 * the IPMC entry for each group once we've gone virtual */
  17584                rv = mbcm_driver[unit]->mbcm_vlan_port_get
  17585                    (unit, vlan, &vlan_pbmp, &vlan_ubmp, NULL);
  17586                                                        
  17587                if (rv < 0) {
  17588                    soc_mem_unlock(unit, VLAN_TABm);
  17589                    return rv;
  17590                }
  17591                /* Deal with each group */
  17592                for (i = 0; i < 3; i++) {
  17593                    mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab,
  17594                                                 group_type[i]);
  17595                    rv = _bcm_esw_multicast_ipmc_read(unit, mc_idx, &pbmp, 
  17596                                                      &l3_pbmp);
  17597                    if (rv < 0) {
  17598                        soc_mem_unlock(unit, VLAN_TABm);
  17599                        return rv;
  17600                    }
  17601                    rv = _bcm_esw_multicast_ipmc_write(unit, mc_idx, vlan_pbmp, 
  17602                                                       l3_pbmp, TRUE);
  17603                    if (rv < 0) {
  17604                        soc_mem_unlock(unit, VLAN_TABm);
  17605                        return rv;
  17606                    }
  17607                }   
  17608             }
  17609         }
  17610 
  17611         /* Check if wlan_port.port is a local port or trunk */
  17612         if (BCM_GPORT_IS_TRUNK(wlan_port.port)) {
  17613             trunk_id = BCM_GPORT_TRUNK_GET(wlan_port.port);
  17614             rv = _bcm_trunk_id_validate(unit, trunk_id);
  17615             if (BCM_FAILURE(rv)) {
  17616                   soc_mem_unlock(unit, VLAN_TABm);
  17617                   return (BCM_E_PORT);
  17618             }
  17619             local_gport = wlan_port.port;
  17620         } else {
  17621             rv = _bcm_esw_gport_resolve(unit, wlan_port.port, &mod_out, &port_out,
  17622                               &trunk_id, &gport_id); 
  17623             if (BCM_FAILURE(rv)) {
  17624                 soc_mem_unlock(unit, VLAN_TABm);
  17625                 return (BCM_E_PORT);
  17626             }
  17627             rv = _bcm_esw_modid_is_local(unit, mod_out, &mod_local);
  17628             if (BCM_FAILURE(rv)) {
  17629                 soc_mem_unlock(unit, VLAN_TABm);
  17630                 return rv;
  17631             }
  17632             if (TRUE != mod_local) {
  17633                 /* Only add this to replication set if destination is local */
  17634                soc_mem_unlock(unit, VLAN_TABm);
  17635                return BCM_E_PORT;
  17636             }
  17637             /* Convert system local_port to physical local_port */
  17638             if (soc_feature(unit, soc_feature_sysport_remap)) {
  17639                 BCM_XLATE_SYSPORT_S2P(unit, &port_out);
  17640             }
  17641             rv = bcm_esw_port_gport_get(unit, port_out, &local_gport);
  17642             if (BCM_FAILURE(rv)) {
  17643                 soc_mem_unlock(unit, VLAN_TABm);
  17644                 return rv;
  17645             }        
  17646         }
  17647         rv = bcm_esw_multicast_wlan_encap_get(unit, group, local_gport,
  17648                                               port, &encap_id);
  17649         if (BCM_FAILURE(rv)) {
  17650             soc_mem_unlock(unit, VLAN_TABm);
  17651             return rv;
  17652         }
  17653 
  17654         /* Add the VP to the BC group */
  17655         mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf);
  17656         _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_WLAN, mc_idx);
  17657         rv = bcm_esw_multicast_egress_add(unit, group, local_gport, encap_id); 
  17658         if (rv < 0) {
  17659             soc_mem_unlock(unit, VLAN_TABm);
  17660             return rv;
  17661         }
  17662 
  17663         /* Add the VP to the UMC group */
  17664         mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UMC_IDXf);
  17665         _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_WLAN, mc_idx);
  17666         rv = bcm_esw_multicast_egress_add(unit, group, local_gport, encap_id); 
  17667         if (rv < 0) {
  17668             soc_mem_unlock(unit, VLAN_TABm);
  17669             return rv;
  17670         }
  17671 
  17672         /* Add the VP to the UUC group */
  17673         mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UUC_IDXf);
  17674         _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_WLAN, mc_idx);
  17675         rv = bcm_esw_multicast_egress_add(unit, group, local_gport, encap_id); 
  17676 
  17677         soc_mem_unlock(unit, VLAN_TABm);
  17678 
  17679     } else if (soc_feature(unit, soc_feature_vlan_vp) && BCM_GPORT_IS_VLAN_PORT(port)) {
  17680 #if defined(BCM_ENDURO_SUPPORT)
  17681         if (SOC_IS_ENDURO(unit)) {
  17682             rv = bcm_enduro_vlan_vp_add(unit, vlan, port, flags);
  17683         } else 
  17684 #endif /* BCM_ENDURO_SUPPORT */
  17685         {
  17686             /* COVERITY
  17687              * up to this point, coverity indicates 7604 bytes stack usage.
  17688              * After this call, it becomes 8220 bytes which exceeds the coverity
  17689              * default check limit 8192 bytes.
  17690              */
  17691             /* coverity[stack_use_overflow : FALSE] */
  17692             rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags);
  17693         }
  17694     } else if (soc_feature(unit, soc_feature_niv) &&
  17695             BCM_GPORT_IS_NIV_PORT(port)) {
  17696         rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags);
  17697     } else if (soc_feature(unit, soc_feature_port_extension) &&
  17698             BCM_GPORT_IS_EXTENDER_PORT(port)) {
  17699         rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags);
  17700     } else if (soc_feature(unit, soc_feature_vp_lag) &&
  17701             BCM_GPORT_IS_TRUNK(port)) {
  17702         rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags);
  17703     } else if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  17704             BCM_GPORT_IS_SUBPORT_PORT(port)) {
  17705         rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags);
  17706     } else if (soc_feature(unit, soc_feature_vxlan) &&
  17707             BCM_GPORT_IS_VXLAN_PORT(port)) {
  17708         rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags);
  17709     } else if (soc_feature(unit, soc_feature_flex_flow) &&
  17710             BCM_GPORT_IS_FLOW_PORT(port)) {
  17711         rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags);
  17712     } else if (soc_feature(unit, soc_feature_l2gre) &&
  17713             BCM_GPORT_IS_L2GRE_PORT(port)) {
  17714         rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags);
  17715     } else if (soc_feature(unit, soc_feature_mim) &&
  17716             BCM_GPORT_IS_MIM_PORT(port)) {
  17717         rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags);
  17718     } else if (soc_feature(unit, soc_feature_mpls) &&
  17719             BCM_GPORT_IS_MPLS_PORT(port)) {
  17720         rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags);
  17721     } else if (BCM_GPORT_IS_VP_GROUP(port)) {
  17722 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
  17723         int vpg = BCM_GPORT_VP_GROUP_GET(port);
  17724 
  17725 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  17726         if (soc_feature(unit, soc_feature_vlan_vfi_membership)){
  17727             bcm_stg_t stg;
  17728 
  17729             if ((flags & BCM_VLAN_PORT_INGRESS_ONLY)) {
  17730                 BCM_IF_ERROR_RETURN(bcm_td2p_ing_vp_group_unmanaged_set(unit,TRUE));
  17731                 BCM_IF_ERROR_RETURN(
  17732                     bcm_td2p_vlan_vp_group_set(unit, vlan, FALSE, vpg, TRUE));
  17733 
  17734                 BCM_IF_ERROR_RETURN(
  17735                     bcm_td2p_vp_group_vlan_vpn_stg_get(unit, vlan, FALSE, &stg));
  17736                 if (stg != BCM_STG_DEFAULT) {
  17737                     BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_stp_state_set(unit, stg,
  17738                         port, FALSE, _bcm_td2_flags_to_stp_state(unit, flags, FALSE)));
  17739                 }
  17740             }
  17741 
  17742             if ((flags & BCM_VLAN_PORT_EGRESS_ONLY)) {
  17743                 BCM_IF_ERROR_RETURN(bcm_td2p_egr_vp_group_unmanaged_set(unit,TRUE));
  17744                 BCM_IF_ERROR_RETURN(
  17745                     bcm_td2p_vlan_vp_group_set(unit, vlan, TRUE, vpg, TRUE));
  17746 
  17747                 BCM_IF_ERROR_RETURN(
  17748                     bcm_td2p_vp_group_vlan_vpn_stg_get(unit, vlan, TRUE, &stg));
  17749                 if (stg != BCM_STG_DEFAULT) {
  17750                     BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_stp_state_set(unit, stg,
  17751                         port, TRUE, _bcm_td2_flags_to_stp_state(unit, flags, TRUE)));
  17752                 }
  17753 
  17754                 if (!_BCM_VPN_VFI_IS_SET(vlan)) {
  17755                     BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_ut_state_set(unit,
  17756                             vlan, vpg, (flags & BCM_VLAN_GPORT_ADD_UNTAGGED)));
  17757                 }
  17758 #if defined(BCM_TRIDENT3_SUPPORT)
  17759                 else if (SOC_MEM_IS_VALID(unit, EGR_VLAN_VFI_UNTAGm)) {
  17760                     BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_ut_state_set(unit,
  17761                             vlan, vpg, (flags & BCM_VLAN_GPORT_ADD_UNTAGGED)));
  17762                 }
  17763 #endif
  17764             }
  17765         } else
  17766 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  17767         {
  17768             if ((flags & BCM_VLAN_PORT_INGRESS_ONLY) && 
  17769                     soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership)) {
  17770                 BCM_IF_ERROR_RETURN(bcm_td_ing_vp_group_unmanaged_set(unit,TRUE));
  17771                 BCM_IF_ERROR_RETURN(bcm_td_vlan_vp_group_set(
  17772                             unit, VLAN_TABLE(unit), vlan, vpg, TRUE));
  17773             }
  17774             if ((flags & BCM_VLAN_PORT_EGRESS_ONLY) &&
  17775                     soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) {
  17776                 BCM_IF_ERROR_RETURN(bcm_td_egr_vp_group_unmanaged_set(unit,TRUE));
  17777                 BCM_IF_ERROR_RETURN(bcm_td_vlan_vp_group_set(
  17778                             unit, EGR_VLANm, vlan, vpg, TRUE));
  17779             }
  17780         }
  17781 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  17782     } else
  17783 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
  17784     {
  17785         bcm_pbmp_t pbmp, ubmp, ing_pbmp;
  17786         bcm_port_t local_port;
  17787 
  17788 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
  17789         if (soc_feature(unit, soc_feature_egr_vp_vlan_membership)) {
  17790             if ((flags & BCM_VLAN_GPORT_ADD_EGRESS_ONLY) &&
  17791                  (flags & BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP) &&
  17792                          _BCM_VPN_VFI_IS_SET(vlan)) {
  17793                 if(!BCM_GPORT_IS_MODPORT(port)) {
  17794                     return BCM_E_PARAM;
  17795                 }
  17796                 rv = bcm_tr2_vlan_gport_add(unit, vlan, port, flags);
  17797                 return rv;
  17798             }
  17799         }
  17800 #endif
  17801 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  17802         if (soc_feature(unit, soc_feature_vlan_vfi_membership) &&
  17803             (flags & BCM_VLAN_GPORT_ADD_VP_VLAN_MEMBERSHIP)) {
  17804                 if (!BCM_GPORT_IS_MODPORT(port)) {
  17805                     return BCM_E_PARAM;
  17806                 }
  17807 
  17808                 MOD_PORT_TO_GLP(unit, BCM_GPORT_MODPORT_MODID_GET(port),
  17809                     BCM_GPORT_MODPORT_PORT_GET(port), port);
  17810                 rv = bcm_td2_vp_vlan_membership_add(unit, port, vlan, flags);
  17811                 return rv;
  17812             }
  17813 #endif
  17814 
  17815         /* If Ingress/Egress only flags are specified and 'ING_PORT_BITMAPf' is
  17816            not a valid field in 'VLAN_TABm' AND if the
  17817            'soc_feature_vlan_vfi_membership' is FALSE, return error. If the
  17818            feature is TRUE, the mentioned field comes from the profiled
  17819            'ING_VLAN_VFI_MEMBERSHIPm' table*/
  17820         if (flags & (BCM_VLAN_PORT_INGRESS_ONLY | BCM_VLAN_PORT_EGRESS_ONLY)) {
  17821             if (!soc_mem_field_valid(unit, VLAN_TABLE(unit), ING_PORT_BITMAPf) &&
  17822                 !(soc_feature(unit, soc_feature_vlan_vfi_membership))) {
  17823                 return BCM_E_PARAM;
  17824             }
  17825         }
  17826         if ((!soc_feature(unit, soc_feature_vlan_egress_membership_l3_only)) &&
  17827             (flags & BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY)) {
  17828             return (BCM_E_UNAVAIL);
  17829         }
  17830 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT)
  17831         if ((flags & BCM_VLAN_GPORT_ADD_EGRESS_ONLY) &&
  17832             (flags & BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY)) {
  17833             return BCM_E_PARAM;
  17834         }
  17835 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_HURRICANE3_SUPPORT */
  17836 
  17837         BCM_IF_ERROR_RETURN(
  17838             bcm_esw_port_local_get(unit, port, &local_port));
  17839 
  17840         if (flags & (BCM_VLAN_PORT_EGRESS_ONLY | BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY)) {
  17841             BCM_PBMP_CLEAR(ing_pbmp);
  17842         } else {
  17843             BCM_PBMP_PORT_SET(ing_pbmp, local_port);
  17844         }
  17845         if (flags & BCM_VLAN_PORT_INGRESS_ONLY) {
  17846             BCM_PBMP_CLEAR(pbmp);
  17847         } else {
  17848             BCM_PBMP_PORT_SET(pbmp, local_port);
  17849         }
  17850         if (flags & BCM_VLAN_PORT_UNTAGGED) {
  17851             BCM_PBMP_PORT_SET(ubmp, local_port);
  17852         } else {
  17853             BCM_PBMP_CLEAR(ubmp);
  17854         }
  17855         if (SOC_IS_FBX(unit)) {
  17856             BCM_LOCK(unit);
  17857             rv = _bcm_vlan_port_add(unit, vlan, pbmp, ubmp, ing_pbmp, flags);
  17858             BCM_UNLOCK(unit);
  17859         } else {  /* don't support virtual port*/
  17860             BCM_PBMP_OR(pbmp, ing_pbmp);
  17861             rv = bcm_esw_vlan_port_add(unit, vlan, pbmp, ubmp);
  17862         }
  17863     }
  17864 
  17865     return rv;
  17866 }
  17867 
  17868 /*
  17869  * Function:
  17870  *      bcm_vlan_gport_delete
  17871  * Purpose:
  17872  *      Delete a Gport from the specified vlan.
  17873  * Parameters:
  17874  *      unit - StrataSwitch PCI device unit number (driver internal).
  17875  *      vlan - VLAN ID to add port to as a member.
  17876  *      port - Gport ID
  17877  * Returns:
  17878  *      BCM_E_NONE - Success.
  17879  *      BCM_E_INTERNAL - Chip access failure.
  17880  *      BCM_E_NOT_FOUND - VLAN ID not in use.
  17881  */
  17882 int
  17883 bcm_esw_vlan_gport_delete(int unit, bcm_vlan_t vlan, bcm_gport_t port)
  17884 {
  17885     int rv = BCM_E_NONE;
  17886 
  17887 #ifdef BCM_TOMAHAWK3_SUPPORT
  17888     if (SOC_IS_TOMAHAWK3(unit)) {
  17889         return bcm_tomahawk3_vlan_gport_delete(unit, vlan, port);
  17890     }
  17891 #endif
  17892 
  17893     CHECK_INIT(unit);
  17894 
  17895     /* VxLAN passes in a VFI, hence check VLAN for non-VxLan cases */
  17896     BCM_IF_ERROR_RETURN(bcmi_esw_vlan_vfi_validate(unit, vlan));
  17897     
  17898     if (port == BCM_GPORT_INVALID)
  17899         return BCM_E_PORT;
  17900 
  17901 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  17902     if (soc_feature(unit, soc_feature_wlan) && BCM_GPORT_IS_WLAN_PORT(port)) {
  17903         int vp, bc_idx,mc_idx,uuc_idx, gport_id, group = 0, mod_local;
  17904         vlan_tab_entry_t vtab;
  17905         bcm_wlan_port_t wlan_port;
  17906         bcm_module_t mod_out;
  17907         bcm_port_t port_out;
  17908         bcm_trunk_t trunk_id;
  17909         bcm_gport_t local_gport;
  17910         bcm_if_t encap_id;
  17911 
  17912         vp = BCM_GPORT_WLAN_PORT_ID_GET(port);
  17913         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) {
  17914             return BCM_E_NOT_FOUND;
  17915         }
  17916         sal_memset(&vtab, 0, sizeof(vlan_tab_entry_t));
  17917 
  17918         soc_mem_lock(unit, VLAN_TABm);
  17919 
  17920         if ((rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vlan, 
  17921              &vtab)) < 0) {
  17922             soc_mem_unlock(unit, VLAN_TABm);
  17923             return rv;
  17924         }
  17925         if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VALIDf)) {
  17926             soc_mem_unlock(unit, VLAN_TABm);
  17927             return BCM_E_NOT_FOUND;
  17928         }
  17929 
  17930         /* Get the VP attributes (need physical port) and encap id */
  17931         if ((rv = bcm_esw_wlan_port_get(unit, port, &wlan_port)) < 0) {
  17932             soc_mem_unlock(unit, VLAN_TABm);
  17933             return rv;
  17934         }
  17935         /* Check if wlan_port.port is a local port or trunk */
  17936         if (BCM_GPORT_IS_TRUNK(wlan_port.port)) {
  17937             trunk_id = BCM_GPORT_TRUNK_GET(wlan_port.port);
  17938             rv = _bcm_trunk_id_validate(unit, trunk_id);
  17939             if (BCM_FAILURE(rv)) {
  17940                   soc_mem_unlock(unit, VLAN_TABm);
  17941                   return (BCM_E_PORT);
  17942             }
  17943             local_gport = wlan_port.port;
  17944         } else {
  17945             rv = _bcm_esw_gport_resolve(unit, wlan_port.port, &mod_out, &port_out,
  17946                                 &trunk_id, &gport_id); 
  17947             if (BCM_FAILURE(rv)) {
  17948                 soc_mem_unlock(unit, VLAN_TABm);
  17949                 return (BCM_E_PORT);
  17950             }
  17951             rv = _bcm_esw_modid_is_local(unit, mod_out, &mod_local);
  17952             if (BCM_FAILURE(rv)) {
  17953                 soc_mem_unlock(unit, VLAN_TABm);
  17954                 return rv;
  17955             }
  17956             if (TRUE != mod_local) {
  17957                 /* Only add this to replication set if destination is local */
  17958                soc_mem_unlock(unit, VLAN_TABm);
  17959                return BCM_E_PORT;
  17960             }
  17961             /* Convert system local_port to physical local_port */
  17962             if (soc_feature(unit, soc_feature_sysport_remap)) {
  17963                 BCM_XLATE_SYSPORT_S2P(unit, &port_out);
  17964             }
  17965             rv = bcm_esw_port_gport_get(unit, port_out, &local_gport);
  17966             if (BCM_FAILURE(rv)) {
  17967                 soc_mem_unlock(unit, VLAN_TABm);
  17968                 return rv;
  17969             }        
  17970         }
  17971         rv = bcm_esw_multicast_wlan_encap_get(unit, group, local_gport,
  17972                                               port, &encap_id);
  17973         if (BCM_FAILURE(rv)) {
  17974             soc_mem_unlock(unit, VLAN_TABm);
  17975             return rv;
  17976         }
  17977 
  17978         /* Remove from the WLAN MC group */
  17979         if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) {
  17980            if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf)) {
  17981                /* No group exists - this is an error*/
  17982                soc_mem_unlock(unit, VLAN_TABm);
  17983                return BCM_E_PORT;
  17984            }
  17985         }
  17986 
  17987         bc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf);
  17988         _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_WLAN, bc_idx);
  17989         rv = bcm_esw_multicast_egress_delete(unit, group, local_gport, 
  17990                                               encap_id); 
  17991 
  17992         mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UMC_IDXf);
  17993         if (mc_idx != bc_idx) {
  17994             _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_WLAN, mc_idx);
  17995             rv = bcm_esw_multicast_egress_delete(unit, group, local_gport, 
  17996                                               encap_id);
  17997         }
  17998 
  17999         uuc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UUC_IDXf);
  18000         if ((uuc_idx != bc_idx) && (uuc_idx != mc_idx)) {
  18001             _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_WLAN, uuc_idx);
  18002             rv = bcm_esw_multicast_egress_delete(unit, group, local_gport, 
  18003                                               encap_id);
  18004         }
  18005 
  18006         soc_mem_unlock(unit, VLAN_TABm);
  18007 
  18008     } else if (soc_feature(unit, soc_feature_vlan_vp) && BCM_GPORT_IS_VLAN_PORT(port)) {
  18009 #if defined(BCM_ENDURO_SUPPORT)
  18010         if (SOC_IS_ENDURO(unit)) {
  18011             rv = bcm_enduro_vlan_vp_delete(unit, vlan, port);
  18012         } else 
  18013 #endif /* BCM_ENDURO_SUPPORT */
  18014         {
  18015             rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18016         }
  18017     } else if (soc_feature(unit, soc_feature_niv) &&
  18018             BCM_GPORT_IS_NIV_PORT(port)) {
  18019         rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18020     } else if (soc_feature(unit, soc_feature_port_extension) &&
  18021             BCM_GPORT_IS_EXTENDER_PORT(port)) {
  18022         rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18023     } else if (soc_feature(unit, soc_feature_vp_lag) &&
  18024             BCM_GPORT_IS_TRUNK(port)) {
  18025         rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18026     } else if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  18027             BCM_GPORT_IS_SUBPORT_PORT(port)) {
  18028         rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18029     } else if (soc_feature(unit, soc_feature_vxlan) &&
  18030             BCM_GPORT_IS_VXLAN_PORT(port)) {
  18031         rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18032     } else if (soc_feature(unit, soc_feature_flex_flow) &&
  18033             BCM_GPORT_IS_FLOW_PORT(port)) {
  18034         rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18035     } else if (soc_feature(unit, soc_feature_l2gre) &&
  18036             BCM_GPORT_IS_L2GRE_PORT(port)) {
  18037         rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18038     } else if (soc_feature(unit, soc_feature_mim) &&
  18039                 BCM_GPORT_IS_MIM_PORT(port)) {
  18040         rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18041     } else if (soc_feature(unit, soc_feature_mpls) &&
  18042             BCM_GPORT_IS_MPLS_PORT(port)) {
  18043         rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18044     } else if (BCM_GPORT_IS_VP_GROUP(port)) {
  18045 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 
  18046 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  18047         if (soc_feature(unit, soc_feature_vlan_vfi_membership)){
  18048             rv = bcm_td2p_vlan_vp_group_set(unit, vlan,
  18049                     FALSE, BCM_GPORT_VP_GROUP_GET(port), FALSE);
  18050             BCM_IF_ERROR_RETURN(rv);
  18051 
  18052             rv = bcm_td2p_vlan_vp_group_set(unit, vlan,
  18053                 TRUE, BCM_GPORT_VP_GROUP_GET(port), FALSE);
  18054             BCM_IF_ERROR_RETURN(rv);
  18055         } else
  18056 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  18057         {
  18058             if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership)) {
  18059                 rv = bcm_td_vlan_vp_group_set(unit,VLAN_TABLE(unit),vlan,
  18060                         BCM_GPORT_VP_GROUP_GET(port),FALSE);
  18061                 BCM_IF_ERROR_RETURN(rv);
  18062             }
  18063             if (soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) {
  18064                 rv = bcm_td_vlan_vp_group_set(unit,EGR_VLANm,vlan,
  18065                         BCM_GPORT_VP_GROUP_GET(port), FALSE);
  18066                 BCM_IF_ERROR_RETURN(rv);
  18067             }
  18068         }
  18069 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  18070     } else
  18071 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
  18072     {
  18073         bcm_pbmp_t pbmp;
  18074         bcm_port_t local_port;
  18075 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  18076         uint32 filter_flags = 0;
  18077 #endif
  18078 
  18079         BCM_IF_ERROR_RETURN(
  18080             bcm_esw_port_local_get(unit, port, &local_port));
  18081 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
  18082         if (soc_feature(unit, soc_feature_egr_vp_vlan_membership)) {
  18083             if (_BCM_VPN_VFI_IS_SET(vlan) && BCM_GPORT_IS_MODPORT(port)) {
  18084                 BCM_IF_ERROR_RETURN(bcm_esw_port_vlan_member_get(unit, local_port, &filter_flags));
  18085                 if ((filter_flags & BCM_PORT_VLAN_MEMBER_EGRESS) &&
  18086                             (filter_flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) {
  18087                     rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18088                     return rv;
  18089                 }
  18090             }
  18091         }
  18092 #endif
  18093 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  18094         if (soc_feature(unit, soc_feature_vlan_vfi_membership) &&
  18095             BCM_GPORT_IS_MODPORT(port)) {
  18096             BCM_IF_ERROR_RETURN(bcm_esw_port_vlan_member_get(unit, local_port, &filter_flags));
  18097             if (filter_flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP) {
  18098                 MOD_PORT_TO_GLP(unit, BCM_GPORT_MODPORT_MODID_GET(port),
  18099                     BCM_GPORT_MODPORT_PORT_GET(port), port);
  18100                 rv = bcm_td2_vp_vlan_membership_delete(unit, port, vlan);
  18101                 return rv;
  18102             }
  18103         }
  18104 #endif
  18105         BCM_PBMP_CLEAR(pbmp);
  18106         BCM_PBMP_PORT_ADD(pbmp, local_port);
  18107         rv = _bcm_vlan_port_remove(unit, vlan, pbmp, pbmp, pbmp, NULL);
  18108     }
  18109     return rv;
  18110 }
  18111 
  18112 /*
  18113  * Function:
  18114  *      bcm_vlan_gport_extended_delete
  18115  * Purpose:
  18116  *      Delete a Gport from the specified vlan.
  18117  * Parameters:
  18118  *      unit - StrataSwitch PCI device unit number (driver internal).
  18119  *      vlan - VLAN ID to add port to as a member.
  18120  *      port - Gport ID
  18121  *      flags -BCM_VLAN_PORT_XXX
  18122  * Returns:
  18123  *      BCM_E_NONE - Success.
  18124  *      BCM_E_INTERNAL - Chip access failure.
  18125  *      BCM_E_NOT_FOUND - VLAN ID not in use.
  18126  */
  18127 int
  18128 bcm_esw_vlan_gport_extended_delete(int unit, bcm_vlan_t vlan, 
  18129                                       bcm_gport_t port, int flags)
  18130 {
  18131     int rv = BCM_E_NONE;
  18132 
  18133 #ifdef BCM_TOMAHAWK3_SUPPORT
  18134     if (SOC_IS_TOMAHAWK3(unit)) {
  18135         return
  18136             bcm_tomahawk3_vlan_gport_extended_delete(unit, vlan, port, flags);
  18137     }
  18138 #endif
  18139 
  18140     CHECK_INIT(unit);
  18141     BCM_IF_ERROR_RETURN(bcmi_esw_vlan_vfi_validate(unit, vlan));
  18142     
  18143     if (port == BCM_GPORT_INVALID)
  18144         return BCM_E_PORT;
  18145 
  18146 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  18147     if (soc_feature(unit, soc_feature_wlan) && BCM_GPORT_IS_WLAN_PORT(port)) {
  18148         int vp, bc_idx,mc_idx,uuc_idx, gport_id, group = 0, mod_local;
  18149         vlan_tab_entry_t vtab;
  18150         bcm_wlan_port_t wlan_port;
  18151         bcm_module_t mod_out;
  18152         bcm_port_t port_out;
  18153         bcm_trunk_t trunk_id;
  18154         bcm_gport_t local_gport;
  18155         bcm_if_t encap_id;
  18156 
  18157         vp = BCM_GPORT_WLAN_PORT_ID_GET(port);
  18158         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) {
  18159             return BCM_E_NOT_FOUND;
  18160         }
  18161         sal_memset(&vtab, 0, sizeof(vlan_tab_entry_t));
  18162 
  18163         soc_mem_lock(unit, VLAN_TABm);
  18164 
  18165         if ((rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vlan, 
  18166              &vtab)) < 0) {
  18167             soc_mem_unlock(unit, VLAN_TABm);
  18168             return rv;
  18169         }
  18170         if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VALIDf)) {
  18171             soc_mem_unlock(unit, VLAN_TABm);
  18172             return BCM_E_NOT_FOUND;
  18173         }
  18174 
  18175         /* Get the VP attributes (need physical port) and encap id */
  18176         if ((rv = bcm_esw_wlan_port_get(unit, port, &wlan_port)) < 0) {
  18177             soc_mem_unlock(unit, VLAN_TABm);
  18178             return rv;
  18179         }
  18180         /* Check if wlan_port.port is a local port or trunk */
  18181         if (BCM_GPORT_IS_TRUNK(wlan_port.port)) {
  18182             trunk_id = BCM_GPORT_TRUNK_GET(wlan_port.port);
  18183             rv = _bcm_trunk_id_validate(unit, trunk_id);
  18184             if (BCM_FAILURE(rv)) {
  18185                   soc_mem_unlock(unit, VLAN_TABm);
  18186                   return (BCM_E_PORT);
  18187             }
  18188             local_gport = wlan_port.port;
  18189         } else {
  18190             rv = _bcm_esw_gport_resolve(unit, wlan_port.port, &mod_out, &port_out,
  18191                                 &trunk_id, &gport_id); 
  18192             if (BCM_FAILURE(rv)) {
  18193                 soc_mem_unlock(unit, VLAN_TABm);
  18194                 return (BCM_E_PORT);
  18195             }
  18196             rv = _bcm_esw_modid_is_local(unit, mod_out, &mod_local);
  18197             if (BCM_FAILURE(rv)) {
  18198                 soc_mem_unlock(unit, VLAN_TABm);
  18199                 return rv;
  18200             }
  18201             if (TRUE != mod_local) {
  18202                 /* Only add this to replication set if destination is local */
  18203                soc_mem_unlock(unit, VLAN_TABm);
  18204                return BCM_E_PORT;
  18205             }
  18206             /* Convert system local_port to physical local_port */
  18207             if (soc_feature(unit, soc_feature_sysport_remap)) {
  18208                 BCM_XLATE_SYSPORT_S2P(unit, &port_out);
  18209             }
  18210             rv = bcm_esw_port_gport_get(unit, port_out, &local_gport);
  18211             if (BCM_FAILURE(rv)) {
  18212                 soc_mem_unlock(unit, VLAN_TABm);
  18213                 return rv;
  18214             }        
  18215         }
  18216         rv = bcm_esw_multicast_wlan_encap_get(unit, group, local_gport,
  18217                                               port, &encap_id);
  18218         if (BCM_FAILURE(rv)) {
  18219             soc_mem_unlock(unit, VLAN_TABm);
  18220             return rv;
  18221         }
  18222 
  18223         /* Remove from the WLAN MC group */
  18224         if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) {
  18225            if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf)) {
  18226                /* No group exists - this is an error*/
  18227                soc_mem_unlock(unit, VLAN_TABm);
  18228                return BCM_E_PORT;
  18229            }
  18230         }
  18231 
  18232         bc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf);
  18233         _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_WLAN, bc_idx);
  18234         rv = bcm_esw_multicast_egress_delete(unit, group, local_gport, 
  18235                                               encap_id); 
  18236 
  18237         mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UMC_IDXf);
  18238         if (mc_idx != bc_idx) {
  18239             _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_WLAN, mc_idx);
  18240             rv = bcm_esw_multicast_egress_delete(unit, group, local_gport, 
  18241                                               encap_id);
  18242         }
  18243 
  18244         uuc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UUC_IDXf);
  18245         if ((uuc_idx != bc_idx) && (uuc_idx != mc_idx)) {
  18246             _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_WLAN, uuc_idx);
  18247             rv = bcm_esw_multicast_egress_delete(unit, group, local_gport, 
  18248                                               encap_id);
  18249         }
  18250 
  18251         soc_mem_unlock(unit, VLAN_TABm);
  18252 
  18253     } else if (soc_feature(unit, soc_feature_vlan_vp) && BCM_GPORT_IS_VLAN_PORT(port)) {
  18254 #if defined(BCM_ENDURO_SUPPORT)
  18255         if (SOC_IS_ENDURO(unit)) {
  18256             rv = bcm_enduro_vlan_vp_delete(unit, vlan, port);
  18257         } else 
  18258 #endif /* BCM_ENDURO_SUPPORT */
  18259         {
  18260             rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18261         }
  18262     } else if (soc_feature(unit, soc_feature_niv) &&
  18263             BCM_GPORT_IS_NIV_PORT(port)) {
  18264         rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18265     } else if (soc_feature(unit, soc_feature_port_extension) &&
  18266             BCM_GPORT_IS_EXTENDER_PORT(port)) {
  18267         rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18268     } else if (soc_feature(unit, soc_feature_vp_lag) &&
  18269             BCM_GPORT_IS_TRUNK(port)) {
  18270         rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18271     } else if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  18272                BCM_GPORT_IS_SUBPORT_PORT(port)) {
  18273         rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18274     } else if (soc_feature(unit, soc_feature_vxlan) &&
  18275                BCM_GPORT_IS_VXLAN_PORT(port)) {
  18276         rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18277     } else if (soc_feature(unit, soc_feature_flex_flow) &&
  18278                BCM_GPORT_IS_FLOW_PORT(port)) {
  18279         rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18280     } else if (soc_feature(unit, soc_feature_l2gre) &&
  18281                BCM_GPORT_IS_L2GRE_PORT(port)) {
  18282         rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18283     } else if (soc_feature(unit, soc_feature_mim) &&
  18284                BCM_GPORT_IS_MIM_PORT(port)) {
  18285         rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18286     } else if (soc_feature(unit, soc_feature_mpls) &&
  18287             BCM_GPORT_IS_MPLS_PORT(port)) {
  18288         rv = bcm_tr2_vlan_gport_delete(unit, vlan, port);
  18289     } else if (BCM_GPORT_IS_VP_GROUP(port)) {
  18290 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 
  18291 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  18292         if (soc_feature(unit, soc_feature_vlan_vfi_membership)){
  18293             rv = bcm_td2p_vlan_vp_group_set(unit, vlan,
  18294                 FALSE, BCM_GPORT_VP_GROUP_GET(port), FALSE);
  18295             BCM_IF_ERROR_RETURN(rv);
  18296 
  18297             rv = bcm_td2p_vlan_vp_group_set(unit, vlan,
  18298                 TRUE, BCM_GPORT_VP_GROUP_GET(port), FALSE);
  18299             BCM_IF_ERROR_RETURN(rv);
  18300         } else
  18301 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  18302         {
  18303             if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership)) {
  18304                 rv = bcm_td_vlan_vp_group_set(unit,VLAN_TABm,vlan,
  18305                         BCM_GPORT_VP_GROUP_GET(port),FALSE);
  18306                 BCM_IF_ERROR_RETURN(rv);
  18307             }
  18308             if (soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) {
  18309                 rv = bcm_td_vlan_vp_group_set(unit,EGR_VLANm,vlan,
  18310                         BCM_GPORT_VP_GROUP_GET(port), FALSE);
  18311                 BCM_IF_ERROR_RETURN(rv);
  18312             }
  18313         }
  18314 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  18315     } else
  18316 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
  18317     {
  18318         bcm_pbmp_t ing_pbmp, pbmp, ubmp;
  18319         bcm_port_t local_port;
  18320         int bc_idx, umc_idx, uuc_idx;
  18321         int bc_do_not_update, umc_do_not_update, uuc_do_not_update;
  18322         vlan_tab_entry_t vtab;
  18323         soc_field_t group_types[3] = {0,0,0};
  18324 
  18325         /* If Ingress/Egress only flags are specified and 'ING_PORT_BITMAPf' is
  18326            not a valid field in 'VLAN_TABm' AND if the
  18327            'soc_feature_vlan_vfi_membership' is FALSE, return error. If the
  18328            feature is TRUE, the mentioned field comes from the profiled
  18329            'ING_VLAN_VFI_MEMBERSHIPm' table*/
  18330         if (flags & (BCM_VLAN_PORT_INGRESS_ONLY | BCM_VLAN_PORT_EGRESS_ONLY)) {
  18331             if (!soc_mem_field_valid(unit, VLAN_TABLE(unit), ING_PORT_BITMAPf) &&
  18332                 !(soc_feature(unit, soc_feature_vlan_vfi_membership))) {
  18333                 return BCM_E_PARAM;
  18334             }
  18335         }
  18336 
  18337         if (flags & BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY) {
  18338             if (!soc_feature(unit, soc_feature_vlan_egress_membership_l3_only)) {
  18339                 return BCM_E_PARAM;
  18340             }
  18341         }
  18342 
  18343         BCM_IF_ERROR_RETURN(
  18344             bcm_esw_port_local_get(unit, port, &local_port));
  18345 
  18346         BCM_IF_ERROR_RETURN
  18347             (READ_VLAN_TABm(unit, MEM_BLOCK_ANY, vlan, &vtab));
  18348 
  18349         if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) {
  18350             bc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf);
  18351             umc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UMC_IDXf);
  18352             uuc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UUC_IDXf);
  18353 
  18354             if (flags & BCM_VLAN_GPORT_BCAST_DO_NOT_UPDATE) {
  18355                 bc_do_not_update = 1;
  18356             } else {
  18357                 bc_do_not_update = 0;
  18358             }
  18359             if (flags & BCM_VLAN_GPORT_UNKNOWN_MCAST_DO_NOT_UPDATE) {
  18360                 umc_do_not_update = 1;
  18361             } else {
  18362                 umc_do_not_update = 0;
  18363             }
  18364             if (flags & BCM_VLAN_GPORT_UNKNOWN_UCAST_DO_NOT_UPDATE) {
  18365                 uuc_do_not_update = 1;
  18366             } else {
  18367                 uuc_do_not_update = 0;
  18368             }
  18369 
  18370             if ((bc_idx == umc_idx) && (bc_do_not_update != umc_do_not_update)) {
  18371                 return BCM_E_PARAM;
  18372             }
  18373             if ((bc_idx == uuc_idx) && (bc_do_not_update != uuc_do_not_update)) {
  18374                 return BCM_E_PARAM;
  18375             }
  18376             if ((umc_idx == uuc_idx) && (umc_do_not_update != uuc_do_not_update)) {
  18377                 return BCM_E_PARAM;
  18378             }
  18379 
  18380             if (!bc_do_not_update) {
  18381                 group_types[0] = BC_IDXf;
  18382             }
  18383             if ((!umc_do_not_update) && (bc_idx != umc_idx)) {
  18384                 group_types[1] = UMC_IDXf;
  18385             }
  18386             if ((!uuc_do_not_update) && (uuc_idx != umc_idx) && (uuc_idx != bc_idx)) {
  18387                 group_types[2] = UUC_IDXf;
  18388             }
  18389         }
  18390         if (flags & 
  18391             (BCM_VLAN_PORT_EGRESS_ONLY | BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY)) {
  18392             BCM_PBMP_CLEAR(ing_pbmp);
  18393         } else {
  18394             BCM_PBMP_PORT_SET(ing_pbmp, local_port);
  18395         }
  18396         if (flags & BCM_VLAN_PORT_INGRESS_ONLY) {
  18397             BCM_PBMP_CLEAR(pbmp);
  18398         } else {
  18399             BCM_PBMP_PORT_SET(pbmp, local_port);
  18400         }
  18401         if (flags & BCM_VLAN_PORT_UNTAGGED) {
  18402             BCM_PBMP_PORT_SET(ubmp, local_port);
  18403         } else {
  18404             BCM_PBMP_CLEAR(ubmp);
  18405         }
  18406         rv = _bcm_vlan_port_remove(unit, vlan, pbmp, ubmp, ing_pbmp, group_types);
  18407     }
  18408     return rv;
  18409 }
  18410 
  18411 /*
  18412  * Function:
  18413  *      bcm_vlan_gport_delete_all
  18414  * Purpose:
  18415  *      Delete all Gports from the specified vlan.
  18416  * Parameters:
  18417  *      unit - StrataSwitch PCI device unit number (driver internal).
  18418  *      vlan - VLAN ID to add port to as a member.
  18419  * Returns:
  18420  *      BCM_E_NONE - Success.
  18421  *      BCM_E_INTERNAL - Chip access failure.
  18422  *      BCM_E_NOT_FOUND - VLAN ID not in use.
  18423  */
  18424 int
  18425 bcm_esw_vlan_gport_delete_all(int unit, bcm_vlan_t vlan)
  18426 {
  18427     int rv = BCM_E_NONE;
  18428     bcm_pbmp_t pbmp, ubmp;
  18429 
  18430 #ifdef BCM_TOMAHAWK3_SUPPORT
  18431     if (SOC_IS_TOMAHAWK3(unit)) {
  18432         return bcm_tomahawk3_vlan_gport_delete_all(unit, vlan);
  18433     }
  18434 #endif
  18435 
  18436     CHECK_INIT(unit);
  18437 
  18438 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
  18439     if (soc_feature(unit, soc_feature_vlan_vfi) &&
  18440         _BCM_VPN_VFI_IS_SET(vlan)) {
  18441         int vfi = 0;
  18442         _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vlan);
  18443         if (_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeVlan)) {
  18444             return bcm_tr2_vlan_gport_delete_all(unit, vlan);
  18445         }
  18446     }
  18447 #endif /* BCM_TRIUMPH3_SUPPORT */
  18448 
  18449 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
  18450     if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
  18451         if (_BCM_VPN_VFI_IS_SET(vlan)) {
  18452             int vfi = 0;
  18453             int vfi_max = soc_mem_index_max(unit, VFIm);
  18454 
  18455             _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vlan);
  18456             if (vfi < 0 || vfi > vfi_max) {
  18457                 return (BCM_E_PARAM);
  18458             }
  18459 
  18460             if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeAny)) {
  18461                 return BCM_E_NOT_FOUND;
  18462             }
  18463         } else {
  18464             VLAN_CHK_ID(unit, vlan);
  18465         }
  18466          
  18467         if (_BCM_VPN_VFI_IS_SET(vlan) || !SOC_IS_MONTEREY(unit)) {
  18468             BCM_IF_ERROR_RETURN(bcm_td2_ing_vp_vlan_membership_delete_all(unit, vlan));
  18469             BCM_IF_ERROR_RETURN(bcm_td2_egr_vp_vlan_membership_delete_all(unit, vlan));
  18470         }
  18471         if (_BCM_VPN_VFI_IS_SET(vlan)) {
  18472             if (bcm_td2p_ing_vp_group_unmanaged_get(unit)) {
  18473                 BCM_IF_ERROR_RETURN(
  18474                     bcm_td2p_vlan_vp_group_set(unit, vlan, FALSE, -1, FALSE));
  18475             } else {
  18476                 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_delete_all(unit, vlan, FALSE));
  18477             }
  18478             if (bcm_td2p_egr_vp_group_unmanaged_get(unit)) {
  18479                 BCM_IF_ERROR_RETURN(
  18480                     bcm_td2p_vlan_vp_group_set(unit, vlan, TRUE, -1, FALSE));
  18481             } else {
  18482                 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_delete_all(unit, vlan, TRUE));
  18483             }
  18484             return BCM_E_NONE;
  18485         }
  18486     }
  18487 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  18488 
  18489     VLAN_CHK_ID(unit, vlan);
  18490 
  18491     soc_mem_lock(unit, VLAN_TABm);
  18492 
  18493 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  18494 
  18495     if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) {
  18496 
  18497         int mc_idx,bc_idx,uuc_idx;
  18498         bcm_multicast_t mc_group;
  18499         vlan_tab_entry_t vtab;
  18500 
  18501         sal_memset(&vtab, 0, sizeof(vlan_tab_entry_t));
  18502 
  18503         if ((rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vlan, 
  18504              &vtab)) < 0) {
  18505             soc_mem_unlock(unit, VLAN_TABm);
  18506             return rv;
  18507         }
  18508         if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VALIDf)) {
  18509             soc_mem_unlock(unit, VLAN_TABm);
  18510             return BCM_E_NOT_FOUND;
  18511         }
  18512 
  18513         if (soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf)) {
  18514             /* Remove all VP members and delete the group */
  18515 
  18516             bc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf);
  18517             rv = _bcm_tr_multicast_ipmc_group_type_get(unit, bc_idx,
  18518                                                             &mc_group);
  18519             if (BCM_FAILURE(rv)) {
  18520                 soc_mem_unlock(unit, VLAN_TABm);
  18521                 return rv;
  18522             }
  18523             if (_BCM_MULTICAST_IS_WLAN(mc_group)) {
  18524 
  18525                 rv = bcm_esw_multicast_egress_delete_all(unit, mc_group); 
  18526                 if (BCM_FAILURE(rv)) {
  18527                     soc_mem_unlock(unit, VLAN_TABm);
  18528                     return rv;
  18529                 }
  18530                 rv = bcm_esw_multicast_destroy(unit, mc_group);
  18531                 if (BCM_FAILURE(rv)) {
  18532                     soc_mem_unlock(unit, VLAN_TABm);
  18533                     return rv;
  18534                 }
  18535 
  18536                 mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UMC_IDXf);
  18537                 if (mc_idx != bc_idx) {
  18538                     rv = _bcm_tr_multicast_ipmc_group_type_get(unit, mc_idx,
  18539                                                               &mc_group);
  18540                     if (BCM_FAILURE(rv)) {
  18541                          soc_mem_unlock(unit, VLAN_TABm);
  18542                          return rv;
  18543                     }
  18544                      
  18545                     rv = bcm_esw_multicast_egress_delete_all(unit, mc_group); 
  18546                     if (BCM_FAILURE(rv)) {
  18547                         soc_mem_unlock(unit, VLAN_TABm);
  18548                         return rv;
  18549                     }
  18550                     
  18551                     rv = bcm_esw_multicast_destroy(unit, mc_group);
  18552                     if (BCM_FAILURE(rv)) {
  18553                         soc_mem_unlock(unit, VLAN_TABm);
  18554                         return rv;
  18555                     }
  18556                 }
  18557                 
  18558                 uuc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, UUC_IDXf);
  18559                 if ((bc_idx != uuc_idx) && (mc_idx != uuc_idx)) {
  18560                     rv = _bcm_tr_multicast_ipmc_group_type_get(unit, uuc_idx,
  18561                                                               &mc_group);
  18562                     if (BCM_FAILURE(rv)) {
  18563                         soc_mem_unlock(unit, VLAN_TABm);
  18564                         return rv;
  18565                     }
  18566                     
  18567                     rv = bcm_esw_multicast_egress_delete_all(unit, mc_group); 
  18568                     if (BCM_FAILURE(rv)) {
  18569                         soc_mem_unlock(unit, VLAN_TABm);
  18570                         return rv;
  18571                     }
  18572                     rv = bcm_esw_multicast_destroy(unit, mc_group);
  18573                     if (BCM_FAILURE(rv)) {
  18574                         soc_mem_unlock(unit, VLAN_TABm);
  18575                         return rv;
  18576                     }
  18577                 }
  18578 
  18579                 if (!SHR_BITGET(vlan_info[unit].vp_mode, vlan)) {
  18580                     soc_mem_field32_set(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf, 0);
  18581                 }
  18582                 
  18583                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vtab, BC_IDXf, 0);
  18584                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vtab, UMC_IDXf, 0);
  18585                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vtab, UUC_IDXf, 0);
  18586                 if ((rv = soc_mem_write(unit, VLAN_TABm, MEM_BLOCK_ALL,
  18587                                 (int)vlan, &vtab)) < 0) {
  18588                     soc_mem_unlock(unit, VLAN_TABm);
  18589                     return rv;
  18590                 }
  18591             } else if (_BCM_MULTICAST_IS_VLAN(mc_group)) {
  18592 #if defined(BCM_ENDURO_SUPPORT)
  18593                 if (SOC_IS_ENDURO(unit)) {
  18594                     rv = bcm_enduro_vlan_vp_delete_all(unit, vlan);
  18595                 } else 
  18596 #endif /* BCM_ENDURO_SUPPORT */
  18597                 {
  18598                     rv = bcm_tr2_vlan_gport_delete_all(unit, vlan);
  18599                 }
  18600                 if (BCM_FAILURE(rv)) {
  18601                     soc_mem_unlock(unit, VLAN_TABm);
  18602                     return rv;
  18603                 }
  18604             } else if (_BCM_MULTICAST_IS_NIV(mc_group) ||
  18605                     _BCM_MULTICAST_IS_EXTENDER(mc_group)) {
  18606                 rv = bcm_tr2_vlan_gport_delete_all(unit, vlan);
  18607                 if (BCM_FAILURE(rv)) {
  18608                     soc_mem_unlock(unit, VLAN_TABm);
  18609                     return rv;
  18610                 }
  18611             } else {
  18612                 /* Invalid multicast group type */
  18613                 soc_mem_unlock(unit, VLAN_TABm);
  18614                 return BCM_E_INTERNAL;
  18615             }
  18616 
  18617             /* check if it is vp group unmanaged mode */
  18618 #if defined(BCM_TRIDENT_SUPPORT) 
  18619 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  18620             if (soc_feature(unit, soc_feature_vlan_vfi_membership)){
  18621                 if (bcm_td2p_ing_vp_group_unmanaged_get(unit)) {
  18622                     /* clear the vp group bitmap for this vlan */
  18623                     rv = bcm_td2p_vlan_vp_group_set(unit, vlan, FALSE, -1, FALSE);
  18624                     if (rv != BCM_E_NONE) {
  18625                         soc_mem_unlock(unit, VLAN_TABm);
  18626                         return rv;
  18627                     }
  18628                  }
  18629                 if (bcm_td2p_egr_vp_group_unmanaged_get(unit)) {
  18630                     /* clear the vp group bitmap for this vlan */
  18631                     rv = bcm_td2p_vlan_vp_group_set(unit, vlan, TRUE, -1, FALSE);
  18632                     if (rv != BCM_E_NONE) {
  18633                         soc_mem_unlock(unit, VLAN_TABm);
  18634                         return rv;
  18635                     }
  18636                 }
  18637             } else
  18638 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  18639             {
  18640                 if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership) &&
  18641                         bcm_td_ing_vp_group_unmanaged_get(unit)) {
  18642                     /* clear the vp group bitmap for this vlan */
  18643                     rv = bcm_td_vlan_vp_group_set(unit,VLAN_TABLE(unit),vlan, -1,FALSE);
  18644                     if (rv != BCM_E_NONE) {
  18645                         soc_mem_unlock(unit, VLAN_TABm);
  18646                         return rv;
  18647                     }
  18648                 }
  18649                 if (soc_feature(unit, soc_feature_vp_group_egress_vlan_membership) &&
  18650                         bcm_td_egr_vp_group_unmanaged_get(unit)) {
  18651                     /* clear the vp group bitmap for this vlan */
  18652                     rv = bcm_td_vlan_vp_group_set(unit,EGR_VLANm,vlan, -1,FALSE);
  18653                     if (rv != BCM_E_NONE) {
  18654                         soc_mem_unlock(unit, VLAN_TABm);
  18655                         return rv;
  18656                     }
  18657                 }
  18658             }
  18659 #endif /* BCM_TRIDENT_SUPPORT */
  18660         }
  18661     } 
  18662 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
  18663 
  18664     /* Now remove all local physical ports */
  18665     BCM_PBMP_CLEAR(pbmp);
  18666     BCM_PBMP_CLEAR(ubmp);
  18667     rv = bcm_esw_vlan_port_get(unit, vlan, &pbmp, &ubmp);
  18668     if (BCM_FAILURE(rv)) {
  18669         soc_mem_unlock(unit, VLAN_TABm);
  18670         return rv;
  18671     }
  18672     rv = bcm_esw_vlan_port_remove(unit, vlan, pbmp);
  18673     soc_mem_unlock(unit, VLAN_TABm);
  18674 
  18675     return rv;
  18676 }
  18677 
  18678 int
  18679 bcm_esw_vlan_gport_get(int unit, bcm_vlan_t vlan, bcm_gport_t port, 
  18680                        int *flags)
  18681 {
  18682     int rv = BCM_E_NONE;
  18683     bcm_pbmp_t pbmp, ubmp, ing_pbmp;
  18684 
  18685 #ifdef BCM_TOMAHAWK3_SUPPORT
  18686     if (SOC_IS_TOMAHAWK3(unit)) {
  18687         return bcm_tomahawk3_vlan_gport_get(unit, vlan, port, flags);
  18688     }
  18689 #endif
  18690 
  18691     CHECK_INIT(unit);
  18692 
  18693     /* VFI types like VxLAN passes in a VFI and not VLAN, hence check one
  18694        or the other */
  18695     BCM_IF_ERROR_RETURN(bcmi_esw_vlan_vfi_validate(unit, vlan));
  18696     
  18697     if (port == BCM_GPORT_INVALID)
  18698         return BCM_E_PORT;
  18699 
  18700 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  18701     if (soc_feature(unit, soc_feature_wlan) && BCM_GPORT_IS_WLAN_PORT(port)) {
  18702         int idx, vp, mc_idx, gport_id, group = 0, mod_local;
  18703         vlan_tab_entry_t vtab;
  18704         bcm_wlan_port_t wlan_port;
  18705         bcm_module_t mod_out;
  18706         bcm_port_t port_out=0;
  18707         bcm_trunk_t trunk_id;
  18708         bcm_port_t trunk_member_port[SOC_MAX_NUM_PORTS];
  18709         bcm_gport_t local_gport;
  18710         bcm_if_t encap_id;
  18711         bcm_if_t *if_array = NULL;
  18712         int alloc_size, if_count, if_cur, if_max, match, trunk_local_ports = 0;
  18713 
  18714         vp = BCM_GPORT_WLAN_PORT_ID_GET(port);
  18715         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) {
  18716             return BCM_E_NOT_FOUND;
  18717         }
  18718         sal_memset(&vtab, 0, sizeof(vlan_tab_entry_t));
  18719 
  18720         BCM_IF_ERROR_RETURN
  18721             (soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vlan, &vtab));
  18722 
  18723         if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VALIDf)) {
  18724             return BCM_E_NOT_FOUND;
  18725         }
  18726 
  18727         /* Get the VP attributes (need physical port) and encap id */
  18728         BCM_IF_ERROR_RETURN(bcm_esw_wlan_port_get(unit, port, &wlan_port));
  18729         /* Check if wlan_port.port is a local port or trunk */
  18730         if (BCM_GPORT_IS_TRUNK(wlan_port.port)) {
  18731             trunk_id = BCM_GPORT_TRUNK_GET(wlan_port.port);
  18732             rv = _bcm_trunk_id_validate(unit, trunk_id);
  18733             if (BCM_FAILURE(rv)) {
  18734                   return (BCM_E_PORT);
  18735             }
  18736             rv = _bcm_esw_trunk_local_members_get(unit, trunk_id,
  18737                     SOC_MAX_NUM_PORTS, trunk_member_port, &trunk_local_ports);
  18738             if (BCM_FAILURE(rv)) {
  18739                   return (BCM_E_PORT);
  18740             }
  18741             local_gport = wlan_port.port;
  18742         } else {
  18743             rv = _bcm_esw_gport_resolve(unit, wlan_port.port, &mod_out, &port_out,
  18744                               &trunk_id, &gport_id); 
  18745             if (BCM_FAILURE(rv)) {
  18746                 return (BCM_E_PORT);
  18747             }
  18748             rv = _bcm_esw_modid_is_local(unit, mod_out, &mod_local);
  18749             BCM_IF_ERROR_RETURN(rv);
  18750             if (TRUE != mod_local) {
  18751                 /* Only add this to replication set if destination is local */
  18752                return BCM_E_PORT;
  18753             }
  18754             /* Convert system local_port to physical local_port */
  18755             if (soc_feature(unit, soc_feature_sysport_remap)) {
  18756                 BCM_XLATE_SYSPORT_S2P(unit, &port_out);
  18757             }
  18758             rv = bcm_esw_port_gport_get(unit, port_out, &local_gport);
  18759             if (BCM_FAILURE(rv)) {
  18760                 return rv;
  18761             }        
  18762         }
  18763         BCM_IF_ERROR_RETURN
  18764             (bcm_esw_multicast_wlan_encap_get(unit, group, local_gport,
  18765                                               port, &encap_id));
  18766 
  18767         /* Search the WLAN MC group */
  18768         if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) {
  18769             if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf)) {
  18770                /* No group exists - so not found */
  18771                return BCM_E_NOT_FOUND;
  18772             }
  18773         }
  18774         mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf);
  18775         _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_WLAN, mc_idx);
  18776 
  18777         /* If trunk, iterate over all local ports in the trunk and search for
  18778          * a match on any local port */
  18779         if_max = soc_mem_index_count(unit, EGR_L3_INTFm) + 
  18780                  soc_mem_index_count(unit, EGR_L3_NEXT_HOPm);
  18781         alloc_size = if_max * sizeof(int);
  18782         if_array = sal_alloc(alloc_size, "temp IPMC repl interface array");
  18783         if (if_array == NULL) {
  18784             return BCM_E_MEMORY;
  18785         }
  18786         match = FALSE;
  18787         if (BCM_GPORT_IS_TRUNK(wlan_port.port)) {
  18788             for (idx = 0; idx < trunk_local_ports; idx++) {
  18789                 rv = bcm_esw_ipmc_egress_intf_get(unit, mc_idx, 
  18790                                                   trunk_member_port[idx], 
  18791                                                   if_max, if_array, &if_count);
  18792                 if (BCM_SUCCESS(rv)) {
  18793                     for (if_cur = 0; if_cur < if_count; if_cur++) {
  18794                         if (if_array[if_cur] == encap_id) {
  18795                             match = TRUE;
  18796                             *flags = 0;
  18797                             break;
  18798                         }
  18799                     }
  18800                     if (match) {
  18801                         break;
  18802                     }
  18803                 }
  18804             }
  18805         } else {
  18806             rv = bcm_esw_ipmc_egress_intf_get(unit, mc_idx, port_out, if_max,
  18807                                               if_array, &if_count);
  18808             if (BCM_SUCCESS(rv)) {
  18809                 for (if_cur = 0; if_cur < if_count; if_cur++) {
  18810                     if (if_array[if_cur] == encap_id) {
  18811                         match = TRUE;
  18812                         *flags = 0;
  18813                         break;
  18814                     }
  18815                 }
  18816             }
  18817         }
  18818 #ifdef BCM_TRIUMPH3_SUPPORT 
  18819         /* Triumph3 WLAN axp port to match replication interface */
  18820         if (SOC_IS_TRIUMPH3(unit) &&
  18821            _BCM_MULTICAST_IS_WLAN(group)) {
  18822                 port_out = AXP_PORT(unit, SOC_AXP_NLF_WLAN_ENCAP);
  18823                 rv = bcm_esw_ipmc_egress_intf_get(unit, mc_idx, port_out, if_max,
  18824                                           if_array, &if_count);
  18825             if (BCM_SUCCESS(rv)) {
  18826                 match = FALSE;
  18827                 for (if_cur = 0; if_cur < if_count; if_cur++) {
  18828                     if (if_array[if_cur] == encap_id) {
  18829                         match = TRUE;
  18830                         *flags = 0;
  18831                         break;
  18832                     }
  18833                 }
  18834 
  18835             }
  18836         } 
  18837 #endif /* BCM_TRIUMPH3_SUPPORT */
  18838 
  18839         if (!match) {
  18840             rv = BCM_E_NOT_FOUND;
  18841         }
  18842         sal_free(if_array);
  18843 
  18844     } else if (soc_feature(unit, soc_feature_vlan_vp) && BCM_GPORT_IS_VLAN_PORT(port)) {
  18845 #if defined(BCM_ENDURO_SUPPORT)
  18846         if (SOC_IS_ENDURO(unit)) {
  18847             rv = bcm_enduro_vlan_vp_get(unit, vlan, port, flags);
  18848         } else 
  18849 #endif /* BCM_ENDURO_SUPPORT */
  18850         {
  18851             /* coverity[stack_use_callee] */
  18852             /* coverity[stack_use_overflow] */
  18853             rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags);
  18854         }
  18855 
  18856     } else if (soc_feature(unit, soc_feature_niv) &&
  18857             BCM_GPORT_IS_NIV_PORT(port)) {
  18858         rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags);
  18859     } else if (soc_feature(unit, soc_feature_port_extension) &&
  18860             BCM_GPORT_IS_EXTENDER_PORT(port)) {
  18861         rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags);
  18862     } else if (soc_feature(unit, soc_feature_vp_lag) &&
  18863             BCM_GPORT_IS_TRUNK(port)) {
  18864         rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags);
  18865     } else if (soc_feature(unit, soc_feature_vxlan) &&
  18866             BCM_GPORT_IS_VXLAN_PORT(port)) {
  18867         rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags);
  18868     } else if (soc_feature(unit, soc_feature_flex_flow) &&
  18869             BCM_GPORT_IS_FLOW_PORT(port)) {
  18870         rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags);
  18871     } else if (soc_feature(unit, soc_feature_l2gre) &&
  18872             BCM_GPORT_IS_L2GRE_PORT(port)) {
  18873         rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags);
  18874     } else if (soc_feature(unit, soc_feature_mim) &&
  18875             BCM_GPORT_IS_MIM_PORT(port)) {
  18876         rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags);
  18877     } else if (soc_feature(unit, soc_feature_mpls) &&
  18878             BCM_GPORT_IS_MPLS_PORT(port)) {
  18879         rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags);
  18880     } else if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  18881             BCM_GPORT_IS_SUBPORT_PORT(port)) {
  18882         rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags);
  18883     } else if (BCM_GPORT_IS_VP_GROUP(port)) {
  18884 #if defined(BCM_TRIDENT_SUPPORT)
  18885         int enable;
  18886         int vpg = BCM_GPORT_VP_GROUP_GET(port);
  18887 
  18888         *flags=0;
  18889 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  18890         if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
  18891             bcm_stg_t stg;
  18892             int ut_state;
  18893             int hw_stp_state;
  18894 
  18895             BCM_IF_ERROR_RETURN(
  18896                 bcm_td2p_vlan_vp_group_get(unit, vlan, FALSE, vpg, &enable));
  18897             if (enable) {
  18898                 *flags = BCM_VLAN_PORT_INGRESS_ONLY;
  18899 
  18900                 BCM_IF_ERROR_RETURN(
  18901                     bcm_td2p_vp_group_vlan_vpn_stg_get(unit, vlan, FALSE, &stg));
  18902                 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_stp_state_get(
  18903                                     unit, stg, port, FALSE, &hw_stp_state));
  18904                 *flags |= _bcm_td2_stp_state_to_flags(unit, hw_stp_state, FALSE);
  18905             }
  18906 
  18907             BCM_IF_ERROR_RETURN(
  18908                 bcm_td2p_vlan_vp_group_get(unit, vlan, TRUE, vpg, &enable));
  18909             if (enable) {
  18910                 *flags |= BCM_VLAN_PORT_EGRESS_ONLY;
  18911 
  18912                 BCM_IF_ERROR_RETURN(
  18913                     bcm_td2p_vp_group_vlan_vpn_stg_get(unit, vlan, TRUE, &stg));
  18914                 BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_stp_state_get(
  18915                                     unit, stg, port, TRUE, &hw_stp_state));
  18916                 *flags |= _bcm_td2_stp_state_to_flags(unit, hw_stp_state, TRUE);
  18917 
  18918                 if (!_BCM_VPN_VFI_IS_SET(vlan)) {
  18919                     BCM_IF_ERROR_RETURN(
  18920                         bcm_td2p_vp_group_ut_state_get(unit, port, vlan, &ut_state));
  18921                     if (ut_state) {
  18922                         *flags |= BCM_VLAN_GPORT_ADD_UNTAGGED;
  18923                     }
  18924                 }
  18925 #if defined(BCM_TRIDENT3_SUPPORT)
  18926                 else if (SOC_MEM_IS_VALID(unit, EGR_VLAN_VFI_UNTAGm)) {
  18927                     BCM_IF_ERROR_RETURN(
  18928                         bcm_td2p_vp_group_ut_state_get(unit, port, vlan, &ut_state));
  18929                     if (ut_state) {
  18930                         *flags |= BCM_VLAN_GPORT_ADD_UNTAGGED;
  18931                     }
  18932                 }
  18933 #endif
  18934             }
  18935         } else
  18936 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  18937         {
  18938             if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership)) {
  18939                 BCM_IF_ERROR_RETURN(bcm_td_vlan_vp_group_get(
  18940                             unit, VLAN_TABLE(unit), vlan, vpg, &enable));
  18941                 if (enable) {
  18942                     *flags = BCM_VLAN_PORT_INGRESS_ONLY;
  18943                 }
  18944             }
  18945             if (soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) {
  18946                 BCM_IF_ERROR_RETURN(bcm_td_vlan_vp_group_get(
  18947                             unit, EGR_VLANm, vlan,vpg, &enable));
  18948                 if (enable) {
  18949                     *flags |= BCM_VLAN_PORT_EGRESS_ONLY;
  18950                 }
  18951             }
  18952         }
  18953 #endif /* BCM_TRIDENT_SUPPORT */
  18954 
  18955     } else
  18956 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
  18957 
  18958     {
  18959         bcm_port_t local_port;
  18960         uint32 local_flags;
  18961 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  18962         uint32 filter_flags = 0;
  18963 #endif
  18964 
  18965         BCM_IF_ERROR_RETURN(
  18966             bcm_esw_port_local_get(unit, port, &local_port));
  18967 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
  18968         if (soc_feature(unit, soc_feature_egr_vp_vlan_membership)) {
  18969             if (_BCM_VPN_VFI_IS_SET(vlan) && BCM_GPORT_IS_MODPORT(port)) {
  18970                 BCM_IF_ERROR_RETURN(bcm_esw_port_vlan_member_get(unit, local_port, &filter_flags));
  18971                 if ((filter_flags & BCM_PORT_VLAN_MEMBER_EGRESS) &&
  18972                             (filter_flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) {
  18973                     rv = bcm_tr2_vlan_gport_get(unit, vlan, port, flags);
  18974                     return rv;
  18975                 }
  18976             }
  18977         }
  18978 #endif
  18979 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  18980         if (soc_feature(unit, soc_feature_vlan_vfi_membership) &&
  18981             BCM_GPORT_IS_MODPORT(port)) {
  18982             BCM_IF_ERROR_RETURN(bcm_esw_port_vlan_member_get(unit, local_port, &filter_flags));
  18983             if (filter_flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP) {
  18984                 MOD_PORT_TO_GLP(unit, BCM_GPORT_MODPORT_MODID_GET(port),
  18985                     BCM_GPORT_MODPORT_PORT_GET(port), port);
  18986                 rv = bcm_td2_vp_vlan_membership_get(unit, port, vlan, flags);
  18987                 return rv;
  18988             }
  18989         }
  18990 #endif
  18991         /* Deal with local physical ports */
  18992         rv = _bcm_vlan_port_get(unit, vlan, &pbmp, &ubmp, &ing_pbmp);
  18993         local_flags = 0;
  18994         if (!BCM_PBMP_MEMBER(pbmp, local_port)) {
  18995             local_flags |= BCM_VLAN_PORT_INGRESS_ONLY;
  18996         }
  18997         if (!BCM_PBMP_MEMBER(ing_pbmp, local_port)) {
  18998             local_flags |= BCM_VLAN_PORT_EGRESS_ONLY;
  18999         }
  19000         if (local_flags ==
  19001             (BCM_VLAN_PORT_INGRESS_ONLY | BCM_VLAN_PORT_EGRESS_ONLY)) {
  19002             return BCM_E_NOT_FOUND;
  19003         }
  19004         if (BCM_PBMP_MEMBER(ubmp, local_port)) {
  19005             local_flags |= BCM_VLAN_PORT_UNTAGGED;
  19006         }
  19007 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT)
  19008         if (soc_feature(unit, soc_feature_vlan_egress_membership_l3_only) &&
  19009             (local_flags & BCM_VLAN_PORT_EGRESS_ONLY) && BCM_VLAN_VALID(vlan)) {
  19010             bcm_pbmp_t vlan_tab_pbmp;
  19011             BCM_IF_ERROR_RETURN
  19012                 (_bcm_xgs3_vlan_table_port_get(unit, vlan, &vlan_tab_pbmp,
  19013                                                 NULL, NULL, VLAN_TABLE(unit)));
  19014             if (!BCM_PBMP_MEMBER(vlan_tab_pbmp, local_port)) {
  19015                 local_flags &= ~BCM_VLAN_PORT_EGRESS_ONLY;
  19016                 local_flags |= BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY;
  19017             }
  19018         }
  19019 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_HURRICANE3_SUPPORT */
  19020         *flags = local_flags;
  19021     }
  19022 
  19023     return rv;
  19024 }
  19025 
  19026 int
  19027 bcm_esw_vlan_gport_get_all(int unit, bcm_vlan_t vlan, int array_max, 
  19028                            bcm_gport_t *gport_array, int *flags_array, 
  19029                            int* array_size)
  19030 {
  19031     bcm_pbmp_t          pbmp, ubmp, ing_pbmp, bmp;
  19032     bcm_port_t          port, gport;
  19033     bcm_module_t        modid;
  19034     int                 port_cnt = 0, is_vfi = 0;
  19035     _bcm_gport_dest_t   gport_dest; 
  19036     vlan_tab_entry_t    vtab;
  19037     uint32              local_flags;
  19038 
  19039 #ifdef BCM_TOMAHAWK3_SUPPORT
  19040     if (SOC_IS_TOMAHAWK3(unit)) {
  19041         return
  19042             bcm_tomahawk3_vlan_gport_get_all(
  19043                 unit, vlan, array_max, gport_array, flags_array, array_size);
  19044     }
  19045 #endif
  19046 
  19047     CHECK_INIT(unit);
  19048 
  19049     if (NULL == array_size || array_max < 0) {
  19050         return BCM_E_PARAM;
  19051     }
  19052 
  19053     if ((array_max > 0) && (NULL == gport_array)) {
  19054         return BCM_E_PARAM;
  19055     }
  19056 
  19057     /*
  19058      * VFI types like VxLAN passes in a VFI and not VLAN,
  19059      * hence check one or the other
  19060      */
  19061     BCM_IF_ERROR_RETURN(bcmi_esw_vlan_vfi_validate(unit, vlan));
  19062 
  19063     if(_BCM_VPN_VFI_IS_SET(vlan)) {
  19064         is_vfi = 1;
  19065     }
  19066 
  19067 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
  19068     if (soc_feature(unit, soc_feature_vlan_vfi) && is_vfi) {
  19069         return bcm_tr2_vlan_gport_get_all(unit, vlan, array_max,
  19070                             gport_array, flags_array, array_size);
  19071     }
  19072 #endif /* BCM_TRIUMPH3_SUPPORT */
  19073 
  19074     if(!is_vfi) {
  19075 
  19076         BCM_IF_ERROR_RETURN(
  19077             soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vlan, &vtab));
  19078         if (!soc_mem_field32_get(unit, VLAN_TABm, &vtab, VALIDf)) {
  19079             return BCM_E_NOT_FOUND;
  19080         }
  19081 
  19082         port_cnt = 0;
  19083 
  19084         BCM_IF_ERROR_RETURN
  19085             (_bcm_vlan_port_get(unit, vlan, &pbmp, &ubmp, &ing_pbmp));
  19086         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &modid));
  19087 
  19088         /* Prepare a superset of bitmaps to itterate over */
  19089         BCM_PBMP_ASSIGN(bmp, pbmp);
  19090         BCM_PBMP_OR(bmp, ubmp);
  19091         BCM_PBMP_OR(bmp, ing_pbmp);
  19092 
  19093         BCM_PBMP_ITER(bmp, port) {
  19094             if ((port_cnt == array_max) && (gport_array)) {
  19095                 break;
  19096             }
  19097             gport_dest.port = port;
  19098             gport_dest.modid = modid;
  19099             gport_dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
  19100             BCM_IF_ERROR_RETURN(
  19101                 _bcm_esw_gport_construct(unit, &gport_dest, &gport));
  19102             local_flags = 0;
  19103             if (!BCM_PBMP_MEMBER(pbmp, port)) {
  19104                 local_flags |= BCM_VLAN_PORT_INGRESS_ONLY;
  19105             }
  19106             if (!BCM_PBMP_MEMBER(ing_pbmp, port)) {
  19107                 local_flags |= BCM_VLAN_PORT_EGRESS_ONLY;
  19108             }
  19109             if (local_flags ==
  19110                 (BCM_VLAN_PORT_INGRESS_ONLY | BCM_VLAN_PORT_EGRESS_ONLY)) {
  19111                 continue;
  19112             }
  19113             if (flags_array) {
  19114                 if (BCM_PBMP_MEMBER(ubmp, port)) {
  19115                     local_flags |= BCM_VLAN_PORT_UNTAGGED;
  19116                 }
  19117                 flags_array[port_cnt] = local_flags;
  19118             }
  19119             if (gport_array) {
  19120                 gport_array[port_cnt] = gport;
  19121             }
  19122             port_cnt++;
  19123         }
  19124     } /* !is_vfi */
  19125 
  19126 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  19127     /* Check existance of virtual ports */
  19128     if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf) && !is_vfi) {
  19129         int get_all_from_tr2 = 0;
  19130         if (soc_mem_field32_get(unit, VLAN_TABm, &vtab, VIRTUAL_PORT_ENf) &&
  19131             (port_cnt < array_max)) {
  19132             int mc_idx;
  19133             bcm_multicast_t mc_group;
  19134 
  19135             mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vtab, BC_IDXf);
  19136             BCM_IF_ERROR_RETURN
  19137                 (_bcm_tr_multicast_ipmc_group_type_get(unit, mc_idx,
  19138                                                        &mc_group));
  19139             if (_BCM_MULTICAST_IS_WLAN(mc_group)) {
  19140                 int i, local_size;
  19141 
  19142                 if (gport_array) {
  19143                     BCM_IF_ERROR_RETURN(
  19144                             bcm_esw_multicast_egress_get(unit, mc_group,
  19145                                 array_max - port_cnt, (gport_array + port_cnt),
  19146                                 NULL, &local_size));
  19147                     for (i = 0; i < local_size; i++) {
  19148                         if ((port_cnt == array_max) && (gport_array)) {
  19149                             break;
  19150                         }
  19151                         if (flags_array) {
  19152                             flags_array[port_cnt] = BCM_VLAN_PORT_UNTAGGED;
  19153                         }
  19154                         port_cnt++;
  19155                     }
  19156                 }
  19157             } else if (_BCM_MULTICAST_IS_VLAN(mc_group)) {
  19158                 if (gport_array) {
  19159 #if defined(BCM_ENDURO_SUPPORT)
  19160                     if (SOC_IS_ENDURO(unit)) {
  19161                         int local_size;
  19162                         if (flags_array) {
  19163                             BCM_IF_ERROR_RETURN
  19164                                 (bcm_enduro_vlan_vp_get_all
  19165                                  (unit, vlan, array_max - port_cnt,
  19166                                   &gport_array[port_cnt], &flags_array[port_cnt],
  19167                                   &local_size));
  19168                         } else {
  19169                             BCM_IF_ERROR_RETURN
  19170                                 (bcm_enduro_vlan_vp_get_all
  19171                                  (unit, vlan, array_max - port_cnt,
  19172                                   &gport_array[port_cnt], NULL, &local_size));
  19173                         }
  19174                         port_cnt += local_size;
  19175                     } else
  19176 #endif /* BCM_ENDURO_SUPPORT */
  19177                     {
  19178                         int local_size;
  19179                         if (flags_array) {
  19180                             BCM_IF_ERROR_RETURN
  19181                                 (bcm_tr2_vlan_gport_get_all
  19182                                  (unit, vlan, array_max - port_cnt,
  19183                                   &gport_array[port_cnt], &flags_array[port_cnt],
  19184                                   &local_size));
  19185                         } else {
  19186                             BCM_IF_ERROR_RETURN
  19187                                 (bcm_tr2_vlan_gport_get_all
  19188                                  (unit, vlan, array_max - port_cnt,
  19189                                   &gport_array[port_cnt], NULL, &local_size));
  19190                         }
  19191                         port_cnt += local_size;
  19192                     }
  19193                 }
  19194                 get_all_from_tr2 = 1;
  19195             } else if (_BCM_MULTICAST_IS_NIV(mc_group) ||
  19196                     _BCM_MULTICAST_IS_EXTENDER(mc_group)) {
  19197                 int local_size;
  19198                 if (gport_array) {
  19199                     if (flags_array) {
  19200                         BCM_IF_ERROR_RETURN
  19201                             (bcm_tr2_vlan_gport_get_all
  19202                              (unit, vlan, array_max - port_cnt,
  19203                               &gport_array[port_cnt], &flags_array[port_cnt],
  19204                               &local_size));
  19205                     } else {
  19206                         BCM_IF_ERROR_RETURN
  19207                             (bcm_tr2_vlan_gport_get_all
  19208                              (unit, vlan, array_max - port_cnt,
  19209                               &gport_array[port_cnt], NULL, &local_size));
  19210                     }
  19211                     port_cnt += local_size;
  19212                 }
  19213                 get_all_from_tr2 = 1;
  19214             } else {
  19215                 /* Unrecognized multicast type */
  19216                 return BCM_E_INTERNAL;
  19217             }
  19218         }
  19219 
  19220         if (!get_all_from_tr2 &&
  19221                 (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_TRIDENT3X(unit) ||
  19222                  SOC_IS_APACHE(unit))) {
  19223 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  19224             BCM_IF_ERROR_RETURN(
  19225                 bcm_td2p_vp_vlan_membership_get_all(unit, vlan,
  19226                 array_max, gport_array, flags_array, &port_cnt));
  19227 #endif
  19228         }
  19229     }
  19230 #if defined(BCM_TRIDENT_SUPPORT)
  19231 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  19232     if (is_vfi) {
  19233         if (soc_feature(unit, soc_feature_ing_vp_vlan_membership) ||
  19234             soc_feature(unit, soc_feature_egr_vp_vlan_membership)) {
  19235             BCM_IF_ERROR_RETURN(bcm_td2p_vp_vlan_membership_get_all(unit, vlan,
  19236                         array_max, gport_array, flags_array, &port_cnt));
  19237         }
  19238     }
  19239 
  19240     if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
  19241         BCM_IF_ERROR_RETURN(bcm_td2p_vlan_vp_group_get_all(unit,vlan,
  19242                     array_max, gport_array,flags_array,&port_cnt));
  19243     } else
  19244 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  19245 #if defined(BCM_TRIDENT2_SUPPORT)
  19246         if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT2(unit) ||
  19247                 SOC_IS_APACHE(unit)) {
  19248         if (soc_feature(unit, soc_feature_ing_vp_vlan_membership) ||
  19249             soc_feature(unit, soc_feature_egr_vp_vlan_membership)) {
  19250             BCM_IF_ERROR_RETURN(bcm_td2_vp_vlan_membership_get_all(unit, vlan,
  19251                         array_max, gport_array, flags_array, &port_cnt));
  19252         }
  19253     } else
  19254 #endif
  19255     {
  19256         BCM_IF_ERROR_RETURN(bcm_td_vlan_vp_group_get_all(unit,vlan,
  19257                     array_max, gport_array,flags_array,&port_cnt));
  19258     }
  19259 #endif /* BCM_TRIDENT_SUPPORT */
  19260 #endif /* BCM_TRIUMPH2_SUPPORT  && INCLUDE_L3 */
  19261 
  19262     /* If all attempts found nothing return not found */
  19263     if (!port_cnt) {
  19264         return BCM_E_NOT_FOUND;
  19265     }
  19266 
  19267     *array_size = port_cnt;
  19268     return BCM_E_NONE;
  19269 }
  19270 
  19271 /*
  19272  * Function:
  19273  *      bcm_esw_vlan_port_create
  19274  * Purpose:
  19275  *      Create a VLAN virtual port.
  19276  * Parameters:
  19277  *      unit - (IN) SOC unit number. 
  19278  *      vlan_port - (IN/OUT) Pointer to a VLAN virtual port structure. 
  19279  * Returns:
  19280  *      BCM_X_XXX
  19281  */
  19282 int
  19283 bcm_esw_vlan_port_create(int unit,
  19284                          bcm_vlan_port_t *vlan_port)
  19285 {
  19286 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  19287     if (soc_feature(unit, soc_feature_vlan_vp)) {
  19288 #if defined(BCM_ENDURO_SUPPORT)
  19289         if (SOC_IS_ENDURO(unit)) {
  19290             return bcm_enduro_vlan_vp_create(unit, vlan_port);
  19291         } else 
  19292 #endif /* BCM_ENDURO_SUPPORT */ 
  19293         {
  19294             return bcm_tr2_vlan_vp_create(unit, vlan_port);
  19295         }
  19296     }
  19297 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
  19298 
  19299     return BCM_E_UNAVAIL;
  19300 }
  19301 
  19302 /*
  19303  * Function:
  19304  *      bcm_esw_vlan_port_destroy
  19305  * Purpose:
  19306  *      Destroy a VLAN virtual port.
  19307  * Parameters:
  19308  *      unit - (IN) SOC unit number. 
  19309  *      gport - (IN) VLAN virtual port GPORT ID. 
  19310  * Returns:
  19311  *      BCM_X_XXX
  19312  */
  19313 int
  19314 bcm_esw_vlan_port_destroy(int unit,
  19315                          bcm_gport_t gport)
  19316 {
  19317 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  19318     if (soc_feature(unit, soc_feature_vlan_vp)) {
  19319 #if defined(BCM_ENDURO_SUPPORT)
  19320         if (SOC_IS_ENDURO(unit)) {
  19321             return bcm_enduro_vlan_vp_destroy(unit, gport);
  19322         } else 
  19323 #endif /* BCM_ENDURO_SUPPORT */
  19324         {
  19325             return bcm_tr2_vlan_vp_destroy(unit, gport);
  19326         }
  19327     }
  19328 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
  19329 
  19330     return BCM_E_UNAVAIL;
  19331 }
  19332 
  19333 /*
  19334  * Function:
  19335  *      bcm_esw_vlan_port_find
  19336  * Purpose:
  19337  *      Get VLAN virtual port info.
  19338  * Parameters:
  19339  *      unit - (IN) SOC unit number. 
  19340  *      vlan_port - (IN/OUT) Pointer to VLAN virtual port structure. 
  19341  * Returns:
  19342  *      BCM_X_XXX
  19343  */
  19344 int
  19345 bcm_esw_vlan_port_find(int unit,
  19346                        bcm_vlan_port_t *vlan_port)
  19347 {
  19348 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  19349     if (soc_feature(unit, soc_feature_vlan_vp)) {
  19350 #if defined(BCM_ENDURO_SUPPORT)
  19351         if (SOC_IS_ENDURO(unit)) {
  19352             return bcm_enduro_vlan_vp_find(unit, vlan_port);
  19353         } else 
  19354 #endif /* BCM_ENDURO_SUPPORT */        
  19355         {
  19356             return bcm_tr2_vlan_vp_find(unit, vlan_port);
  19357         }
  19358     }
  19359 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
  19360 
  19361     return BCM_E_UNAVAIL;
  19362 }
  19363 
  19364 /*
  19365  * Function:
  19366  *      _bcm_esw_vlan_port_source_vp_lag_set
  19367  * Purpose:
  19368  *      Set source VP LAG for a VLAN virtual port.
  19369  * Parameters:
  19370  *      unit - (IN) SOC unit number. 
  19371  *      gport - (IN) VLAN virtual port GPORT ID. 
  19372  *      vp_lag_vp - (IN) VP representing the VP LAG. 
  19373  * Returns:
  19374  *      BCM_X_XXX
  19375  */
  19376 int
  19377 _bcm_esw_vlan_port_source_vp_lag_set(int unit, bcm_gport_t gport,
  19378         int vp_lag_vp)
  19379 {
  19380 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  19381     if (soc_feature(unit, soc_feature_vlan_vp) &&
  19382             soc_feature(unit, soc_feature_vp_lag)) {
  19383         return bcm_td2_vlan_vp_source_vp_lag_set(unit, gport, vp_lag_vp);
  19384     }
  19385 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */
  19386 
  19387     return BCM_E_UNAVAIL;
  19388 }
  19389 
  19390 /*
  19391  * Function:
  19392  *      _bcm_esw_vlan_port_source_vp_lag_clear
  19393  * Purpose:
  19394  *      Clear source VP LAG for a VLAN virtual port.
  19395  * Parameters:
  19396  *      unit - (IN) SOC unit number. 
  19397  *      gport - (IN) VLAN virtual port GPORT ID. 
  19398  *      vp_lag_vp - (IN) VP representing the VP LAG. 
  19399  * Returns:
  19400  *      BCM_X_XXX
  19401  */
  19402 int
  19403 _bcm_esw_vlan_port_source_vp_lag_clear(int unit, bcm_gport_t gport,
  19404         int vp_lag_vp)
  19405 {
  19406 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  19407     if (soc_feature(unit, soc_feature_vlan_vp) &&
  19408             soc_feature(unit, soc_feature_vp_lag)) {
  19409         return bcm_td2_vlan_vp_source_vp_lag_clear(unit, gport, vp_lag_vp);
  19410     }
  19411 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */
  19412 
  19413     return BCM_E_UNAVAIL;
  19414 }
  19415 
  19416 /*
  19417  * Function:
  19418  *      _bcm_esw_vlan_port_source_vp_lag_get
  19419  * Purpose:
  19420  *      Get source VP LAG for a VLAN virtual port.
  19421  * Parameters:
  19422  *      unit - (IN) SOC unit number. 
  19423  *      gport - (IN) VLAN virtual port GPORT ID. 
  19424  *      vp_lag_vp - (OUT) VP representing the VP LAG. 
  19425  * Returns:
  19426  *      BCM_X_XXX
  19427  */
  19428 int
  19429 _bcm_esw_vlan_port_source_vp_lag_get(int unit, bcm_gport_t gport,
  19430         int *vp_lag_vp)
  19431 {
  19432 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  19433     if (soc_feature(unit, soc_feature_vlan_vp) &&
  19434             soc_feature(unit, soc_feature_vp_lag)) {
  19435         return bcm_td2_vlan_vp_source_vp_lag_get(unit, gport, vp_lag_vp);
  19436     }
  19437 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */
  19438 
  19439     return BCM_E_UNAVAIL;
  19440 }
  19441 
  19442 #define VALID_VLAN_ID(vid)                                              \
  19443     ((((vid) >= 0) && ((vid) <= BCM_VLAN_MAX)) || (vid == BCM_VLAN_INVALID))
  19444 
  19445 /*
  19446  * Function:
  19447  *     _bcm_esw_vlan_system_reserved_set
  19448  * Purpose:
  19449  *     Set ingress or egress system reserved VLAN
  19450  * Parameters:
  19451  *     unit  - Device unit number
  19452  *     arg   - VLAN
  19453  * Returns:
  19454  *     BCM_E_XXX
  19455  */
  19456 int
  19457 _bcm_esw_vlan_system_reserved_set(int unit, int arg)
  19458 {
  19459     int rv = BCM_E_UNAVAIL;
  19460     if (VALID_VLAN_ID(arg)) {
  19461 #ifdef BCM_TRX_SUPPORT
  19462         if (soc_feature(unit, soc_feature_system_reserved_vlan)) {
  19463             rv = _bcm_trx_system_reserved_vlan_ing_set(unit, arg);
  19464             if (SOC_SUCCESS(rv)) {
  19465                 rv = _bcm_trx_system_reserved_vlan_egr_set(unit, arg);
  19466             }
  19467         }
  19468 #endif
  19469     } else {
  19470         rv = BCM_E_PARAM;
  19471     }
  19472         
  19473     return rv;
  19474 }
  19475 
  19476 /*
  19477  * Function:
  19478  *     _bcm_esw_vlan_system_reserved_get
  19479  * Purpose:
  19480  *     Get ingress or egress system reserved VLAN
  19481  * Parameters:
  19482  *     unit  - Device unit number
  19483  *     arg   - pointer to VLAN
  19484  * Returns:
  19485  *     BCM_E_XXX
  19486  */
  19487 int
  19488 _bcm_esw_vlan_system_reserved_get(int unit, int *arg)
  19489 {
  19490     int rv = BCM_E_UNAVAIL;
  19491 
  19492     if (arg != NULL) {
  19493 #ifdef BCM_TRX_SUPPORT
  19494         if (soc_feature(unit, soc_feature_system_reserved_vlan)) {
  19495             rv = _bcm_trx_system_reserved_vlan_ing_get(unit, arg);
  19496         }
  19497 #endif
  19498     } else {
  19499         rv = BCM_E_PARAM;
  19500     }
  19501     return rv;
  19502 }
  19503 
  19504 /*
  19505  * Function:
  19506  *     _bcm_vlan_count_get
  19507  * Purpose:
  19508  *     Retrieves the number of VLAN created in the system
  19509  * Parameters:
  19510  *     unit - Device unit number
  19511  *     arg  - Vlan Count
  19512  * Returns:
  19513  *     BCM_E_XXX
  19514  */
  19515 int
  19516 _bcm_vlan_count_get(int unit, int *arg)
  19517 {
  19518     bcm_vlan_info_t    *vi = &vlan_info[unit];
  19519 
  19520     if (arg == NULL) {
  19521         return (BCM_E_PARAM);
  19522     }
  19523 
  19524     if (vi->init != TRUE) {
  19525         return (BCM_E_INIT);
  19526     }
  19527 
  19528     *arg = vi->count;
  19529     return (BCM_E_NONE);
  19530 }
  19531 
  19532 #ifdef BCM_WARM_BOOT_SUPPORT
  19533 /*
  19534  * _bcm_vlan_reinit
  19535  *
  19536  * Recover VLAN state from hardware (reload)
  19537  */
  19538 STATIC int
  19539 _bcm_vlan_reinit(int unit)
  19540 {
  19541     bcm_vlan_info_t *vi = &vlan_info[unit];
  19542     int rv;
  19543     soc_scache_handle_t scache_handle;
  19544     uint8 *vlan_scache_ptr;
  19545     uint8  flood_mode;
  19546     int    qm_num = 0;
  19547     int    qm_bmp_size;
  19548     int    i;
  19549 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
  19550     uint8 ing_vp_group_flag = 0;
  19551     uint8 egr_vp_group_flag = 0;
  19552 #endif
  19553     uint16 recovered_ver = BCM_WB_VERSION_1_0;
  19554     int additional_scache_size = 0;
  19555 
  19556     /* Clean up existing vlan_info */
  19557     vi->init = TRUE;
  19558     BCM_IF_ERROR_RETURN
  19559         (_bcm_vlan_cleanup(unit));
  19560 
  19561 #ifdef BCM_MCAST_FLOOD_DEFAULT
  19562     BCM_IF_ERROR_RETURN
  19563         (_bcm_esw_vlan_flood_default_set(unit, BCM_MCAST_FLOOD_DEFAULT));
  19564 #else
  19565     BCM_IF_ERROR_RETURN
  19566         (_bcm_esw_vlan_flood_default_set(unit,
  19567                                          BCM_VLAN_MCAST_FLOOD_UNKNOWN));
  19568 #endif
  19569 
  19570     /* VLAN Queue Map */
  19571 #ifdef BCM_TRIUMPH2_SUPPORT
  19572     if (soc_feature(unit, soc_feature_vlan_queue_map)) {
  19573         int    qm_size;
  19574 
  19575         if (vi->qm_bmp != NULL) {
  19576             sal_free(vi->qm_bmp);
  19577         }
  19578         if (vi->qm_it_bmp != NULL) {
  19579             sal_free(vi->qm_it_bmp);
  19580         }
  19581 
  19582         qm_num = 1 << soc_mem_field_length(unit, VLAN_PROFILE_TABm,
  19583                                            PHB2_DOT1P_MAPPING_PTRf);
  19584 
  19585         qm_size = SHR_BITALLOCSIZE(qm_num);
  19586         vi->qm_bmp = sal_alloc(qm_size, "VLAN queue mapping bitmap");
  19587         if (vi->qm_bmp == NULL) {
  19588             return BCM_E_MEMORY;
  19589         }
  19590         sal_memset(vi->qm_bmp, 0, qm_size); 
  19591         vi->qm_it_bmp = sal_alloc(qm_size, "VLAN queue mapping bitmap");
  19592         if (vi->qm_it_bmp == NULL) {
  19593             return BCM_E_MEMORY;
  19594         }
  19595         sal_memset(vi->qm_it_bmp, 0, qm_size); 
  19596     }
  19597 #endif
  19598 
  19599     if (SOC_IS_SHADOW(unit)) { /* Shadow doesn't implement VLAN module */
  19600         return BCM_E_NONE;
  19601     }
  19602 
  19603     /*
  19604      * Initialize software structures
  19605      */
  19606     vi->defl = BCM_VLAN_DEFAULT;
  19607     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_VLAN, 0);
  19608     rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE,
  19609                                  0, &vlan_scache_ptr, 
  19610                                  BCM_WB_DEFAULT_VERSION, &recovered_ver);
  19611     if (rv == SOC_E_NOT_FOUND) {
  19612         /* Use non-Level 2 case */
  19613     } else if (SOC_FAILURE(rv)) {
  19614         return rv;
  19615     } else {
  19616         /* Success, recover default VLAN */
  19617         sal_memcpy(&vi->defl, vlan_scache_ptr, sizeof(vi->defl));
  19618         vlan_scache_ptr += sizeof(vi->defl);
  19619 
  19620         /* VLAN XLATE OLD counter */
  19621         sal_memcpy(&vi->old_egr_xlate_cnt, vlan_scache_ptr, 
  19622                    sizeof(vi->old_egr_xlate_cnt));
  19623         vlan_scache_ptr += sizeof(vi->old_egr_xlate_cnt);
  19624 
  19625         /* Flood mode */
  19626         /* Type for 'flood_mode' is an enum, which values fit in uint8 */
  19627         sal_memcpy(&flood_mode, vlan_scache_ptr, sizeof(flood_mode));
  19628         vi->flood_mode = flood_mode;
  19629         vlan_scache_ptr += sizeof(flood_mode);
  19630 
  19631         /* VLAN Queue Map */
  19632         if (soc_feature(unit, soc_feature_vlan_queue_map)) {
  19633             qm_bmp_size = _SHR_BITDCLSIZE(qm_num);
  19634             for (i = 0; i < qm_bmp_size; i++) {
  19635                 sal_memcpy(&vi->qm_bmp[i], vlan_scache_ptr,
  19636                            sizeof(SHR_BITDCL));
  19637                 vlan_scache_ptr += sizeof(SHR_BITDCL);
  19638             }
  19639             for (i = 0; i < qm_bmp_size; i++) {
  19640                 sal_memcpy(&vi->qm_it_bmp[i], vlan_scache_ptr,
  19641                            sizeof(SHR_BITDCL));
  19642                 vlan_scache_ptr += sizeof(SHR_BITDCL);
  19643             }
  19644         }
  19645 
  19646 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
  19647         /* recover vp group unmanaged flags */
  19648         if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership) ||
  19649             soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) {
  19650 
  19651             sal_memcpy(&ing_vp_group_flag, vlan_scache_ptr, 
  19652                                      sizeof(ing_vp_group_flag));
  19653             vlan_scache_ptr += sizeof(ing_vp_group_flag);
  19654             sal_memcpy(&egr_vp_group_flag, vlan_scache_ptr, 
  19655                                      sizeof(egr_vp_group_flag));
  19656             vlan_scache_ptr += sizeof(egr_vp_group_flag);
  19657         }
  19658 #endif
  19659 
  19660         if (recovered_ver >= BCM_WB_VERSION_1_1) {
  19661             /* recover VLAN VP Multicast control mode */
  19662             sal_memcpy(&vi->vp_mode, vlan_scache_ptr, 
  19663                        sizeof(vi->vp_mode));
  19664             vlan_scache_ptr += sizeof(vi->vp_mode);
  19665         } else {
  19666             additional_scache_size += sizeof(vi->vp_mode);
  19667         }
  19668 
  19669 #ifdef BCM_TRIDENT3_SUPPORT
  19670         if (soc_feature(unit, soc_feature_pvlan_on_vfi)) {
  19671             if (recovered_ver >= BCM_WB_VERSION_1_2) {
  19672                 sal_memcpy(&vi->shared_vlan_enable, vlan_scache_ptr,
  19673                        sizeof(vi->shared_vlan_enable));
  19674                 vlan_scache_ptr += sizeof(vi->shared_vlan_enable);
  19675             } else {
  19676                 uint64 val64 = 0;
  19677                 SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, &val64));
  19678                 vi->shared_vlan_enable =
  19679                     soc_reg64_field32_get(unit, ING_CONFIG_64r, val64, SVL_ENABLEf);
  19680                 additional_scache_size += sizeof(vi->shared_vlan_enable);
  19681             }
  19682         }
  19683 #endif
  19684 
  19685         if (additional_scache_size > 0) {
  19686             BCM_IF_ERROR_RETURN(
  19687                 soc_scache_realloc(unit, scache_handle, additional_scache_size));
  19688         }
  19689     }
  19690 
  19691     vi->count = 0;
  19692     vi->init = TRUE;
  19693 
  19694     BCM_IF_ERROR_RETURN
  19695         (_bcm_vbmp_init(&vi->bmp));
  19696     BCM_IF_ERROR_RETURN(_bcm_vbmp_init(&vi->pre_cfg_bmp));
  19697 
  19698     BCM_IF_ERROR_RETURN
  19699         (mbcm_driver[unit]->mbcm_vlan_reload(unit, &vi->bmp, &vi->count));
  19700 
  19701     if (0 == _BCM_VBMP_LOOKUP(vi->bmp, vi->defl)) {
  19702         LOG_WARN(BSL_LS_BCM_VLAN,
  19703                  (BSL_META_U(unit,
  19704                              "Warm Reboot: Default VLAN %4d does not exist!\n"),
  19705                   vi->defl));
  19706     }
  19707 
  19708 #ifdef BCM_FIREBOLT_SUPPORT
  19709     if (SOC_IS_FBX(unit) && !SOC_IS_TRX(unit)) {
  19710         /* Recreate software state for vlan translation */
  19711         
  19712         /*
  19713          * NOTE: Skipped for TRX.
  19714          * VLAN translation for TRX happens in
  19715          * _bcm_trx_vlan_action_profile_init().  This routine is
  19716          * called by the PORT module.
  19717          *
  19718          * TRX uses its own data cache tables ing_action_profile[],
  19719          * egr_action_profileuse[], rather than 'ing_trans', 'egr_trans' in
  19720          * the common vlan_info[].
  19721          */
  19722         BCM_IF_ERROR_RETURN
  19723             (_bcm_fb_vlan_translate_reload(unit, BCM_VLAN_XLATE_ING));
  19724         BCM_IF_ERROR_RETURN
  19725             (_bcm_fb_vlan_translate_reload(unit, BCM_VLAN_XLATE_EGR));
  19726     }
  19727 #endif
  19728 
  19729 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  19730     if (soc_feature(unit, soc_feature_vlan_vp)) {
  19731 #ifdef BCM_ENDURO_SUPPORT
  19732         if (SOC_IS_ENDURO(unit)) {
  19733             BCM_IF_ERROR_RETURN(bcm_enduro_vlan_virtual_init(unit));
  19734         } else
  19735 #endif /* BCM_ENDURO_SUPPORT */
  19736         {
  19737             BCM_IF_ERROR_RETURN(bcm_tr2_vlan_virtual_init(unit));
  19738         } 
  19739     }
  19740 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
  19741 
  19742 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 
  19743 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  19744     if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
  19745         (void)bcm_td2p_ing_vp_group_unmanaged_set(unit, ing_vp_group_flag);
  19746         (void)bcm_td2p_egr_vp_group_unmanaged_set(unit, egr_vp_group_flag);
  19747         BCM_IF_ERROR_RETURN(bcm_td2p_vp_group_init(unit));
  19748     } else
  19749 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  19750     if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership) ||
  19751         soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) {
  19752         (void)bcm_td_ing_vp_group_unmanaged_set(unit,ing_vp_group_flag);
  19753         (void)bcm_td_egr_vp_group_unmanaged_set(unit,egr_vp_group_flag);
  19754         BCM_IF_ERROR_RETURN(bcm_td_vp_group_init(unit));
  19755         
  19756     }
  19757 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  19758 
  19759     return BCM_E_NONE;
  19760 }
  19761 
  19762 /*
  19763  * Function:
  19764  *      _bcm_vlan_cleanup
  19765  * Purpose:
  19766  *      Free up resources without touching hardware
  19767  * Parameters:
  19768  *      unit - StrataSwitch PCI device unit number (driver internal).
  19769  * Returns:
  19770  *      BCM_E_NONE - Success.
  19771  */
  19772 int
  19773 _bcm_vlan_cleanup(int unit)
  19774 {
  19775     bcm_vlan_info_t *vi;
  19776 
  19777     CHECK_INIT(unit);
  19778 
  19779     BCM_LOCK(unit);
  19780     vi = &vlan_info[unit];
  19781     _bcm_vbmp_destroy(&vi->bmp);
  19782     if (vi->qm_bmp != NULL) {
  19783         sal_free(vi->qm_bmp);
  19784     }
  19785     if (vi->qm_it_bmp != NULL) {
  19786         sal_free(vi->qm_it_bmp);
  19787     }
  19788     if (vi->egr_trans != NULL) {
  19789         sal_free(vi->egr_trans);
  19790     }
  19791     if (vi->ing_trans != NULL) {
  19792         sal_free(vi->ing_trans);
  19793     }
  19794     sal_memset(vi, 0, sizeof(bcm_vlan_info_t));
  19795     BCM_UNLOCK(unit);
  19796 
  19797     return BCM_E_NONE;
  19798 }
  19799 
  19800 /*
  19801  * Function:
  19802  *      _bcm_esw_vlan_sync
  19803  * Purpose:
  19804  *      Record VLAN module persisitent info for Level 2 Warm Boot
  19805  * Parameters:
  19806  *      unit - StrataSwitch unit number.
  19807  * Returns:
  19808  *      BCM_E_XXX
  19809  */
  19810 
  19811 int
  19812 _bcm_esw_vlan_sync(int unit)
  19813 {
  19814     bcm_vlan_info_t     *vi = &vlan_info[unit];
  19815     soc_scache_handle_t scache_handle;
  19816     uint8 *vlan_scache_ptr;
  19817     uint8  flood_mode;
  19818     int    qm_bmp_size;
  19819     int    i;
  19820 
  19821 #ifdef BCM_TOMAHAWK3_SUPPORT
  19822     if (SOC_IS_TOMAHAWK3(unit)) {
  19823         return _bcm_th3_vlan_sync(unit);
  19824     }
  19825 #endif
  19826 
  19827     CHECK_INIT(unit);
  19828 
  19829     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_VLAN, 0);
  19830     BCM_IF_ERROR_RETURN
  19831         (_bcm_esw_scache_ptr_get(unit, scache_handle, FALSE,
  19832                                  0, &vlan_scache_ptr, 
  19833                                  BCM_WB_DEFAULT_VERSION, NULL));
  19834     /* Default VLAN */
  19835     sal_memcpy(vlan_scache_ptr, &vi->defl, sizeof(vi->defl));
  19836     vlan_scache_ptr += sizeof(vi->defl);
  19837 
  19838     /* VLAN XLATE OLD counter */
  19839     sal_memcpy(vlan_scache_ptr, &vi->old_egr_xlate_cnt, 
  19840                sizeof(vi->old_egr_xlate_cnt));
  19841     vlan_scache_ptr += sizeof(vi->old_egr_xlate_cnt);
  19842 
  19843     /* Flood mode */
  19844     /* Type for 'flood_mode' is an enum, which values fit in uint8 */
  19845     flood_mode = vlan_info[unit].flood_mode;
  19846     sal_memcpy(vlan_scache_ptr, &flood_mode, sizeof(flood_mode));
  19847     vlan_scache_ptr += sizeof(flood_mode);
  19848 
  19849     /* VLAN Queue Map */
  19850     if (soc_feature(unit, soc_feature_vlan_queue_map)) {
  19851         qm_bmp_size = _SHR_BITDCLSIZE
  19852             (1 << soc_mem_field_length(unit, VLAN_PROFILE_TABm,
  19853                                        PHB2_DOT1P_MAPPING_PTRf));
  19854         for (i = 0; i < qm_bmp_size; i++) {
  19855             sal_memcpy(vlan_scache_ptr, &vi->qm_bmp[i], sizeof(SHR_BITDCL));
  19856             vlan_scache_ptr += sizeof(SHR_BITDCL);
  19857         }
  19858         for (i = 0; i < qm_bmp_size; i++) {
  19859             sal_memcpy(vlan_scache_ptr, &vi->qm_it_bmp[i], sizeof(SHR_BITDCL));
  19860             vlan_scache_ptr += sizeof(SHR_BITDCL);
  19861         }
  19862     }
  19863 
  19864 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 
  19865     /* vp group unmanaged flags */
  19866 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  19867     if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
  19868         uint8 flag = 0;
  19869 
  19870         flag = (uint8)bcm_td2p_ing_vp_group_unmanaged_get(unit);
  19871         sal_memcpy(vlan_scache_ptr, &flag, sizeof(flag));
  19872         vlan_scache_ptr += sizeof(flag);
  19873         flag = (uint8)bcm_td2p_egr_vp_group_unmanaged_get(unit);
  19874         sal_memcpy(vlan_scache_ptr, &flag, sizeof(flag));
  19875         vlan_scache_ptr += sizeof(flag);
  19876     } else
  19877 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  19878     if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership) ||
  19879         soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) {
  19880         uint8 flag = 0;
  19881 
  19882         flag = (uint8)bcm_td_ing_vp_group_unmanaged_get(unit);
  19883         sal_memcpy(vlan_scache_ptr, &flag, sizeof(flag));
  19884         vlan_scache_ptr += sizeof(flag);
  19885         flag = (uint8)bcm_td_egr_vp_group_unmanaged_get(unit);
  19886         sal_memcpy(vlan_scache_ptr, &flag, sizeof(flag));
  19887         vlan_scache_ptr += sizeof(flag);
  19888     }
  19889 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  19890 
  19891     if (BCM_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_1) {
  19892         /* sync VLAN info VP Multicast control mode */
  19893         sal_memcpy(vlan_scache_ptr, &vi->vp_mode, 
  19894                    sizeof(vi->vp_mode));
  19895         vlan_scache_ptr += sizeof(vi->vp_mode);
  19896     }
  19897 
  19898 #ifdef BCM_TRIDENT3_SUPPORT
  19899     if (soc_feature(unit, soc_feature_pvlan_on_vfi)) {
  19900         if (BCM_WB_DEFAULT_VERSION >= BCM_WB_VERSION_1_2) {
  19901             sal_memcpy(vlan_scache_ptr, &vi->shared_vlan_enable,
  19902                    sizeof(vi->shared_vlan_enable));
  19903             vlan_scache_ptr += sizeof(vi->shared_vlan_enable);
  19904         }
  19905     }
  19906 #endif
  19907     return BCM_E_NONE;
  19908 }
  19909 #endif /* BCM_WARM_BOOT_SUPPORT */
  19910 
  19911 
  19912 #ifndef BCM_SW_STATE_DUMP_DISABLE
  19913 /*
  19914  * Function:
  19915  *     _bcm_vlan_compar
  19916  * Purpose:
  19917  *     Compares two VLAN IDs.  Used by sorting utility routine
  19918  * Parameters:
  19919  *     a - Pointer to first VLAN ID of type bcm_vlan_t to compare
  19920  *     b - Pointer to second VLAN ID of type bcm_vlan_t to compare
  19921  * Returns:
  19922  *     0 If vlan1 == vlan2
  19923  *    -1 If vlan1 <  vlan2
  19924  *     1 If vlan1 >  vlan2
  19925  */
  19926 int
  19927 _bcm_vlan_compar(void *a, void *b)
  19928 {
  19929     bcm_vlan_t vlan1, vlan2;
  19930 
  19931     vlan1 = *(bcm_vlan_t *)a;
  19932     vlan2 = *(bcm_vlan_t *)b;
  19933 
  19934     return ( (vlan1 < vlan2) ? -1 : ((vlan1 > vlan2) ? 1 : 0));
  19935 }
  19936 
  19937 /*
  19938  * Function:
  19939  *     _bcm_vlan_sw_dump
  19940  * Purpose:
  19941  *     Displays VLAN software structure information.
  19942  * Parameters:
  19943  *     unit - Device unit number
  19944  * Returns:
  19945  *     None
  19946  */
  19947 void
  19948 _bcm_vlan_sw_dump(int unit)
  19949 {
  19950     int             i;
  19951     bcm_vlan_info_t *vi = &vlan_info[unit];
  19952     int             vlan_count = 0;
  19953 #ifdef BCM_FIREBOLT_SUPPORT
  19954     int             ixmem, index_min, count;
  19955     soc_mem_t       mem;
  19956     uint32          *vtcachep, vtcache;
  19957 #endif /* BCM_FIREBOLT_SUPPORT */
  19958 
  19959     LOG_CLI((BSL_META_U(unit,
  19960                         "\nSW Information VLAN\n")));
  19961     LOG_CLI((BSL_META_U(unit,
  19962                         "  Init       : %4d\n"), vi->init));
  19963     LOG_CLI((BSL_META_U(unit,
  19964                         "  Default    : %4d\n"), vi->defl));
  19965     LOG_CLI((BSL_META_U(unit,
  19966                         "  Flood Mode : %4d\n"), vi->flood_mode));
  19967     LOG_CLI((BSL_META_U(unit,
  19968                         "  Count      : %4d\n"), vi->count));
  19969 
  19970     /* Print VLAN list sorted */
  19971     LOG_CLI((BSL_META_U(unit,
  19972                         "  List       :")));
  19973     for (i = BCM_VLAN_MIN; i < BCM_VLAN_COUNT; i++) {
  19974         if (0 == _BCM_VBMP_LOOKUP(vi->bmp, i)){
  19975             continue;
  19976         }
  19977         if ((vlan_count > 0) && (!(vlan_count % 10))) {
  19978             LOG_CLI((BSL_META_U(unit,
  19979                                 "\n              ")));
  19980         }
  19981         LOG_CLI((BSL_META_U(unit,
  19982                             " %4d"), i));
  19983         vlan_count++;
  19984         if (vi->count == vlan_count) {
  19985             break;
  19986         }
  19987     }
  19988     LOG_CLI((BSL_META_U(unit,
  19989                         "\n")));
  19990 
  19991 #ifdef BCM_FIREBOLT_SUPPORT
  19992     if (soc_feature(unit, soc_feature_vlan_translation)) {
  19993         LOG_CLI((BSL_META_U(unit,
  19994                             "\n  VLAN translation       :")));
  19995         
  19996         for (ixmem = 0; ixmem < 2; ixmem++) {
  19997             if (ixmem == 1) {
  19998                 mem = EGR_VLAN_XLATEm;
  19999                 vtcachep = vlan_info[unit].egr_trans;
  20000                 if (vtcachep == NULL) {
  20001                     continue;
  20002                 }
  20003                 LOG_CLI((BSL_META_U(unit,
  20004                                     "\n\n  Egress       :")));
  20005             } else {
  20006                 mem = VLAN_XLATEm;
  20007                 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
  20008                     mem = VLAN_XLATE_1_DOUBLEm;
  20009                 }
  20010                 vtcachep = vlan_info[unit].ing_trans;
  20011                 if (vtcachep == NULL) {
  20012                     continue;
  20013                 }
  20014                 LOG_CLI((BSL_META_U(unit,
  20015                                     "\n  Ingress       :")));
  20016             }
  20017 
  20018             if (!SOC_MEM_IS_VALID(unit, mem)) {
  20019                 continue;
  20020             }
  20021 
  20022             index_min = soc_mem_index_min(unit, mem);
  20023             count = soc_mem_index_count(unit, mem);
  20024             for (i = 0; i < count; i++) {
  20025                 vtcache = vtcachep[index_min + i];
  20026                 if (BCM_VTCACHE_VALID_GET(vtcache)) {
  20027                     LOG_CLI((BSL_META_U(unit,
  20028                                         "\n    Entry %d:  Port %s, VLAN 0x%03x%s"),
  20029                              i,
  20030                              SOC_PORT_NAME(unit, BCM_VTCACHE_PORT_GET(vtcache)),
  20031                              BCM_VTCACHE_VID_GET(vtcache),
  20032                              BCM_VTCACHE_ADD_GET(vtcache) ? ", Add" : ""));
  20033                 }
  20034             }
  20035         }
  20036         LOG_CLI((BSL_META_U(unit,
  20037                             "\n")));
  20038     }
  20039 #endif /* BCM_FIREBOLT_SUPPORT */
  20040 
  20041 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) || defined(BCM_RAPTOR_SUPPORT)
  20042     if (SOC_IS_FIREBOLT2(unit) || SOC_IS_TRX(unit) ||
  20043         SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) {
  20044         _bcm_fb2_vlan_profile_sw_dump(unit);
  20045     }
  20046 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAPTOR_SUPPORT */ 
  20047 
  20048 #if defined(BCM_TRX_SUPPORT)
  20049 #if defined(BCM_TOMAHAWK3_SUPPORT)
  20050     if (SOC_IS_TOMAHAWK3(unit)) {
  20051         _bcm_th3_vlan_sw_tag_action_profile_dump(unit);
  20052     } else
  20053 #endif
  20054     if (SOC_IS_TRX(unit)) {
  20055         _bcm_trx_vlan_sw_dump(unit);
  20056     }
  20057 #endif /* BCM_TRX_SUPPORT */
  20058 
  20059     /* VLAN Queue Map */
  20060     if (soc_feature(unit, soc_feature_vlan_queue_map)) {
  20061         int qm_num;
  20062         int count = 0;
  20063         int inner;
  20064 
  20065         LOG_CLI((BSL_META_U(unit,
  20066                             "\nSW Information VLAN Queue Map\n")));
  20067         qm_num = 1 << soc_mem_field_length(unit, VLAN_PROFILE_TABm,
  20068                                            PHB2_DOT1P_MAPPING_PTRf);
  20069 
  20070         if (vi->qm_bmp != NULL) {
  20071             for (i = 0; i < qm_num; i++) {
  20072                 if (!SHR_BITGET(vlan_info[unit].qm_bmp, i)) {
  20073                     continue;
  20074                 }
  20075                 if ((count > 0) && (!(count % 10))) {
  20076                     LOG_CLI((BSL_META_U(unit,
  20077                                         "\n              ")));
  20078                 }
  20079                 if (!SHR_BITGET(vlan_info[unit].qm_it_bmp, i)) {
  20080                     inner = 0;
  20081                 } else {
  20082                     inner = 1;
  20083                 }
  20084                 LOG_CLI((BSL_META_U(unit,
  20085                                     " %2d(%1d)"), i, inner));
  20086                 count++;
  20087             }
  20088             LOG_CLI((BSL_META_U(unit,
  20089                                 "\n")));
  20090         }
  20091     }
  20092 
  20093 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  20094     if (soc_feature(unit, soc_feature_vlan_vp)) {
  20095 #ifdef BCM_ENDURO_SUPPORT
  20096         if (SOC_IS_ENDURO(unit)) {
  20097             bcm_enduro_vlan_vp_sw_dump(unit);
  20098         } else
  20099 #endif /* BCM_ENDURO_SUPPORT */
  20100         {
  20101             bcm_tr2_vlan_vp_sw_dump(unit);
  20102         } 
  20103     }
  20104 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
  20105 
  20106 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
  20107 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  20108     if (soc_feature(unit, soc_feature_vlan_vfi_membership)){
  20109         bcm_td2p_vp_group_sw_dump(unit);
  20110     } else
  20111 #endif
  20112     if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership) ||
  20113             soc_feature(unit, soc_feature_vp_group_egress_vlan_membership)) {
  20114         bcm_td_vp_group_sw_dump(unit);
  20115     }
  20116 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  20117 
  20118     return;
  20119 }
  20120 #endif /* BCM_SW_STATE_DUMP_DISABLE */
  20121 
  20122 #if defined(INCLUDE_L3)
  20123 /*
  20124  * Function:
  20125  *      bcm_esw_vlan_vpn_create
  20126  * Purpose:
  20127  *      Create a VPN instance
  20128  * Parameters:
  20129  *      unit  - (IN)  Device Number
  20130  *      info  - (IN/OUT) VPN configuration info
  20131  * Returns:
  20132  *      BCM_E_XXX
  20133  */
  20134 int
  20135 bcm_esw_vlan_vpn_create(int unit, bcm_vlan_vpn_config_t *info)
  20136 {
  20137 #if defined(BCM_TRIUMPH3_SUPPORT)
  20138     int rv = BCM_E_PARAM;
  20139     vfi_entry_t vfi_entry;
  20140     int vfi_index = -1;
  20141     int bc_group = 0, umc_group = 0, uuc_group = 0;
  20142     int bc_group_type = 0, umc_group_type = 0, uuc_group_type = 0;
  20143 
  20144     if (!soc_feature(unit, soc_feature_vlan_vfi)) {
  20145         return BCM_E_UNAVAIL;
  20146     }
  20147 
  20148     if (info == NULL) {
  20149         return BCM_E_PARAM;
  20150     }
  20151 
  20152     if (!(info->flags & (BCM_VLAN_VPN_ELINE | BCM_VLAN_VPN_ELAN))) {
  20153         return BCM_E_PARAM;
  20154     }
  20155 
  20156     /*Allocate VFI*/
  20157     if (info->flags & BCM_VLAN_VPN_WITH_ID) {
  20158         rv = _bcm_tr3_vlan_vpn_is_valid(unit, info->vpn);
  20159         if (BCM_E_NONE == rv) {
  20160             return BCM_E_EXISTS;
  20161         } else if (BCM_E_NOT_FOUND != rv) {
  20162             return rv;
  20163         }
  20164 
  20165         _BCM_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, info->vpn);
  20166         BCM_IF_ERROR_RETURN(_bcm_vfi_alloc_with_id(unit, VFIm, _bcmVfiTypeVlan, vfi_index));
  20167     } else {
  20168         BCM_IF_ERROR_RETURN(_bcm_vfi_alloc(unit, VFIm, _bcmVfiTypeVlan, &vfi_index));
  20169         _BCM_VPN_SET(info->vpn, _BCM_VPN_TYPE_VFI, vfi_index);
  20170     }
  20171 
  20172     /*Initial and configure VFI*/
  20173     BCM_IF_ERROR_RETURN(READ_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry));
  20174     if (info->flags & BCM_VLAN_VPN_ELINE) {
  20175         soc_VFIm_field32_set(unit, &vfi_entry, PT2PT_ENf, 0x1);
  20176     } else if (info->flags & BCM_VLAN_VPN_ELAN) {
  20177         /* Check that the groups are valid. */
  20178         bc_group_type = _BCM_MULTICAST_TYPE_GET(info->broadcast_group);
  20179         bc_group = _BCM_MULTICAST_ID_GET(info->broadcast_group);
  20180         umc_group_type = _BCM_MULTICAST_TYPE_GET(info->unknown_multicast_group);
  20181         umc_group = _BCM_MULTICAST_ID_GET(info->unknown_multicast_group);
  20182         uuc_group_type = _BCM_MULTICAST_TYPE_GET(info->unknown_unicast_group);
  20183         uuc_group = _BCM_MULTICAST_ID_GET(info->unknown_unicast_group);
  20184 
  20185         if ((bc_group_type != _BCM_MULTICAST_TYPE_VLAN) ||
  20186             (umc_group_type != _BCM_MULTICAST_TYPE_VLAN) ||
  20187             (uuc_group_type != _BCM_MULTICAST_TYPE_VLAN) ||
  20188             (bc_group >= soc_mem_index_count(unit, L3_IPMCm)) ||
  20189             (umc_group >= soc_mem_index_count(unit, L3_IPMCm)) ||
  20190             (uuc_group >= soc_mem_index_count(unit, L3_IPMCm))) {
  20191             (void) _bcm_vfi_free(unit, _bcmVfiTypeVlan, vfi_index);
  20192             return BCM_E_PARAM;
  20193         }
  20194 
  20195         /* Commit the entry to HW */
  20196         soc_VFIm_field32_set(unit, &vfi_entry, UMC_INDEXf, umc_group);
  20197         soc_VFIm_field32_set(unit, &vfi_entry, UUC_INDEXf, uuc_group);
  20198         soc_VFIm_field32_set(unit, &vfi_entry, BC_INDEXf, bc_group);
  20199     }
  20200 
  20201     /*Write VFI to ASIC*/
  20202     rv = WRITE_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry);
  20203     if (rv < 0) {
  20204         (void) _bcm_vfi_free(unit, _bcmVfiTypeVlan, vfi_index);
  20205     }
  20206 
  20207     return BCM_E_NONE;
  20208 #else
  20209     return BCM_E_UNAVAIL;
  20210 #endif /* BCM_TRIUMPH3_SUPPORT */
  20211 }
  20212 
  20213 /*
  20214  * Function:
  20215  *              bcm_esw_vlan_vpn_destroy
  20216  * Purpose:
  20217  *              Delete a VPN instance
  20218  * Parameters:
  20219  *              unit - Device Number
  20220  *              vpn - VPN instance ID
  20221  * Returns:
  20222  *              BCM_E_XXX
  20223  */
  20224 int bcm_esw_vlan_vpn_destroy(int unit, bcm_vpn_t vpn)
  20225 {
  20226 #if defined(BCM_TRIUMPH3_SUPPORT)
  20227     int vfi = 0;
  20228 
  20229     if (!soc_feature(unit, soc_feature_vlan_vfi)) {
  20230         return BCM_E_UNAVAIL;
  20231     }
  20232 
  20233     /* Get vfi index */
  20234     BCM_IF_ERROR_RETURN(_bcm_tr3_vlan_vpn_is_valid(unit, vpn));
  20235     _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn);
  20236 
  20237     /* Delete all VLAN ports on this VPN */
  20238     BCM_IF_ERROR_RETURN(_bcm_tr3_vlan_vp_destroy_all(unit, vpn));
  20239 
  20240     /* Reset VFI table */
  20241     (void) _bcm_vfi_free(unit, _bcmVfiTypeVlan, vfi);
  20242 
  20243     return BCM_E_NONE;
  20244 #else
  20245     return BCM_E_UNAVAIL;
  20246 #endif /* BCM_TRIUMPH3_SUPPORT */
  20247 }
  20248 
  20249 /* Function:
  20250 *          bcm_esw_vlan_vpn_destroy_all
  20251 * Purpose:
  20252 *          Delete all VPN instances
  20253 * Parameters:
  20254 *          unit         - Device Number
  20255 * Returns:
  20256 *          BCM_E_XXXX
  20257 */
  20258 int bcm_esw_vlan_vpn_destroy_all(int unit)
  20259 {
  20260 #if defined(BCM_TRIUMPH3_SUPPORT)
  20261     int num_vfi = 0, idx = 0;
  20262     bcm_vpn_t vpn = 0;
  20263 
  20264     if (!soc_feature(unit, soc_feature_vlan_vfi)) {
  20265         return BCM_E_UNAVAIL;
  20266     }
  20267 
  20268     /* Destroy all VLAN VPNs */
  20269     num_vfi = soc_mem_index_count(unit, VFIm);
  20270     for (idx = 0; idx < num_vfi; idx++) {
  20271         if (_bcm_vfi_used_get(unit, idx, _bcmVfiTypeVlan)) {
  20272             _BCM_VPN_SET(vpn, _BCM_VPN_TYPE_VFI, idx);
  20273             BCM_IF_ERROR_RETURN(bcm_esw_vlan_vpn_destroy(unit, vpn));
  20274         }
  20275     }
  20276 
  20277     return BCM_E_NONE;
  20278 #else
  20279     return BCM_E_UNAVAIL;
  20280 #endif /* BCM_TRIUMPH3_SUPPORT */
  20281 }
  20282 
  20283 /* Function:
  20284 *          bcm_esw_vlan_vpn_get
  20285 * Purpose:
  20286 *          Get VPN information
  20287 * Parameters:
  20288 *          unit   - (IN) Device Number
  20289 *          vpn    - (IN) VLAN VPN
  20290 *          info   - (OUT) VLAN VPN Config
  20291 * Returns:
  20292 *          BCM_E_XXXX
  20293 */
  20294 int
  20295 bcm_esw_vlan_vpn_get(int unit, bcm_vpn_t vpn, bcm_vlan_vpn_config_t *info)
  20296 {
  20297 #if defined(BCM_TRIUMPH3_SUPPORT)
  20298     int vfi_index = -1;
  20299     vfi_entry_t vfi_entry;
  20300     uint8 isEline=0;
  20301 
  20302     if (!soc_feature(unit, soc_feature_vlan_vfi)) {
  20303         return BCM_E_UNAVAIL;
  20304     }
  20305 
  20306     if (info == NULL) {
  20307         return BCM_E_PARAM;
  20308     }
  20309 
  20310     /*Get vfi table*/
  20311     BCM_IF_ERROR_RETURN(_bcm_tr3_vlan_vpn_is_eline(unit, vpn, &isEline));
  20312     _BCM_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, vpn);
  20313     BCM_IF_ERROR_RETURN(READ_VFIm(unit, MEM_BLOCK_ALL, vfi_index, &vfi_entry));
  20314 
  20315     /* Get info associated with vfi table */
  20316     if (isEline) {
  20317         info->flags |= BCM_VLAN_VPN_ELINE;
  20318     } else {
  20319         info->flags |= BCM_VLAN_VPN_ELAN;
  20320 
  20321         _BCM_MULTICAST_GROUP_SET(info->broadcast_group,
  20322                  _BCM_MULTICAST_TYPE_VLAN,
  20323                  soc_VFIm_field32_get(unit, &vfi_entry, BC_INDEXf));
  20324         _BCM_MULTICAST_GROUP_SET(info->unknown_unicast_group,
  20325                  _BCM_MULTICAST_TYPE_VLAN,
  20326                  soc_VFIm_field32_get(unit, &vfi_entry, UUC_INDEXf));
  20327         _BCM_MULTICAST_GROUP_SET(info->unknown_multicast_group,
  20328                  _BCM_MULTICAST_TYPE_VLAN,
  20329                  soc_VFIm_field32_get(unit, &vfi_entry, UMC_INDEXf));
  20330     }
  20331 
  20332     _BCM_VPN_SET(info->vpn, _BCM_VPN_TYPE_VFI, vfi_index);
  20333 
  20334     return BCM_E_NONE;
  20335 #else
  20336     return BCM_E_UNAVAIL;
  20337 #endif /* BCM_TRIUMPH3_SUPPORT */
  20338 }
  20339 
  20340 /*
  20341  * Function:
  20342  *      bcm_esw_vlan_vpn_traverse
  20343  * Purpose:
  20344  *      VPN instance Traverse
  20345  * Parameters:
  20346  *      unit  - (IN)  Device Number
  20347  *      cb    - (IN)  User-provided callback
  20348  *      user_data  - (IN/OUT) Cookie
  20349  * Returns:
  20350  *      BCM_E_XXX
  20351  */
  20352 int
  20353 bcm_esw_vlan_vpn_traverse(int unit, bcm_vlan_vpn_traverse_cb cb,
  20354                              void *user_data)
  20355 {
  20356 #if defined(BCM_TRIUMPH3_SUPPORT)
  20357     int idx, num_vfi;
  20358     int vpn;
  20359     bcm_vlan_vpn_config_t info;
  20360 
  20361     if (!soc_feature(unit, soc_feature_vlan_vfi)) {
  20362         return BCM_E_UNAVAIL;
  20363     }
  20364 
  20365     if (cb == NULL) {
  20366         return BCM_E_PARAM;
  20367     }
  20368 
  20369     /* VLAN VPNs */
  20370     num_vfi = soc_mem_index_count(unit, VFIm);
  20371     for (idx = 0; idx < num_vfi; idx++) {
  20372         if (_bcm_vfi_used_get(unit, idx, _bcmVfiTypeVlan)) {
  20373             _BCM_VPN_SET(vpn, _BCM_VPN_TYPE_VFI, idx);
  20374             bcm_vlan_vpn_config_t_init(&info);
  20375             BCM_IF_ERROR_RETURN(bcm_esw_vlan_vpn_get(unit, vpn, &info));
  20376             BCM_IF_ERROR_RETURN(cb(unit, &info, user_data));
  20377         }
  20378     }
  20379 
  20380     return BCM_E_NONE;
  20381 #else
  20382     return BCM_E_UNAVAIL;
  20383 #endif /* BCM_TRIUMPH3_SUPPORT */
  20384 }
  20385 #endif
  20386 
  20387 /*
  20388  * Function:
  20389  *      bcm_vlan_match_action_add
  20390  * Purpose:
  20391  *      Add action for match criteria for Vlan assignment.
  20392  * Parameters:
  20393  *      unit  - (IN)  Device Number
  20394  *      options - (IN) Option from BCM_VLAN_MATCH_ACTION_XXX
  20395  *      match_info - (IN) Match criteria info
  20396  *      action_set - (IN) Action Set.
  20397  * Returns:
  20398  *      BCM_E_XXX
  20399  */
  20400 int
  20401 bcm_esw_vlan_match_action_add(int unit, uint32 options,
  20402                           bcm_vlan_match_info_t *match_info,
  20403                           bcm_vlan_action_set_t *action_set)
  20404 {
  20405 #ifdef BCM_TRX_SUPPORT
  20406     if (SOC_IS_TRX(unit)) {
  20407         if (!soc_feature(unit, soc_feature_vlan_action)
  20408                 || !soc_feature(unit, soc_feature_mac_based_vlan)) {
  20409             return BCM_E_UNAVAIL;
  20410         }
  20411         return _bcm_trx_vlan_match_action_add(unit, options,
  20412                 BCM_GPORT_INVALID, match_info, action_set);
  20413     }
  20414 #endif
  20415 
  20416     return BCM_E_UNAVAIL;
  20417 }
  20418 
  20419 /*
  20420  * Function:
  20421  *      bcm_esw_vlan_match_action_get
  20422  * Purpose:
  20423  *      Get action for given match criteria.
  20424  * Parameters:
  20425  *      unit  - (IN)  Device Number
  20426  *      match_info - (IN) Match criteria info
  20427  *      action_set - (IN) Action Set.
  20428  * Returns:
  20429  *      BCM_E_XXX
  20430  */
  20431 int
  20432 bcm_esw_vlan_match_action_get(int unit, bcm_vlan_match_info_t *match_info,
  20433                           bcm_vlan_action_set_t *action_set)
  20434 {
  20435 #ifdef BCM_TRX_SUPPORT
  20436     if (SOC_IS_TRX(unit)) {
  20437         if (!soc_feature(unit, soc_feature_vlan_action)
  20438                 || !soc_feature(unit, soc_feature_mac_based_vlan)) {
  20439             return BCM_E_UNAVAIL;
  20440         }
  20441         return _bcm_trx_vlan_match_action_get(unit,
  20442                 BCM_GPORT_INVALID, match_info, action_set);
  20443     }
  20444 #endif
  20445 
  20446     return BCM_E_UNAVAIL;
  20447 }
  20448 
  20449 /*
  20450  * Function:
  20451  *      bcm_esw_vlan_match_action_multi_get
  20452  * Purpose:
  20453  *      Get all actions and match criteria for given vlan match.
  20454  * Parameters:
  20455  *      unit  - (IN)  Device Number
  20456  *      match - (IN) vlan match.
  20457  *      size  - (IN) Number of elements in match info array.
  20458  *      match_info_array - (OUT) Match criteria info array.
  20459  *      action_set_array - (OUT) Action Set array.
  20460  *      count - (OUT) Valid Match criteria info count.
  20461  * Returns:
  20462  *      BCM_E_XXX
  20463  */
  20464 int
  20465 bcm_esw_vlan_match_action_multi_get(int unit, bcm_vlan_match_t match,
  20466                              int size, bcm_vlan_match_info_t *match_info_array,
  20467                              bcm_vlan_action_set_t *action_set, int *count)
  20468 {
  20469 #ifdef BCM_TRX_SUPPORT
  20470     if (SOC_IS_TRX(unit)) {
  20471         if (!soc_feature(unit, soc_feature_vlan_action)
  20472                 || !soc_feature(unit, soc_feature_mac_based_vlan)) {
  20473             return BCM_E_UNAVAIL;
  20474         }
  20475         return _bcm_trx_vlan_match_action_multi_get(unit, match,
  20476                 BCM_GPORT_INVALID, size, match_info_array,
  20477                 action_set, count);
  20478     }
  20479 #endif
  20480 
  20481     return BCM_E_UNAVAIL;
  20482 }
  20483 
  20484 /*
  20485  * Function:
  20486  *      bcm_esw_vlan_match_action_delete
  20487  * Purpose:
  20488  *      Remove action for a match criteria
  20489  * Parameters:
  20490  *      unit  - (IN)  Device Number
  20491  *      match_info - (IN) Match criteria info.
  20492  * Returns:
  20493  *      BCM_E_XXX
  20494  */
  20495 int
  20496 bcm_esw_vlan_match_action_delete(int unit, bcm_vlan_match_info_t *match_info)
  20497 {
  20498 #ifdef BCM_TRX_SUPPORT
  20499     if (SOC_IS_TRX(unit)) {
  20500         if (!soc_feature(unit, soc_feature_vlan_action)
  20501                 || !soc_feature(unit, soc_feature_mac_based_vlan)) {
  20502             return BCM_E_UNAVAIL;
  20503         }
  20504         return _bcm_trx_vlan_match_action_delete(unit,
  20505                 BCM_GPORT_INVALID, match_info);
  20506     }
  20507 #endif
  20508 
  20509     return BCM_E_UNAVAIL;
  20510 }
  20511 
  20512 /*
  20513  * Function:
  20514  *      bcm_esw_vlan_match_action_delete_all
  20515  * Purpose:
  20516  *      Remove all actions for vlan match.
  20517  * Parameters:
  20518  *      unit  - (IN)  Device Number
  20519  *      match - (IN) Vlan Match
  20520  * Returns:
  20521  *      BCM_E_XXX
  20522  */
  20523 int
  20524 bcm_esw_vlan_match_action_delete_all(int unit, bcm_vlan_match_t match)
  20525 {
  20526 #ifdef BCM_TRX_SUPPORT
  20527     if (SOC_IS_TRX(unit)) {
  20528         if (!soc_feature(unit, soc_feature_vlan_action)
  20529                 || !soc_feature(unit, soc_feature_mac_based_vlan)) {
  20530             return BCM_E_UNAVAIL;
  20531         }
  20532         return _bcm_trx_vlan_match_action_delete_all(unit,
  20533                 match, BCM_GPORT_INVALID);
  20534     }
  20535 #endif
  20536 
  20537     return BCM_E_UNAVAIL;
  20538 }
  20539 
  20540 
  20541 #ifdef BCM_TRX_SUPPORT
  20542 /*
  20543  * Function:
  20544  *      _bcm_vlan_match_action_multi_get
  20545  * Purpose:
  20546  *      Get all action and match criteria for given vlan match/port.
  20547  * Parameters:
  20548  *      unit       (IN)  Device Number
  20549  *      port       (IN)  gport number
  20550  *      size       (IN)  Number of elements in match_info_array
  20551  *      match_array (OUT)  match info array
  20552  *      start      (IN) Start index in match_array to be filled.
  20553  *      count      (OUT) Actual number of elements in match_array
  20554  * Returns:
  20555  *      BCM_E_XXX
  20556  */
  20557 int
  20558 _bcm_vlan_match_action_multi_get(int unit, bcm_gport_t port, int size,
  20559         bcm_port_match_info_t *match_array, int start, int *count)
  20560 {
  20561     int rv, i;
  20562     int ctr;
  20563     int valid_count = 0;
  20564     bcm_vlan_match_t match;
  20565     bcm_vlan_match_info_t *vlan_match_array = NULL;
  20566     bcm_vlan_action_set_t *action_set = NULL;
  20567 
  20568     /* Proceed only if VLAN_MACx is present */
  20569     if (!SOC_MEM_IS_VALID(unit, VLAN_MACm)) {
  20570         return BCM_E_NONE;
  20571     }
  20572 
  20573     if (size == 0) {
  20574         match = BCM_VLAN_MATCH_INVALID;
  20575         rv = _bcm_trx_vlan_match_action_multi_get(unit, match,
  20576                 port, size, NULL, NULL, &valid_count);
  20577         BCM_IF_ERROR_RETURN(rv);
  20578 
  20579         *count = (start + valid_count);
  20580         return BCM_E_NONE;
  20581     }
  20582 
  20583     /* Allocate mem */
  20584     vlan_match_array = sal_alloc(sizeof(bcm_vlan_match_info_t) * size,
  20585             "Vlan match info array");
  20586     if (vlan_match_array == NULL) {
  20587         return BCM_E_MEMORY;
  20588     }
  20589     action_set = sal_alloc(sizeof (bcm_vlan_action_set_t) * size,
  20590             "Vlan action set");
  20591     if (action_set == NULL) {
  20592         sal_free(vlan_match_array);
  20593         return BCM_E_MEMORY;
  20594     }
  20595 
  20596     match = BCM_VLAN_MATCH_INVALID;
  20597     rv = _bcm_trx_vlan_match_action_multi_get(unit, match,
  20598             port, size, vlan_match_array, action_set, &valid_count);
  20599     if (rv == BCM_E_NONE) {
  20600         for (i = 0, ctr = start;
  20601                 (size > ctr) && (i < valid_count); i++, ctr++) {
  20602             switch(vlan_match_array[i].match) {
  20603                 case BCM_VLAN_MATCH_MAC_PORT:
  20604                 case BCM_VLAN_MATCH_MAC_PORT_CLASS:
  20605                     if (vlan_match_array[i].match == BCM_VLAN_MATCH_MAC_PORT) {
  20606                         match_array->match = BCM_PORT_MATCH_MAC_PORT;
  20607                         match_array->port = vlan_match_array[i].port;
  20608                     } else if (vlan_match_array[i].match ==
  20609                             BCM_VLAN_MATCH_MAC_PORT_CLASS) {
  20610                         match_array->match = BCM_PORT_MATCH_MAC_PORT_CLASS;
  20611                         match_array->port_class =
  20612                             vlan_match_array[i].port_class;
  20613                     }
  20614                     sal_memcpy(match_array->src_mac,
  20615                             vlan_match_array[i].src_mac, sizeof (bcm_mac_t));
  20616 
  20617                     if (match_array->action != NULL) {
  20618                         sal_memcpy(match_array->action, &action_set[i],
  20619                                 sizeof(bcm_vlan_action_set_t));
  20620                     }
  20621                     match_array++;
  20622                     break;
  20623                 default:
  20624                     continue;
  20625             }
  20626         }
  20627     }
  20628 
  20629     *count = (start + valid_count);
  20630 
  20631     if (vlan_match_array != NULL) {
  20632         sal_free(vlan_match_array);
  20633     }
  20634     if (action_set != NULL) {
  20635         sal_free(action_set);
  20636     }
  20637 
  20638     return BCM_E_NONE;
  20639 }
  20640 #endif