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


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:        vlan.c
      8  * Purpose:     Provide low-level access to Triumph VLAN resources
      9  */
     10 #include <sal/core/boot.h>
     11 
     12 #include <soc/defs.h>
     13 #if defined(BCM_TRX_SUPPORT)
     14 #include <soc/drv.h>
     15 #include <soc/hash.h>
     16 #include <soc/mem.h>
     17 #include <soc/profile_mem.h>
     18 #include <shared/bsl.h>
     19 #include <bcm/error.h>
     20 #include <bcm/vlan.h>
     21 #include <bcm/stg.h>
     22 #include <bcm/port.h>
     23 #include <bcm/trunk.h>
     24 #include <bcm/stack.h>
     25 
     26 #include <bcm_int/esw/mbcm.h>
     27 #include <bcm_int/esw/triumph.h>
     28 #include <bcm_int/esw/vlan.h>
     29 #include <bcm_int/esw/stack.h>
     30 #include <bcm_int/esw/xgs3.h>
     31 #include <bcm_int/esw/trx.h>
     32 #include <bcm_int/esw/port.h>
     33 #if defined(BCM_TRIUMPH2_SUPPORT)
     34 #include <bcm_int/esw/triumph2.h>
     35 #endif /* BCM_TRIUMPH2_SUPPORT */
     36 
     37 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
     38     defined(BCM_GREYHOUND2_SUPPORT)
     39 #include <bcm_int/esw/policer.h>
     40 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT ||
     41           BCM_GREYHOUND2_SUPPORT */
     42 #include <bcm_int/esw_dispatch.h>
     43 
     44 #if defined(BCM_TRIDENT_SUPPORT)
     45 #include <bcm_int/esw/trident.h>
     46 #endif
     47 
     48 #if defined(BCM_TRIDENT2_SUPPORT)
     49 #include <bcm/fcoe.h>
     50 #include <bcm_int/esw/trident2.h>
     51 #endif
     52 
     53 #if defined(BCM_TRIDENT3_SUPPORT)
     54 #include <bcm_int/esw/trident3.h>
     55 #include <soc/esw/flow_db.h>
     56 #endif
     57 
     58 #if defined(BCM_KATANA2_SUPPORT)
     59 #include <bcm_int/esw/katana2.h>
     60 #endif
     61 
     62 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
     63 #include <soc/td2_td2p.h>
     64 #endif
     65 
     66 #if (defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_KATANA2_SUPPORT)) && defined(INCLUDE_L3)
     67 #include <bcm_int/esw/virtual.h>
     68 #endif
     69 
     70 #if defined(BCM_HGPROXY_COE_SUPPORT)
     71 #include <bcm_int/esw/subport.h>
     72 #include <bcm_int/esw/xgs5.h>
     73 #endif /* BCM_HGPROXY_COE_SUPPORT */
     74 
     75 #if defined(BCM_TOMAHAWK3_SUPPORT)
     76 #include <bcm_int/esw/tomahawk3.h>
     77 #endif
     78 #ifdef BCM_GREYHOUND2_SUPPORT
     79 #include <bcm_int/esw/greyhound2.h>
     80 #endif /* BCM_GREYHOUND2_SUPPORT */
     81 
     82 #if defined(BCM_TOMAHAWK_SUPPORT)
     83 STATIC int
     84 _bcm_fast_egr_vlan_port_egress_default_action_set(
     85             int unit,
     86             bcm_port_t port,
     87             bcm_vlan_action_set_t *action);
     88 
     89 STATIC int
     90 _bcm_fast_egr_vlan_port_egress_default_action_get(
     91             int unit,
     92             bcm_port_t port,
     93             bcm_vlan_action_set_t *action);
     94 #endif
     95 
     96 /* Cache of Ingress Vlan Translate Action Profile Table */
     97 static soc_profile_mem_t *ing_action_profile[BCM_MAX_NUM_UNITS] = {NULL};
     98 static int ing_action_profile_def[BCM_MAX_NUM_UNITS] = {0};
     99 
    100 /* Cache of Engress Vlan Translate Action Profile Table */
    101 static soc_profile_mem_t *egr_action_profile[BCM_MAX_NUM_UNITS] = {NULL};
    102 #define EGR_ACTION_PROFILE_DEFAULT  BCM_TRX_EGR_VLAN_ACTION_PROFILE_DEFAULT
    103 
    104 /* Cache of Ingress Vlan Range Profile Table */
    105 static soc_profile_mem_t *vlan_range_profile[BCM_MAX_NUM_UNITS] = {NULL};
    106 #define VLAN_RANGE_PROFILE_DEFAULT  0
    107 
    108 typedef struct _bcm_trx_vlan_subnet_entry_s {
    109     bcm_ip6_t   ip;
    110     bcm_ip6_t   mask;
    111     int         prefix;
    112     bcm_vlan_t  ovid;
    113     bcm_vlan_t  ivid;
    114     uint8       opri;
    115     uint8       ocfi;
    116     uint8       ipri;
    117     uint8       icfi;
    118     int         profile_idx;
    119 }_bcm_trx_vlan_subnet_entry_t;
    120 
    121 #if defined(BCM_TRIUMPH3_SUPPORT)
    122 typedef int (*tr3_vxlate_extd_entry_update_func_t)(int unit,
    123                    vlan_xlate_entry_t *vent_in,
    124                    void *ctxt,
    125                    vlan_xlate_entry_t *vent_out,
    126                    vlan_xlate_extd_entry_t *vxent_out,
    127                    int *use_extd_tbl);
    128 #endif
    129 
    130 #define PKT_VLAN_OUTER_ACTION_SET(unit, mem, vent_ptr, _action) \
    131    do { \
    132             if ((_action->ot_outer == bcmVlanActionAdd ) ||\
    133                 (_action->ot_outer == bcmVlanActionReplace ) ||\
    134                 (_action->ot_outer == bcmVlanActionOuterAdd ) ||\
    135                 (_action->dt_outer == bcmVlanActionAdd ) ||\
    136                 (_action->dt_outer == bcmVlanActionReplace ) ||\
    137                 (_action->dt_outer == bcmVlanActionOuterAdd ) ||\
    138                 (_action->it_outer == bcmVlanActionAdd ) ||\
    139                 (_action->it_outer == bcmVlanActionReplace ) ||\
    140                 (_action->it_outer == bcmVlanActionOuterAdd ) ||\
    141                 (_action->ut_outer == bcmVlanActionAdd ) ||\
    142                 (_action->ut_outer == bcmVlanActionReplace )||\
    143                 (_action->ut_outer == bcmVlanActionOuterAdd )) {\
    144                 soc_mem_field32_set(unit, mem, vent_ptr, OPRI_CFI_SELf, 1);\
    145             }\
    146    } while(0)
    147 
    148 #define PKT_VLAN_INNER_ACTION_SET(unit, mem, vent_ptr, _action) \
    149    do { \
    150             if ((_action->ot_inner == bcmVlanActionAdd ) ||\
    151                 (_action->ot_inner == bcmVlanActionReplace ) ||\
    152                 (_action->ot_inner == bcmVlanActionInnerAdd ) ||\
    153                 (_action->dt_inner == bcmVlanActionAdd ) ||\
    154                 (_action->dt_inner == bcmVlanActionReplace ) ||\
    155                 (_action->dt_inner == bcmVlanActionInnerAdd ) ||\
    156                 (_action->it_inner == bcmVlanActionAdd ) ||\
    157                 (_action->it_inner == bcmVlanActionReplace ) ||\
    158                 (_action->it_inner == bcmVlanActionInnerAdd ) ||\
    159                 (_action->ut_inner == bcmVlanActionAdd ) ||\
    160                 (_action->ut_inner == bcmVlanActionReplace )||\
    161                 (_action->ut_inner == bcmVlanActionInnerAdd )) {\
    162                 soc_mem_field32_set(unit, mem, vent_ptr, IPRI_CFI_SELf, 1);\
    163             }\
    164    } while(0)
    165 
    166 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
    167 #define SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_GET(m_unit, m_mem, m_entry_data, m_field, m_field_data) \
    168         soc_meminfo_fieldinfo_field_get((uint32*)(m_entry_data), (&SOC_MEM_INFO(m_unit, m_mem)), \
    169             (m_field), (m_field_data))
    170 #define SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_SET(m_unit, m_mem, m_entry_data, m_field, m_field_data) \
    171         soc_meminfo_fieldinfo_field_set((uint32*)(m_entry_data), (&SOC_MEM_INFO(m_unit, m_mem)), \
    172             (m_field), (m_field_data))
    173 #endif
    174 
    175 #define ING_VLAN_TAG_ACTION_LOCK(unit) \
    176         do {\
    177             if (soc_mem_is_valid(unit, ING_VLAN_TAG_ACTION_PROFILEm)) {\
    178                 soc_mem_lock(unit, ING_VLAN_TAG_ACTION_PROFILEm); \
    179             } else if (soc_mem_is_valid(unit, ING_VLAN_TAG_ACTION_PROFILE_2m)) {\
    180                 soc_mem_lock(unit, ING_VLAN_TAG_ACTION_PROFILE_2m); \
    181             }\
    182         } while (0)
    183 
    184 #define ING_VLAN_TAG_ACTION_UNLOCK(unit) \
    185         do {\
    186             if (soc_mem_is_valid(unit, ING_VLAN_TAG_ACTION_PROFILEm)) {\
    187                 soc_mem_unlock(unit, ING_VLAN_TAG_ACTION_PROFILEm); \
    188             } else if (soc_mem_is_valid(unit, ING_VLAN_TAG_ACTION_PROFILE_2m)) {\
    189                 soc_mem_unlock(unit, ING_VLAN_TAG_ACTION_PROFILE_2m); \
    190             }\
    191         } while (0)
    192 
    193 #define EGR_VLAN_TAG_ACTION_LOCK(unit) \
    194         do {\
    195             if (soc_mem_is_valid(unit, EGR_VLAN_TAG_ACTION_PROFILEm)) {\
    196                 soc_mem_lock(unit, EGR_VLAN_TAG_ACTION_PROFILEm); \
    197             } else if (soc_mem_is_valid(unit, EGR_VLAN_TAG_ACTION_PROFILE_2m)) {\
    198                 soc_mem_lock(unit, EGR_VLAN_TAG_ACTION_PROFILE_2m); \
    199             }\
    200         } while (0)
    201 
    202 #define EGR_VLAN_TAG_ACTION_UNLOCK(unit) \
    203         do {\
    204             if (soc_mem_is_valid(unit, EGR_VLAN_TAG_ACTION_PROFILEm)) {\
    205                 soc_mem_unlock(unit, EGR_VLAN_TAG_ACTION_PROFILEm); \
    206             } else if (soc_mem_is_valid(unit, EGR_VLAN_TAG_ACTION_PROFILE_2m)) {\
    207                 soc_mem_unlock(unit, EGR_VLAN_TAG_ACTION_PROFILE_2m); \
    208             }\
    209         } while (0)
    210 
    211 #define VLAN_RANGE_LOCK(unit) \
    212         do {\
    213             if (soc_mem_is_valid(unit, ING_VLAN_RANGEm)) {\
    214                 soc_mem_lock(unit, ING_VLAN_RANGEm); \
    215             }\
    216         } while (0)
    217 
    218 #define VLAN_RANGE_UNLOCK(unit) \
    219         do {\
    220             if (soc_mem_is_valid(unit, ING_VLAN_RANGEm)) {\
    221                 soc_mem_unlock(unit, ING_VLAN_RANGEm); \
    222             }\
    223         } while (0)
    224 
    225 STATIC int _bcm_trx_vlan_range_profile_init(int unit);
    226 
    227 #ifdef BCM_WARM_BOOT_SUPPORT
    228 STATIC int _bcm_trx_vlan_port_protocol_action_reinit(int unit);
    229 #endif /* BCM_WARM_BOOT_SUPPORT */
    230 
    231 #if defined(BCM_TRIUMPH3_SUPPORT)
    232 /*
    233  * Function : 
    234  *   _bcm_tr3_vxlate_extd2vxlate
    235  *
    236  * Purpose  : 
    237  *   convert extended vlan translation table to regular vlan translation
    238  *   table for all applicable fields.  
    239  *
    240  * Parameters:
    241  *   vxxent  -  (IN) extended vlan translation table 
    242  *   vxent   -  (OUT) regular vlan translation table
    243  *   use_svp -  (IN) Is SVP used in vxxent
    244  */
    245 
    246 int
    247 _bcm_tr3_vxlate_extd2vxlate(int unit,
    248                 vlan_xlate_extd_entry_t *vxxent,
    249                 vlan_xlate_entry_t *vxent,
    250                 int use_svp)
    251 {
    252     uint32 key[2];
    253     uint32 value;
    254 
    255     value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, VALID_0f);
    256     soc_mem_field32_set(unit, VLAN_XLATEm, vxent, VALIDf,value);
    257 
    258     soc_mem_field_get(unit, VLAN_XLATE_EXTDm, 
    259                       (uint32 *)vxxent, XLATE__KEY_0f, key);
    260     soc_mem_field_set(unit, VLAN_XLATEm,
    261                     (uint32 *)vxent,  KEYf, key);
    262 
    263     /* key type value for VLAN_XLATE_EXTDm: VLAN_XLATE_1 value + 1 */
    264     value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, KEY_TYPE_0f);
    265     value--;
    266     soc_VLAN_XLATEm_field32_set(unit, vxent, KEY_TYPEf,value);
    267 
    268     value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, 
    269                     XLATE__TAG_ACTION_PROFILE_PTRf);
    270     soc_VLAN_XLATEm_field32_set(unit, vxent, 
    271                                TAG_ACTION_PROFILE_PTRf,value);
    272     value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, 
    273                     XLATE__NEW_OVIDf);
    274     soc_VLAN_XLATEm_field32_set(unit, vxent, 
    275                                NEW_OVIDf,value);
    276     value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, 
    277                     XLATE__NEW_OPRIf);
    278     soc_VLAN_XLATEm_field32_set(unit, vxent, 
    279                                NEW_OPRIf,value);
    280     value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, 
    281                     XLATE__NEW_OCFIf);
    282     soc_VLAN_XLATEm_field32_set(unit, vxent, 
    283                                NEW_OCFIf,value);
    284 
    285     /* VLAN_XLATE source_vp and new_ivid are overlay fields while
    286      * VLAN_XLATE_EXTD's are not
    287      */
    288     if (use_svp) {
    289         value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, 
    290                         XLATE__SOURCE_VPf);
    291         soc_VLAN_XLATEm_field32_set(unit, vxent, SOURCE_VPf,value);
    292         soc_VLAN_XLATEm_field32_set(unit, vxent, SVP_VALIDf,1);
    293     } else {
    294         soc_VLAN_XLATEm_field32_set(unit, vxent, SVP_VALIDf,0);
    295         value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, 
    296                         XLATE__NEW_IVIDf);
    297         soc_VLAN_XLATEm_field32_set(unit, vxent, 
    298                                    NEW_IVIDf,value);
    299         value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, 
    300                         XLATE__NEW_IPRIf);
    301         soc_VLAN_XLATEm_field32_set(unit, vxent, 
    302                                    NEW_IPRIf,value);
    303         value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, 
    304                         XLATE__NEW_ICFIf);
    305         soc_VLAN_XLATEm_field32_set(unit, vxent, 
    306                                    NEW_ICFIf,value);
    307     }
    308 
    309     if (SOC_MEM_FIELD_VALID(unit, VLAN_XLATEm,
    310                             ESM_SEARCH_OFFSETf)) {
    311         value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, 
    312                         XLATE__ESM_SEARCH_OFFSETf);
    313         soc_VLAN_XLATEm_field32_set(unit, vxent, 
    314                                    ESM_SEARCH_OFFSETf,value);
    315     }
    316     if (SOC_MEM_FIELD_VALID(unit, VLAN_XLATEm,
    317                             ESM_SEARCH_PRIORITYf)) {
    318         value = soc_VLAN_XLATE_EXTDm_field32_get(unit, vxxent, 
    319                         XLATE__ESM_SEARCH_PRIORITYf);
    320         soc_VLAN_XLATEm_field32_set(unit, vxent, 
    321                                    ESM_SEARCH_PRIORITYf,value);
    322     }
    323 
    324     return BCM_E_NONE;    
    325 }
    326 
    327 /*
    328  * Function :
    329  *   _bcm_tr3_vxlate2vxlate_extd
    330  *
    331  * Purpose  :
    332  *   convert the regular vlan translation table to the extended vlan translation
    333  *   table for all applicable fields.
    334  *
    335  * Parameters:
    336  *   vxent   -  (IN) regular vlan translation table
    337  *   vxxent  -  (OUT) extended vlan translation table
    338  */
    339 
    340 int
    341 _bcm_tr3_vxlate2vxlate_extd(int unit,
    342                 vlan_xlate_entry_t *vxent,
    343                 vlan_xlate_extd_entry_t *vxxent)
    344 {
    345     uint32 key[2];
    346     uint32 value;
    347     int svp_valid;
    348 
    349     value = soc_mem_field32_get(unit, VLAN_XLATEm, vxent, VALIDf);
    350     soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, VALID_0f, value);
    351     soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, VALID_1f, value);
    352 
    353     soc_mem_field_get(unit, VLAN_XLATEm,
    354                     (uint32 *)vxent,  KEYf, key);
    355     soc_mem_field_set(unit, VLAN_XLATE_EXTDm, 
    356                       (uint32 *)vxxent, XLATE__KEY_0f, key);
    357 
    358     value = soc_VLAN_XLATEm_field32_get(unit, vxent, KEY_TYPEf);
    359 
    360     /* key type value for VLAN_XLATE_EXTDm: VLAN_XLATE_1 value + 1 */
    361     value++;    
    362     soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, KEY_TYPE_0f, value);
    363     soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, KEY_TYPE_1f, value);
    364 
    365     value = soc_VLAN_XLATEm_field32_get(unit, vxent, 
    366                                    TAG_ACTION_PROFILE_PTRf);
    367     soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, 
    368                         XLATE__TAG_ACTION_PROFILE_PTRf, value);
    369     value = soc_VLAN_XLATEm_field32_get(unit, vxent, 
    370                                    NEW_OVIDf);
    371     soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, 
    372                         XLATE__NEW_OVIDf, value);
    373     value = soc_VLAN_XLATEm_field32_get(unit, vxent, 
    374                                    NEW_OPRIf);
    375     soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, 
    376                         XLATE__NEW_OPRIf, value);
    377     value = soc_VLAN_XLATEm_field32_get(unit, vxent, 
    378                                    NEW_OCFIf);
    379     soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, 
    380                         XLATE__NEW_OCFIf, value);
    381     svp_valid = soc_VLAN_XLATEm_field32_get(unit, vxent, 
    382                                    SVP_VALIDf);
    383     if (svp_valid) {
    384         value = soc_VLAN_XLATEm_field32_get(unit, vxent, 
    385                                    SOURCE_VPf);
    386         soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, 
    387                             XLATE__SOURCE_VPf, value);
    388     } else {
    389         value = soc_VLAN_XLATEm_field32_get(unit, vxent, 
    390                                    NEW_IVIDf);
    391         soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, 
    392                         XLATE__NEW_IVIDf, value);
    393         value = soc_VLAN_XLATEm_field32_get(unit, vxent, 
    394                                    NEW_IPRIf);
    395         soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, 
    396                         XLATE__NEW_IPRIf, value);
    397         value = soc_VLAN_XLATEm_field32_get(unit, vxent, 
    398                                    NEW_ICFIf);
    399         soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, 
    400                         XLATE__NEW_ICFIf, value);
    401     }
    402 
    403     if (SOC_MEM_FIELD_VALID(unit, VLAN_XLATEm,
    404                                     ESM_SEARCH_OFFSETf)) {
    405         value = soc_VLAN_XLATEm_field32_get(unit, vxent, 
    406                                    ESM_SEARCH_OFFSETf);
    407         soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, 
    408                             XLATE__ESM_SEARCH_OFFSETf, value);
    409     }
    410     if (SOC_MEM_FIELD_VALID(unit, VLAN_XLATEm,
    411                                     ESM_SEARCH_PRIORITYf)) {
    412         value = soc_VLAN_XLATEm_field32_get(unit, vxent, 
    413                                    ESM_SEARCH_PRIORITYf);
    414         soc_VLAN_XLATE_EXTDm_field32_set(unit, vxxent, 
    415                             XLATE__ESM_SEARCH_PRIORITYf, value);
    416     }
    417     return BCM_E_NONE;    
    418 }
    419 
    420 
    421 /*
    422  * Function :
    423  *   _bcm_tr3_vxlate_entry_add
    424  *
    425  * Purpose  :
    426  *   Add or update a vlan translation entry to the appropriate table. 
    427  *   BCM56640 has two type of vlan translation tables, a regular sized 
    428  *   table VLAN_XLATE and a extended sized table VLAN_XLATE_EXTD. This
    429  *   function takes a regular sized entry as input, add or update 
    430  *   either in regular sized table or extended sized table if fields 
    431  *   only in extended table are used.   
    432  *
    433  * Parameters:
    434  *  vent   -    the regular sized entry to be added/updated
    435  *  ctxt   -    context used by update_func 
    436  *  update_func - function determines whether to use regular or extd entry
    437  */                   
    438 int
    439 _bcm_tr3_vxlate_entry_add(int unit,
    440                 vlan_xlate_entry_t *vent,
    441                 void *ctxt,
    442                 tr3_vxlate_extd_entry_update_func_t update_func,
    443                 int *existing_updated)
    444 {
    445     vlan_xlate_entry_t vent_old;
    446     vlan_xlate_extd_entry_t vxent;
    447     vlan_xlate_extd_entry_t vxent_old;
    448     vlan_xlate_extd_entry_t vxent_tmp;
    449     int idx;
    450     int use_extd_table = 0;
    451     int rv;
    452  
    453     sal_memset(&vent_old, 0, sizeof(vent_old));
    454     sal_memset(&vxent, 0, sizeof(vxent));
    455     sal_memset(&vxent_old, 0, sizeof(vxent_old));
    456 
    457     /*
    458      * first searches the regular entry table VLAN_XLATEm, if a match is found,
    459      * update and write it back if the entry can be added to this table. 
    460      * If not, delete this entry and add it to VLAN_XLATE_EXTDm. If no match is
    461      * found, check VLAN_XLATE_EXTDm, if a match is found, update and write it
    462      * back, if not, add it to either VLAN_XLATEm or VLAN_XLATE_EXTDm 
    463      * appropriately. 
    464      */ 
    465     
    466     /* look up existing entry */
    467     soc_mem_lock(unit, VLAN_XLATEm);
    468     rv = soc_mem_search(unit, VLAN_XLATEm, MEM_BLOCK_ALL, &idx, vent, 
    469                         &vent_old, 0);
    470     soc_mem_unlock(unit, VLAN_XLATEm);
    471 
    472     /* regular entry exist */
    473     if (rv == SOC_E_NONE) {
    474 
    475         if (update_func) {
    476             BCM_IF_ERROR_RETURN
    477                 (update_func(unit,vent,ctxt,&vent_old,&vxent_old,
    478                       &use_extd_table));
    479 
    480             if (use_extd_table) {
    481                 /* remove the existing entry */
    482                 soc_mem_lock(unit, VLAN_XLATEm);
    483                 rv = (soc_mem_delete(unit, VLAN_XLATEm, MEM_BLOCK_ANY, 
    484                                      &vent_old));
    485                 soc_mem_unlock(unit, VLAN_XLATEm);
    486 
    487                 if (rv != SOC_E_NONE) {
    488                     return rv;
    489                 }
    490  
    491                 /* search for the extd entry. It should not exist because
    492                  * we already found a regular one
    493                  */
    494                 soc_mem_lock(unit, VLAN_XLATE_EXTDm);
    495                 rv = soc_mem_search(unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ALL,
    496                              &idx, &vxent, &vxent_tmp, 0);
    497                 soc_mem_unlock(unit, VLAN_XLATE_EXTDm);
    498     
    499                 if (rv == SOC_E_NONE) {
    500                     return BCM_E_EXISTS;  /* XXX ERROR message */
    501                 } else if (rv != SOC_E_NOT_FOUND) {
    502                     return rv;
    503                 } else { 
    504                     soc_mem_lock(unit, VLAN_XLATE_EXTDm);
    505 
    506                     /* no extry exists, insert */
    507                     rv = soc_mem_insert(unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ALL, 
    508                                     &vxent_old);    
    509                     soc_mem_unlock(unit, VLAN_XLATE_EXTDm);
    510                     if (existing_updated != NULL) {
    511                         *existing_updated = 1;
    512                     }
    513                     return rv;
    514                 }
    515             }  /* use_extd_table */
    516         } /*  update_func */ 
    517 
    518         /* regular entry */
    519         soc_mem_lock(unit, VLAN_XLATEm);
    520         rv = soc_mem_write(unit, VLAN_XLATEm,  MEM_BLOCK_ALL, 
    521                     idx, update_func == NULL? vent: &vent_old);
    522         soc_mem_unlock(unit, VLAN_XLATEm);
    523         return BCM_E_NONE;
    524     } else if (rv != SOC_E_NOT_FOUND) {
    525         return rv;
    526     } else {  /* no regular entry found */
    527         BCM_IF_ERROR_RETURN
    528             (_bcm_tr3_vxlate2vxlate_extd(unit,vent,&vxent));
    529         soc_mem_lock(unit, VLAN_XLATE_EXTDm);
    530         rv = soc_mem_search(unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ALL, &idx,
    531                             &vxent, &vxent_old, 0);
    532         soc_mem_unlock(unit, VLAN_XLATE_EXTDm);
    533         if (rv == SOC_E_NONE) {
    534             /* found extd entry */
    535 
    536             if (update_func) {
    537                 /* need update the entry before writing it back */
    538                 BCM_IF_ERROR_RETURN
    539                     (update_func(unit,vent,ctxt,NULL,&vxent_old,
    540                                       &use_extd_table));
    541             }
    542             soc_mem_lock(unit, VLAN_XLATE_EXTDm);
    543             rv = soc_mem_write(unit, VLAN_XLATE_EXTDm,
    544                           MEM_BLOCK_ALL, idx, &vxent_old);
    545             soc_mem_unlock(unit, VLAN_XLATE_EXTDm);
    546             if (existing_updated != NULL) {
    547                 *existing_updated = 1;
    548             }
    549         } else if (rv != SOC_E_NOT_FOUND) {
    550             return rv;
    551         } else {
    552             /* both regular and extd table are not found */
    553             /* need update the entry before insert */
    554             BCM_IF_ERROR_RETURN
    555                 (_bcm_tr3_vxlate2vxlate_extd(unit,vent,&vxent));
    556             if (update_func) {
    557                 BCM_IF_ERROR_RETURN
    558                     (update_func(unit,vent,ctxt,NULL,&vxent,
    559                                       &use_extd_table));
    560             }
    561 
    562             if (use_extd_table) {
    563                 soc_mem_lock(unit, VLAN_XLATE_EXTDm);
    564                 rv = soc_mem_insert(unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ALL, 
    565                                 &vxent);    
    566                 soc_mem_unlock(unit, VLAN_XLATE_EXTDm);
    567             } else {
    568                 soc_mem_lock(unit, VLAN_XLATEm);
    569                 rv = soc_mem_insert(unit, VLAN_XLATEm, MEM_BLOCK_ALL, 
    570                                 vent);    
    571                 soc_mem_unlock(unit, VLAN_XLATEm);
    572             }
    573         }
    574     }
    575     return rv;    
    576 }
    577 #endif /* BCM_TRIUMPH3_SUPPORT */
    578 
    579 /*
    580  * Function : _bcm_trx_vlan_action_verify
    581  *
    582  * Purpose  : to validate all members of action structure
    583  */
    584 int
    585 _bcm_trx_vlan_action_verify(int unit, bcm_vlan_action_set_t *action)
    586 {
    587     if (NULL == action) {
    588         return BCM_E_PARAM;
    589     }
    590     VLAN_CHK_ID(unit, action->new_inner_vlan);
    591     VLAN_CHK_ID(unit, action->new_outer_vlan);
    592 
    593     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
    594         if (action->priority < -1 || action->priority > 7 ||
    595             action->new_inner_pkt_prio > 7 ||
    596             action->new_outer_cfi > 1 || action->new_inner_cfi > 1) {
    597             return BCM_E_PARAM;
    598         }
    599     }
    600 
    601 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    602     if(soc_feature(unit, soc_feature_vlan_xlate_has_class_id)) {
    603         /* The max value of CLASS_ID should not be greater than 0xff since
    604          * length of IFP_KEY to qualify CLASS_ID is 8 bits.
    605          */
    606         if(action->class_id) {
    607             if(action->class_id > 0xff) {
    608                 return BCM_E_PARAM;
    609             }
    610         }
    611     }
    612 #endif
    613 
    614     switch (action->dt_outer) {
    615     case bcmVlanActionNone:
    616     case bcmVlanActionAdd:
    617     case bcmVlanActionReplace:
    618     case bcmVlanActionDelete:
    619         break;
    620     case bcmVlanActionCopy:
    621         if (!soc_feature(unit, soc_feature_vlan_copy_action)) {
    622             return BCM_E_UNAVAIL;
    623         }
    624         break;
    625 
    626 #if defined(BCM_TRIDENT2_SUPPORT)
    627     case bcmVlanActionCopyVsan:
    628     case bcmVlanActionReplaceVsan:
    629         if (!soc_feature(unit, soc_feature_fcoe)) {
    630             return BCM_E_UNAVAIL;
    631         }
    632         break;
    633 #endif
    634     default:
    635         return BCM_E_PARAM;
    636     }
    637 
    638     switch (action->dt_outer_prio) {
    639     case bcmVlanActionNone:
    640     case bcmVlanActionAdd:
    641     case bcmVlanActionReplace:
    642     case bcmVlanActionDelete:
    643         break;
    644     case bcmVlanActionCopy:
    645         if (!soc_feature(unit, soc_feature_vlan_copy_action)) {
    646             return BCM_E_UNAVAIL;
    647         }
    648         break;
    649 #if defined(BCM_TRIDENT2_SUPPORT)
    650     case bcmVlanActionCopyVsan:
    651     case bcmVlanActionReplaceVsan:
    652         if (!soc_feature(unit, soc_feature_fcoe)) {
    653             return BCM_E_UNAVAIL;
    654         }
    655         break;
    656 #endif
    657     default:
    658         return BCM_E_PARAM;
    659     }
    660 
    661     switch (action->dt_outer_pkt_prio) {
    662     case bcmVlanActionNone:
    663         break;
    664     case bcmVlanActionAdd:
    665     case bcmVlanActionReplace:
    666     case bcmVlanActionCopy:
    667         if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
    668             return BCM_E_UNAVAIL;
    669         }
    670         break;
    671 #if defined(BCM_TRIDENT2_SUPPORT)
    672     case bcmVlanActionCopyVsan:
    673     case bcmVlanActionReplaceVsan:
    674         if (!soc_feature(unit, soc_feature_fcoe)) {
    675             return BCM_E_UNAVAIL;
    676         }
    677         break;
    678 #endif
    679     default:
    680         return BCM_E_PARAM;
    681     }
    682 
    683     switch (action->dt_outer_cfi) {
    684     case bcmVlanActionNone:
    685         break;
    686     case bcmVlanActionAdd:
    687     case bcmVlanActionReplace:
    688     case bcmVlanActionCopy:
    689         if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
    690             return BCM_E_UNAVAIL;
    691         }
    692         break;
    693     default:
    694         return BCM_E_PARAM;
    695     }
    696 
    697     switch (action->dt_inner) {
    698     case bcmVlanActionNone:
    699     case bcmVlanActionReplace:
    700     case bcmVlanActionDelete:
    701         break;
    702     case bcmVlanActionCopy:
    703         if (!soc_feature(unit, soc_feature_vlan_copy_action)) {
    704             return BCM_E_UNAVAIL;
    705         }
    706         break;
    707 #if defined(BCM_TRIDENT2_SUPPORT)
    708     case bcmVlanActionCopyVsan:
    709     case bcmVlanActionReplaceVsan:
    710         if (!soc_feature(unit, soc_feature_fcoe)) {
    711             return BCM_E_UNAVAIL;
    712         }
    713         break;
    714 #endif
    715     default:
    716         return BCM_E_PARAM;
    717     }
    718 
    719     switch (action->dt_inner_prio) {
    720     case bcmVlanActionNone:
    721     case bcmVlanActionReplace:
    722     case bcmVlanActionDelete:
    723         break;
    724     case bcmVlanActionCopy:
    725         if (!soc_feature(unit, soc_feature_vlan_copy_action)) {
    726             return BCM_E_UNAVAIL;
    727         }
    728         break;
    729 #if defined(BCM_TRIDENT2_SUPPORT)
    730     case bcmVlanActionCopyVsan:
    731     case bcmVlanActionReplaceVsan:
    732         if (!soc_feature(unit, soc_feature_fcoe)) {
    733             return BCM_E_UNAVAIL;
    734         }
    735         break;
    736 #endif
    737     default:
    738         return BCM_E_PARAM;
    739     }
    740 
    741     switch (action->dt_inner_pkt_prio) {
    742     case bcmVlanActionNone:
    743         break;
    744     case bcmVlanActionReplace:
    745     case bcmVlanActionCopy:
    746         if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
    747             return BCM_E_UNAVAIL;
    748         }
    749         break;
    750 #if defined(BCM_TRIDENT2_SUPPORT)
    751     case bcmVlanActionCopyVsan:
    752     case bcmVlanActionReplaceVsan:
    753         if (!soc_feature(unit, soc_feature_fcoe)) {
    754             return BCM_E_UNAVAIL;
    755         }
    756         break;
    757 #endif
    758     default:
    759         return BCM_E_PARAM;
    760     }
    761 
    762     switch (action->dt_inner_cfi) {
    763     case bcmVlanActionNone:
    764         break;
    765     case bcmVlanActionReplace:
    766     case bcmVlanActionCopy:
    767         if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
    768             return BCM_E_UNAVAIL;
    769         }
    770         break;
    771     default:
    772         return BCM_E_PARAM;
    773     }
    774 
    775     switch (action->ot_outer) {
    776     case bcmVlanActionNone:
    777     case bcmVlanActionAdd:
    778     case bcmVlanActionReplace:
    779     case bcmVlanActionDelete:
    780         break;
    781 #if defined(BCM_TRIDENT2_SUPPORT)
    782     case bcmVlanActionCopyVsan:
    783     case bcmVlanActionReplaceVsan:
    784         if (!soc_feature(unit, soc_feature_fcoe)) {
    785             return BCM_E_UNAVAIL;
    786         }
    787         break;
    788 #endif
    789     default:
    790         return BCM_E_PARAM;
    791     }
    792 
    793     switch (action->ot_outer_prio) {
    794     case bcmVlanActionNone:
    795     case bcmVlanActionAdd:
    796     case bcmVlanActionReplace:
    797     case bcmVlanActionDelete:
    798         break;
    799 #if defined(BCM_TRIDENT2_SUPPORT)
    800     case bcmVlanActionCopyVsan:
    801     case bcmVlanActionReplaceVsan:
    802         if (!soc_feature(unit, soc_feature_fcoe)) {
    803             return BCM_E_UNAVAIL;
    804         }
    805         break;
    806 #endif
    807     default:
    808         return BCM_E_PARAM;
    809     }
    810 
    811     switch (action->ot_outer_pkt_prio) {
    812     case bcmVlanActionNone:
    813         break;
    814     case bcmVlanActionReplace:
    815         if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
    816             return BCM_E_UNAVAIL;
    817         }
    818         break;
    819 #if defined(BCM_TRIDENT2_SUPPORT)
    820     case bcmVlanActionCopyVsan:
    821     case bcmVlanActionReplaceVsan:
    822         if (!soc_feature(unit, soc_feature_fcoe)) {
    823             return BCM_E_UNAVAIL;
    824         }
    825         break;
    826 #endif
    827     default:
    828         return BCM_E_PARAM;
    829     }
    830 
    831     switch (action->ot_outer_cfi) {
    832     case bcmVlanActionNone:
    833         break;
    834     case bcmVlanActionReplace:
    835         if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
    836             return BCM_E_UNAVAIL;
    837         }
    838         break;
    839     default:
    840         return BCM_E_PARAM;
    841     }
    842 
    843     switch (action->ot_inner) {
    844     case bcmVlanActionNone:
    845     case bcmVlanActionAdd:
    846         break;
    847     case bcmVlanActionCopy:
    848         if (!soc_feature(unit, soc_feature_vlan_copy_action)) {
    849             return BCM_E_UNAVAIL;
    850         }
    851         break;
    852 #if defined(BCM_TRIDENT2_SUPPORT)
    853     case bcmVlanActionCopyVsan:
    854     case bcmVlanActionReplaceVsan:
    855         if (!soc_feature(unit, soc_feature_fcoe)) {
    856             return BCM_E_UNAVAIL;
    857         }
    858         break;
    859 #endif
    860     default:
    861         return BCM_E_PARAM;
    862     }
    863 
    864     switch (action->ot_inner_pkt_prio) {
    865     case bcmVlanActionNone:
    866         break;
    867     case bcmVlanActionAdd:
    868     case bcmVlanActionCopy:
    869         if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
    870             return BCM_E_UNAVAIL;
    871         }
    872         break;
    873 #if defined(BCM_TRIDENT2_SUPPORT)
    874     case bcmVlanActionCopyVsan:
    875     case bcmVlanActionReplaceVsan:
    876         if (!soc_feature(unit, soc_feature_fcoe)) {
    877             return BCM_E_UNAVAIL;
    878         }
    879         break;
    880 #endif
    881     default:
    882         return BCM_E_PARAM;
    883     }
    884 
    885     switch (action->ot_inner_cfi) {
    886     case bcmVlanActionNone:
    887         break;
    888     case bcmVlanActionAdd:
    889     case bcmVlanActionCopy:
    890         if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
    891             return BCM_E_UNAVAIL;
    892         }
    893         break;
    894     default:
    895         return BCM_E_PARAM;
    896     }
    897 
    898     switch (action->it_outer) {
    899     case bcmVlanActionNone:
    900     case bcmVlanActionAdd:
    901         break;
    902     case bcmVlanActionCopy:
    903         if (!soc_feature(unit, soc_feature_vlan_copy_action)) {
    904             return BCM_E_UNAVAIL;
    905         }
    906         break;
    907 #if defined(BCM_TRIDENT2_SUPPORT)
    908     case bcmVlanActionCopyVsan:
    909     case bcmVlanActionReplaceVsan:
    910         if (!soc_feature(unit, soc_feature_fcoe)) {
    911             return BCM_E_UNAVAIL;
    912         }
    913         break;
    914 #endif
    915     default:
    916         return BCM_E_PARAM;
    917     }
    918 
    919     switch (action->it_outer_pkt_prio) {
    920     case bcmVlanActionNone:
    921         break;
    922     case bcmVlanActionAdd:
    923     case bcmVlanActionCopy:
    924         if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
    925             return BCM_E_UNAVAIL;
    926         }
    927         break;
    928 #if defined(BCM_TRIDENT2_SUPPORT)
    929     case bcmVlanActionCopyVsan:
    930     case bcmVlanActionReplaceVsan:
    931         if (!soc_feature(unit, soc_feature_fcoe)) {
    932             return BCM_E_UNAVAIL;
    933         }
    934         break;
    935 #endif
    936     default:
    937         return BCM_E_PARAM;
    938     }
    939 
    940     switch (action->it_outer_cfi) {
    941     case bcmVlanActionNone:
    942         break;
    943     case bcmVlanActionAdd:
    944     case bcmVlanActionCopy:
    945         if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
    946             return BCM_E_UNAVAIL;
    947         }
    948         break;
    949     default:
    950         return BCM_E_PARAM;
    951     }
    952 
    953     switch (action->it_inner) {
    954     case bcmVlanActionNone:
    955     case bcmVlanActionReplace:
    956     case bcmVlanActionDelete:
    957         break;
    958 #if defined(BCM_TRIDENT2_SUPPORT)
    959     case bcmVlanActionCopyVsan:
    960     case bcmVlanActionReplaceVsan:
    961         if (!soc_feature(unit, soc_feature_fcoe)) {
    962             return BCM_E_UNAVAIL;
    963         }
    964         break;
    965 #endif
    966     default:
    967         return BCM_E_PARAM;
    968     }
    969 
    970     switch (action->it_inner_prio) {
    971     case bcmVlanActionNone:
    972     case bcmVlanActionReplace:
    973     case bcmVlanActionDelete:
    974         break;
    975 #if defined(BCM_TRIDENT2_SUPPORT)
    976     case bcmVlanActionCopyVsan:
    977     case bcmVlanActionReplaceVsan:
    978         if (!soc_feature(unit, soc_feature_fcoe)) {
    979             return BCM_E_UNAVAIL;
    980         }
    981         break;
    982 #endif
    983     default:
    984         return BCM_E_PARAM;
    985     }
    986 
    987     switch (action->it_inner_pkt_prio) {
    988     case bcmVlanActionNone:
    989         break;
    990     case bcmVlanActionReplace:
    991         if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
    992             return BCM_E_UNAVAIL;
    993         }
    994         break;
    995 #if defined(BCM_TRIDENT2_SUPPORT)
    996     case bcmVlanActionCopyVsan:
    997     case bcmVlanActionReplaceVsan:
    998         if (!soc_feature(unit, soc_feature_fcoe)) {
    999             return BCM_E_UNAVAIL;
   1000         }
   1001         break;
   1002 #endif
   1003     default:
   1004         return BCM_E_PARAM;
   1005     }
   1006 
   1007     switch (action->it_inner_cfi) {
   1008     case bcmVlanActionNone:
   1009         break;
   1010     case bcmVlanActionReplace:
   1011         if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   1012             return BCM_E_UNAVAIL;
   1013         }
   1014         break;
   1015     default:
   1016         return BCM_E_PARAM;
   1017     }
   1018 
   1019     switch (action->ut_outer) {
   1020     case bcmVlanActionNone:
   1021     case bcmVlanActionAdd:
   1022         break;
   1023 #if defined(BCM_TRIDENT2_SUPPORT)
   1024     case bcmVlanActionCopyVsan:
   1025     case bcmVlanActionReplaceVsan:
   1026         if (!soc_feature(unit, soc_feature_fcoe)) {
   1027             return BCM_E_UNAVAIL;
   1028         }
   1029         break;
   1030 #endif
   1031     default:
   1032         return BCM_E_PARAM;
   1033     }
   1034 
   1035     switch (action->ut_outer_pkt_prio) {
   1036     case bcmVlanActionNone:
   1037         break;
   1038     case bcmVlanActionAdd:
   1039         if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   1040             return BCM_E_UNAVAIL;
   1041         }
   1042         break;
   1043 #if defined(BCM_TRIDENT2_SUPPORT)
   1044     case bcmVlanActionCopyVsan:
   1045     case bcmVlanActionReplaceVsan:
   1046         if (!soc_feature(unit, soc_feature_fcoe)) {
   1047             return BCM_E_UNAVAIL;
   1048         }
   1049         break;
   1050 #endif
   1051     default:
   1052         return BCM_E_PARAM;
   1053     }
   1054 
   1055     switch (action->ut_outer_cfi) {
   1056     case bcmVlanActionNone:
   1057         break;
   1058     case bcmVlanActionAdd:
   1059         if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   1060             return BCM_E_UNAVAIL;
   1061         }
   1062         break;
   1063     default:
   1064         return BCM_E_PARAM;
   1065     }
   1066 
   1067     switch (action->ut_inner) {
   1068     case bcmVlanActionNone:
   1069     case bcmVlanActionAdd:
   1070         break;
   1071 #if defined(BCM_TRIDENT2_SUPPORT)
   1072     case bcmVlanActionCopyVsan:
   1073     case bcmVlanActionReplaceVsan:
   1074         if (!soc_feature(unit, soc_feature_fcoe)) {
   1075             return BCM_E_UNAVAIL;
   1076         }
   1077         break;
   1078 #endif
   1079     default:
   1080         return BCM_E_PARAM;
   1081     }
   1082 
   1083     switch (action->ut_inner_pkt_prio) {
   1084     case bcmVlanActionNone:
   1085         break;
   1086     case bcmVlanActionAdd:
   1087         if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   1088             return BCM_E_UNAVAIL;
   1089         }
   1090         break;
   1091 #if defined(BCM_TRIDENT2_SUPPORT)
   1092     case bcmVlanActionCopyVsan:
   1093     case bcmVlanActionReplaceVsan:
   1094         if (!soc_feature(unit, soc_feature_fcoe)) {
   1095             return BCM_E_UNAVAIL;
   1096         }
   1097         break;
   1098 #endif
   1099     default:
   1100         return BCM_E_PARAM;
   1101     }
   1102 
   1103     switch (action->ut_inner_cfi) {
   1104     case bcmVlanActionNone:
   1105         break;
   1106     case bcmVlanActionAdd:
   1107         if (!soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   1108             return BCM_E_UNAVAIL;
   1109         }
   1110         break;
   1111     default:
   1112         return BCM_E_PARAM;
   1113     }
   1114 
   1115     return BCM_E_NONE;
   1116 }
   1117 
   1118 /*
   1119  * Function : _bcm_trx_egr_vlan_action_verify
   1120  *
   1121  * Purpose  : to validate all members of action structure for egress vlan 
   1122  *            more strict validation than ingress  
   1123  */
   1124 STATIC int 
   1125 _bcm_trx_egr_vlan_action_verify(int unit, bcm_vlan_action_set_t *action)
   1126 {
   1127     BCM_IF_ERROR_RETURN(
   1128         _bcm_trx_vlan_action_verify(unit, action));
   1129 
   1130     if (action->dt_outer == bcmVlanActionAdd ||
   1131         action->dt_outer_prio == bcmVlanActionAdd ||
   1132         action->ot_outer == bcmVlanActionAdd ||
   1133         action->ot_outer_prio == bcmVlanActionAdd) {
   1134         return BCM_E_PARAM;
   1135     }
   1136 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   1137     /*Ensure that class_id doesnt overcross CLASS_IDf*/
   1138     if(soc_feature(unit, soc_feature_vlan_xlate_has_class_id)) {
   1139         /* The max value of CLASS_ID should not be greater than 0xff since
   1140          * length of IFP_KEY to qualify CLASS_ID is 8 bits.
   1141          */
   1142         if(action->class_id) {
   1143             if(action->class_id > 0xff) {
   1144                 return BCM_E_PARAM;
   1145             }
   1146         }
   1147     }
   1148 #endif
   1149     /* Single inner tag modification is available for egress vlan actions */
   1150     if (!soc_feature(unit, soc_feature_vlan_egr_it_inner_replace)) {
   1151         if (action->dt_outer_prio != bcmVlanActionNone) {
   1152             return BCM_E_PARAM;
   1153         }
   1154         if (action->ot_outer_prio != bcmVlanActionNone) {
   1155             return BCM_E_PARAM;
   1156         }
   1157         if (action->it_outer != bcmVlanActionNone) {
   1158             return BCM_E_PARAM;
   1159         }
   1160         if (action->it_inner != bcmVlanActionNone) {
   1161             return BCM_E_PARAM;
   1162         }
   1163         if (action->it_inner_prio != bcmVlanActionNone) {
   1164             return BCM_E_PARAM;
   1165         }
   1166         if (action->ut_inner != bcmVlanActionNone) {
   1167             return BCM_E_PARAM;
   1168         }
   1169         if (action->ut_outer != bcmVlanActionNone) {
   1170             return BCM_E_PARAM;
   1171         }
   1172     }
   1173 
   1174     return BCM_E_NONE;
   1175 }
   1176 
   1177 /*
   1178  * Function : _bcm_trx_vlan_ip_verify
   1179  *
   1180  * Purpose  : to validate members of vlan_ip structure
   1181  */
   1182 STATIC int 
   1183 _bcm_trx_vlan_ip_verify(int unit, bcm_vlan_ip_t *vlan_ip)
   1184 {
   1185     if (NULL == vlan_ip) {
   1186         return BCM_E_PARAM;
   1187     }
   1188     VLAN_CHK_ID(unit, vlan_ip->vid);
   1189     VLAN_CHK_PRIO(unit, vlan_ip->prio);
   1190 
   1191     return BCM_E_NONE;
   1192 }
   1193 
   1194 /*
   1195  * Function : bcm_trx_vlan_action_profile_detach
   1196  *
   1197  * Purpose  : to initialize hardware ING_VLAN_TAG_ACTION_PROFILE and
   1198  *            EGR_VLAN_TAG_ACTION_PROFILE tables and allocate memory
   1199  *            to cache hardware tables in RAM.
   1200  *
   1201  * Note:
   1202  *      Allocate memory to cache the profile tables and initialize.
   1203  *      If memory to cache the profile table is already allocated, just
   1204  *      initialize the table.
   1205  */
   1206 int
   1207 _bcm_trx_vlan_action_profile_detach(int unit)
   1208 {
   1209     int rv;
   1210     soc_mem_t mem = ING_VLAN_TAG_ACTION_PROFILEm;
   1211     if (SOC_MEM_IS_VALID(unit, ING_VLAN_TAG_ACTION_PROFILE_2m)) {
   1212         mem = ING_VLAN_TAG_ACTION_PROFILE_2m;
   1213     }
   1214     if (SOC_MEM_IS_VALID(unit, mem)) {
   1215         /* De-initialize the ING_VLAN_TAG_ACTION_PROFILE table */
   1216         ING_VLAN_TAG_ACTION_LOCK(unit);
   1217         rv = soc_profile_mem_destroy(unit, ing_action_profile[unit]);
   1218         if (BCM_SUCCESS(rv)) {
   1219             sal_free(ing_action_profile[unit]);
   1220             ing_action_profile[unit] = NULL;
   1221         }
   1222         ING_VLAN_TAG_ACTION_UNLOCK(unit);
   1223         BCM_IF_ERROR_RETURN(rv);
   1224     }
   1225 
   1226     EGR_VLAN_TAG_ACTION_LOCK(unit);
   1227     rv = soc_profile_mem_destroy(unit, egr_action_profile[unit]);
   1228     if (BCM_SUCCESS(rv)) {
   1229         sal_free(egr_action_profile[unit]);
   1230         egr_action_profile[unit] = NULL;
   1231     }
   1232     EGR_VLAN_TAG_ACTION_UNLOCK(unit);
   1233     BCM_IF_ERROR_RETURN(rv);
   1234 
   1235     VLAN_RANGE_LOCK(unit);
   1236     rv = soc_profile_mem_destroy(unit, vlan_range_profile[unit]);
   1237     if (BCM_SUCCESS(rv)) {
   1238         sal_free(vlan_range_profile[unit]);
   1239         vlan_range_profile[unit] = NULL;
   1240     }
   1241     VLAN_RANGE_UNLOCK(unit);
   1242     BCM_IF_ERROR_RETURN(rv);
   1243 
   1244     return BCM_E_NONE;
   1245 }
   1246 
   1247 /*
   1248  * Function : bcm_trx_vlan_action_profile_init
   1249  *
   1250  * Purpose  : to initialize hardware ING_VLAN_TAG_ACTION_PROFILE and
   1251  *            EGR_VLAN_TAG_ACTION_PROFILE tables and allocate memory
   1252  *            to cache hardware tables in RAM.
   1253  *
   1254  * Note:
   1255  *      Allocate memory to cache the profile tables and initialize.
   1256  *      If memory to cache the profile table is already allocated, just
   1257  *      initialize the table.
   1258  */
   1259 int
   1260 _bcm_trx_vlan_action_profile_init(int unit)
   1261 {
   1262     int i, idx, num_ports;
   1263     vlan_protocol_data_entry_t proto_entry;
   1264     vlan_subnet_entry_t subnet_entry;
   1265     vlan_mac_entry_t vlan_mac_entry;
   1266     vlan_xlate_entry_t vx_ent;
   1267     vlan_xlate_1_double_entry_t vx1d_ent;
   1268     egr_vlan_xlate_entry_t evx_ent;
   1269     egr_vlan_xlate_1_double_entry_t evx1d_ent;
   1270     ing_vlan_tag_action_profile_entry_t ing_profile;
   1271     egr_vlan_tag_action_profile_entry_t egr_profile_entry;
   1272     uint32 rval, temp_index;
   1273     soc_mem_t mem[2];
   1274     soc_mem_t mem_cnt = 1;
   1275     int table_cnt = 1;
   1276     int entry_idxmin[2], entry_idxmax[2];
   1277     int entry_words[2];
   1278     void *entries[2];
   1279     int key_type_value, key_type;
   1280 #if defined(BCM_TRIUMPH2_SUPPORT)
   1281     _bcm_flex_stat_handle_t handle;
   1282     vlan_xlate_entry_t vent;
   1283     egr_vlan_xlate_entry_t event;
   1284     uint32 key[2];
   1285     int fs_idx;
   1286 #endif
   1287     ing_vlan_tag_action_profile_2_entry_t ing_profile_2;
   1288     void *ing_profile_entry;
   1289     uint32 ing_ent_sz;
   1290     int rv;
   1291 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   1292     uint32 entry[SOC_MAX_MEM_WORDS];
   1293     soc_field_info_t *field_info = NULL, *field_info_1 = NULL;
   1294     int type;
   1295     soc_field_t type_fld = ENTRY_TYPEf;
   1296 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */
   1297 
   1298     soc_mem_t ing_mem = VLAN_XLATEm;
   1299     soc_mem_t egr_mem = EGR_VLAN_XLATEm;
   1300     soc_field_t vf = VALIDf;
   1301     void *xlate_entry = &vx_ent;
   1302     void *egr_xlate_entry = &evx_ent;
   1303     ing_vlan_tag_action_profile_entry_t ing_vlan_tag_action_profile_mask;
   1304     void *entry_mask[1];
   1305 
   1306     if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) {
   1307         ing_action_profile_def[unit] = 1;
   1308     }
   1309 
   1310     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
   1311         ing_mem = VLAN_XLATE_1_DOUBLEm;
   1312         egr_mem = EGR_VLAN_XLATE_1_DOUBLEm;
   1313         vf = BASE_VALID_0f;
   1314         xlate_entry = &vx1d_ent;
   1315         egr_xlate_entry = &evx1d_ent;
   1316 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   1317         type_fld = KEY_TYPEf;
   1318 #endif
   1319     }
   1320 
   1321     /* Create profile table cache (or re-init if it already exists) */
   1322     if (SOC_MEM_IS_VALID(unit, ING_VLAN_TAG_ACTION_PROFILE_2m)) {
   1323         mem[0] = ING_VLAN_TAG_ACTION_PROFILE_2m;
   1324         mem[1] = ING_VLAN_TAG_ACTION_PROFILE_1m;
   1325         ing_ent_sz = sizeof(ing_vlan_tag_action_profile_2_entry_t);
   1326         ing_profile_entry = &ing_profile_2;
   1327         table_cnt = 2;
   1328         entry_idxmin[0] = entry_idxmin[1] = 1;
   1329     } else {
   1330         mem[0] = ING_VLAN_TAG_ACTION_PROFILEm;
   1331         ing_ent_sz = sizeof(ing_vlan_tag_action_profile_entry_t);
   1332         ing_profile_entry = &ing_profile;
   1333         entry_idxmin[0] = entry_idxmin[1] = 0;
   1334         sal_memset(&ing_vlan_tag_action_profile_mask, 0xff,
   1335                    sizeof(ing_vlan_tag_action_profile_mask));
   1336     }
   1337     /* Create profile table cache (or re-init if it already exists) */
   1338     entry_words[0] = entry_words[1] = ing_ent_sz / sizeof(uint32);
   1339 
   1340     if (SOC_MEM_IS_VALID(unit, mem[0])) {
   1341         /* Initialize the ING_VLAN_TAG_ACTION_PROFILE table */
   1342     
   1343         if (ing_action_profile[unit] == NULL) {
   1344             ing_action_profile[unit] = sal_alloc(sizeof(soc_profile_mem_t),
   1345                                                  "Ing Action Profile Mem");
   1346             if (ing_action_profile[unit] == NULL) {
   1347                 return BCM_E_MEMORY;
   1348             }
   1349             soc_profile_mem_t_init(ing_action_profile[unit]);
   1350         }
   1351     
   1352         entry_idxmax[0] = entry_idxmax[1] = soc_mem_index_max(unit, mem[0]);
   1353         if (mem[0] == ING_VLAN_TAG_ACTION_PROFILEm) {
   1354             entry_mask[0] = &ing_vlan_tag_action_profile_mask;
   1355             if (SOC_MEM_FIELD_VALID(unit, mem[0], ECCPf)) {
   1356                 soc_mem_field32_set(unit, mem[0], entry_mask[0], ECCPf, 0);
   1357             } else if (SOC_MEM_FIELD_VALID(unit, mem[0], EVEN_PARITYf)) {
   1358                 soc_mem_field32_set(unit, mem[0], entry_mask[0], EVEN_PARITYf,
   1359                                     0);
   1360             }
   1361             SOC_IF_ERROR_RETURN(
   1362                 soc_profile_mem_index_create(unit, mem, entry_words,
   1363                                              entry_idxmin, entry_idxmax, entry_mask,
   1364                                              table_cnt, ing_action_profile[unit]));
   1365         } else {
   1366             SOC_IF_ERROR_RETURN(
   1367                 soc_profile_mem_index_create(unit, mem, entry_words,
   1368                                              entry_idxmin, entry_idxmax, NULL,
   1369                                              table_cnt, ing_action_profile[unit]));
   1370         }
   1371 
   1372         if (SOC_WARM_BOOT(unit)) {
   1373             soc_mem_t port_mem = PORT_TABm;
   1374             if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) {
   1375                 port_mem = ING_DEVICE_PORTm;
   1376             }
   1377 
   1378             /* Increment the ref count for all ports */
   1379             for (i = 0; i < soc_mem_index_count(unit, port_mem); i++) {
   1380                 if (!SOC_PORT_VALID(unit, i)) {
   1381                     continue;
   1382                 }
   1383                     SOC_IF_ERROR_RETURN(_bcm_esw_port_tab_get(unit, i,
   1384                                         TAG_ACTION_PROFILE_PTRf, &idx));
   1385                     SOC_IF_ERROR_RETURN(
   1386                         soc_profile_mem_reference(unit, ing_action_profile[unit],
   1387                         idx, 1));
   1388                     SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, ing_action_profile[unit],
   1389                                                     idx - entry_idxmin[0], 1);
   1390                 }
   1391     
   1392             /* TH/TH2/TD3/KT2 and some other chips need use another method to revocer
   1393              * the reference count in _bcm_th_port_vlan_action_profile_reinit().
   1394              */
   1395             if (!SOC_IS_TOMAHAWK(unit) && !SOC_IS_TOMAHAWK2(unit) &&
   1396                 !SOC_IS_KATANA2(unit)) {
   1397                 /* Increment the ref count for all Protocol-based VLANs */
   1398                 for (i = 0; i < soc_mem_index_count(unit, VLAN_PROTOCOL_DATAm);
   1399                      i++) {
   1400                     SOC_IF_ERROR_RETURN(
   1401                         READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY, i,
   1402                         &proto_entry));
   1403                     idx = soc_mem_field32_get(unit, VLAN_PROTOCOL_DATAm,
   1404                                               &proto_entry,
   1405                                               TAG_ACTION_PROFILE_PTRf);
   1406                     if (!SOC_IS_TRIDENT3X(unit)) {
   1407                         SOC_IF_ERROR_RETURN(
   1408                             soc_profile_mem_reference(unit,
   1409                             ing_action_profile[unit], idx, 1));
   1410                         SOC_PROFILE_MEM_ENTRIES_PER_SET(
   1411                             unit, ing_action_profile[unit],
   1412                             idx - entry_idxmin[0], 1);
   1413                     }
   1414                     if (idx < ing_action_profile_def[unit]) {
   1415                         SOC_IF_ERROR_RETURN(
   1416                             soc_profile_mem_reference(unit,
   1417                             ing_action_profile[unit],
   1418                             ing_action_profile_def[unit], 1));
   1419                     }
   1420                 }
   1421             }
   1422 
   1423             /* Increment the ref count for all Subnet-based VLANs */
   1424             for (i = 0; i < soc_mem_index_count(unit, VLAN_SUBNETm); i++) {
   1425                 SOC_IF_ERROR_RETURN
   1426                     (READ_VLAN_SUBNETm(unit, MEM_BLOCK_ANY, i, &subnet_entry));
   1427                 if (!soc_mem_field32_get(unit, VLAN_SUBNETm, 
   1428                                          &subnet_entry, VALIDf)) {
   1429                     continue;
   1430                 }
   1431                 idx = soc_mem_field32_get(unit, VLAN_SUBNETm,
   1432                                           &subnet_entry, TAG_ACTION_PROFILE_PTRf);
   1433                 if (idx >= entry_idxmin[0]) {
   1434                     SOC_IF_ERROR_RETURN(
   1435                         soc_profile_mem_reference(unit, ing_action_profile[unit],
   1436                         idx, 1));
   1437                     SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, ing_action_profile[unit],
   1438                                                     idx - entry_idxmin[0], 1);
   1439                 }
   1440             }
   1441     
   1442             /* Increment the ref count for all Mac-based VLANs & vlan translations */
   1443             if (SOC_MEM_IS_VALID(unit, VLAN_MACm)) {
   1444                 for (i = 0; i < soc_mem_index_count(unit, VLAN_MACm); i++) {
   1445                     SOC_IF_ERROR_RETURN
   1446                         (READ_VLAN_MACm(unit, MEM_BLOCK_ANY, i,
   1447                                         &vlan_mac_entry));
   1448                     if (!soc_mem_field32_get(unit, VLAN_MACm,
   1449                                 &vlan_mac_entry, VALIDf)) {
   1450                         continue;
   1451                     }
   1452                     key_type_value = soc_mem_field32_get(unit, VLAN_MACm,
   1453                             &vlan_mac_entry, KEY_TYPEf);
   1454                     (void) _bcm_esw_vlan_xlate_key_type_get(unit, key_type_value,
   1455                             &key_type);
   1456                     if (VLXLT_HASH_KEY_TYPE_VLAN_MAC == key_type) {
   1457                         idx = soc_mem_field32_get(unit, VLAN_MACm, &vlan_mac_entry,
   1458                                 MAC__TAG_ACTION_PROFILE_PTRf);
   1459                     } else if (VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT == key_type) {
   1460                         idx = soc_mem_field32_get(unit, VLAN_MACm, &vlan_mac_entry,
   1461                                 MAC_PORT__TAG_ACTION_PROFILE_PTRf);
   1462                     } else {
   1463                         continue;
   1464                     }
   1465                     SOC_IF_ERROR_RETURN(
   1466                             soc_profile_mem_reference(unit, ing_action_profile[unit],
   1467                                 idx, 1));
   1468                     SOC_PROFILE_MEM_ENTRIES_PER_SET(unit,
   1469                             ing_action_profile[unit], idx - entry_idxmin[0], 1);
   1470                 }
   1471             }
   1472 
   1473             for (i = 0; i < soc_mem_index_count(unit, ing_mem); i++) {
   1474                 SOC_IF_ERROR_RETURN
   1475                     (soc_mem_read(unit, ing_mem, MEM_BLOCK_ANY, i, xlate_entry));
   1476                 if (!soc_mem_field32_get(unit, ing_mem, xlate_entry, vf)) {
   1477                     continue;
   1478                 }
   1479                 key_type_value = soc_mem_field32_get(unit, ing_mem, xlate_entry,
   1480                                                      KEY_TYPEf);
   1481     
   1482                 /* Here return value is not being checked (that is intentional); in case
   1483                    it returns BCM_E_UNAVAIL, will proceed with else condition below */
   1484                 /* Coverity[unchecked_value] */
   1485                 _bcm_esw_vlan_xlate_key_type_get(unit, key_type_value, &key_type);
   1486                 if (key_type == VLXLT_HASH_KEY_TYPE_VIF ||
   1487                     key_type == VLXLT_HASH_KEY_TYPE_VIF_VLAN ||
   1488                     key_type == VLXLT_HASH_KEY_TYPE_VIF_CVLAN ||
   1489                     key_type == VLXLT_HASH_KEY_TYPE_VIF_OTAG ||
   1490                     key_type == VLXLT_HASH_KEY_TYPE_VIF_ITAG) {
   1491                     idx = soc_mem_field32_get(unit, ing_mem, xlate_entry,
   1492                                               VIF__TAG_ACTION_PROFILE_PTRf);
   1493                 } else {
   1494                     idx = soc_mem_field32_get(unit, ing_mem, xlate_entry,
   1495                                               TAG_ACTION_PROFILE_PTRf);
   1496 #ifdef BCM_TRIDENT3_SUPPORT
   1497                     if (soc_feature(unit, soc_feature_flex_flow)) {
   1498                         soc_mem_t mem_view_id;
   1499                         uint32 data_type;
   1500                         int rv;
   1501 
   1502                         data_type = 0;
   1503                         if (SOC_MEM_FIELD_VALID(unit, ing_mem, DATA_TYPEf)) {
   1504                             data_type = soc_mem_field32_get(unit, ing_mem, 
   1505                                           xlate_entry,DATA_TYPEf);
   1506                         }
   1507                         rv = soc_flow_db_mem_to_view_id_get (unit, ing_mem, 
   1508                                 key_type_value, data_type, 0, NULL, 
   1509                                 (uint32 *)&mem_view_id);
   1510                         if (SOC_SUCCESS(rv)) {
   1511                             idx = 0;
   1512                             if (SOC_MEM_FIELD_VALID(unit, mem_view_id, 
   1513                                                 TAG_ACTION_SETf)) {
   1514                                 idx = soc_mem_field32_get(unit, mem_view_id, 
   1515                                         xlate_entry, TAG_ACTION_SETf);
   1516                             }
   1517                         }
   1518                     }
   1519 #endif
   1520                 }
   1521                 rv = soc_profile_mem_reference(unit, ing_action_profile[unit], 
   1522                                            idx, 1);
   1523                 if (SOC_SUCCESS(rv)) {
   1524                 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, ing_action_profile[unit],
   1525                                                 idx - entry_idxmin[0], 1);
   1526                 } else {
   1527                     /* TAG_ACTION_PROFILE_PTR may not be used for all key types.
   1528                      * In this case, it has default value 0. Ignore it.
   1529                      */
   1530                     if (idx) {
   1531                         return rv;
   1532                     }
   1533                 }
   1534     
   1535     #if defined(BCM_TRIUMPH2_SUPPORT)
   1536                 if (soc_feature(unit, soc_feature_gport_service_counters)) {
   1537                     fs_idx =
   1538                         soc_mem_field32_get(unit, ing_mem, xlate_entry, VINTF_CTR_IDXf);
   1539                     if (SOC_MEM_FIELD_VALID(unit, ing_mem, USE_VINTF_CTR_IDXf)) {
   1540                         if (0 == soc_mem_field32_get(unit, ing_mem,
   1541                                          xlate_entry, USE_VINTF_CTR_IDXf)) {
   1542                             fs_idx = 0;
   1543                         }
   1544                     }
   1545                     if (0 != fs_idx) { /* Recover flex stat counter */
   1546                         sal_memset(&vent, 0, sizeof(vent));
   1547                         /* Construct key-only entry, copy to FS handle */
   1548                         soc_mem_field32_set(unit, ing_mem, &vent, KEY_TYPEf,
   1549                                  soc_mem_field32_get(unit, ing_mem, xlate_entry,
   1550                                                              KEY_TYPEf));
   1551                         soc_mem_field_get(unit, ing_mem, (uint32 *) xlate_entry,
   1552                                           KEYf, (uint32 *) key);
   1553                         soc_mem_field_set(unit, ing_mem, (uint32 *) &vent,
   1554                                           KEYf, (uint32 *) key);
   1555     
   1556                         _BCM_FLEX_STAT_HANDLE_CLEAR(handle);
   1557                         _BCM_FLEX_STAT_HANDLE_COPY(handle, vent);
   1558                         _bcm_esw_flex_stat_ext_reinit_add(unit,
   1559                                       _bcmFlexStatTypeVxlt, fs_idx, handle);
   1560                     }
   1561                 }
   1562     #endif
   1563             }
   1564     
   1565             /* One extra increment to preserve location
   1566              * ING_ACTION_PROFILE_DEFAULT */
   1567             SOC_IF_ERROR_RETURN(
   1568                 soc_profile_mem_reference(unit, ing_action_profile[unit],
   1569                 ing_action_profile_def[unit], 1));
   1570         } else {
   1571             /* Initialize the ING_ACTION_PROFILE_DEFAULT. For untagged and
   1572              * inner-tagged packets, always add an outer tag.
   1573              */
   1574             soc_mem_t port_mem = PORT_TABm;
   1575             sal_memset(ing_profile_entry, 0, ing_ent_sz);
   1576             soc_mem_field32_set(unit, mem[0], ing_profile_entry, UT_OTAG_ACTIONf,
   1577                                 _BCM_TRX_TAG_ACTION_ENCODE(bcmVlanActionAdd));
   1578             if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   1579                 soc_mem_field32_set(unit, mem[0], ing_profile_entry, UT_OPRI_ACTIONf,
   1580                                     _BCM_TRX_PRI_CFI_ACTION_ENCODE(bcmVlanActionAdd));
   1581                 soc_mem_field32_set(unit, mem[0], ing_profile_entry, UT_OCFI_ACTIONf,
   1582                                     _BCM_TRX_PRI_CFI_ACTION_ENCODE(bcmVlanActionAdd));
   1583             }
   1584             soc_mem_field32_set(unit, mem[0], ing_profile_entry, SIT_OTAG_ACTIONf,
   1585                                 _BCM_TRX_TAG_ACTION_ENCODE(bcmVlanActionAdd));
   1586             if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   1587                 soc_mem_field32_set(unit, mem[0], ing_profile_entry, SIT_OPRI_ACTIONf,
   1588                                     _BCM_TRX_PRI_CFI_ACTION_ENCODE(bcmVlanActionAdd));
   1589                 soc_mem_field32_set(unit, mem[0], ing_profile_entry, SIT_OCFI_ACTIONf,
   1590                                     _BCM_TRX_PRI_CFI_ACTION_ENCODE(bcmVlanActionAdd));
   1591             }
   1592             soc_mem_field32_set(unit, mem[0], ing_profile_entry, SIT_PITAG_ACTIONf,
   1593                                 _BCM_TRX_TAG_ACTION_ENCODE(bcmVlanActionNone));
   1594             soc_mem_field32_set(unit, mem[0], ing_profile_entry, SOT_POTAG_ACTIONf,
   1595                                 _BCM_TRX_TAG_ACTION_ENCODE(bcmVlanActionReplace));
   1596             soc_mem_field32_set(unit, mem[0], ing_profile_entry, DT_POTAG_ACTIONf,
   1597                                 _BCM_TRX_TAG_ACTION_ENCODE(bcmVlanActionReplace));
   1598             entries[0] = ing_profile_entry;
   1599             entries[1] = ing_profile_entry;
   1600             SOC_IF_ERROR_RETURN
   1601                 (soc_profile_mem_add(unit, ing_action_profile[unit],
   1602                                      (void *) &entries, 1, &temp_index));
   1603     
   1604             /* Increment the ref count for all ports */
   1605             if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) {
   1606                 port_mem = ING_DEVICE_PORTm;
   1607             }
   1608 
   1609             for (i = 0; i < soc_mem_index_count(unit, port_mem); i++) {
   1610                 if (SOC_PORT_VALID(unit, i)) {
   1611                 SOC_IF_ERROR_RETURN(
   1612                     soc_profile_mem_reference(unit, ing_action_profile[unit],
   1613                     ing_action_profile_def[unit], 1));
   1614             }
   1615             }
   1616     
   1617             /* Increment the ref count for all Protocol-based VLANs */
   1618             for (i = 0; i < soc_mem_index_count(unit, VLAN_PROTOCOL_DATAm);
   1619                  i++) {
   1620 #if 0
   1621                 vlan_protocol_data_entry_t vp_ent;
   1622                 sal_memset(&vp_ent, 0, sizeof(vp_ent));
   1623                 if (ing_action_profile_def[unit] != 0) {
   1624                     soc_mem_field32_set(unit, VLAN_PROTOCOL_DATAm, &vp_ent,
   1625                                         TAG_ACTION_PROFILE_PTRf,
   1626                                         ing_action_profile_def[unit]);
   1627                     SOC_IF_ERROR_RETURN(
   1628                         soc_mem_write(unit, VLAN_PROTOCOL_DATAm, SOC_BLOCK_ALL,
   1629                                       i, &vp_ent));
   1630                 }
   1631 #endif
   1632                 SOC_IF_ERROR_RETURN(
   1633                     soc_profile_mem_reference(unit, ing_action_profile[unit],
   1634                     ing_action_profile_def[unit], 1));
   1635             }
   1636         }
   1637     }
   1638 
   1639     /* Initialize the EGR_VLAN_TAG_ACTION_PROFILE table */
   1640     if (egr_action_profile[unit] == NULL) {
   1641         egr_action_profile[unit] = sal_alloc(sizeof(soc_profile_mem_t),
   1642                                              "Egr Action Profile Mem");
   1643         if (egr_action_profile[unit] == NULL) {
   1644             return BCM_E_MEMORY;
   1645         }
   1646         soc_profile_mem_t_init(egr_action_profile[unit]);
   1647     }
   1648 
   1649     /* Create profile table cache (or re-init if it already exists) */
   1650     mem[0] = EGR_VLAN_TAG_ACTION_PROFILEm;
   1651     entry_words[0] = sizeof(egr_vlan_tag_action_profile_entry_t) / sizeof(uint32);
   1652     entry_idxmin[0] = soc_mem_index_min(unit, mem[0]);
   1653     entry_idxmax[0] = soc_mem_index_max(unit, mem[0]);
   1654 
   1655     mem[1] = EGR_VLAN_TAG_ACTION_PROFILE_2m;
   1656     if (soc_mem_is_valid(unit, mem[1])) {
   1657         entry_words[1] = sizeof(egr_vlan_tag_action_profile_entry_t) / sizeof(uint32);
   1658         entry_idxmin[1] = soc_mem_index_min(unit, mem[1]);
   1659         entry_idxmax[1] = soc_mem_index_max(unit, mem[1]) - 1;
   1660         /* For EGR_VLAN_TAG_ACTION_PROFILE_2m device,
   1661          * last entry (index 63) is reserved for VT_MISS_UNTAG */
   1662         entry_idxmax[0] --;
   1663         mem_cnt = 2;
   1664     }
   1665 
   1666     SOC_IF_ERROR_RETURN(
   1667         soc_profile_mem_index_create(unit, mem, entry_words,
   1668                                      entry_idxmin, entry_idxmax, NULL,
   1669                                      mem_cnt, egr_action_profile[unit]));
   1670 
   1671     SOC_PBMP_COUNT(PBMP_ALL(unit), num_ports);
   1672     if (SOC_WARM_BOOT(unit)) {
   1673         /* Increment the ref count for all ports */
   1674         PBMP_ALL_ITER(unit, i) {
   1675 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   1676             if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
   1677                 if (soc_feature(unit, soc_feature_egr_all_profile)) {
   1678                     soc_field_t fld = TAG_ACTION_PROFILE_PTRf;
   1679                     BCM_IF_ERROR_RETURN(
   1680                         bcm_esw_port_egr_lport_fields_get(unit, i,
   1681                         EGR_VLAN_CONTROL_3m, 1, &fld, (uint32 *)&idx));
   1682                 } else {
   1683                 egr_vlan_control_3_entry_t entry;
   1684                 SOC_IF_ERROR_RETURN(
   1685                             READ_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY,
   1686                             i, &entry));
   1687                 idx = soc_EGR_VLAN_CONTROL_3m_field32_get(unit, &entry,
   1688                         TAG_ACTION_PROFILE_PTRf);
   1689                 }
   1690             } else
   1691 #endif
   1692             {
   1693                 SOC_IF_ERROR_RETURN
   1694                     (READ_EGR_VLAN_CONTROL_3r(unit, i, &rval));
   1695                 idx = soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r,
   1696                         rval, TAG_ACTION_PROFILE_PTRf);
   1697             }
   1698             soc_profile_mem_reference(unit, egr_action_profile[unit], idx, 1);
   1699         }
   1700 
   1701         if (SOC_MEM_IS_VALID(unit, egr_mem)) {
   1702            /* Increment the ref count for all egress vlan translations */
   1703             for (i = 0; i < soc_mem_index_count(unit, egr_mem); i++) {
   1704                SOC_IF_ERROR_RETURN
   1705                     (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, i, egr_xlate_entry));
   1706                 if (!soc_mem_field32_get(unit, egr_mem, egr_xlate_entry, vf)) {
   1707                    continue;
   1708                }
   1709 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   1710                 type = soc_mem_field32_get(unit, egr_mem, egr_xlate_entry,
   1711                                            type_fld);
   1712                 if (type == TD2PLUS_EVLXLT_HASH_KEY_TYPE_VFI_DVP_GROUP) {
   1713                     field_info = soc_mem_fieldinfo_get(
   1714                                      unit, egr_mem,
   1715                                      VFI_DVP_GROUP__XLATE_DATAf);
   1716                 } else if (type ==
   1717                            TD2PLUS_EVLXLT_HASH_KEY_TYPE_VLAN_XLATE_VFI) {
   1718                     field_info = soc_mem_fieldinfo_get(
   1719                                      unit, egr_mem,
   1720                                      VLAN_XLATE_VFI__XLATE_DATAf);
   1721                 }
   1722                 if (field_info) {
   1723                     sal_memset(entry, 0, SOC_MAX_MEM_WORDS * sizeof(uint32));
   1724                     SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_GET(
   1725                         unit, egr_mem, egr_xlate_entry, field_info, entry);
   1726                     field_info_1 = soc_mem_fieldinfo_get(unit, egr_mem,
   1727                                                          XLATE_DATAf);
   1728                     if (!field_info_1) {
   1729                         return BCM_E_UNAVAIL;
   1730                     }
   1731                     SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_SET(
   1732                         unit, egr_mem, egr_xlate_entry, field_info_1, entry);
   1733                 }
   1734 #endif
   1735                 idx = soc_mem_field32_get(unit, egr_mem,
   1736                                           egr_xlate_entry, TAG_ACTION_PROFILE_PTRf);
   1737                 soc_profile_mem_reference(unit, egr_action_profile[unit],
   1738                                           idx, 1);
   1739    #if defined(BCM_TRIUMPH2_SUPPORT)
   1740                if (soc_feature(unit, soc_feature_gport_service_counters)) {
   1741                    fs_idx =
   1742                         soc_mem_field32_get(unit, egr_mem, egr_xlate_entry,
   1743                                                    VINTF_CTR_IDXf);
   1744                     if (SOC_MEM_FIELD_VALID(unit, egr_mem,
   1745                                            USE_VINTF_CTR_IDXf)) {
   1746                         if (0 == soc_mem_field32_get(unit, egr_mem,
   1747                                          egr_xlate_entry, USE_VINTF_CTR_IDXf)) {
   1748                            fs_idx = 0;
   1749                        }
   1750                    }
   1751                    if (0 != fs_idx) { /* Recover flex stat counter */
   1752                        sal_memset(&event, 0, sizeof(event));
   1753                        /* Construct key-only entry, copy to FS handle */
   1754                         soc_mem_field32_set(unit, egr_mem, &event, ENTRY_TYPEf,
   1755                                  soc_mem_field32_get(unit, egr_mem,
   1756                                                      egr_xlate_entry, ENTRY_TYPEf));
   1757                         soc_mem_field_get(unit, egr_mem,
   1758                                           (uint32 *) egr_xlate_entry,
   1759                                          KEYf, (uint32 *) key);
   1760                         soc_mem_field_set(unit, egr_mem,
   1761                                          (uint32 *) &event,
   1762                                          KEYf, (uint32 *) key);
   1763    
   1764                        _BCM_FLEX_STAT_HANDLE_CLEAR(handle);
   1765                        _BCM_FLEX_STAT_HANDLE_COPY(handle, event);
   1766                        _bcm_esw_flex_stat_ext_reinit_add(unit,
   1767                                      _bcmFlexStatTypeVxlt, fs_idx, handle);
   1768                    }
   1769                }
   1770    #endif
   1771            }
   1772         }
   1773 #if defined(BCM_TRIDENT3_SUPPORT)
   1774         if (soc_feature(unit, soc_feature_vxlan_decoupled_mode)) {
   1775             uint32 entry_type;
   1776             egr_l3_next_hop_entry_t egr_nh;
   1777             egr_vlan_xlate_1_single_entry_t egr_single_entry;
   1778             egr_mem = EGR_VLAN_XLATE_1_SINGLEm;
   1779             for (i = 0; i < soc_mem_index_count(unit, egr_mem); i++) {
   1780                 SOC_IF_ERROR_RETURN
   1781                     (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, i, &egr_single_entry));
   1782                     if (soc_mem_field32_get(unit, egr_mem, &egr_single_entry, BASE_VALIDf)) {
   1783                         idx = soc_mem_field32_get(unit, egr_mem,
   1784                                           &egr_single_entry, TAG_ACTION_PROFILE_PTRf);
   1785                         soc_profile_mem_reference(unit, egr_action_profile[unit], idx, 1);
   1786                     }
   1787             }
   1788 
   1789             egr_mem = EGR_L3_NEXT_HOPm;
   1790             for (i = 0; i < soc_mem_index_count(unit, egr_mem); i++) {
   1791                 SOC_IF_ERROR_RETURN
   1792                     (soc_mem_read(unit, egr_mem, MEM_BLOCK_ANY, i, &egr_nh));
   1793                 entry_type = soc_mem_field32_get(unit, egr_mem, &egr_nh, DATA_TYPEf);
   1794                 if (entry_type == _BCM_VXLAN_EGR_NEXT_HOP_L2OTAG_VIEW) {
   1795                     idx = soc_mem_field32_get(unit, egr_mem, &egr_nh,
   1796                         L2_OTAG__TAG_ACTION_PROFILE_PTRf);
   1797                     soc_profile_mem_reference(unit, egr_action_profile[unit], idx, 1);
   1798                 }
   1799             }
   1800         }
   1801 #endif
   1802         /* One extra increment to preserve location EGR_ACTION_PROFILE_DEFAULT */
   1803         soc_profile_mem_reference(unit, egr_action_profile[unit],
   1804                               EGR_ACTION_PROFILE_DEFAULT, 1);
   1805     } else {
   1806         /* Initialize the EGR_ACTION_PROFILE_DEFAULT to have all
   1807          * actions as NOP (0).
   1808          */
   1809         sal_memset(&egr_profile_entry, 0, sizeof(egr_vlan_tag_action_profile_entry_t));
   1810         entries[0] = &egr_profile_entry;
   1811         entries[1] = &egr_profile_entry;
   1812         SOC_IF_ERROR_RETURN
   1813             (soc_profile_mem_add(unit, egr_action_profile[unit],
   1814                                  (void *) &entries, 1, &temp_index));
   1815 
   1816         /* Increment the ref count for all ports */
   1817         for (i = 0; i < num_ports; i++) {
   1818             soc_profile_mem_reference(unit, egr_action_profile[unit],
   1819                                       EGR_ACTION_PROFILE_DEFAULT, 1);
   1820         }
   1821     }
   1822 
   1823     /* Initialize the VLAN range profile table */
   1824     _bcm_trx_vlan_range_profile_init(unit);
   1825 
   1826 #ifdef BCM_WARM_BOOT_SUPPORT
   1827     /* Reload VLAN protocol action data */
   1828     if (SOC_WARM_BOOT(unit)) {
   1829         BCM_IF_ERROR_RETURN(_bcm_trx_vlan_port_protocol_action_reinit(unit));
   1830     }
   1831 #endif /* BCM_WARM_BOOT_SUPPORT */
   1832 
   1833     return BCM_E_NONE;
   1834 }
   1835 
   1836 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) || \
   1837     defined(BCM_KATANA2_SUPPORT)
   1838 /*
   1839  * Function : _bcm_th_port_vlan_action_profile_reinit
   1840  *
   1841  * Purpose  :
   1842  *      Recover 'vlan_prot_ptr' in port_info structure.
   1843  *      Recover reference count of ING_VLAN_TAG_ACTION_PROFILE
   1844  *      for all Protocol-based VLANs.
   1845  *
   1846  * Note:
   1847  *      'vlan_prot_ptr' in port_info structure was recovered
   1848  *      from scache for TH2.
   1849  */
   1850 int
   1851 _bcm_th_port_vlan_action_profile_reinit(int unit)
   1852 {
   1853     int rv = BCM_E_NONE;
   1854     int i, idx;
   1855     int vlan_prot_entries;
   1856     bcm_port_t port;
   1857     uint32 vlan_protocol_data_index = 0;
   1858     _bcm_port_info_t *pinfo;
   1859     bcm_pbmp_t all_pbmp;
   1860     uint32 action_profile_idx;
   1861     vlan_protocol_data_entry_t vde;
   1862 
   1863     BCM_PBMP_CLEAR(all_pbmp);
   1864     BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
   1865 
   1866     vlan_prot_entries = soc_mem_index_count(unit, VLAN_PROTOCOLm);
   1867     PBMP_ITER(all_pbmp, port) {
   1868         if (!IS_LB_PORT(unit, port)) {
   1869             /* update vlan port protocol data memory */
   1870             BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
   1871 
   1872             /* TH2/TD3X/KT2 have already recovered it from scache */
   1873             if (!SOC_IS_TOMAHAWK2(unit) && !SOC_IS_TRIDENT3X(unit) &&
   1874                 !SOC_IS_KATANA2(unit)) {
   1875                 /* Get VLAN_PROTOCOL_DATA_INDEXf  in PORT_TAB. */
   1876                 SOC_IF_ERROR_RETURN(_bcm_esw_port_tab_get(unit, port,
   1877                                     VLAN_PROTOCOL_DATA_INDEXf, &idx));
   1878                 vlan_protocol_data_index = idx * vlan_prot_entries;
   1879                 pinfo->vlan_prot_ptr = vlan_protocol_data_index;
   1880 
   1881                 BCM_IF_ERROR_RETURN(
   1882                         _bcm_port_vlan_protocol_data_entry_reference (unit,
   1883                             vlan_protocol_data_index, 16));
   1884             }
   1885 
   1886             for (i = 0; i < vlan_prot_entries; i++) {
   1887                 rv = READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY,
   1888                                               pinfo->vlan_prot_ptr + i, &vde);
   1889                 if (BCM_FAILURE(rv)) {
   1890                     return (rv);
   1891                 }
   1892                 action_profile_idx = soc_VLAN_PROTOCOL_DATAm_field32_get(unit,
   1893                                      &vde, TAG_ACTION_PROFILE_PTRf);
   1894                 if (SOC_IS_TRIDENT3X(unit)) {
   1895                     if (action_profile_idx >= ing_action_profile_def[unit]) {
   1896                         SOC_IF_ERROR_RETURN(
   1897                             soc_profile_mem_reference(unit, ing_action_profile[unit],
   1898                             action_profile_idx, 1));
   1899                         SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, ing_action_profile[unit],
   1900                             action_profile_idx - ing_action_profile_def[unit], 1);
   1901                     }
   1902                 } else {
   1903                     SOC_IF_ERROR_RETURN(
   1904                         soc_profile_mem_reference(unit, ing_action_profile[unit],
   1905                         action_profile_idx, 1));
   1906                     SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, ing_action_profile[unit],
   1907                         action_profile_idx, 1);
   1908                 }
   1909             }
   1910         }
   1911     }
   1912 
   1913     return (rv);
   1914 }
   1915 #endif
   1916 
   1917 /*
   1918  * Function : _bcm_trx_vlan_action_profile_entry_add
   1919  *
   1920  * Purpose  : add a new entry to vlan action profile table
   1921  */
   1922 int
   1923 _bcm_trx_vlan_action_profile_entry_add(int unit,
   1924                                       bcm_vlan_action_set_t *action,
   1925                                       uint32 *index)
   1926 {
   1927     int rv = BCM_E_NONE;
   1928     ing_vlan_tag_action_profile_entry_t entry1;
   1929     ing_vlan_tag_action_profile_2_entry_t entry2;
   1930     void *entries[2];
   1931     void *entry;
   1932     soc_mem_t vtap_mem = ING_VLAN_TAG_ACTION_PROFILEm;
   1933 
   1934     if (SOC_MEM_IS_VALID(unit, ING_VLAN_TAG_ACTION_PROFILE_2m)) {
   1935         vtap_mem = ING_VLAN_TAG_ACTION_PROFILE_2m;
   1936         sal_memset(&entry2, 0, sizeof(ing_vlan_tag_action_profile_2_entry_t));
   1937         entry = &entry2;
   1938     } else {
   1939         sal_memset(&entry1, 0, sizeof(ing_vlan_tag_action_profile_entry_t));
   1940         entry = &entry1;
   1941     }
   1942 
   1943     BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action));
   1944 
   1945     soc_mem_field32_set(unit, vtap_mem, entry, DT_OTAG_ACTIONf,
   1946                         _BCM_TRX_TAG_ACTION_ENCODE(action->dt_outer));
   1947     soc_mem_field32_set(unit, vtap_mem, entry, DT_POTAG_ACTIONf,
   1948                         _BCM_TRX_TAG_ACTION_ENCODE(action->dt_outer_prio));
   1949     soc_mem_field32_set(unit, vtap_mem, entry, DT_ITAG_ACTIONf,
   1950                         _BCM_TRX_TAG_ACTION_ENCODE(action->dt_inner));
   1951     soc_mem_field32_set(unit, vtap_mem, entry, DT_PITAG_ACTIONf,
   1952                         _BCM_TRX_TAG_ACTION_ENCODE(action->dt_inner_prio));
   1953     soc_mem_field32_set(unit, vtap_mem, entry, SOT_OTAG_ACTIONf,
   1954                         _BCM_TRX_TAG_ACTION_ENCODE(action->ot_outer));
   1955     soc_mem_field32_set(unit, vtap_mem, entry, SOT_POTAG_ACTIONf,
   1956                         _BCM_TRX_TAG_ACTION_ENCODE(action->ot_outer_prio));
   1957     soc_mem_field32_set(unit, vtap_mem, entry, SOT_ITAG_ACTIONf,
   1958                         _BCM_TRX_TAG_ACTION_ENCODE(action->ot_inner));
   1959     soc_mem_field32_set(unit, vtap_mem, entry, SIT_OTAG_ACTIONf,
   1960                         _BCM_TRX_TAG_ACTION_ENCODE(action->it_outer));
   1961     soc_mem_field32_set(unit, vtap_mem, entry, SIT_ITAG_ACTIONf,
   1962                         _BCM_TRX_TAG_ACTION_ENCODE(action->it_inner));
   1963     soc_mem_field32_set(unit, vtap_mem, entry, SIT_PITAG_ACTIONf,
   1964                         _BCM_TRX_TAG_ACTION_ENCODE(action->it_inner_prio));
   1965     soc_mem_field32_set(unit, vtap_mem, entry, UT_OTAG_ACTIONf,
   1966                         _BCM_TRX_TAG_ACTION_ENCODE(action->ut_outer));
   1967     soc_mem_field32_set(unit, vtap_mem, entry, UT_ITAG_ACTIONf,
   1968                         _BCM_TRX_TAG_ACTION_ENCODE(action->ut_inner));
   1969 
   1970     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   1971         soc_mem_field32_set
   1972             (unit, vtap_mem, entry, DT_OPRI_ACTIONf,
   1973              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->dt_outer_pkt_prio));
   1974         soc_mem_field32_set
   1975             (unit, vtap_mem, entry, DT_OCFI_ACTIONf,
   1976              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->dt_outer_cfi));
   1977         soc_mem_field32_set
   1978             (unit, vtap_mem, entry, DT_IPRI_ACTIONf,
   1979              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->dt_inner_pkt_prio));
   1980         soc_mem_field32_set
   1981             (unit, vtap_mem, entry, DT_ICFI_ACTIONf,
   1982              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->dt_inner_cfi));
   1983         soc_mem_field32_set
   1984             (unit, vtap_mem, entry, SOT_OPRI_ACTIONf,
   1985              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_outer_pkt_prio));
   1986         soc_mem_field32_set
   1987             (unit, vtap_mem, entry, SOT_OCFI_ACTIONf,
   1988              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_outer_cfi));
   1989         soc_mem_field32_set
   1990             (unit, vtap_mem, entry, SOT_IPRI_ACTIONf,
   1991              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_inner_pkt_prio));
   1992         soc_mem_field32_set
   1993             (unit, vtap_mem, entry, SOT_ICFI_ACTIONf,
   1994              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_inner_cfi));
   1995         soc_mem_field32_set
   1996             (unit, vtap_mem, entry, SIT_OPRI_ACTIONf,
   1997              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->it_outer_pkt_prio));
   1998         soc_mem_field32_set
   1999             (unit, vtap_mem, entry, SIT_OCFI_ACTIONf,
   2000              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->it_outer_cfi));
   2001         soc_mem_field32_set
   2002             (unit, vtap_mem, entry, SIT_IPRI_ACTIONf,
   2003              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->it_inner_pkt_prio));
   2004         soc_mem_field32_set
   2005             (unit, vtap_mem, entry, SIT_ICFI_ACTIONf,
   2006              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->it_inner_cfi));
   2007         soc_mem_field32_set
   2008             (unit, vtap_mem, entry, UT_OPRI_ACTIONf,
   2009              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ut_outer_pkt_prio));
   2010         soc_mem_field32_set
   2011             (unit, vtap_mem, entry, UT_OCFI_ACTIONf,
   2012              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ut_outer_cfi));
   2013         soc_mem_field32_set
   2014             (unit, vtap_mem, entry, UT_IPRI_ACTIONf,
   2015              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ut_inner_pkt_prio));
   2016         soc_mem_field32_set
   2017             (unit, vtap_mem, entry, UT_ICFI_ACTIONf,
   2018              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ut_inner_cfi));
   2019 
   2020 #if defined(BCM_TRIDENT2_SUPPORT)
   2021         if (soc_feature(unit, soc_feature_fcoe)) {
   2022 
   2023             /* overwrite just fcoe related fields (pri)*/
   2024             soc_mem_field32_set
   2025                 (unit, vtap_mem, entry, DT_OPRI_ACTIONf,
   2026                  _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT(
   2027                                                    action->dt_outer_pkt_prio));
   2028             soc_mem_field32_set
   2029                 (unit, vtap_mem, entry, DT_IPRI_ACTIONf,
   2030                  _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT(
   2031                                                    action->dt_inner_pkt_prio));
   2032             soc_mem_field32_set
   2033                 (unit, vtap_mem, entry, SOT_OPRI_ACTIONf,
   2034                  _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT(
   2035                                                    action->ot_outer_pkt_prio));
   2036             soc_mem_field32_set
   2037                 (unit, vtap_mem, entry, SOT_IPRI_ACTIONf,
   2038                  _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT(
   2039                                                    action->ot_inner_pkt_prio));
   2040             soc_mem_field32_set
   2041                 (unit, vtap_mem, entry, SIT_OPRI_ACTIONf,
   2042                  _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT(
   2043                                                    action->it_outer_pkt_prio));
   2044             soc_mem_field32_set
   2045                 (unit, vtap_mem, entry, SIT_IPRI_ACTIONf,
   2046                  _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT(
   2047                                                    action->it_inner_pkt_prio));
   2048             soc_mem_field32_set
   2049                 (unit, vtap_mem, entry, UT_OPRI_ACTIONf,
   2050                  _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT(
   2051                                                    action->ut_outer_pkt_prio));
   2052             soc_mem_field32_set
   2053                 (unit, vtap_mem, entry, UT_IPRI_ACTIONf,
   2054                  _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT(
   2055                                                    action->ut_inner_pkt_prio));
   2056         }
   2057 #endif  /* BCM_TRIDENT2_SUPPORT */
   2058     }
   2059 
   2060     entries[0] = entry;
   2061     entries[1] = entry;
   2062     ING_VLAN_TAG_ACTION_LOCK(unit);
   2063     rv = soc_profile_mem_add(unit, ing_action_profile[unit],
   2064                              (void *) &entries, 1, index);
   2065     ING_VLAN_TAG_ACTION_UNLOCK(unit);
   2066     return rv;
   2067 }
   2068 
   2069 #if defined(BCM_TRIDENT2_SUPPORT)
   2070 
   2071 /*
   2072  * add a new entry to ingress vlan action profile table(without modification)
   2073  */
   2074 int
   2075 _bcm_trx_ing_vlan_action_profile_entry_no_mod_add(
   2076                                int                                 unit, 
   2077                                ing_vlan_tag_action_profile_entry_t *entry, 
   2078                                uint32                              *index)
   2079 {
   2080     int rv = BCM_E_NONE;
   2081     void *entries[2];
   2082 
   2083     entries[0] = entry;
   2084     entries[1] = entry;
   2085     ING_VLAN_TAG_ACTION_LOCK(unit);
   2086     rv = soc_profile_mem_add(unit, ing_action_profile[unit],
   2087                              (void *) &entries, 1, index);
   2088     ING_VLAN_TAG_ACTION_UNLOCK(unit);
   2089     return rv;
   2090 }
   2091 
   2092 /*
   2093  * add a new entry to egress vlan action profile table(without modification)
   2094  */
   2095 int
   2096 _bcm_trx_egr_vlan_action_profile_entry_no_mod_add(
   2097                                int                                 unit, 
   2098                                egr_vlan_tag_action_profile_entry_t *entry, 
   2099                                uint32                              *index)
   2100 {
   2101     int rv = BCM_E_NONE;
   2102     void *entries[2];
   2103 
   2104     entries[0] = entry;
   2105     entries[1] = entry;
   2106     EGR_VLAN_TAG_ACTION_LOCK(unit);
   2107     rv = soc_profile_mem_add(unit, egr_action_profile[unit],
   2108                                (void *) &entries, 1, index);
   2109     EGR_VLAN_TAG_ACTION_UNLOCK(unit);
   2110     return rv;
   2111 }
   2112 
   2113 #endif
   2114 
   2115 
   2116 /*
   2117  * Function : _bcm_trx_vlan_action_profile_entry_increment
   2118  *
   2119  * Purpose  : increment the refcount for a vlan action profile table entry
   2120  */
   2121 void
   2122 _bcm_trx_vlan_action_profile_entry_increment(int unit, uint32 index)
   2123 {   
   2124     /* In case other module try to increase default index */
   2125     if (index == 0) {
   2126         index = ing_action_profile_def[unit];
   2127     }
   2128     ING_VLAN_TAG_ACTION_LOCK(unit);
   2129     (void)soc_profile_mem_reference(unit, ing_action_profile[unit], index, 1);
   2130     ING_VLAN_TAG_ACTION_UNLOCK(unit);
   2131 }
   2132 
   2133 /*
   2134  * Function : _bcm_trx_vlan_action_profile_entry_get
   2135  *
   2136  * Purpose  : get a copy of cached vlan action profile table
   2137  */
   2138 void
   2139 _bcm_trx_vlan_action_profile_entry_get(int unit,
   2140                                       bcm_vlan_action_set_t *action, 
   2141                                       uint32 index)
   2142 {
   2143     ing_vlan_tag_action_profile_entry_t p1;
   2144     ing_vlan_tag_action_profile_2_entry_t p2;
   2145     void *entries[2];
   2146     uint32 *entry;
   2147     uint32 val;
   2148     soc_mem_t mem = ING_VLAN_TAG_ACTION_PROFILEm;
   2149 
   2150     if (SOC_MEM_IS_VALID(unit, ING_VLAN_TAG_ACTION_PROFILE_2m)) {
   2151         mem = ING_VLAN_TAG_ACTION_PROFILE_2m;
   2152         entries[0] = &p2;
   2153         entries[1] = &p2;
   2154     } else {
   2155         entries[0] = &p1;
   2156     }
   2157 
   2158     ING_VLAN_TAG_ACTION_LOCK(unit);
   2159     (void) soc_profile_mem_get(unit, ing_action_profile[unit],
   2160                                index, 1, entries);
   2161     entry = entries[0];
   2162 
   2163     val = soc_mem_field32_get(unit, mem, entry, DT_OTAG_ACTIONf);
   2164     action->dt_outer = _BCM_TRX_TAG_ACTION_DECODE(val);
   2165 
   2166     val = soc_mem_field32_get(unit, mem, entry, DT_POTAG_ACTIONf);
   2167     action->dt_outer_prio = _BCM_TRX_TAG_ACTION_DECODE(val);
   2168 
   2169     val = soc_mem_field32_get(unit, mem, entry, DT_ITAG_ACTIONf);
   2170     action->dt_inner = _BCM_TRX_TAG_ACTION_DECODE(val);
   2171 
   2172     val = soc_mem_field32_get(unit, mem, entry, DT_PITAG_ACTIONf);
   2173     action->dt_inner_prio = _BCM_TRX_TAG_ACTION_DECODE(val);
   2174 
   2175     val = soc_mem_field32_get(unit, mem, entry, SOT_OTAG_ACTIONf);
   2176     action->ot_outer = _BCM_TRX_TAG_ACTION_DECODE(val);
   2177 
   2178     val = soc_mem_field32_get(unit, mem, entry, SOT_POTAG_ACTIONf);
   2179     action->ot_outer_prio = _BCM_TRX_TAG_ACTION_DECODE(val);
   2180 
   2181     val = soc_mem_field32_get(unit, mem, entry, SOT_ITAG_ACTIONf);
   2182     action->ot_inner = _BCM_TRX_TAG_ACTION_DECODE(val);
   2183 
   2184     val = soc_mem_field32_get(unit, mem, entry, SIT_OTAG_ACTIONf);
   2185     action->it_outer = _BCM_TRX_TAG_ACTION_DECODE(val);
   2186 
   2187     val = soc_mem_field32_get(unit, mem, entry, SIT_ITAG_ACTIONf);
   2188     action->it_inner = _BCM_TRX_TAG_ACTION_DECODE(val);
   2189 
   2190     val = soc_mem_field32_get(unit, mem, entry, SIT_PITAG_ACTIONf);
   2191     action->it_inner_prio = _BCM_TRX_TAG_ACTION_DECODE(val);
   2192 
   2193     val = soc_mem_field32_get(unit, mem, entry, UT_OTAG_ACTIONf);
   2194     action->ut_outer = _BCM_TRX_TAG_ACTION_DECODE(val);
   2195 
   2196     val = soc_mem_field32_get(unit, mem, entry, UT_ITAG_ACTIONf);
   2197     action->ut_inner = _BCM_TRX_TAG_ACTION_DECODE(val);
   2198 
   2199     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   2200         val = soc_mem_field32_get(unit, mem, entry, DT_OPRI_ACTIONf);
   2201         action->dt_outer_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2202 
   2203         val = soc_mem_field32_get(unit, mem, entry, DT_OCFI_ACTIONf);
   2204         action->dt_outer_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2205 
   2206         val = soc_mem_field32_get(unit, mem, entry, DT_IPRI_ACTIONf);
   2207         action->dt_inner_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2208 
   2209         val = soc_mem_field32_get(unit, mem, entry, DT_ICFI_ACTIONf);
   2210         action->dt_inner_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2211 
   2212         val = soc_mem_field32_get(unit, mem, entry, SOT_OPRI_ACTIONf);
   2213         action->ot_outer_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2214 
   2215         val = soc_mem_field32_get(unit, mem, entry, SOT_OCFI_ACTIONf);
   2216         action->ot_outer_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2217 
   2218         val = soc_mem_field32_get(unit, mem, entry, SOT_IPRI_ACTIONf);
   2219         action->ot_inner_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2220 
   2221         val = soc_mem_field32_get(unit, mem, entry, SOT_ICFI_ACTIONf);
   2222         action->ot_inner_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2223 
   2224         val = soc_mem_field32_get(unit, mem, entry, SIT_OPRI_ACTIONf);
   2225         action->it_outer_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2226 
   2227         val = soc_mem_field32_get(unit, mem, entry, SIT_OCFI_ACTIONf);
   2228         action->it_outer_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2229 
   2230         val = soc_mem_field32_get(unit, mem, entry, SIT_IPRI_ACTIONf);
   2231         action->it_inner_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2232 
   2233         val = soc_mem_field32_get(unit, mem, entry, SIT_ICFI_ACTIONf);
   2234         action->it_inner_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2235 
   2236         val = soc_mem_field32_get(unit, mem, entry, UT_OPRI_ACTIONf);
   2237         action->ut_outer_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2238 
   2239         val = soc_mem_field32_get(unit, mem, entry, UT_OCFI_ACTIONf);
   2240         action->ut_outer_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2241 
   2242         val = soc_mem_field32_get(unit, mem, entry, UT_IPRI_ACTIONf);
   2243         action->ut_inner_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2244 
   2245         val = soc_mem_field32_get(unit, mem, entry, UT_ICFI_ACTIONf);
   2246         action->ut_inner_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2247 
   2248 #if defined(BCM_TRIDENT2_SUPPORT)
   2249 
   2250         if (soc_feature(unit, soc_feature_fcoe)) {
   2251 
   2252             /* overwrite only fcoe related values (pri) */
   2253 
   2254             val = soc_mem_field32_get(unit, mem, entry, DT_OPRI_ACTIONf);
   2255             action->dt_outer_pkt_prio = 
   2256                 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val);
   2257 
   2258             val = soc_mem_field32_get(unit, mem, entry, DT_IPRI_ACTIONf);
   2259             action->dt_inner_pkt_prio = 
   2260                 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val);
   2261 
   2262             val = soc_mem_field32_get(unit, mem, entry, SOT_OPRI_ACTIONf);
   2263             action->ot_outer_pkt_prio = 
   2264                 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val);
   2265 
   2266             val = soc_mem_field32_get(unit, mem, entry, SOT_IPRI_ACTIONf);
   2267             action->ot_inner_pkt_prio = 
   2268                 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val);
   2269 
   2270             val = soc_mem_field32_get(unit, mem, entry, SIT_OPRI_ACTIONf);
   2271             action->it_outer_pkt_prio = 
   2272                 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val);
   2273 
   2274             val = soc_mem_field32_get(unit, mem, entry, SIT_IPRI_ACTIONf);
   2275             action->it_inner_pkt_prio = 
   2276                 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val);
   2277 
   2278             val = soc_mem_field32_get(unit, mem, entry, UT_OPRI_ACTIONf);
   2279             action->ut_outer_pkt_prio = 
   2280                 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val);
   2281 
   2282             val = soc_mem_field32_get(unit, mem, entry, UT_IPRI_ACTIONf);
   2283             action->ut_inner_pkt_prio = 
   2284                 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val);
   2285                 
   2286         }
   2287 #endif /* BCM_TRIDENT2_SUPPORT */
   2288 
   2289     } else {
   2290         action->dt_outer_pkt_prio = bcmVlanActionNone;
   2291         action->dt_outer_cfi = bcmVlanActionNone;
   2292         action->dt_inner_pkt_prio = bcmVlanActionNone;
   2293         action->dt_inner_cfi = bcmVlanActionNone;
   2294         action->ot_outer_pkt_prio = bcmVlanActionNone;
   2295         action->ot_outer_cfi = bcmVlanActionNone;
   2296         action->ot_inner_pkt_prio = bcmVlanActionNone;
   2297         action->ot_inner_cfi = bcmVlanActionNone;
   2298         action->it_outer_pkt_prio = bcmVlanActionNone;
   2299         action->it_outer_cfi = bcmVlanActionNone;
   2300         action->it_inner_pkt_prio = bcmVlanActionNone;
   2301         action->it_inner_cfi = bcmVlanActionNone;
   2302         action->ut_outer_pkt_prio = bcmVlanActionNone;
   2303         action->ut_outer_cfi = bcmVlanActionNone;
   2304         action->ut_inner_pkt_prio = bcmVlanActionNone;
   2305         action->ut_inner_cfi = bcmVlanActionNone;
   2306     }
   2307     ING_VLAN_TAG_ACTION_UNLOCK(unit);
   2308 
   2309 }
   2310 
   2311 /*
   2312  * Function : _bcm_trx_vlan_action_profile_entry_delete
   2313  *
   2314  * Purpose  : remove an entry from vlan action profile table
   2315  */
   2316 int
   2317 _bcm_trx_vlan_action_profile_entry_delete(int unit, uint32 index)
   2318 {
   2319     int rv = BCM_E_NONE;
   2320 
   2321     if (index >= ing_action_profile_def[unit]) {
   2322         ING_VLAN_TAG_ACTION_LOCK(unit);
   2323         rv = soc_profile_mem_delete(unit, ing_action_profile[unit], index);
   2324         ING_VLAN_TAG_ACTION_UNLOCK(unit);
   2325     }
   2326     return rv;
   2327 }
   2328 
   2329 /*
   2330  * Function : _bcm_trx_egr_vlan_action_profile_entry_add
   2331  *
   2332  * Purpose  : add a new entry to egress vlan action profile table
   2333  */
   2334 int
   2335 _bcm_trx_egr_vlan_action_profile_entry_add(int unit,
   2336                                           bcm_vlan_action_set_t *action,
   2337                                           uint32 *index)
   2338 {
   2339     int rv = BCM_E_NONE;
   2340     egr_vlan_tag_action_profile_entry_t entry1;
   2341     egr_vlan_tag_action_profile_2_entry_t entry2;
   2342     void *entries[2];
   2343     void *entry;
   2344     soc_mem_t mem = EGR_VLAN_TAG_ACTION_PROFILEm;
   2345 
   2346     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_TAG_ACTION_PROFILE_2m)) {
   2347         mem = EGR_VLAN_TAG_ACTION_PROFILE_2m;
   2348         sal_memset(&entry2, 0, sizeof(entry2));
   2349         entry = &entry2;
   2350     } else {
   2351         sal_memset(&entry1, 0, sizeof(entry1));
   2352         entry = &entry1;
   2353     }
   2354 
   2355     soc_mem_field32_set(unit, mem, entry, DT_OTAG_ACTIONf,
   2356                         _BCM_TRX_TAG_ACTION_ENCODE(action->dt_outer));
   2357     soc_mem_field32_set(unit, mem, entry, DT_ITAG_ACTIONf,
   2358                         _BCM_TRX_TAG_ACTION_ENCODE(action->dt_inner));
   2359     soc_mem_field32_set(unit, mem, entry, DT_PITAG_ACTIONf,
   2360                         _BCM_TRX_TAG_ACTION_ENCODE(action->dt_inner_prio));
   2361     soc_mem_field32_set(unit, mem, entry, SOT_OTAG_ACTIONf,
   2362                         _BCM_TRX_TAG_ACTION_ENCODE(action->ot_outer));
   2363     soc_mem_field32_set(unit, mem, entry, SOT_ITAG_ACTIONf,
   2364                         _BCM_TRX_TAG_ACTION_ENCODE(action->ot_inner));
   2365 
   2366 #if defined(BCM_TRIDENT2_SUPPORT)
   2367 
   2368     if (soc_feature(unit, soc_feature_fcoe)) {
   2369         soc_mem_field32_set(unit, mem, entry, DT_OTAG_ACTIONf,
   2370                             _BCM_TRX_TAG_ACTION_ENCODE_EGR_FCOE_EXT(
   2371                                                            action->dt_outer));
   2372         soc_mem_field32_set(unit, mem, entry, DT_ITAG_ACTIONf,
   2373                             _BCM_TRX_TAG_ACTION_ENCODE_EGR_FCOE_EXT(
   2374                                                            action->dt_inner));
   2375         soc_mem_field32_set(unit, mem, entry, DT_PITAG_ACTIONf,
   2376                             _BCM_TRX_TAG_ACTION_ENCODE_EGR_FCOE_EXT(
   2377                                                        action->dt_inner_prio));
   2378         soc_mem_field32_set(unit, mem, entry, SOT_OTAG_ACTIONf,
   2379                             _BCM_TRX_TAG_ACTION_ENCODE_EGR_FCOE_EXT(
   2380                                                            action->ot_outer));
   2381         soc_mem_field32_set(unit, mem, entry, SOT_ITAG_ACTIONf,
   2382                             _BCM_TRX_TAG_ACTION_ENCODE_EGR_FCOE_EXT(
   2383                                                            action->ot_inner));
   2384     }
   2385 
   2386 #endif  /* BCM_TRIDENT2_SUPPORT */
   2387 
   2388     if (soc_feature(unit, soc_feature_vlan_egr_it_inner_replace)) {
   2389         soc_mem_field32_set(unit, mem, entry, DT_POTAG_ACTIONf,
   2390                             _BCM_TRX_TAG_ACTION_ENCODE(action->dt_outer_prio));
   2391         soc_mem_field32_set(unit, mem, entry, SOT_POTAG_ACTIONf,
   2392                             _BCM_TRX_TAG_ACTION_ENCODE(action->ot_outer_prio));
   2393         soc_mem_field32_set(unit, mem, entry, SIT_OTAG_ACTIONf,
   2394                             _BCM_TRX_TAG_ACTION_ENCODE(action->it_outer));
   2395         soc_mem_field32_set(unit, mem, entry, SIT_ITAG_ACTIONf,
   2396                             _BCM_TRX_TAG_ACTION_ENCODE(action->it_inner));
   2397         soc_mem_field32_set(unit, mem, entry, SIT_PITAG_ACTIONf,
   2398                             _BCM_TRX_TAG_ACTION_ENCODE(action->it_inner_prio));
   2399         soc_mem_field32_set(unit, mem, entry, UT_OTAG_ACTIONf,
   2400                             _BCM_TRX_TAG_ACTION_ENCODE(action->ut_outer));
   2401         soc_mem_field32_set(unit, mem, entry, UT_ITAG_ACTIONf,
   2402                             _BCM_TRX_TAG_ACTION_ENCODE(action->ut_inner));
   2403     }
   2404 
   2405     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   2406         soc_mem_field32_set
   2407             (unit, mem, entry, DT_OPRI_ACTIONf,
   2408              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->dt_outer_pkt_prio));
   2409         soc_mem_field32_set
   2410             (unit, mem, entry, DT_OCFI_ACTIONf,
   2411              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->dt_outer_cfi));
   2412         soc_mem_field32_set
   2413             (unit, mem, entry, DT_IPRI_ACTIONf,
   2414              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->dt_inner_pkt_prio));
   2415         soc_mem_field32_set
   2416             (unit, mem, entry, DT_ICFI_ACTIONf,
   2417              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->dt_inner_cfi));
   2418         soc_mem_field32_set
   2419             (unit, mem, entry, SOT_OPRI_ACTIONf,
   2420              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_outer_pkt_prio));
   2421         soc_mem_field32_set
   2422             (unit, mem, entry, SOT_OCFI_ACTIONf,
   2423              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_outer_cfi));
   2424         soc_mem_field32_set
   2425             (unit, mem, entry, SOT_IPRI_ACTIONf,
   2426              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_inner_pkt_prio));
   2427         soc_mem_field32_set
   2428             (unit, mem, entry, SOT_ICFI_ACTIONf,
   2429              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_inner_cfi));
   2430         soc_mem_field32_set
   2431             (unit, mem, entry, SIT_OPRI_ACTIONf,
   2432              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->it_outer_pkt_prio));
   2433         soc_mem_field32_set
   2434             (unit, mem, entry, SIT_OCFI_ACTIONf,
   2435              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->it_outer_cfi));
   2436         soc_mem_field32_set
   2437             (unit, mem, entry, SIT_IPRI_ACTIONf,
   2438              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->it_inner_pkt_prio));
   2439         soc_mem_field32_set
   2440             (unit, mem, entry, SIT_ICFI_ACTIONf,
   2441              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->it_inner_cfi));
   2442         soc_mem_field32_set
   2443             (unit, mem, entry, UT_OPRI_ACTIONf,
   2444              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ut_outer_pkt_prio));
   2445         soc_mem_field32_set
   2446             (unit, mem, entry, UT_OCFI_ACTIONf,
   2447              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ut_outer_cfi));
   2448         soc_mem_field32_set
   2449             (unit, mem, entry, UT_IPRI_ACTIONf,
   2450              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ut_inner_pkt_prio));
   2451         soc_mem_field32_set
   2452             (unit, mem, entry, UT_ICFI_ACTIONf,
   2453              _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ut_inner_cfi));
   2454 
   2455 #if defined(BCM_TRIDENT2_SUPPORT)
   2456 
   2457         if (soc_feature(unit, soc_feature_fcoe)) {
   2458 
   2459             /* overwrite fcoe related fields (pri) */
   2460             soc_mem_field32_set
   2461                 (unit, mem, entry, DT_OPRI_ACTIONf,
   2462                  _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT(
   2463                                                 action->dt_outer_pkt_prio));
   2464             soc_mem_field32_set
   2465                 (unit, mem, entry, DT_IPRI_ACTIONf,
   2466                  _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT(
   2467                                                 action->dt_inner_pkt_prio));
   2468             soc_mem_field32_set
   2469                 (unit, mem, entry, SOT_OPRI_ACTIONf,
   2470                  _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT(
   2471                                                 action->ot_outer_pkt_prio));
   2472             soc_mem_field32_set
   2473                 (unit, mem, entry, SOT_IPRI_ACTIONf,
   2474                  _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT(
   2475                                                 action->ot_inner_pkt_prio));
   2476             soc_mem_field32_set
   2477                 (unit, mem, entry, SIT_OPRI_ACTIONf,
   2478                  _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT(
   2479                                                 action->it_outer_pkt_prio));
   2480             soc_mem_field32_set
   2481                 (unit, mem, entry, SIT_IPRI_ACTIONf,
   2482                  _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT(
   2483                                                 action->it_inner_pkt_prio));
   2484             soc_mem_field32_set
   2485                 (unit, mem, entry, UT_OPRI_ACTIONf,
   2486                  _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT(
   2487                                                 action->ut_outer_pkt_prio));
   2488             soc_mem_field32_set
   2489                 (unit, mem, entry, UT_IPRI_ACTIONf,
   2490                  _BCM_TRX_PRI_CFI_ACTION_ENCODE_FCOE_EXT(
   2491                                                 action->ut_inner_pkt_prio));
   2492         }
   2493 #endif  /* BCM_TRIDENT2_SUPPORT */
   2494     }
   2495 
   2496 #if defined(BCM_TRIDENT3_SUPPORT)
   2497     if (soc_mem_field_valid(unit, mem, OTPID_ACTIONf)) {
   2498         soc_mem_field32_set
   2499             (unit, mem, entry, OTPID_ACTIONf,
   2500              _BCM_TD3_TPID_ACTION_ENCODE(action->outer_tpid_action));
   2501     }
   2502 #endif
   2503 
   2504     entries[0] = entry;
   2505     entries[1] = entry;
   2506     EGR_VLAN_TAG_ACTION_LOCK(unit);
   2507     rv = soc_profile_mem_add(unit, egr_action_profile[unit],
   2508                              (void *) &entries, 1, index);
   2509     EGR_VLAN_TAG_ACTION_UNLOCK(unit);
   2510     return rv;
   2511 }
   2512 
   2513 /*
   2514  * Function : _bcm_trx_egr_vlan_action_profile_entry_increment
   2515  *
   2516  * Purpose  : increment the refcount for an egress vlan action profile table entry
   2517  */
   2518 void
   2519 _bcm_trx_egr_vlan_action_profile_entry_increment(int unit, uint32 index)
   2520 {
   2521 #if defined(BCM_TOMAHAWK3_SUPPORT)
   2522     if (SOC_IS_TOMAHAWK3(unit)) {
   2523         _bcm_th3_egr_vlan_action_profile_entry_increment(unit, index);
   2524         return;
   2525     }
   2526 #endif/* BCM_TOMAHAWK3_SUPPORT */
   2527     EGR_VLAN_TAG_ACTION_LOCK(unit);
   2528     soc_profile_mem_reference(unit, egr_action_profile[unit],
   2529                               index, 1);
   2530     EGR_VLAN_TAG_ACTION_UNLOCK(unit);
   2531 }
   2532 
   2533 /*
   2534  * Function : _bcm_trx_egr_vlan_action_profile_entry_get
   2535  *
   2536  * Purpose  : get a copy of cached egress vlan action profile table
   2537  */
   2538 void
   2539 _bcm_trx_egr_vlan_action_profile_entry_get(int unit,
   2540                                           bcm_vlan_action_set_t *action, 
   2541                                           uint32 index)
   2542 {
   2543     egr_vlan_tag_action_profile_entry_t p1;
   2544     egr_vlan_tag_action_profile_2_entry_t p2;
   2545     void *entries[2];
   2546     uint32 *entry;
   2547     uint32 val;
   2548     soc_mem_t mem = EGR_VLAN_TAG_ACTION_PROFILEm;
   2549 
   2550     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_TAG_ACTION_PROFILE_2m)) {
   2551         mem = EGR_VLAN_TAG_ACTION_PROFILE_2m;
   2552         entries[0] = &p1;
   2553         entries[1] = &p2;
   2554     } else {
   2555         entries[0] = &p1;
   2556     }
   2557 
   2558     EGR_VLAN_TAG_ACTION_LOCK(unit);
   2559     (void) soc_profile_mem_get(unit, egr_action_profile[unit],
   2560                                index, 1, entries);
   2561     entry = entries[0];
   2562 
   2563     val = soc_mem_field32_get(unit, mem, entry, DT_OTAG_ACTIONf);
   2564     action->dt_outer = _BCM_TRX_TAG_ACTION_DECODE(val);
   2565 
   2566     val = soc_mem_field32_get(unit, mem, entry, DT_ITAG_ACTIONf);
   2567     action->dt_inner = _BCM_TRX_TAG_ACTION_DECODE(val);
   2568 
   2569     val = soc_mem_field32_get(unit, mem, entry, DT_PITAG_ACTIONf);
   2570     action->dt_inner_prio = _BCM_TRX_TAG_ACTION_DECODE(val);
   2571 
   2572     val = soc_mem_field32_get(unit, mem, entry, SOT_OTAG_ACTIONf);
   2573     action->ot_outer = _BCM_TRX_TAG_ACTION_DECODE(val);
   2574 
   2575     val = soc_mem_field32_get(unit, mem, entry, SOT_ITAG_ACTIONf);
   2576     action->ot_inner = _BCM_TRX_TAG_ACTION_DECODE(val);
   2577 
   2578 #if defined(BCM_TRIDENT3_SUPPORT)
   2579     if (soc_mem_field_valid(unit, mem, OTPID_ACTIONf)) {
   2580         val = soc_mem_field32_get(unit, mem, entry, OTPID_ACTIONf);
   2581         action->outer_tpid_action = _BCM_TD3_TPID_ACTION_DECODE(val);
   2582     }
   2583 #endif
   2584 
   2585 #if defined(BCM_TRIDENT2_SUPPORT)
   2586 
   2587     if (soc_feature(unit, soc_feature_fcoe)) {
   2588         val = soc_mem_field32_get(unit, mem, entry, DT_OTAG_ACTIONf);
   2589         action->dt_outer = _BCM_TRX_TAG_ACTION_DECODE_EGR_FCOE_EXT(val);
   2590 
   2591         val = soc_mem_field32_get(unit, mem, entry, DT_ITAG_ACTIONf);
   2592         action->dt_inner = _BCM_TRX_TAG_ACTION_DECODE_EGR_FCOE_EXT(val);
   2593 
   2594         val = soc_mem_field32_get(unit, mem, entry, DT_PITAG_ACTIONf);
   2595         action->dt_inner_prio = _BCM_TRX_TAG_ACTION_DECODE_EGR_FCOE_EXT(val);
   2596 
   2597         val = soc_mem_field32_get(unit, mem, entry, SOT_OTAG_ACTIONf);
   2598         action->ot_outer = _BCM_TRX_TAG_ACTION_DECODE_EGR_FCOE_EXT(val);
   2599 
   2600         val = soc_mem_field32_get(unit, mem, entry, SOT_ITAG_ACTIONf);
   2601         action->ot_inner = _BCM_TRX_TAG_ACTION_DECODE_EGR_FCOE_EXT(val);
   2602     }
   2603 
   2604 #endif  /* BCM_TRIDENT2_SUPPORT */
   2605 
   2606     if (soc_feature(unit, soc_feature_vlan_egr_it_inner_replace)) {
   2607         val = soc_mem_field32_get(unit, mem, entry, DT_POTAG_ACTIONf);
   2608         action->dt_outer_prio = _BCM_TRX_TAG_ACTION_DECODE(val);
   2609 
   2610         val = soc_mem_field32_get(unit, mem, entry, SOT_POTAG_ACTIONf);
   2611         action->ot_outer_prio = _BCM_TRX_TAG_ACTION_DECODE(val);
   2612 
   2613         val = soc_mem_field32_get(unit, mem, entry, SIT_OTAG_ACTIONf);
   2614         action->it_outer = _BCM_TRX_TAG_ACTION_DECODE(val);
   2615 
   2616         val = soc_mem_field32_get(unit, mem, entry, SIT_ITAG_ACTIONf);
   2617         action->it_inner = _BCM_TRX_TAG_ACTION_DECODE(val);
   2618 
   2619         val = soc_mem_field32_get(unit, mem, entry, SIT_PITAG_ACTIONf);
   2620         action->it_inner_prio = _BCM_TRX_TAG_ACTION_DECODE(val);
   2621 
   2622         val = soc_mem_field32_get(unit, mem, entry, UT_OTAG_ACTIONf);
   2623         action->ut_outer = _BCM_TRX_TAG_ACTION_DECODE(val);
   2624 
   2625         val = soc_mem_field32_get(unit, mem, entry, UT_ITAG_ACTIONf);
   2626         action->ut_inner = _BCM_TRX_TAG_ACTION_DECODE(val);
   2627     } else {
   2628         action->it_outer = bcmVlanActionNone;
   2629         action->it_inner = bcmVlanActionNone;
   2630         action->it_inner_prio = bcmVlanActionNone;
   2631         action->ut_outer = bcmVlanActionNone;
   2632         action->ut_inner = bcmVlanActionNone;
   2633     }
   2634 
   2635     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   2636         val = soc_mem_field32_get(unit, mem, entry, DT_OPRI_ACTIONf);
   2637         action->dt_outer_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2638 
   2639         val = soc_mem_field32_get(unit, mem, entry, DT_OCFI_ACTIONf);
   2640         action->dt_outer_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2641 
   2642         val = soc_mem_field32_get(unit, mem, entry, DT_IPRI_ACTIONf);
   2643         action->dt_inner_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2644 
   2645         val = soc_mem_field32_get(unit, mem, entry, DT_ICFI_ACTIONf);
   2646         action->dt_inner_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2647 
   2648         val = soc_mem_field32_get(unit, mem, entry, SOT_OPRI_ACTIONf);
   2649         action->ot_outer_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2650 
   2651         val = soc_mem_field32_get(unit, mem, entry, SOT_OCFI_ACTIONf);
   2652         action->ot_outer_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2653 
   2654         val = soc_mem_field32_get(unit, mem, entry, SOT_IPRI_ACTIONf);
   2655         action->ot_inner_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2656 
   2657         val = soc_mem_field32_get(unit, mem, entry, SOT_ICFI_ACTIONf);
   2658         action->ot_inner_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2659 
   2660         val = soc_mem_field32_get(unit, mem, entry, SIT_OPRI_ACTIONf);
   2661         action->it_outer_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2662 
   2663         val = soc_mem_field32_get(unit, mem, entry, SIT_OCFI_ACTIONf);
   2664         action->it_outer_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2665 
   2666         val = soc_mem_field32_get(unit, mem, entry, SIT_IPRI_ACTIONf);
   2667         action->it_inner_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2668 
   2669         val = soc_mem_field32_get(unit, mem, entry, SIT_ICFI_ACTIONf);
   2670         action->it_inner_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2671 
   2672         val = soc_mem_field32_get(unit, mem, entry, UT_OPRI_ACTIONf);
   2673         action->ut_outer_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2674 
   2675         val = soc_mem_field32_get(unit, mem, entry, UT_OCFI_ACTIONf);
   2676         action->ut_outer_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2677 
   2678         val = soc_mem_field32_get(unit, mem, entry, UT_IPRI_ACTIONf);
   2679         action->ut_inner_pkt_prio = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2680 
   2681         val = soc_mem_field32_get(unit, mem, entry, UT_ICFI_ACTIONf);
   2682         action->ut_inner_cfi = _BCM_TRX_PRI_CFI_ACTION_DECODE(val);
   2683 
   2684 #if defined(BCM_TRIDENT2_SUPPORT)
   2685 
   2686         if (soc_feature(unit, soc_feature_fcoe)) {
   2687 
   2688             /* overwrite fcoe related values (pri) */
   2689             val = soc_mem_field32_get(unit, mem, entry, DT_OPRI_ACTIONf);
   2690             action->dt_outer_pkt_prio = 
   2691                 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val);
   2692 
   2693             val = soc_mem_field32_get(unit, mem, entry, DT_IPRI_ACTIONf);
   2694             action->dt_inner_pkt_prio = 
   2695                 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val);
   2696 
   2697             val = soc_mem_field32_get(unit, mem, entry, SOT_OPRI_ACTIONf);
   2698             action->ot_outer_pkt_prio = 
   2699                 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val);
   2700 
   2701             val = soc_mem_field32_get(unit, mem, entry, SOT_IPRI_ACTIONf);
   2702             action->ot_inner_pkt_prio = 
   2703                 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val);
   2704 
   2705             val = soc_mem_field32_get(unit, mem, entry, SIT_OPRI_ACTIONf);
   2706             action->it_outer_pkt_prio = 
   2707                 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val);
   2708 
   2709             val = soc_mem_field32_get(unit, mem, entry, SIT_IPRI_ACTIONf);
   2710             action->it_inner_pkt_prio = 
   2711                 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val);
   2712 
   2713             val = soc_mem_field32_get(unit, mem, entry, UT_OPRI_ACTIONf);
   2714             action->ut_outer_pkt_prio = 
   2715                 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val);
   2716 
   2717             val = soc_mem_field32_get(unit, mem, entry,
   2718                                       UT_IPRI_ACTIONf);
   2719             action->ut_inner_pkt_prio = 
   2720                 _BCM_TRX_PRI_CFI_ACTION_DECODE_FCOE_EXT(val);
   2721 
   2722         }
   2723 
   2724 #endif  /* BCM_TRIDENT2_SUPPORT */
   2725 
   2726     } else {
   2727         action->dt_outer_pkt_prio = bcmVlanActionNone;
   2728         action->dt_outer_cfi = bcmVlanActionNone;
   2729         action->dt_inner_pkt_prio = bcmVlanActionNone;
   2730         action->dt_inner_cfi = bcmVlanActionNone;
   2731         action->ot_outer_pkt_prio = bcmVlanActionNone;
   2732         action->ot_outer_cfi = bcmVlanActionNone;
   2733         action->ot_inner_pkt_prio = bcmVlanActionNone;
   2734         action->ot_inner_cfi = bcmVlanActionNone;
   2735         action->it_outer_pkt_prio = bcmVlanActionNone;
   2736         action->it_outer_cfi = bcmVlanActionNone;
   2737         action->it_inner_pkt_prio = bcmVlanActionNone;
   2738         action->it_inner_cfi = bcmVlanActionNone;
   2739         action->ut_outer_pkt_prio = bcmVlanActionNone;
   2740         action->ut_outer_cfi = bcmVlanActionNone;
   2741         action->ut_inner_pkt_prio = bcmVlanActionNone;
   2742         action->ut_inner_cfi = bcmVlanActionNone;
   2743     }
   2744     EGR_VLAN_TAG_ACTION_UNLOCK(unit);
   2745 }
   2746 
   2747 /*
   2748  * Function : _bcm_trx_egr_vlan_action_profile_entry_delete
   2749  *
   2750  * Purpose  : remove an entry from egress vlan action profile table
   2751  */
   2752 int
   2753 _bcm_trx_egr_vlan_action_profile_entry_delete(int unit, uint32 index)
   2754 {
   2755     int rv = BCM_E_NONE;
   2756 
   2757     EGR_VLAN_TAG_ACTION_LOCK(unit);
   2758     rv = soc_profile_mem_delete(unit, egr_action_profile[unit], index);
   2759     EGR_VLAN_TAG_ACTION_UNLOCK(unit);
   2760     return rv;
   2761 }
   2762 
   2763 STATIC soc_field_t _tr_range_min_f[] = {VLAN_MIN_0f, VLAN_MIN_1f, 
   2764                                         VLAN_MIN_2f, VLAN_MIN_3f,
   2765                                         VLAN_MIN_4f, VLAN_MIN_5f, 
   2766                                         VLAN_MIN_6f, VLAN_MIN_7f};
   2767 STATIC soc_field_t _tr_range_max_f[] = {VLAN_MAX_0f, VLAN_MAX_1f, 
   2768                                         VLAN_MAX_2f, VLAN_MAX_3f,
   2769                                         VLAN_MAX_4f, VLAN_MAX_5f, 
   2770                                         VLAN_MAX_6f, VLAN_MAX_7f}; 
   2771 
   2772 /*
   2773  * Function : bcm_trx_vlan_range_profile_init
   2774  *
   2775  * Purpose  : to initialize hardware ING_VLAN_RANGE table
   2776  *            allocate memory to cache hardware tables in RAM.
   2777  *
   2778  * Note:
   2779  *      Allocate memory to cache the profile tables and initialize.
   2780  *      If memory to cache the profile table is already allocated, just
   2781  *      initialize the table.
   2782  */
   2783 STATIC int
   2784 _bcm_trx_vlan_range_profile_init(int unit)
   2785 {
   2786     int i, idx, inner_idx;
   2787     source_trunk_map_table_entry_t stm_entry;
   2788     trunk32_port_table_entry_t trunk32_entry;
   2789     ing_vlan_range_entry_t profile_entry;
   2790     uint32 temp_index, temp_inner_index;
   2791     soc_mem_t mem;
   2792     int entry_words;
   2793     void *entries[1];
   2794     soc_field_t field;
   2795 
   2796     /* Initialize the ING_VLAN_RANGE table */
   2797 
   2798     if (vlan_range_profile[unit] == NULL) {
   2799         vlan_range_profile[unit] = sal_alloc(sizeof(soc_profile_mem_t),
   2800                                              "Vlan Range Profile Mem");
   2801         if (vlan_range_profile[unit] == NULL) {
   2802             return BCM_E_MEMORY;
   2803         }
   2804         soc_profile_mem_t_init(vlan_range_profile[unit]);
   2805     }
   2806 
   2807     /* Create profile table cache (or re-init if it already exists) */
   2808     mem = ING_VLAN_RANGEm;
   2809     entry_words = sizeof(ing_vlan_range_entry_t) / sizeof(uint32);
   2810     SOC_IF_ERROR_RETURN(soc_profile_mem_create(unit, &mem, &entry_words, 1,
   2811                                                vlan_range_profile[unit]));
   2812 
   2813     if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
   2814                 OUTER_VLAN_RANGE_IDXf)) {
   2815         field = OUTER_VLAN_RANGE_IDXf;
   2816     } else {
   2817         field = VLAN_RANGE_IDXf;
   2818     }
   2819     if (SOC_WARM_BOOT(unit)) {
   2820         /* Increment the ref count for all ports */
   2821         for (i = 0;
   2822              i < soc_mem_index_count(unit, SOURCE_TRUNK_MAP_TABLEm); i++) {
   2823             SOC_IF_ERROR_RETURN
   2824                 (READ_SOURCE_TRUNK_MAP_TABLEm(unit,
   2825                                               MEM_BLOCK_ANY, i, &stm_entry));
   2826        
   2827             idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm,
   2828                                       &stm_entry, field);
   2829             SOC_PROFILE_MEM_REFERENCE(unit, vlan_range_profile[unit], idx, 1);
   2830             SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, vlan_range_profile[unit],
   2831                                             idx, 1);
   2832             if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
   2833                                    INNER_VLAN_RANGE_IDXf)) {
   2834                 inner_idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm,
   2835                                          &stm_entry, INNER_VLAN_RANGE_IDXf);
   2836                 SOC_PROFILE_MEM_REFERENCE(unit, vlan_range_profile[unit],
   2837                                          inner_idx, 1);
   2838                 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, vlan_range_profile[unit],
   2839                                          inner_idx, 1);
   2840             }
   2841         }
   2842 
   2843         if (SOC_MEM_FIELD_VALID(unit, TRUNK32_PORT_TABLEm, VLAN_RANGE_IDXf)) {
   2844             if (!soc_property_get(unit, spn_TRUNK_EXTEND, 1)) {
   2845                 for (i = 0;
   2846                      i < soc_mem_index_count(unit, TRUNK32_PORT_TABLEm); i++) {
   2847                     SOC_IF_ERROR_RETURN
   2848                         (READ_TRUNK32_PORT_TABLEm(unit,
   2849                                             MEM_BLOCK_ANY, i, &trunk32_entry));
   2850                     idx = soc_mem_field32_get(unit, TRUNK32_PORT_TABLEm,
   2851                             &trunk32_entry, VLAN_RANGE_IDXf);
   2852                     SOC_PROFILE_MEM_REFERENCE(unit,
   2853                             vlan_range_profile[unit], idx, 1);
   2854                     SOC_PROFILE_MEM_ENTRIES_PER_SET(unit,
   2855                             vlan_range_profile[unit], idx, 1);
   2856                 }
   2857             }
   2858         }
   2859 
   2860         /* One extra increment to preserve location VLAN_RANGE_PROFILE_DEFAULT */
   2861         SOC_PROFILE_MEM_REFERENCE(unit, vlan_range_profile[unit], 
   2862                                   VLAN_RANGE_PROFILE_DEFAULT, 1);
   2863 
   2864     } else {
   2865         int rv, size;
   2866         source_trunk_map_table_entry_t *ent;
   2867         uint8 *mbuf;
   2868 
   2869         sal_memset(&profile_entry, 0, sizeof(ing_vlan_range_entry_t));
   2870         for (i = 0; i < 8; i++) {
   2871             soc_mem_field32_set(unit, ING_VLAN_RANGEm,
   2872                                 &profile_entry, _tr_range_min_f[i], 1);
   2873             soc_mem_field32_set(unit, ING_VLAN_RANGEm,
   2874                                 &profile_entry, _tr_range_max_f[i], 0);
   2875         }
   2876 
   2877         /* Initialize the VLAN_RANGE_PROFILE_DEFAULT to have 
   2878          * all ranges unused (min == 1, max == 0).
   2879          */
   2880         entries[0] = &profile_entry;
   2881         SOC_IF_ERROR_RETURN
   2882             (soc_profile_mem_add(unit, vlan_range_profile[unit],
   2883                                  (void *) &entries, 1, &temp_index));
   2884 
   2885         if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
   2886                                 INNER_VLAN_RANGE_IDXf)) {
   2887             SOC_IF_ERROR_RETURN
   2888                 (soc_profile_mem_add(unit, vlan_range_profile[unit],
   2889                                  (void *) &entries, 1, &temp_inner_index));
   2890         }
   2891 
   2892         size = SOC_MEM_TABLE_BYTES(unit, SOURCE_TRUNK_MAP_TABLEm);
   2893         mbuf = soc_cm_salloc(unit, size, "SOURCE_TRUNK_MAP_TABLE");
   2894         if (NULL == mbuf) {
   2895             return BCM_E_MEMORY;
   2896         }
   2897 
   2898         soc_mem_lock(unit, SOURCE_TRUNK_MAP_TABLEm);
   2899         rv = soc_mem_read_range(unit, SOURCE_TRUNK_MAP_TABLEm, MEM_BLOCK_ANY,
   2900                                 soc_mem_index_min(unit, SOURCE_TRUNK_MAP_TABLEm),
   2901                                 soc_mem_index_max(unit, SOURCE_TRUNK_MAP_TABLEm),
   2902                                 mbuf);
   2903         if (BCM_FAILURE(rv)) {
   2904             soc_cm_sfree(unit, mbuf);
   2905             soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm);
   2906             return rv;
   2907         }
   2908         /* Increment the ref count for all ports */
   2909         for (i = 0;
   2910              i < soc_mem_index_count(unit, SOURCE_TRUNK_MAP_TABLEm); i++) {
   2911             ent = soc_mem_table_idx_to_pointer(unit, 
   2912                         SOURCE_TRUNK_MAP_TABLEm, 
   2913                         source_trunk_map_table_entry_t *, mbuf, i);
   2914 
   2915             soc_mem_field32_set(unit, SOURCE_TRUNK_MAP_TABLEm, ent, field,
   2916                                 temp_index);
   2917 
   2918             SOC_PROFILE_MEM_REFERENCE(unit,
   2919                     vlan_range_profile[unit], temp_index, 1);
   2920 
   2921             if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
   2922                                     INNER_VLAN_RANGE_IDXf)) {
   2923                 soc_mem_field32_set(unit, SOURCE_TRUNK_MAP_TABLEm, ent,
   2924                                     INNER_VLAN_RANGE_IDXf, temp_inner_index);
   2925                 SOC_PROFILE_MEM_REFERENCE(unit, vlan_range_profile[unit], 
   2926                                           temp_inner_index, 1);
   2927             }
   2928         }
   2929         rv = soc_mem_write_range(unit, SOURCE_TRUNK_MAP_TABLEm, MEM_BLOCK_ANY,
   2930                                  soc_mem_index_min(unit, SOURCE_TRUNK_MAP_TABLEm),
   2931                                  soc_mem_index_max(unit, SOURCE_TRUNK_MAP_TABLEm),
   2932                                  mbuf);
   2933         soc_cm_sfree(unit, mbuf);
   2934         soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm);
   2935         if (BCM_FAILURE(rv)) {
   2936             return rv;
   2937         }
   2938 
   2939         if (SOC_MEM_FIELD_VALID(unit, TRUNK32_PORT_TABLEm, VLAN_RANGE_IDXf)) {
   2940             if (!soc_property_get(unit, spn_TRUNK_EXTEND, 1)) {
   2941                 for (i = 0;
   2942                      i < soc_mem_index_count(unit, TRUNK32_PORT_TABLEm); i++) {
   2943                     if (soc_mem_field32_modify(unit, TRUNK32_PORT_TABLEm, i, 
   2944                             VLAN_RANGE_IDXf, temp_index) != BCM_E_NONE) {
   2945                         continue;
   2946                     }
   2947                     SOC_PROFILE_MEM_REFERENCE(unit, vlan_range_profile[unit],
   2948                             temp_index, 1);
   2949                 }
   2950             }
   2951         }
   2952     }
   2953 
   2954     return BCM_E_NONE;
   2955 }
   2956 
   2957 /*
   2958  * Function : _bcm_trx_vlan_range_profile_entry_add
   2959  *
   2960  * Purpose  : add a new entry to vlan range profile table
   2961  */
   2962 int
   2963 _bcm_trx_vlan_range_profile_entry_add(int unit, bcm_vlan_t *min_vlan,
   2964                                      bcm_vlan_t *max_vlan, uint32 *index)
   2965 {   
   2966     ing_vlan_range_entry_t profile_entry;
   2967     void *entries[1];
   2968     int i, rv = BCM_E_NONE;
   2969 
   2970     sal_memset(&profile_entry, 0, sizeof(ing_vlan_range_entry_t));
   2971 
   2972     for (i = 0; i < 8; i++) {
   2973         soc_mem_field32_set(unit, ING_VLAN_RANGEm,
   2974                             &profile_entry, _tr_range_min_f[i], min_vlan[i]);
   2975         soc_mem_field32_set(unit, ING_VLAN_RANGEm,
   2976                             &profile_entry, _tr_range_max_f[i], max_vlan[i]);
   2977     }
   2978     entries[0] = &profile_entry;
   2979     VLAN_RANGE_LOCK(unit);
   2980     rv = soc_profile_mem_add(unit, vlan_range_profile[unit],
   2981                              (void *) &entries, 1, index);
   2982     VLAN_RANGE_UNLOCK(unit);
   2983     return rv;
   2984 }
   2985 
   2986 /*
   2987  * Function : _bcm_trx_vlan_range_profile_entry_increment
   2988  *
   2989  * Purpose  : increment the refcount for a vlan range profile table entry
   2990  */
   2991 void
   2992 _bcm_trx_vlan_range_profile_entry_increment(int unit, uint32 index)
   2993 {
   2994     VLAN_RANGE_LOCK(unit);
   2995     SOC_PROFILE_MEM_REFERENCE(unit, vlan_range_profile[unit], index, 1);
   2996     VLAN_RANGE_UNLOCK(unit);
   2997 }
   2998 
   2999 /*
   3000  * Function : _bcm_trx_vlan_range_profile_entry_get
   3001  *
   3002  * Purpose  : get a copy of cached vlan range profile table
   3003  */
   3004 void
   3005 _bcm_trx_vlan_range_profile_entry_get(int unit, bcm_vlan_t *min_vlan, 
   3006                                      bcm_vlan_t *max_vlan, uint32 index)
   3007 {
   3008     int i;
   3009     ing_vlan_range_entry_t *profile_entry;
   3010 
   3011     VLAN_RANGE_LOCK(unit);
   3012     profile_entry = SOC_PROFILE_MEM_ENTRY(unit, vlan_range_profile[unit],
   3013                                           ing_vlan_range_entry_t *,
   3014                                           index);
   3015     for (i = 0; i < 8; i++) {
   3016         min_vlan[i] = soc_mem_field32_get(unit, ING_VLAN_RANGEm,
   3017                                           profile_entry, _tr_range_min_f[i]);
   3018         max_vlan[i] = soc_mem_field32_get(unit, ING_VLAN_RANGEm,
   3019                                           profile_entry, _tr_range_max_f[i]);
   3020     }
   3021     VLAN_RANGE_UNLOCK(unit);
   3022 }
   3023 
   3024 /*
   3025  * Function : _bcm_trx_vlan_range_profile_entry_delete
   3026  *
   3027  * Purpose  : remove an entry from vlan range profile table
   3028  */
   3029 int
   3030 _bcm_trx_vlan_range_profile_entry_delete(int unit, uint32 index)
   3031 {
   3032     int rv = BCM_E_NONE;
   3033     VLAN_RANGE_LOCK(unit);
   3034     rv = soc_profile_mem_delete(unit, vlan_range_profile[unit], index);
   3035     VLAN_RANGE_UNLOCK(unit);
   3036     return rv;
   3037 }
   3038 
   3039 /*
   3040  * On XGS3, VLAN_SUBNET.IP_ADDR stores only a top half (64 bits) of
   3041  * the IPV6 address. Comparing it against a full length of a parameter
   3042  * will have certainly result in a mismatch. There should be a
   3043  * special type for a stored part of the address; meanwhile, a
   3044  * symbolic constant is used.
   3045  */
   3046 
   3047 #define VLAN_SUBNET_IP_ADDR_LENGTH 8
   3048 
   3049 /*
   3050  * Function:
   3051  *      _trx_vlan_ip_addr_mask_get
   3052  * Purpose:
   3053  *      Get IPV6 address and mask from vlan_ip structure
   3054  * Parameters:
   3055  *      vlan_ip -   structure specifying IP address and other info
   3056  *      ip6addr -   IPv6 address to retrieve
   3057  *      ip6mask -   IPv6 mask to retrieve
   3058  * Returns:
   3059  *      BCM_E_XXX
   3060  */
   3061 
   3062 STATIC int
   3063 _trx_vlan_ip_addr_mask_get(bcm_vlan_ip_t *vlan_ip, bcm_ip6_t ip6addr, 
   3064                            bcm_ip6_t ip6mask)
   3065 {
   3066     if (vlan_ip->flags & BCM_VLAN_SUBNET_IP6) {
   3067         if (vlan_ip->prefix > 64) {
   3068             return BCM_E_PARAM;
   3069         }
   3070 
   3071         bcm_ip6_mask_create(ip6mask, vlan_ip->prefix); 
   3072         sal_memcpy(ip6addr, vlan_ip->ip6, sizeof(bcm_ip6_t));
   3073     } else { /* IPv4 entry */
   3074         sal_memcpy(ip6addr, "\xff\xff\x00\x00", 4);
   3075         ip6addr[4] = vlan_ip->ip4 >> 24;
   3076         ip6addr[5] = (vlan_ip->ip4 >> 16) & 0xff;
   3077         ip6addr[6] = (vlan_ip->ip4 >> 8) & 0xff;
   3078         ip6addr[7] = vlan_ip->ip4 & 0xff;
   3079 
   3080         sal_memcpy(ip6mask, "\xff\xff\xff\xff", 4);
   3081         ip6mask[4] = vlan_ip->mask >> 24;
   3082         ip6mask[5] = (vlan_ip->mask >> 16) & 0xff;
   3083         ip6mask[6] = (vlan_ip->mask >> 8) & 0xff;
   3084         ip6mask[7] = vlan_ip->mask & 0xff;
   3085     }
   3086 
   3087     return BCM_E_NONE;
   3088 }
   3089 
   3090 /*
   3091  * Function:
   3092  *      _tr_vlan_subnet_mem_read
   3093  * Purpose:
   3094  *      Helper function to allocated memory and read by range all 
   3095  *      VLAN_SUBNET memory
   3096  * Parameters:
   3097  *      unit    -       (IN) BCM Device unit
   3098  *      vstab   -       (OUT) pointer to memory
   3099  *      nent    -       (OUT) total number of entries in the memory
   3100  * Returns:
   3101  *      BCM_E_XXX
   3102  * Note: 
   3103  *      This routine will allocate a memory, it is up to caller responsibility
   3104  *      to free it 
   3105  */
   3106 STATIC int 
   3107 _tr_vlan_subnet_mem_read(int unit, vlan_subnet_entry_t **vstab, int *nent)
   3108 {
   3109     int imin, imax, vsbytes, rv;
   3110 
   3111     imin = soc_mem_index_min(unit, VLAN_SUBNETm);
   3112     imax = soc_mem_index_max(unit, VLAN_SUBNETm);
   3113     *nent = soc_mem_index_count(unit, VLAN_SUBNETm);
   3114     vsbytes = soc_mem_entry_words(unit, VLAN_SUBNETm);
   3115     vsbytes = WORDS2BYTES(vsbytes);
   3116     *vstab = soc_cm_salloc(unit, *nent * sizeof(vlan_subnet_entry_t), "vlan_subnet");
   3117     if (*vstab == NULL) {
   3118         return BCM_E_MEMORY;
   3119     }
   3120 
   3121     rv = soc_mem_read_range(unit, VLAN_SUBNETm, MEM_BLOCK_ANY,
   3122                             imin, imax, *vstab);
   3123     return rv;
   3124 }
   3125 
   3126 /*
   3127  * Function:
   3128  *      _trx_vlan_subnet_entry_parse
   3129  * Purpose:
   3130  *      Helper function to parse all information fields from 
   3131  *      VLAN_SUBNET memory entry
   3132  * Parameters:
   3133  *      unit    -       (IN) BCM Device unit
   3134  *      ventry   -      (IN) pointer to a vlan subnet entry 
   3135  *      subnet_fields - (OUT) Structure contains all entry fields
   3136  * Returns:
   3137  *      none
   3138  * Note: 
   3139  */
   3140 STATIC void 
   3141 _trx_vlan_subnet_entry_parse(int unit, vlan_subnet_entry_t *ventry, 
   3142                            _bcm_trx_vlan_subnet_entry_t *subnet_fields)
   3143 {
   3144     bcm_ip6_t   ip6tmp;
   3145     vlan_subnet_entry_t entry;
   3146     uint32      fval[SOC_MAX_MEM_WORDS];
   3147 
   3148     soc_mem_ip6_addr_get(unit, VLAN_SUBNETm, ventry, IP_ADDRf,
   3149                          subnet_fields->ip, SOC_MEM_IP6_UPPER_ONLY);
   3150 
   3151     if (soc_mem_field_valid(unit, VLAN_SUBNETm, KEYf)) {
   3152         soc_mem_field_get(unit, VLAN_SUBNETm, (uint32 *)ventry, MASKf, fval);
   3153         soc_mem_field_set(unit, VLAN_SUBNETm, (uint32 *)&entry, KEYf, fval);
   3154         soc_mem_ip6_addr_get(unit, VLAN_SUBNETm, &entry, IP_ADDRf,
   3155                              ip6tmp, SOC_MEM_IP6_UPPER_ONLY);
   3156     } else {
   3157         soc_mem_ip6_addr_get(unit, VLAN_SUBNETm, ventry, MASKf,
   3158                              ip6tmp, SOC_MEM_IP6_UPPER_ONLY);
   3159     }
   3160     subnet_fields->prefix = bcm_ip6_mask_length(ip6tmp);
   3161 
   3162     subnet_fields->ovid = soc_VLAN_SUBNETm_field32_get(unit, ventry, OVIDf);
   3163     subnet_fields->ivid = soc_VLAN_SUBNETm_field32_get(unit, ventry, IVIDf);
   3164     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   3165         subnet_fields->opri =
   3166             soc_VLAN_SUBNETm_field32_get(unit, ventry, OPRIf);
   3167         subnet_fields->ocfi =
   3168             soc_VLAN_SUBNETm_field32_get(unit, ventry, OCFIf);
   3169         subnet_fields->ipri =
   3170             soc_VLAN_SUBNETm_field32_get(unit, ventry, IPRIf);
   3171         subnet_fields->icfi =
   3172             soc_VLAN_SUBNETm_field32_get(unit, ventry, ICFIf);
   3173     } else {
   3174         subnet_fields->opri = soc_VLAN_SUBNETm_field32_get(unit, ventry, PRIf);
   3175     }
   3176     subnet_fields->profile_idx = soc_VLAN_SUBNETm_field32_get(unit, ventry, 
   3177                                                     TAG_ACTION_PROFILE_PTRf);
   3178 }
   3179 
   3180 /*
   3181  * Function:
   3182  *      _trx_vlan_subnet_entry_set
   3183  * Purpose:
   3184  *      Helper function to write all fields to 
   3185  *      VLAN_SUBNET memory entry
   3186  * Parameters:
   3187  *      unit    -       (IN) BCM Device unit
   3188  *      ventry   -      (IN) pointer to a vlan subnet entry 
   3189  *      subnet_fields - (IN) Structure contains all entry fields
   3190  * Returns:
   3191  *      none
   3192  * Note: 
   3193  *      This routine assumes that all rovided fields has correct values
   3194  */
   3195 
   3196 STATIC void 
   3197 _trx_vlan_subnet_entry_set(int unit, vlan_subnet_entry_t *ventry, 
   3198                            _bcm_trx_vlan_subnet_entry_t *subnet_fields)
   3199 {
   3200     uint32      fval[SOC_MAX_MEM_WORDS];
   3201 
   3202     sal_memset(fval, 0, sizeof(fval));
   3203     if (soc_mem_field_valid(unit, VLAN_SUBNETm, KEYf)) {
   3204         soc_mem_field_set(unit, VLAN_SUBNETm, (uint32 *)ventry, KEYf, fval);
   3205         soc_mem_ip6_addr_set(unit, VLAN_SUBNETm, ventry, IP_ADDRf,
   3206                              subnet_fields->mask, SOC_MEM_IP6_UPPER_ONLY);
   3207         soc_mem_field_get(unit, VLAN_SUBNETm, (uint32 *)ventry, KEYf, fval);
   3208         soc_mem_field_set(unit, VLAN_SUBNETm, (uint32 *)ventry, MASKf, fval);
   3209     } else {
   3210         soc_mem_ip6_addr_set(unit, VLAN_SUBNETm, ventry, MASKf,
   3211                              subnet_fields->mask, SOC_MEM_IP6_UPPER_ONLY);
   3212     }
   3213     soc_mem_ip6_addr_set(unit, VLAN_SUBNETm, ventry, IP_ADDRf,
   3214                          subnet_fields->ip, SOC_MEM_IP6_UPPER_ONLY);
   3215     soc_VLAN_SUBNETm_field32_set(unit, ventry, OVIDf, subnet_fields->ovid);
   3216     soc_VLAN_SUBNETm_field32_set(unit, ventry, IVIDf, subnet_fields->ivid);
   3217     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   3218         soc_VLAN_SUBNETm_field32_set(unit, ventry, OPRIf, subnet_fields->opri);
   3219         soc_VLAN_SUBNETm_field32_set(unit, ventry, OCFIf, subnet_fields->ocfi);
   3220         soc_VLAN_SUBNETm_field32_set(unit, ventry, IPRIf, subnet_fields->ipri);
   3221         soc_VLAN_SUBNETm_field32_set(unit, ventry, ICFIf, subnet_fields->icfi);
   3222     } else {
   3223         soc_VLAN_SUBNETm_field32_set(unit, ventry, PRIf, subnet_fields->opri);
   3224     }
   3225     soc_VLAN_SUBNETm_field32_set(unit, ventry, TAG_ACTION_PROFILE_PTRf, 
   3226                                  subnet_fields->profile_idx);
   3227     soc_VLAN_SUBNETm_field32_set(unit, ventry, VALIDf, 1);
   3228 }
   3229 
   3230 /*
   3231  * Function:
   3232  *      _trx_vlan_subnet_lookup
   3233  * Purpose:
   3234  *      Get index into table with settings matching to subnet
   3235  * Parameters:
   3236  *      unit            (IN) BCM Device unit
   3237  *      vstab           (IN) pointer to memory
   3238  *      nent            (IN) number of entries in the memory
   3239  *      ip              (IN) IP address
   3240  *      ip_mask         (IN) IP address mask
   3241  *      entry_index     (OUT) target entry index (if BCM_E_NONE)
   3242  *                            index to be used for insert or -1 when full
   3243  *                            (if BCM_E_NOT_FOUND)
   3244  *      free_index      (OUT) (optional) index of last used entry + 1
   3245  * Returns:
   3246  *      BCM_E_XXX
   3247  */
   3248 STATIC int
   3249 _trx_vlan_subnet_lookup(int unit, vlan_subnet_entry_t *vstab, int nent,
   3250                         bcm_ip6_t ip, bcm_ip6_t ip_mask, int *entry_index,
   3251                         int *free_index)
   3252 {
   3253     bcm_ip6_t           ip_key, ip6_full_mask;
   3254     vlan_subnet_entry_t *vstabp, entry0, entry1, entry2, mask0, mask1;
   3255     int                 index_min, index_max;
   3256     int                 index, i, entry_words, rv;
   3257     uint32              fval[SOC_MAX_MEM_WORDS];
   3258 
   3259     sal_memcpy(ip_key, ip, VLAN_SUBNET_IP_ADDR_LENGTH);
   3260 #ifdef BCM_TRIDENT_SUPPORT
   3261     
   3262     if (soc_feature(unit, soc_feature_xy_tcam)) {
   3263         for (i = 0; i < VLAN_SUBNET_IP_ADDR_LENGTH; i++) {
   3264             ip_key[i] &= ip_mask[i];
   3265         }
   3266     }
   3267 #endif /* BCM_TRIDENT_SUPPORT */
   3268 
   3269     sal_memset(&ip6_full_mask, 0xff, sizeof(ip6_full_mask));
   3270     entry_words = soc_mem_entry_words(unit, VLAN_SUBNETm);
   3271 
   3272     /* entry2 is for checking VALID bit */
   3273     sal_memset(&entry2, 0, sizeof(entry2));
   3274     soc_mem_field32_set(unit, VLAN_SUBNETm, &entry2, VALIDf, 1);
   3275 
   3276     /* entry1 and mask1 are for prefix length check */
   3277     entry1 = entry2;
   3278     if (soc_mem_field_valid(unit, VLAN_SUBNETm, KEYf)) {
   3279         sal_memset(&entry0, 0, sizeof(entry0));
   3280         soc_mem_ip6_addr_set(unit, VLAN_SUBNETm, &entry0, IP_ADDRf, ip_mask,
   3281                              SOC_MEM_IP6_UPPER_ONLY);
   3282         soc_mem_field_get(unit, VLAN_SUBNETm, (uint32 *)&entry0, KEYf, fval);
   3283         soc_mem_field_set(unit, VLAN_SUBNETm, (uint32 *)&entry1, MASKf, fval);
   3284         mask1 = entry1;
   3285         soc_mem_ip6_addr_set(unit, VLAN_SUBNETm, &entry0, IP_ADDRf,
   3286                              ip6_full_mask, SOC_MEM_IP6_UPPER_ONLY);
   3287         soc_mem_field_get(unit, VLAN_SUBNETm, (uint32 *)&entry0, KEYf, fval);
   3288         soc_mem_field_set(unit, VLAN_SUBNETm, (uint32 *)&mask1, MASKf, fval);
   3289     } else {
   3290         soc_mem_ip6_addr_set(unit, VLAN_SUBNETm, &entry1, MASKf, ip_mask,
   3291                              SOC_MEM_IP6_UPPER_ONLY);
   3292         mask1 = entry1;
   3293         soc_mem_ip6_addr_set(unit, VLAN_SUBNETm, &mask1, MASKf,
   3294                              ip6_full_mask, SOC_MEM_IP6_UPPER_ONLY);
   3295     }
   3296 
   3297     /* entry0 and mask0 are for target entry matching */
   3298     entry0 = entry1;
   3299     soc_mem_ip6_addr_set(unit, VLAN_SUBNETm, &entry0, IP_ADDRf, ip_key,
   3300                          SOC_MEM_IP6_UPPER_ONLY);
   3301     mask0 = mask1;
   3302     soc_mem_field32_set(unit, VLAN_SUBNETm, &mask0, VALIDf, 1);
   3303     soc_mem_ip6_addr_set(unit, VLAN_SUBNETm, &mask0, IP_ADDRf, ip_mask,
   3304                          SOC_MEM_IP6_UPPER_ONLY);
   3305 
   3306     /* Do binary search to find the first entry whose prefix length
   3307      * is shorter than or equal to the target entry */
   3308     index_min = 0;
   3309     index_max = nent - 1;
   3310     while (index_min < index_max) {
   3311         index = (index_min + index_max) / 2;
   3312         vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm,
   3313                                               vlan_subnet_entry_t *,
   3314                                               vstab, index);
   3315 
   3316         /* Check if the entry has longer prefix */
   3317         for (i = 0; i < entry_words; i++) {
   3318             if ((vstabp->entry_data[i] & mask1.entry_data[i]) >
   3319                 entry1.entry_data[i]) {
   3320                 break;
   3321             }
   3322         }
   3323         if (i != entry_words) { /* prefix length is longer than target entry */
   3324             index_min = index + 1;
   3325         } else { /* prefix length is shorter than or equal to target entry */
   3326             index_max = index;
   3327         }
   3328     }
   3329 
   3330     /* Match against entries with the same prefix length as target entry */
   3331     rv = BCM_E_NOT_FOUND;
   3332     *entry_index = -1;
   3333     for (index = index_min; index < nent; index++) {
   3334         vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm,
   3335                                               vlan_subnet_entry_t *,
   3336                                               vstab, index);
   3337         /* Try matching the entry */
   3338         for (i = 0; i < entry_words; i++) {
   3339             if ((vstabp->entry_data[i] ^ entry0.entry_data[i]) &
   3340                 mask0.entry_data[i]) {
   3341                 break;
   3342             }
   3343         }
   3344         if (i == entry_words) {
   3345             rv = BCM_E_NONE;
   3346             *entry_index = index;
   3347             break;
   3348         }
   3349 
   3350         /* Find the first shorter prefix entry */
   3351         for (i = 0; i < entry_words; i++) {
   3352             if ((vstabp->entry_data[i] & mask1.entry_data[i]) <
   3353                 entry1.entry_data[i]) {
   3354                 break;
   3355             }
   3356         }
   3357         if (i != entry_words) {
   3358             *entry_index = index;
   3359             break;
   3360         }
   3361     }
   3362 
   3363 
   3364     if (free_index == NULL) {
   3365         return rv;
   3366     }
   3367 
   3368     /* Do binary search to find the index after the last used entry */
   3369     index_min = index;
   3370     index_max = nent - 1;
   3371     while (index_min <= index_max) {
   3372         index = (index_min + index_max) / 2;
   3373         vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm,
   3374                                               vlan_subnet_entry_t *,
   3375                                               vstab, index);
   3376 
   3377         /* Check if the entry is valid */
   3378         for (i = 0; i < entry_words; i++) {
   3379             if (vstabp->entry_data[i] & entry2.entry_data[i]) {
   3380                 break;
   3381             }
   3382         }
   3383         if (i == entry_words) { /* free entry */
   3384             if (index_min == index_max) {
   3385                 break;
   3386             }
   3387             index_max = index;
   3388         } else { /* entry in used */
   3389             index_min = index + 1;
   3390         }
   3391     }
   3392 
   3393     *free_index = index_min;
   3394     return rv;
   3395 }
   3396 
   3397 /*
   3398  * Function:
   3399  *      _trx_vlan_subnet_entry_add
   3400  * Purpose:
   3401  *      Add vlan settings for given subnet
   3402  * Parameters:
   3403  *      unit            - (IN) BCM Device unit
   3404  *      entry_fields    - (IN) Entry fields to add
   3405  * Returns:
   3406  *      BCM_E_XXX
   3407  */
   3408 STATIC int 
   3409 _trx_vlan_subnet_entry_add(int unit,
   3410                            _bcm_trx_vlan_subnet_entry_t *entry_fields)
   3411 {
   3412     int                         rv, nent, i;
   3413     vlan_subnet_entry_t         *vstab, *vstabp;
   3414     uint32                      old_profile_idx;
   3415     int                         entry_index, free_index;
   3416 
   3417     soc_mem_lock(unit, VLAN_SUBNETm);
   3418 
   3419     rv = _tr_vlan_subnet_mem_read(unit, &vstab, &nent);
   3420     if (BCM_FAILURE(rv)) {
   3421         if (NULL != vstab) {
   3422             soc_cm_sfree(unit, vstab);
   3423         }
   3424         soc_mem_unlock(unit, VLAN_SUBNETm);
   3425         return rv;
   3426     }
   3427 
   3428     rv = _trx_vlan_subnet_lookup(unit, vstab, nent, entry_fields->ip,
   3429                                  entry_fields->mask, &entry_index,
   3430                                  &free_index);
   3431     if (rv == BCM_E_NOT_FOUND && entry_index == -1) {
   3432         rv = BCM_E_FULL;
   3433     }
   3434 
   3435     if (BCM_SUCCESS(rv)) {   /* found an exact match */
   3436         vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm,
   3437                                               vlan_subnet_entry_t *, vstab,
   3438                                               entry_index);
   3439 
   3440         /* retrieve old vlan action profile pointer */
   3441         old_profile_idx = soc_VLAN_SUBNETm_field32_get
   3442             (unit, vstabp, TAG_ACTION_PROFILE_PTRf);   
   3443         _trx_vlan_subnet_entry_set(unit, vstabp, entry_fields);
   3444         rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ALL, entry_index, vstabp);
   3445         if (BCM_SUCCESS(rv)) {
   3446             /* Delete the old vlan action profile entry */
   3447             rv = _bcm_trx_vlan_action_profile_entry_delete(unit,
   3448                                                            old_profile_idx);
   3449         }
   3450     } else if (rv == BCM_E_NOT_FOUND) {
   3451         /* shift down entries starting at the insert point to create hole */
   3452         for (i = free_index - 1; i >= entry_index; i--) {
   3453             vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm,
   3454                                                   vlan_subnet_entry_t *, vstab,
   3455                                                   i);
   3456             rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ANY, i + 1, vstabp);
   3457             if (BCM_FAILURE(rv)) {
   3458                 break;
   3459             }
   3460         }
   3461         if (i < entry_index) {
   3462             /* insert new entry at the created hole */
   3463             vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm,
   3464                                                   vlan_subnet_entry_t *, vstab,
   3465                                                   entry_index);
   3466             sal_memset(vstabp, 0,
   3467                        WORDS2BYTES(soc_mem_entry_words(unit, VLAN_SUBNETm)));
   3468             _trx_vlan_subnet_entry_set(unit, vstabp, entry_fields);
   3469             rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ALL, entry_index, vstabp);
   3470         }
   3471     }
   3472     soc_mem_unlock(unit, VLAN_SUBNETm);
   3473     soc_cm_sfree(unit, vstab);
   3474     return rv;
   3475 }
   3476 
   3477 
   3478 
   3479 /*
   3480  * Function:
   3481  *      _trx_vlan_subnet_entry_get
   3482  * Purpose:
   3483  *      Get vlan settings for given subnet
   3484  * Parameters:
   3485  *      unit -          (IN) BCM Device unit
   3486  *      subnet_fields - (IN/OUT) Structure contains all entry fields
   3487  * Returns:
   3488  *      BCM_E_XXX
   3489  */
   3490 STATIC int 
   3491 _trx_vlan_subnet_entry_get(int unit,
   3492                            _bcm_trx_vlan_subnet_entry_t *entry_fields)
   3493 {
   3494     vlan_subnet_entry_t         *vstab, *vstabp;
   3495     int                         entry_index, rv, nent;
   3496 
   3497     if (NULL == entry_fields) {
   3498         return (BCM_E_PARAM);
   3499     }
   3500     soc_mem_lock(unit, VLAN_SUBNETm);
   3501 
   3502     rv = _tr_vlan_subnet_mem_read(unit, &vstab, &nent);
   3503     if (BCM_FAILURE(rv)) {
   3504         if (NULL != vstab) {
   3505             soc_cm_sfree(unit, vstab);
   3506         }
   3507         soc_mem_unlock(unit, VLAN_SUBNETm);
   3508         return rv;
   3509     }
   3510     
   3511     rv = _trx_vlan_subnet_lookup(unit, vstab, nent, entry_fields->ip,
   3512                                  entry_fields->mask, &entry_index, NULL);
   3513     if (BCM_SUCCESS(rv)) {
   3514         vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm, 
   3515                                               vlan_subnet_entry_t *, vstab,
   3516                                               entry_index);
   3517         _trx_vlan_subnet_entry_parse(unit, vstabp, entry_fields);
   3518     }
   3519 
   3520     soc_cm_sfree(unit, vstab);
   3521     soc_mem_unlock(unit, VLAN_SUBNETm);
   3522     return (BCM_E_NONE);
   3523 }
   3524 
   3525 
   3526 /*
   3527  * Function:
   3528  *      _trx_vlan_subnet_entry_delete
   3529  * Purpose:
   3530  *      Delete vlan settings for given subnet
   3531  * Parameters:
   3532  *      unit -        (IN) BCM Device unit
   3533  *      ip -          (IN) IP address
   3534  *      mask -        (IN) IP mask
   3535  * Returns:
   3536  *      BCM_E_XXX
   3537  */
   3538 static int
   3539 _trx_vlan_subnet_entry_delete(int unit, bcm_ip6_t ip, bcm_ip6_t mask)
   3540 {
   3541     int                         rv, nent, i;
   3542     vlan_subnet_entry_t         *vstab, *vstabp;
   3543     uint32                      old_profile_idx;
   3544     int                         entry_index, free_index;
   3545 
   3546     soc_mem_lock(unit, VLAN_SUBNETm);
   3547     rv = _tr_vlan_subnet_mem_read(unit, &vstab, &nent);
   3548     if (BCM_FAILURE(rv)) {
   3549         if (NULL != vstab) {
   3550             soc_cm_sfree(unit, vstab);
   3551         }
   3552         soc_mem_unlock(unit, VLAN_SUBNETm);
   3553         return rv;
   3554     }
   3555 
   3556     rv = _trx_vlan_subnet_lookup(unit, vstab, nent, ip, mask, &entry_index,
   3557                                  &free_index);
   3558     if (BCM_FAILURE(rv)) {
   3559         soc_cm_sfree(unit, vstab);
   3560         soc_mem_unlock(unit, VLAN_SUBNETm);
   3561         return (rv);
   3562     }
   3563 
   3564     /* Get the old vlan action profile pointer */
   3565     vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm,
   3566                                           vlan_subnet_entry_t *, vstab,
   3567                                           entry_index);
   3568     old_profile_idx = soc_mem_field32_get(unit, VLAN_SUBNETm, vstabp,
   3569                                           TAG_ACTION_PROFILE_PTRf);
   3570 
   3571     for (i = entry_index; i < free_index - 1; i++) {
   3572         vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm,
   3573                                               vlan_subnet_entry_t *, vstab,
   3574                                               (i + 1));
   3575         rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ANY, i, vstabp);
   3576         if (BCM_FAILURE(rv)) {
   3577             break;
   3578         }
   3579     }
   3580     if (i >= free_index - 1) {
   3581         rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ANY, free_index - 1,
   3582                                 soc_mem_entry_null(unit, VLAN_SUBNETm));
   3583         if (BCM_SUCCESS(rv)) {
   3584             /* Delete the old vlan action profile entry */
   3585             rv = _bcm_trx_vlan_action_profile_entry_delete(unit,
   3586                                                            old_profile_idx);
   3587         }
   3588     }
   3589 
   3590     soc_mem_unlock(unit, VLAN_SUBNETm);
   3591     soc_cm_sfree(unit, vstab);
   3592     return rv;
   3593 }
   3594 
   3595 /*
   3596  * Function:
   3597  *      _bcm_trx_vlan_ip_action_add
   3598  * Purpose:
   3599  *      Add a subnet lookup to select vlan and priority for
   3600  *      untagged packets
   3601  * Parameters:
   3602  *      unit    -   device number
   3603  *      vlan_ip -   structure specifying IP address and other info
   3604  *      action  -   structure VLAN tag actions
   3605  * Returns:
   3606  *      BCM_E_XXX
   3607  */
   3608 int
   3609 _bcm_trx_vlan_ip_action_add(int unit, bcm_vlan_ip_t *vlan_ip,
   3610                            bcm_vlan_action_set_t *action)
   3611 {
   3612     int rv;
   3613     _bcm_trx_vlan_subnet_entry_t entry_fields;
   3614 
   3615     BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action));
   3616 
   3617     BCM_IF_ERROR_RETURN(_bcm_trx_vlan_ip_verify(unit, vlan_ip));
   3618 
   3619     sal_memset(&entry_fields, 0, sizeof(_bcm_trx_vlan_subnet_entry_t));
   3620     BCM_IF_ERROR_RETURN(_trx_vlan_ip_addr_mask_get(vlan_ip, entry_fields.ip,
   3621                                                    entry_fields.mask));
   3622 
   3623     BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_profile_entry_add
   3624                         (unit, action, (uint32 *)&entry_fields.profile_idx));
   3625 
   3626     entry_fields.ovid = action->new_outer_vlan;
   3627     entry_fields.ivid = action->new_inner_vlan;
   3628     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   3629         entry_fields.opri = action->priority;
   3630         entry_fields.ocfi = action->new_outer_cfi;
   3631         entry_fields.ipri = action->new_inner_pkt_prio;
   3632         entry_fields.icfi = action->new_inner_cfi;
   3633     } else {
   3634         entry_fields.opri = action->priority;
   3635     }
   3636 
   3637     rv = _trx_vlan_subnet_entry_add(unit, &entry_fields);
   3638     if (BCM_FAILURE(rv)) {
   3639         /* Add failed, back out the new profile entry */
   3640         (void)_bcm_trx_vlan_action_profile_entry_delete
   3641             (unit, entry_fields.profile_idx);
   3642     }
   3643 
   3644     return rv;
   3645 }
   3646 
   3647 /*
   3648  * Function:
   3649  *      _bcm_trx_vlan_ip_action_get
   3650  * Purpose:
   3651  *      Helper funtion for the API, implementation for TRX
   3652  * Parameters:
   3653  *      unit    -   (IN) device number
   3654  *      vlan_ip -   (IN) structure specifying IP address and other info
   3655  *      action  -   (OUT) structure VLAN tag actions
   3656  * Returns:
   3657  *      BCM_E_XXX
   3658  */
   3659 int
   3660 _bcm_trx_vlan_ip_action_get(int unit, bcm_vlan_ip_t *vlan_ip,
   3661                            bcm_vlan_action_set_t *action)
   3662 {
   3663     _bcm_trx_vlan_subnet_entry_t    entry_fields;
   3664 
   3665     /* Parameter check */
   3666     if (NULL == action) {
   3667         return (BCM_E_PARAM);
   3668     }
   3669     BCM_IF_ERROR_RETURN(_bcm_trx_vlan_ip_verify(unit, vlan_ip));
   3670 
   3671     sal_memset(&entry_fields, 0, sizeof(_bcm_trx_vlan_subnet_entry_t));
   3672     BCM_IF_ERROR_RETURN(
   3673         _trx_vlan_ip_addr_mask_get(vlan_ip, entry_fields.ip, entry_fields.mask));  
   3674     
   3675     BCM_IF_ERROR_RETURN(
   3676         _trx_vlan_subnet_entry_get(unit, &entry_fields));
   3677 
   3678     action->new_outer_vlan = entry_fields.ovid; 
   3679     action->new_inner_vlan = entry_fields.ivid;
   3680     action->priority = entry_fields.opri;
   3681     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   3682         action->new_outer_cfi = entry_fields.ocfi;
   3683         action->new_inner_pkt_prio = entry_fields.ipri;
   3684         action->new_inner_cfi = entry_fields.icfi;
   3685     }
   3686 
   3687     _bcm_trx_vlan_action_profile_entry_get(unit, action, 
   3688                                            entry_fields.profile_idx);
   3689 
   3690     return (BCM_E_NONE);
   3691 }
   3692 
   3693 /*
   3694  * Function:
   3695  *      _bcm_trx_vlan_ip_action_traverse
   3696  * Purpose:
   3697  *      Helper funtion for the API, implementation for TRX
   3698  * Parameters:
   3699  *      unit    -   (IN) device number
   3700  *      cb      -   (IN) user specified call back function
   3701  *      user_data - (IN) pointer to user_data
   3702  * Returns:
   3703  *      BCM_E_XXX
   3704  */
   3705 int
   3706 _bcm_trx_vlan_ip_action_traverse(int unit, 
   3707                                  bcm_vlan_ip_action_traverse_cb cb,
   3708                                  void * user_data)
   3709 {
   3710     vlan_subnet_entry_t         *vstab, *vstabp;
   3711     int                         nent, rv, i;
   3712     bcm_vlan_action_set_t       action;
   3713     bcm_vlan_ip_t               vlan_ip;
   3714     _bcm_trx_vlan_subnet_entry_t entry_fields;
   3715 
   3716     /* Input parameters check. */
   3717     if (NULL == cb) {
   3718         return (BCM_E_PARAM);
   3719     }
   3720     sal_memset(&entry_fields, 0, sizeof(_bcm_trx_vlan_subnet_entry_t));
   3721 
   3722     
   3723     rv = _tr_vlan_subnet_mem_read(unit, &vstab, &nent);
   3724     if (BCM_FAILURE(rv)) {
   3725         if (NULL != vstab) {
   3726             soc_cm_sfree(unit, vstab);
   3727         }
   3728         return rv;
   3729     }
   3730     
   3731     for(i = 0; i < nent; i++) {
   3732         sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t));
   3733         sal_memset(&vlan_ip, 0, sizeof(bcm_vlan_ip_t));
   3734         vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm,
   3735                                               vlan_subnet_entry_t *, 
   3736                                               vstab, i);
   3737         if (0 == soc_VLAN_SUBNETm_field32_get(unit, vstabp, VALIDf)){
   3738             continue;
   3739         }
   3740         _trx_vlan_subnet_entry_parse(unit, vstabp, &entry_fields);
   3741 
   3742         if (*(uint32*)entry_fields.ip == 0xffff0000) {
   3743             /* IPv4 case */
   3744             bcm_ip6_t   ip6tmp;
   3745 
   3746             vlan_ip.ip4 = (entry_fields.ip[4] << 24) |
   3747                 (entry_fields.ip[5] << 16) | (entry_fields.ip[6] << 8) |
   3748                 entry_fields.ip[7];
   3749             bcm_ip6_mask_create(ip6tmp, entry_fields.prefix);
   3750             vlan_ip.mask = (ip6tmp[4] << 24) | (ip6tmp[5] << 16) |
   3751                 (ip6tmp[6] << 8) | ip6tmp[7];
   3752         } else {
   3753             /* IPv6 case */
   3754             sal_memcpy(vlan_ip.ip6, entry_fields.ip, sizeof(bcm_ip6_t));
   3755             vlan_ip.prefix = entry_fields.prefix;
   3756             vlan_ip.flags |= BCM_VLAN_SUBNET_IP6;
   3757         }
   3758 
   3759         vlan_ip.prefix = entry_fields.prefix;
   3760         vlan_ip.vid = entry_fields.ovid;
   3761         action.new_outer_vlan = entry_fields.ovid;
   3762         action.new_inner_vlan = entry_fields.ivid;
   3763         action.priority = entry_fields.opri;
   3764         if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   3765             action.new_outer_cfi = entry_fields.ocfi;
   3766             action.new_inner_pkt_prio = entry_fields.ipri;
   3767             action.new_inner_cfi = entry_fields.icfi;
   3768         }
   3769          
   3770          /* Read action profile data. */
   3771         _bcm_trx_vlan_action_profile_entry_get(unit, &action, 
   3772                                                entry_fields.profile_idx);
   3773         /* Call traverse callback with the data. */
   3774         rv = cb(unit, &vlan_ip, &action, user_data);
   3775         if (BCM_FAILURE(rv)) {
   3776             soc_cm_sfree(unit, vstab);
   3777             return rv; 
   3778         }
   3779     }
   3780 
   3781     soc_cm_sfree(unit, vstab);
   3782     return rv;
   3783 
   3784 }
   3785 
   3786 /*
   3787  * Function:
   3788  *      bcm_vlan_ip_delete
   3789  * Purpose:
   3790  *      Delete a subnet lookup entry.
   3791  * Parameters:
   3792  *      unit -          device number
   3793  *      vlan_ip -       structure specifying IP address and other info
   3794  * Returns:
   3795  *      BCM_E_XXX
   3796  */
   3797 int
   3798 _bcm_trx_vlan_ip_delete(int unit, bcm_vlan_ip_t *vlan_ip)
   3799 {
   3800     bcm_ip6_t   ip6addr, ip6mask;
   3801 
   3802     BCM_IF_ERROR_RETURN(
   3803         _bcm_trx_vlan_ip_verify(unit, vlan_ip));
   3804 
   3805     BCM_IF_ERROR_RETURN(
   3806         _trx_vlan_ip_addr_mask_get(vlan_ip, ip6addr, ip6mask));
   3807     return _trx_vlan_subnet_entry_delete(unit, ip6addr, ip6mask); 
   3808 }
   3809 
   3810 /*
   3811  * Function:
   3812  *      bcm_vlan_ip_delete_all
   3813  * Purpose:
   3814  *      Delete all subnet lookup entries.
   3815  * Parameters:
   3816  *      unit -          device number
   3817  * Returns:
   3818  *      BCM_E_XXX
   3819  */
   3820 int
   3821 _bcm_trx_vlan_ip_delete_all(int unit)
   3822 {
   3823     int i, nent,  rv;
   3824     uint32 old_profile_idx;
   3825     vlan_subnet_entry_t *vstab, *vsnull,  *vstabp;
   3826 
   3827     rv = _tr_vlan_subnet_mem_read(unit, &vstab, &nent);
   3828     if (BCM_FAILURE(rv)) {
   3829         if (NULL != vstab) {
   3830             soc_cm_sfree(unit, vstab);
   3831         }
   3832         return rv;
   3833     }
   3834 
   3835     vsnull = soc_mem_entry_null(unit, VLAN_SUBNETm);
   3836 
   3837     soc_mem_lock(unit, VLAN_SUBNETm);
   3838     for(i = 0; i < nent; i++) {
   3839         vstabp = soc_mem_table_idx_to_pointer(unit, VLAN_SUBNETm,
   3840                         vlan_subnet_entry_t *, vstab, i);
   3841 
   3842         if (!soc_VLAN_SUBNETm_field32_get(unit, vstabp, VALIDf)) {
   3843             continue;
   3844         }
   3845         old_profile_idx = soc_VLAN_SUBNETm_field32_get(unit, vstabp,
   3846                                                        TAG_ACTION_PROFILE_PTRf);
   3847 
   3848         rv = WRITE_VLAN_SUBNETm(unit, MEM_BLOCK_ANY, i, vsnull);
   3849 
   3850         /* Increment the vlan action profile refcount for the cleared entry */
   3851         _bcm_trx_vlan_action_profile_entry_increment(unit, ing_action_profile_def[unit]);
   3852 
   3853         if (rv >= 0) {
   3854             /* Delete the old vlan action profile entry */
   3855             rv = _bcm_trx_vlan_action_profile_entry_delete(unit, old_profile_idx);
   3856         }
   3857     }
   3858 
   3859     soc_mem_unlock(unit, VLAN_SUBNETm);
   3860     soc_cm_sfree(unit, vstab);
   3861     return rv;
   3862 }
   3863 
   3864 #if defined(BCM_TRIUMPH3_SUPPORT)
   3865 STATIC int 
   3866 _bcm_tr3_vlan_mac_action_add(int                   unit,
   3867                                  bcm_mac_t              mac,
   3868                                  bcm_vlan_action_set_t *action) 
   3869 {
   3870     int rv;
   3871     uint32 profile_idx;
   3872     vlan_xlate_entry_t vxent;
   3873     
   3874     BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action));
   3875     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   3876         if (action->priority == -1) {
   3877             return BCM_E_PARAM;  /* no default priority action to take*/
   3878         }
   3879     }
   3880     BCM_IF_ERROR_RETURN
   3881         (_bcm_trx_vlan_action_profile_entry_add(unit, action, &profile_idx));
   3882 
   3883     sal_memset(&vxent, 0, sizeof(vxent));
   3884     soc_mem_mac_addr_set(unit, VLAN_XLATEm, (uint32 *)(&vxent),
   3885                        VLAN_MAC__MAC_ADDRf, mac);
   3886 
   3887     soc_VLAN_XLATEm_field32_set(unit, &vxent, KEY_TYPEf, 
   3888              TR3_VLXLT_HASH_KEY_TYPE_VLAN_MAC);
   3889     soc_VLAN_XLATEm_field32_set(unit, &vxent, VLAN_MAC__OVIDf, 
   3890                                 action->new_outer_vlan);
   3891     soc_VLAN_XLATEm_field32_set(unit, &vxent, VLAN_MAC__IVIDf, 
   3892                                 action->new_inner_vlan);
   3893     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   3894         soc_VLAN_XLATEm_field32_set(unit, &vxent, VLAN_MAC__OPRIf, 
   3895                                     action->priority);
   3896         soc_VLAN_XLATEm_field32_set(unit, &vxent, VLAN_MAC__OCFIf, 
   3897                                     action->new_outer_cfi);
   3898         soc_VLAN_XLATEm_field32_set(unit, &vxent, VLAN_MAC__IPRIf,
   3899                                     action->new_inner_pkt_prio);
   3900         soc_VLAN_XLATEm_field32_set(unit, &vxent, VLAN_MAC__ICFIf, 
   3901                                     action->new_inner_cfi);
   3902     } else {
   3903         if (action->priority >= BCM_PRIO_MIN &&
   3904             action->priority <= BCM_PRIO_MAX) {
   3905             soc_VLAN_XLATEm_field32_set(unit, &vxent, VLAN_MAC__OPRIf, 
   3906                                         action->priority);
   3907         }
   3908     }
   3909     soc_VLAN_XLATEm_field32_set(unit, &vxent, VALIDf, 1);
   3910     soc_VLAN_XLATEm_field32_set(unit, &vxent, 
   3911                     VLAN_MAC__TAG_ACTION_PROFILE_PTRf, profile_idx);
   3912 
   3913     rv = soc_mem_insert_return_old(unit, VLAN_XLATEm, MEM_BLOCK_ALL, 
   3914                                       &vxent, &vxent);
   3915 
   3916     if (rv == SOC_E_EXISTS) {
   3917         /* Delete the old vlan action profile entry */
   3918         profile_idx = soc_VLAN_XLATEm_field32_get(unit, &vxent,
   3919                                       VLAN_MAC__TAG_ACTION_PROFILE_PTRf);
   3920         rv = _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx);
   3921     }
   3922 
   3923     return rv;
   3924 }
   3925 #endif /* BCM_TRIUMPH3_SUPPORT */
   3926 
   3927 /*
   3928  * Function:
   3929  *      bcm_vlan_mac_action_add
   3930  * Description   :
   3931  *      Add association from MAC address to VLAN.
   3932  *      If the entry already exists, update the action.
   3933  * Parameters   :
   3934  *      unit      (IN) BCM unit number
   3935  *      mac       (IN) MAC address
   3936  *      action    (IN) Action for outer and inner tag
   3937  * Note:
   3938  *   Program VLAN_XLATEm.
   3939  */
   3940 int _bcm_trx_vlan_mac_action_add(int                   unit,
   3941                                  bcm_mac_t              mac,
   3942                                  bcm_vlan_action_set_t *action) 
   3943 {
   3944 #if defined(BCM_TRIUMPH3_SUPPORT)
   3945     if (SOC_IS_TRIUMPH3(unit)) {
   3946         BCM_IF_ERROR_RETURN
   3947             (_bcm_tr3_vlan_mac_action_add(unit,mac,action));
   3948         return BCM_E_NONE;
   3949     } else
   3950 #endif /* BCM_TRIUMPH3_SUPPORT */
   3951     {
   3952     int rv;
   3953     uint32 profile_idx;
   3954     vlan_mac_entry_t vment;
   3955 
   3956     BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action));
   3957     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   3958         if (action->priority == -1) {
   3959             return BCM_E_PARAM;  /* no default priority action to take*/
   3960         }
   3961     }
   3962 
   3963     BCM_IF_ERROR_RETURN
   3964         (_bcm_trx_vlan_action_profile_entry_add(unit, action, &profile_idx));
   3965 
   3966     sal_memset(&vment, 0, sizeof(vment));
   3967     soc_VLAN_MACm_mac_addr_set(unit, &vment, MAC_ADDRf, mac);
   3968     soc_VLAN_MACm_field32_set(unit, &vment, KEY_TYPEf,
   3969                               TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC);
   3970     soc_VLAN_MACm_field32_set(unit, &vment, OVIDf, action->new_outer_vlan);
   3971     soc_VLAN_MACm_field32_set(unit, &vment, IVIDf, action->new_inner_vlan);
   3972     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   3973         soc_VLAN_MACm_field32_set(unit, &vment, OPRIf, action->priority);
   3974         soc_VLAN_MACm_field32_set(unit, &vment, OCFIf, action->new_outer_cfi);
   3975         soc_VLAN_MACm_field32_set(unit, &vment, IPRIf,
   3976                                   action->new_inner_pkt_prio);
   3977         soc_VLAN_MACm_field32_set(unit, &vment, ICFIf, action->new_inner_cfi);
   3978     } else {
   3979         if (action->priority >= BCM_PRIO_MIN &&
   3980             action->priority <= BCM_PRIO_MAX) {
   3981             soc_VLAN_MACm_field32_set(unit, &vment, PRIf, action->priority);
   3982         }
   3983     }
   3984     soc_VLAN_MACm_field32_set(unit, &vment, TAG_ACTION_PROFILE_PTRf, 
   3985                               profile_idx);
   3986     if (SOC_MEM_FIELD_VALID(unit, VLAN_MACm, VLAN_ACTION_VALIDf)) {
   3987         soc_VLAN_MACm_field32_set(unit, &vment, VLAN_ACTION_VALIDf, 1);
   3988     }
   3989     soc_VLAN_MACm_field32_set(unit, &vment, VALIDf, 1);
   3990 
   3991     rv = soc_mem_insert_return_old(unit, VLAN_MACm, MEM_BLOCK_ALL, &vment, &vment);
   3992 
   3993     if (rv == SOC_E_EXISTS) {
   3994         /* Delete the old vlan action profile entry */
   3995         profile_idx = soc_VLAN_MACm_field32_get(unit, &vment,
   3996                                                 TAG_ACTION_PROFILE_PTRf);
   3997         rv = _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx);
   3998     }
   3999 
   4000     return rv;
   4001     }
   4002 }
   4003 
   4004 #if defined(BCM_TRIUMPH3_SUPPORT)
   4005 STATIC int 
   4006 _bcm_tr3_vlan_mac_action_get(int unit, bcm_mac_t  mac,
   4007                              bcm_vlan_action_set_t *action) 
   4008 {
   4009     vlan_xlate_entry_t vxent;             /* Lookup key hw buffer.      */
   4010     vlan_xlate_entry_t res_vxent;         /* Lookup result buffer.      */
   4011     uint32 profile_idx;                 /* Vlan action profile index. */
   4012     int rv;                             /* Operation return status.   */
   4013     int idx = 0;                        /* Lookup result entry index. */
   4014 
   4015     /* Input parameters check. */
   4016     if (NULL == action) {
   4017         return (BCM_E_PARAM);
   4018     }
   4019 
   4020     /* Reset lookup key and result destination buffer. */
   4021     sal_memset(&vxent, 0, sizeof(vlan_xlate_entry_t));
   4022     sal_memset(&res_vxent, 0, sizeof(vlan_xlate_entry_t));
   4023 
   4024     /* Initialize lookup key. */
   4025     soc_mem_mac_addr_set(unit, VLAN_XLATEm, (uint32 *)(&vxent),
   4026                        VLAN_MAC__MAC_ADDRf, mac);
   4027 
   4028     soc_VLAN_XLATEm_field32_set(unit, &vxent, KEY_TYPEf,
   4029                               TR3_VLXLT_HASH_KEY_TYPE_VLAN_MAC);
   4030 
   4031     /* Perform VLAN_MAC table search by mac address. */
   4032     soc_mem_lock(unit, VLAN_XLATEm);
   4033     rv = soc_mem_search(unit, VLAN_XLATEm, MEM_BLOCK_ALL, &idx, 
   4034                         &vxent, &res_vxent, 0);
   4035     soc_mem_unlock(unit, VLAN_XLATEm);
   4036     BCM_IF_ERROR_RETURN(rv);
   4037 
   4038     action->new_outer_vlan =
   4039         soc_VLAN_XLATEm_field32_get(unit, &res_vxent, VLAN_MAC__OVIDf);
   4040     action->new_inner_vlan =
   4041         soc_VLAN_XLATEm_field32_get(unit, &res_vxent, VLAN_MAC__IVIDf);
   4042     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   4043         action->priority = soc_VLAN_XLATEm_field32_get(unit, &res_vxent, 
   4044                                     VLAN_MAC__OPRIf);
   4045         action->new_outer_cfi =
   4046             soc_VLAN_XLATEm_field32_get(unit, &res_vxent, VLAN_MAC__OCFIf);
   4047         action->new_inner_pkt_prio =
   4048             soc_VLAN_XLATEm_field32_get(unit, &res_vxent, VLAN_MAC__IPRIf);
   4049         action->new_inner_cfi =
   4050             soc_VLAN_XLATEm_field32_get(unit, &res_vxent, VLAN_MAC__ICFIf);
   4051     } else {
   4052         action->priority = soc_VLAN_XLATEm_field32_get(unit, &res_vxent, 
   4053                                    VLAN_MAC__OPRIf);
   4054     }
   4055 
   4056     /* Read action profile data. */
   4057     profile_idx = soc_VLAN_XLATEm_field32_get(unit, &res_vxent, 
   4058                                    VLAN_MAC__TAG_ACTION_PROFILE_PTRf);
   4059     _bcm_trx_vlan_action_profile_entry_get(unit, action, profile_idx);
   4060 
   4061     return (BCM_E_NONE);
   4062 }
   4063 #endif /* BCM_TRIUMPH3_SUPPORT */
   4064 
   4065 /*
   4066  * Function:
   4067  *      _bcm_trx_vlan_mac_action_get
   4068  * Description   :
   4069  *      Get association from MAC address to VLAN tag actions.
   4070  * Parameters   :
   4071  *      unit      (IN) BCM unit number
   4072  *      mac       (IN) MAC address
   4073  *      action    (OUT) Action for outer and inner tag
   4074  * Returns:
   4075  *      BCM_E_XXX
   4076  */
   4077 int 
   4078 _bcm_trx_vlan_mac_action_get(int unit, bcm_mac_t  mac,
   4079                              bcm_vlan_action_set_t *action) 
   4080 {
   4081 #if defined(BCM_TRIUMPH3_SUPPORT)
   4082     if (SOC_IS_TRIUMPH3(unit)) {
   4083         BCM_IF_ERROR_RETURN
   4084             (_bcm_tr3_vlan_mac_action_get(unit,mac,action));
   4085         return BCM_E_NONE;
   4086     } else
   4087 #endif /* BCM_TRIUMPH3_SUPPORT */
   4088     {
   4089     vlan_mac_entry_t vment;             /* Lookup key hw buffer.      */
   4090     vlan_mac_entry_t res_vment;         /* Lookup result buffer.      */
   4091     uint32 profile_idx;                 /* Vlan action profile index. */
   4092     int rv;                             /* Operation return status.   */
   4093     int idx = 0;                        /* Lookup result entry index. */
   4094 
   4095     /* Input parameters check. */
   4096     if (NULL == action) {
   4097         return (BCM_E_PARAM);
   4098     }
   4099 
   4100     /* Reset lookup key and result destination buffer. */
   4101     sal_memset(&vment, 0, sizeof(vlan_mac_entry_t));
   4102     sal_memset(&res_vment, 0, sizeof(vlan_mac_entry_t));
   4103 
   4104     /* Initialize lookup key. */
   4105     soc_VLAN_MACm_mac_addr_set(unit, &vment, MAC_ADDRf, mac);
   4106     soc_VLAN_MACm_field32_set(unit, &vment, KEY_TYPEf,
   4107                               TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC);
   4108 
   4109     /* Perform VLAN_MAC table search by mac address. */
   4110     soc_mem_lock(unit, VLAN_MACm);
   4111     rv = soc_mem_search(unit, VLAN_MACm, MEM_BLOCK_ALL, &idx, 
   4112                         &vment, &res_vment, 0);
   4113     soc_mem_unlock(unit, VLAN_MACm);
   4114     BCM_IF_ERROR_RETURN(rv);
   4115 
   4116     action->new_outer_vlan =
   4117         soc_VLAN_MACm_field32_get(unit, &res_vment, OVIDf);
   4118     action->new_inner_vlan =
   4119         soc_VLAN_MACm_field32_get(unit, &res_vment, IVIDf);
   4120     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   4121         action->priority = soc_VLAN_MACm_field32_get(unit, &res_vment, OPRIf);
   4122         action->new_outer_cfi =
   4123             soc_VLAN_MACm_field32_get(unit, &res_vment, OCFIf);
   4124         action->new_inner_pkt_prio =
   4125             soc_VLAN_MACm_field32_get(unit, &res_vment, IPRIf);
   4126         action->new_inner_cfi =
   4127             soc_VLAN_MACm_field32_get(unit, &res_vment, ICFIf);
   4128     } else {
   4129         action->priority = soc_VLAN_MACm_field32_get(unit, &res_vment, PRIf);
   4130     }
   4131 
   4132     /* Read action profile data. */
   4133     profile_idx =
   4134         soc_VLAN_MACm_field32_get(unit, &res_vment, TAG_ACTION_PROFILE_PTRf);
   4135     _bcm_trx_vlan_action_profile_entry_get(unit, action, profile_idx);
   4136 
   4137     return (BCM_E_NONE);
   4138     }
   4139 }
   4140 
   4141 #if defined(BCM_TRIUMPH3_SUPPORT)
   4142 STATIC int
   4143 _bcm_tr3_vlan_mac_delete(int unit, bcm_mac_t mac)
   4144 {
   4145     vlan_xlate_entry_t  vxent;
   4146     int rv;
   4147     uint32 profile_idx;
   4148 
   4149     sal_memset(&vxent, 0, sizeof(vxent));
   4150     soc_mem_mac_addr_set(unit, VLAN_XLATEm, (uint32 *)(&vxent),
   4151                        VLAN_MAC__MAC_ADDRf, mac);
   4152     soc_VLAN_XLATEm_field32_set(unit, &vxent, KEY_TYPEf,
   4153                               TR3_VLXLT_HASH_KEY_TYPE_VLAN_MAC);
   4154     soc_mem_lock(unit, VLAN_XLATEm);
   4155     rv = soc_mem_delete_return_old(unit, VLAN_XLATEm, MEM_BLOCK_ALL,
   4156                                    &vxent, &vxent);
   4157     soc_mem_unlock(unit, VLAN_XLATEm);
   4158     if (rv == SOC_E_NOT_FOUND) {
   4159         rv = SOC_E_NONE;
   4160     } else if ((rv == SOC_E_NONE) && soc_VLAN_XLATEm_field32_get(unit, 
   4161                &vxent, VALIDf)) {
   4162         profile_idx = soc_VLAN_XLATEm_field32_get(unit, &vxent,
   4163                                                 VLAN_MAC__TAG_ACTION_PROFILE_PTRf);
   4164         /* Delete the old vlan action profile entry */
   4165         rv = _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx);
   4166     }
   4167     return rv;
   4168 }
   4169 #endif /* BCM_TRIUMPH3_SUPPORT */
   4170 
   4171 /*
   4172  * Function:
   4173  *      bcm_vlan_mac_delete
   4174  * Purpose:
   4175  *      Delete a vlan mac lookup entry.
   4176  * Parameters:
   4177  *      unit      (IN) BCM unit number
   4178  *      mac       (IN) MAC address
   4179  * Returns:
   4180  *      BCM_E_XXX
   4181  */
   4182 int
   4183 _bcm_trx_vlan_mac_delete(int unit, bcm_mac_t mac) 
   4184 {
   4185 #if defined(BCM_TRIUMPH3_SUPPORT)
   4186     if (SOC_IS_TRIUMPH3(unit)) {
   4187         BCM_IF_ERROR_RETURN
   4188             (_bcm_tr3_vlan_mac_delete(unit,mac));
   4189         return BCM_E_NONE;
   4190     } else
   4191 #endif /* BCM_TRIUMPH3_SUPPORT */
   4192     {
   4193     vlan_mac_entry_t  vment;
   4194     int rv; 
   4195     uint32 profile_idx;
   4196 
   4197     sal_memset(&vment, 0, sizeof(vment));
   4198     soc_VLAN_MACm_mac_addr_set(unit, &vment, MAC_ADDRf, mac);
   4199     soc_VLAN_MACm_field32_set(unit, &vment, KEY_TYPEf,
   4200                               TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC);
   4201     soc_mem_lock(unit, VLAN_MACm);
   4202     rv = soc_mem_delete_return_old(unit, VLAN_MACm, MEM_BLOCK_ALL,
   4203                                    &vment, &vment);
   4204     soc_mem_unlock(unit, VLAN_MACm);
   4205     if (rv == SOC_E_NOT_FOUND) {
   4206         rv = SOC_E_NONE;
   4207     } else if ((rv == SOC_E_NONE) && soc_VLAN_MACm_field32_get(unit, &vment, VALIDf)) {
   4208         profile_idx = soc_VLAN_MACm_field32_get(unit, &vment,
   4209                                                 TAG_ACTION_PROFILE_PTRf);       
   4210         /* Delete the old vlan action profile entry */
   4211         rv = _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx);
   4212     }
   4213     return rv;
   4214     }
   4215 }
   4216 
   4217 #if defined(BCM_TRIUMPH3_SUPPORT)
   4218 STATIC int
   4219 _bcm_tr3_vlan_mac_delete_all(int unit) 
   4220 {
   4221     int i, imin, imax, nent, vmbytes, rv;
   4222     uint32 old_profile_idx;
   4223     vlan_xlate_entry_t *vxtab, *vmnull, *vxtabp;
   4224     
   4225     imin = soc_mem_index_min(unit, VLAN_XLATEm);
   4226     imax = soc_mem_index_max(unit, VLAN_XLATEm);
   4227     nent = soc_mem_index_count(unit, VLAN_XLATEm);
   4228     vmbytes = soc_mem_entry_words(unit, VLAN_XLATEm);
   4229     vmbytes = WORDS2BYTES(vmbytes);
   4230 
   4231     vxtab = soc_cm_salloc(unit, nent * vmbytes, "vlan_xlate");
   4232 
   4233     if (vxtab == NULL) {
   4234         return BCM_E_MEMORY;
   4235     }
   4236     
   4237     vmnull = soc_mem_entry_null(unit, VLAN_XLATEm);
   4238 
   4239     soc_mem_lock(unit, VLAN_XLATEm);
   4240     rv = soc_mem_read_range(unit, VLAN_XLATEm, MEM_BLOCK_ANY,
   4241                             imin, imax, vxtab);
   4242     if (rv < 0) {
   4243         soc_mem_unlock(unit, VLAN_XLATEm);
   4244         soc_cm_sfree(unit, vxtab);
   4245         return rv; 
   4246     }
   4247     
   4248     for(i = 0; i < nent; i++) {
   4249         vxtabp = soc_mem_table_idx_to_pointer(unit, VLAN_XLATEm,
   4250                         vlan_xlate_entry_t *, vxtab, i);
   4251 
   4252         if (!soc_VLAN_XLATEm_field32_get(unit, vxtabp, VALIDf) ||
   4253             (soc_VLAN_XLATEm_field32_get(unit, vxtabp, KEY_TYPEf) !=
   4254              TR3_VLXLT_HASH_KEY_TYPE_VLAN_MAC)) {
   4255             continue;
   4256         }
   4257         old_profile_idx = soc_VLAN_XLATEm_field32_get(unit, vxtabp,
   4258                                                       VLAN_MAC__TAG_ACTION_PROFILE_PTRf);
   4259 
   4260         rv = WRITE_VLAN_XLATEm(unit, MEM_BLOCK_ANY, i, vmnull);
   4261 
   4262         if (rv >= 0) {
   4263             /* Delete the old vlan action profile entry */
   4264             rv = _bcm_trx_vlan_action_profile_entry_delete(unit, old_profile_idx);
   4265         }
   4266     }
   4267     
   4268     soc_mem_unlock(unit, VLAN_XLATEm);
   4269     soc_cm_sfree(unit, vxtab);
   4270     return rv;
   4271 }
   4272 #endif /* BCM_TRIUMPH3_SUPPORT */
   4273 
   4274 /*
   4275  * Function:
   4276  *      bcm_vlan_mac_delete_all
   4277  * Purpose:
   4278  *      Delete all vlan mac lookup entries.
   4279  * Parameters:
   4280  *      unit      (IN) BCM unit number
   4281  * Returns:
   4282  *      BCM_E_XXX
   4283  */
   4284 int
   4285 _bcm_trx_vlan_mac_delete_all(int unit) 
   4286 {
   4287 #if defined(BCM_TRIUMPH3_SUPPORT)
   4288     if (SOC_IS_TRIUMPH3(unit)) {
   4289         BCM_IF_ERROR_RETURN
   4290             (_bcm_tr3_vlan_mac_delete_all(unit));
   4291         return BCM_E_NONE;
   4292     } else
   4293 #endif /* BCM_TRIUMPH3_SUPPORT */
   4294 #if defined(BCM_TRIDENT3_SUPPORT)
   4295     if (SOC_IS_TRIDENT3X(unit)) {
   4296         BCM_IF_ERROR_RETURN
   4297             (_bcm_td3_vlan_mac_delete_all(unit));
   4298         return BCM_E_NONE;
   4299     } else
   4300 #endif /* BCM_TRIDENT3_SUPPORT */
   4301 
   4302     {
   4303     int i, imin, imax, nent, vmbytes, rv;
   4304     uint32 old_profile_idx;
   4305     vlan_mac_entry_t *vmtab, *vmnull, *vmtabp;
   4306     
   4307     imin = soc_mem_index_min(unit, VLAN_MACm);
   4308     imax = soc_mem_index_max(unit, VLAN_MACm);
   4309     nent = soc_mem_index_count(unit, VLAN_MACm);
   4310     vmbytes = soc_mem_entry_words(unit, VLAN_MACm);
   4311     vmbytes = WORDS2BYTES(vmbytes);
   4312 
   4313     vmtab = soc_cm_salloc(unit, nent * vmbytes, "vlan_mac");
   4314 
   4315     if (vmtab == NULL) {
   4316         return BCM_E_MEMORY;
   4317     }
   4318     
   4319     vmnull = soc_mem_entry_null(unit, VLAN_MACm);
   4320 
   4321     soc_mem_lock(unit, VLAN_MACm);
   4322     rv = soc_mem_read_range(unit, VLAN_MACm, MEM_BLOCK_ANY,
   4323                             imin, imax, vmtab);
   4324     soc_mem_unlock(unit, VLAN_MACm);
   4325 
   4326     if (rv < 0) {
   4327         soc_cm_sfree(unit, vmtab);
   4328         return rv; 
   4329     }
   4330 
   4331     soc_mem_lock(unit, VLAN_MACm);
   4332     for(i = 0; i < nent; i++) {
   4333         vmtabp = soc_mem_table_idx_to_pointer(unit, VLAN_MACm,
   4334                         vlan_mac_entry_t *, vmtab, i);
   4335 
   4336         if (!soc_VLAN_MACm_field32_get(unit, vmtabp, VALIDf) ||
   4337             (soc_VLAN_MACm_field32_get(unit, vmtabp, KEY_TYPEf) !=
   4338              TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC)) {
   4339             continue;
   4340         }
   4341         old_profile_idx = soc_VLAN_MACm_field32_get(unit, vmtabp,
   4342                                                     TAG_ACTION_PROFILE_PTRf);
   4343 
   4344         rv = WRITE_VLAN_MACm(unit, MEM_BLOCK_ANY, i, vmnull);
   4345 
   4346         if (rv >= 0) {
   4347             /* Delete the old vlan action profile entry */
   4348             rv = _bcm_trx_vlan_action_profile_entry_delete(unit, old_profile_idx);
   4349         }
   4350     }
   4351     
   4352     soc_mem_unlock(unit, VLAN_MACm);
   4353     soc_cm_sfree(unit, vmtab);
   4354     return rv;
   4355     }
   4356 }
   4357 
   4358 #if defined(BCM_TRIUMPH3_SUPPORT)
   4359 STATIC int 
   4360 _bcm_tr3_vlan_mac_action_traverse(int unit, 
   4361                                   bcm_vlan_mac_action_traverse_cb cb, 
   4362                                   void *user_data)
   4363 {
   4364     int idx, imin, imax, nent, vmbytes, rv;
   4365     uint32 profile_idx;
   4366     bcm_mac_t  mac;
   4367     bcm_vlan_action_set_t action;
   4368     vlan_xlate_entry_t * vxtab, *vxtabp;
   4369     
   4370     /* Input parameters check. */
   4371     if (NULL == cb) {
   4372         return (BCM_E_PARAM);
   4373     }
   4374 
   4375     imin = soc_mem_index_min(unit, VLAN_XLATEm);
   4376     imax = soc_mem_index_max(unit, VLAN_XLATEm);
   4377     nent = soc_mem_index_count(unit, VLAN_XLATEm);
   4378     vmbytes = soc_mem_entry_words(unit, VLAN_XLATEm);
   4379     vmbytes = WORDS2BYTES(vmbytes);
   4380     vxtab = soc_cm_salloc(unit, nent * sizeof(*vxtab), "vlan_xlate");
   4381 
   4382     if (vxtab == NULL) {
   4383         return BCM_E_MEMORY;
   4384     }
   4385     
   4386     soc_mem_lock(unit, VLAN_XLATEm);
   4387     rv = soc_mem_read_range(unit, VLAN_XLATEm, MEM_BLOCK_ANY,
   4388                             imin, imax, vxtab);
   4389     if (BCM_FAILURE(rv)) {
   4390         soc_mem_unlock(unit, VLAN_XLATEm);
   4391         soc_cm_sfree(unit, vxtab);
   4392         return rv; 
   4393     }
   4394     
   4395     for(idx = 0; idx < nent; idx++) {
   4396         sal_memset(mac, 0, sizeof(bcm_mac_t));
   4397         sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t));
   4398         vxtabp = soc_mem_table_idx_to_pointer(unit, VLAN_XLATEm,
   4399                                               vlan_xlate_entry_t *, 
   4400                                               vxtab, idx);
   4401 
   4402         if ((0 == soc_VLAN_XLATEm_field32_get(unit, vxtabp, VALIDf)) ||
   4403             (TR3_VLXLT_HASH_KEY_TYPE_VLAN_MAC !=
   4404              soc_VLAN_XLATEm_field32_get(unit, vxtabp, KEY_TYPEf))) {
   4405             continue;
   4406         }
   4407 
   4408         /* Get entry mac address. */
   4409         soc_mem_mac_addr_get(unit, VLAN_XLATEm, (uint32 *)vxtabp, 
   4410                      VLAN_MAC__MAC_ADDRf, mac);
   4411 
   4412         action.new_outer_vlan =
   4413             soc_VLAN_XLATEm_field32_get(unit, vxtabp, VLAN_MAC__OVIDf);
   4414         action.new_inner_vlan =
   4415             soc_VLAN_XLATEm_field32_get(unit, vxtabp, VLAN_MAC__IVIDf);
   4416         if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   4417             action.priority = soc_VLAN_XLATEm_field32_get(unit, vxtabp, VLAN_MAC__OPRIf);
   4418             action.new_outer_cfi =
   4419                 soc_VLAN_XLATEm_field32_get(unit, vxtabp, VLAN_MAC__OCFIf);
   4420             action.new_inner_pkt_prio =
   4421                 soc_VLAN_XLATEm_field32_get(unit, vxtabp, VLAN_MAC__IPRIf);
   4422             action.new_inner_cfi =
   4423                 soc_VLAN_XLATEm_field32_get(unit, vxtabp, VLAN_MAC__ICFIf);
   4424         } else {
   4425             action.priority =
   4426                 soc_VLAN_XLATEm_field32_get(unit, vxtabp, VLAN_MAC__OPRIf);
   4427         }
   4428 
   4429         /* Read action profile data. */
   4430         profile_idx =
   4431             soc_VLAN_XLATEm_field32_get(unit, vxtabp, 
   4432                                       VLAN_MAC__TAG_ACTION_PROFILE_PTRf);
   4433         _bcm_trx_vlan_action_profile_entry_get(unit, &action, profile_idx);
   4434 
   4435         /* Call traverse callback with the data. */
   4436         rv = cb(unit, mac, &action, user_data);
   4437         if (BCM_FAILURE(rv)) {
   4438             soc_mem_unlock(unit, VLAN_XLATEm);
   4439             soc_cm_sfree(unit, vxtab);
   4440             return rv; 
   4441         }
   4442     }
   4443     
   4444     soc_mem_unlock(unit, VLAN_XLATEm);
   4445     soc_cm_sfree(unit, vxtab);
   4446     return rv;
   4447 }
   4448 #endif /* BCM_TRIUMPH3_SUPPORT */
   4449 
   4450 /*
   4451  * Function:
   4452  *      _bcm_trx_vlan_mac_action_traverse
   4453  * Description   :
   4454  *      Traverse over vlan mac actions, which are used for VLAN
   4455  *      tag/s assignment to untagged packets.
   4456  * Parameters   :
   4457  *      unit            (IN) BCM unit number
   4458  *      cb              (IN) Call back function
   4459  *      user_data       (IN) User provided data to pass to a call back
   4460  * Returns:
   4461  *      BCM_E_XXX
   4462  */
   4463 int 
   4464 _bcm_trx_vlan_mac_action_traverse(int unit, 
   4465                                   bcm_vlan_mac_action_traverse_cb cb, 
   4466                                   void *user_data)
   4467 {
   4468 #if defined(BCM_TRIUMPH3_SUPPORT)
   4469     if (SOC_IS_TRIUMPH3(unit)) {
   4470         BCM_IF_ERROR_RETURN
   4471             (_bcm_tr3_vlan_mac_action_traverse(unit,cb,user_data));
   4472         return BCM_E_NONE;
   4473     } else
   4474 #endif /* BCM_TRIUMPH3_SUPPORT */
   4475     {
   4476     int idx, imin, imax, nent, vmbytes, rv;
   4477     uint32 profile_idx;
   4478     bcm_mac_t  mac;
   4479     bcm_vlan_action_set_t action;
   4480     vlan_mac_entry_t * vmtab, *vmtabp;
   4481     
   4482     /* Input parameters check. */
   4483     if (NULL == cb) {
   4484         return (BCM_E_PARAM);
   4485     }
   4486 
   4487     imin = soc_mem_index_min(unit, VLAN_MACm);
   4488     imax = soc_mem_index_max(unit, VLAN_MACm);
   4489     nent = soc_mem_index_count(unit, VLAN_MACm);
   4490     vmbytes = soc_mem_entry_words(unit, VLAN_MACm);
   4491     vmbytes = WORDS2BYTES(vmbytes);
   4492     vmtab = soc_cm_salloc(unit, nent * sizeof(*vmtab), "vlan_mac");
   4493 
   4494     if (vmtab == NULL) {
   4495         return BCM_E_MEMORY;
   4496     }
   4497     
   4498     soc_mem_lock(unit, VLAN_MACm);
   4499     rv = soc_mem_read_range(unit, VLAN_MACm, MEM_BLOCK_ANY,
   4500                             imin, imax, vmtab);
   4501     if (BCM_FAILURE(rv)) {
   4502         soc_mem_unlock(unit, VLAN_MACm);
   4503         soc_cm_sfree(unit, vmtab);
   4504         return rv; 
   4505     }
   4506     
   4507     for(idx = 0; idx < nent; idx++) {
   4508         sal_memset(mac, 0, sizeof(bcm_mac_t));
   4509         sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t));
   4510         vmtabp = soc_mem_table_idx_to_pointer(unit, VLAN_MACm,
   4511                                               vlan_mac_entry_t *, 
   4512                                               vmtab, idx);
   4513 
   4514         if ((0 == soc_VLAN_MACm_field32_get(unit, vmtabp, VALIDf)) ||
   4515             (TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC !=
   4516              soc_VLAN_MACm_field32_get(unit, vmtabp, KEY_TYPEf))) {
   4517             continue;
   4518         }
   4519 
   4520         /* Get entry mac address. */
   4521         soc_VLAN_MACm_mac_addr_get(unit, vmtabp, MAC_ADDRf, mac);
   4522 
   4523         action.new_outer_vlan =
   4524             soc_VLAN_MACm_field32_get(unit, vmtabp, OVIDf);
   4525         action.new_inner_vlan =
   4526             soc_VLAN_MACm_field32_get(unit, vmtabp, IVIDf);
   4527         if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   4528             action.priority = soc_VLAN_MACm_field32_get(unit, vmtabp, OPRIf);
   4529             action.new_outer_cfi =
   4530                 soc_VLAN_MACm_field32_get(unit, vmtabp, OCFIf);
   4531             action.new_inner_pkt_prio =
   4532                 soc_VLAN_MACm_field32_get(unit, vmtabp, IPRIf);
   4533             action.new_inner_cfi =
   4534                 soc_VLAN_MACm_field32_get(unit, vmtabp, ICFIf);
   4535         } else {
   4536             action.priority =
   4537                 soc_VLAN_MACm_field32_get(unit, vmtabp, PRIf);
   4538         }
   4539 
   4540         /* Read action profile data. */
   4541         profile_idx =
   4542             soc_VLAN_MACm_field32_get(unit, vmtabp, TAG_ACTION_PROFILE_PTRf);
   4543         _bcm_trx_vlan_action_profile_entry_get(unit, &action, profile_idx);
   4544 
   4545         /* Call traverse callback with the data. */
   4546         rv = cb(unit, mac, &action, user_data);
   4547         if (BCM_FAILURE(rv)) {
   4548             soc_mem_unlock(unit, VLAN_MACm);
   4549             soc_cm_sfree(unit, vmtab);
   4550             return rv; 
   4551         }
   4552     }
   4553     
   4554     soc_mem_unlock(unit, VLAN_MACm);
   4555     soc_cm_sfree(unit, vmtab);
   4556     return rv;
   4557     }
   4558 }
   4559 
   4560 /*
   4561  * Function:
   4562  *      _bcm_trx_vif_vlan_translate_entry_parse
   4563  * Purpose:
   4564  *      Parses vlan translate entry by given key_type, for inner and outer vlans
   4565  * Parameters: 
   4566  *      unit            (IN) BCM unit number
   4567  *      mem             (IN) Vlan translate memory id.
   4568  *      vent            (IN) vlan translate entry to parse
   4569  *      action          (OUT) Action to fill
   4570  * Returns:
   4571  *      BCM_E_XXX
   4572  */     
   4573 STATIC int
   4574 _bcm_trx_vif_vlan_translate_entry_parse(int unit, soc_mem_t mem, uint32 *vent,
   4575                                    bcm_vlan_action_set_t *action)
   4576 {
   4577 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
   4578     if (soc_feature(unit, soc_feature_niv)) {
   4579         action->new_outer_vlan = soc_mem_field32_get(unit, VLAN_XLATEm,
   4580                          vent, VIF__NEW_OVIDf);
   4581         action->new_inner_vlan = soc_mem_field32_get (unit, VLAN_XLATEm,
   4582                          vent, VIF__NEW_IVIDf);
   4583     
   4584         if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   4585             action->priority = soc_mem_field32_get(unit, VLAN_XLATEm,
   4586                                 vent, VIF__NEW_OPRIf);
   4587             action->new_outer_cfi = soc_mem_field32_get(unit, VLAN_XLATEm,
   4588                      vent, VIF__NEW_OCFIf);
   4589             action->new_inner_pkt_prio = soc_mem_field32_get(unit, VLAN_XLATEm,
   4590                      vent, VIF__NEW_IPRIf);
   4591             action->new_inner_cfi = soc_mem_field32_get(unit, VLAN_XLATEm,
   4592                      vent, VIF__NEW_ICFIf);
   4593         } else {
   4594             action->priority = soc_mem_field32_get(unit, VLAN_XLATEm,
   4595                            vent, VIF__PRIf);
   4596         }
   4597 
   4598         if (SOC_MEM_FIELD_VALID(unit, VLAN_XLATEm, VIF__L3_IIF_VALIDf) &&
   4599             soc_mem_field32_get(unit, VLAN_XLATEm, vent, VIF__L3_IIF_VALIDf)) {
   4600             action->ingress_if = soc_mem_field32_get(unit, VLAN_XLATEm,
   4601                                                      vent, VIF__L3_IIFf);
   4602         }
   4603         return BCM_E_NONE;
   4604     }
   4605 #endif   /* defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) */
   4606     return BCM_E_UNAVAIL;
   4607 }
   4608 
   4609 /*
   4610  * Function:
   4611  *      _bcm_trx_vlan_translate_entry_parse
   4612  * Purpose:
   4613  *      Parses vlan translate entry by given key_type, for inner and outer vlans
   4614  * Parameters:
   4615  *      unit            (IN) BCM unit number
   4616  *      mem             (IN) Vlan translate memory id.
   4617  *      vent            (IN) vlan translate entry to parse
   4618  *      action          (OUT) Action to fill
   4619  * Returns:
   4620  *      BCM_E_XXX
   4621  */
   4622 STATIC int 
   4623 _bcm_trx_vlan_translate_entry_parse(int unit, soc_mem_t mem, uint32 *vent,
   4624                                    bcm_vlan_action_set_t *action)
   4625 {
   4626 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
   4627     defined(BCM_APACHE_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
   4628     int offset = 0, index = 0;
   4629 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT ||
   4630           BCM_APACHE_SUPPORT || BCM_GREYHOUND2_SUPPORT */
   4631     if ((NULL == vent) || (NULL == action) || (INVALIDm == mem)) {
   4632         return BCM_E_PARAM;
   4633     }
   4634 
   4635     action->new_outer_vlan = soc_mem_field32_get(unit, mem, vent, NEW_OVIDf);
   4636     action->new_inner_vlan = soc_mem_field32_get (unit, mem, vent, NEW_IVIDf);
   4637 
   4638     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   4639         action->priority = soc_mem_field32_get(unit, mem, vent, NEW_OPRIf);
   4640         action->new_outer_cfi =
   4641             soc_mem_field32_get(unit, mem, vent, NEW_OCFIf);
   4642         action->new_inner_pkt_prio =
   4643             soc_mem_field32_get(unit, mem, vent, NEW_IPRIf);
   4644         action->new_inner_cfi =
   4645             soc_mem_field32_get(unit, mem, vent, NEW_ICFIf);
   4646     } else {
   4647         action->priority = soc_mem_field32_get(unit, mem, vent, PRIf);
   4648     }
   4649 
   4650     if (SOC_MEM_FIELD_VALID(unit, mem, DISABLE_VLAN_CHECKSf) &&
   4651         soc_mem_field32_get(unit, mem, vent, DISABLE_VLAN_CHECKSf)) {
   4652         action->flags |= BCM_VLAN_ACTION_SET_VLAN_CHECKS_DISABLE;
   4653     }
   4654 
   4655 #if defined(BCM_TSN_SR_SUPPORT)
   4656     if (soc_feature(unit, soc_feature_tsn_sr)) {
   4657         if (soc_mem_field32_get(unit, mem, vent, SR_ENABLEf)) {
   4658             action->flags |= BCM_VLAN_ACTION_SET_SR_ENABLE;
   4659             if (soc_mem_field32_get(unit, mem, vent, SR_LAN_IDf)) {
   4660                 action->flags |= BCM_VLAN_ACTION_SET_SR_LAN_ID;
   4661             }
   4662         }
   4663     }
   4664 #endif /* BCM_TSN_SR_SUPPORT*/
   4665 
   4666 #if defined(BCM_TSN_SUPPORT)
   4667     if (soc_feature(unit, soc_feature_tsn_taf) &&
   4668         SOC_MEM_FIELD_VALID(unit, mem, TAF_GATE_ID_PROFILEf)) {
   4669         uint32 value =
   4670             soc_mem_field32_get(unit, mem, vent, TAF_GATE_ID_PROFILEf);
   4671         if (0 != value) {
   4672             bcm_tsn_pri_map_t sw_index;
   4673 
   4674             BCM_IF_ERROR_RETURN(
   4675                 bcmi_esw_tsn_pri_map_map_id_get(unit, bcmTsnPriMapTypeTafGate,
   4676                                                 value, &sw_index));
   4677             action->taf_gate_primap = sw_index;
   4678         } else {
   4679             action->taf_gate_primap = BCM_TSN_PRI_MAP_INVALID;
   4680         }
   4681     } else
   4682 #endif /* BCM_TSN_SUPPORT */
   4683     {
   4684         action->taf_gate_primap = BCM_TSN_PRI_MAP_INVALID;
   4685     }
   4686 
   4687     if (SOC_IS_TR_VL(unit) && (!(SOC_IS_HURRICANE(unit) || 
   4688         SOC_IS_HURRICANE2(unit)))) {
   4689         if (SOC_MEM_FIELD_VALID(unit, mem, MPLS_ACTIONf)) {
   4690             if (soc_mem_field32_get(unit, mem, vent, MPLS_ACTIONf) == 0x2) {
   4691                 action->ingress_if = 
   4692                    soc_mem_field32_get(unit, mem, vent, L3_IIFf);
   4693             }
   4694 #if defined(BCM_TRIDENT2_SUPPORT)
   4695             else if (soc_mem_field32_get(unit, mem, vent, MPLS_ACTIONf) == 0x3) {
   4696                 if (soc_feature(unit, soc_feature_vlan_xlate_iif_with_dummy_vp) &&
   4697                     soc_property_get(unit, spn_VLAN_ACTION_DUMMY_VP_RESERVED, 0) &&
   4698                     soc_mem_field32_get(unit, mem, vent, SOURCE_VPf) == _BCM_VLAN_XLATE_DUMMY_PORT) {
   4699                     action->flags |= BCM_VLAN_ACTION_SET_DUMMY_VP;
   4700                     action->ingress_if =
   4701                        soc_mem_field32_get(unit, mem, vent, L3_IIFf);
   4702                 }
   4703 
   4704             }
   4705 #endif /* BCM_TRIDENT2_SUPPORT */
   4706 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   4707             else if (SOC_MEM_FIELD_VALID(unit, mem, CLASS_IDf)) {
   4708                 action->class_id = soc_mem_field32_get(unit, mem, vent, CLASS_IDf);
   4709             }
   4710 #endif
   4711         } 
   4712 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   4713         else if (SOC_MEM_FIELD_VALID(unit, mem, CLASS_ID_VALIDf)) {
   4714             if (soc_mem_field32_get(unit, mem, vent, CLASS_ID_VALIDf)) {
   4715                 action->class_id = soc_mem_field32_get(unit, mem, vent, CLASS_IDf);
   4716             }
   4717         }
   4718 #endif
   4719     }
   4720 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
   4721     defined(BCM_APACHE_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
   4722     if (soc_feature(unit, soc_feature_global_meter)) {
   4723         if (SOC_IS_KATANAX(unit) || SOC_IS_GREYHOUND2(unit) ||
   4724             (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit))) {
   4725 
   4726             if (SOC_MEM_FIELD_VALID(unit, mem, SVC_METER_OFFSET_MODEf)) {
   4727                 offset = soc_mem_field32_get(unit, mem, vent,
   4728                                                   SVC_METER_OFFSET_MODEf);
   4729             }
   4730             if (SOC_MEM_FIELD_VALID(unit, mem, SVC_METER_INDEXf)) {
   4731                 index = soc_mem_field32_get(unit, mem, vent, SVC_METER_INDEXf);
   4732             }
   4733         } else if (SOC_IS_TRIUMPH3(unit)) {
   4734             if (SOC_MEM_FIELD_VALID(unit, mem,
   4735                                          XLATE__SVC_METER_OFFSET_MODEf)) {
   4736                 offset = soc_mem_field32_get(unit, mem, vent,
   4737                                          XLATE__SVC_METER_OFFSET_MODEf);
   4738             }
   4739             if (SOC_MEM_FIELD_VALID(unit, mem, XLATE__SVC_METER_INDEXf)) {
   4740                 index = soc_mem_field32_get(unit, mem, vent, 
   4741                                                   XLATE__SVC_METER_INDEXf);
   4742             }
   4743         }
   4744         _bcm_esw_get_policer_id_from_index_offset(unit, index, offset, 
   4745                                                      &action->policer_id);
   4746        }
   4747 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT ||
   4748           BCM_APACHE_SUPPORT || BCM_GREYHOUND2_SUPPORT */
   4749 
   4750     return BCM_E_NONE;
   4751 }
   4752 
   4753 /*
   4754  * Function:
   4755  *      _bcm_trx_vif_vlan_translate_entry_assemble
   4756  * Purpose:
   4757  *      Constructs vif vlan translate entry from given key_type, inner and outer vlans
   4758  * Parameters:
   4759  *      unit            (IN) BCM unit number
   4760  *      vent            (IN/OUT) vlan translate entry to construct
   4761  *      key_type        (IN) Key Type : bcmVlanTranslateKey*
   4762  *      inner_vlan      (IN) inner VLAN ID
   4763  *      outer_vlan      (IN) outer VLAN ID
   4764  * Returns:
   4765  *      BCM_E_XXX
   4766  */
   4767 int
   4768 _bcm_trx_vif_vlan_translate_entry_assemble(int unit, void *vent,
   4769                                       bcm_gport_t niv_port_id,
   4770                                       bcm_vlan_translate_key_t key_type,
   4771                                       bcm_vlan_t inner_vlan,
   4772                                       bcm_vlan_t outer_vlan)
   4773 {
   4774 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
   4775     if (soc_feature(unit, soc_feature_niv)) {
   4776         int             tmp_id;
   4777         bcm_module_t    mod_out;
   4778         bcm_port_t      port_out;
   4779         bcm_trunk_t     trunk_out;
   4780         int key_type_value;
   4781         bcm_niv_port_t niv_port;
   4782         bcm_niv_egress_t niv_egress;
   4783         int              rv                   = BCM_E_NONE;
   4784         uint16           virtual_interface_id = 0;
   4785         bcm_gport_t      gport;
   4786         int              count;
   4787 
   4788         soc_mem_t mem = VLAN_XLATEm;
   4789         if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
   4790             mem = VLAN_XLATE_1_DOUBLEm;
   4791         }
   4792 
   4793         if (!BCM_GPORT_IS_NIV_PORT(niv_port_id)) {
   4794             return BCM_E_PORT;
   4795         }
   4796     
   4797         switch (key_type) {
   4798             case bcmVlanTranslateKeyPortOuterTag:
   4799                 key_type = VLXLT_HASH_KEY_TYPE_VIF_OTAG;
   4800                 soc_mem_field32_set(unit, mem, vent, VIF__OTAGf, outer_vlan);
   4801                 break;
   4802     
   4803             case bcmVlanTranslateKeyPortInnerTag:
   4804                 key_type = VLXLT_HASH_KEY_TYPE_VIF_ITAG;
   4805                 soc_mem_field32_set(unit, mem, vent, VIF__ITAGf, inner_vlan);
   4806                 break;
   4807     
   4808             case bcmVlanTranslateKeyPortOuter:
   4809                 key_type = VLXLT_HASH_KEY_TYPE_VIF_VLAN;
   4810                 soc_mem_field32_set(unit, mem, vent, VIF__VLANf, outer_vlan);
   4811                 break;
   4812     
   4813             case bcmVlanTranslateKeyPortInner:
   4814                 key_type = VLXLT_HASH_KEY_TYPE_VIF_CVLAN;
   4815                 soc_mem_field32_set(unit, mem, vent, VIF__CVLANf,inner_vlan);
   4816                 break;
   4817     
   4818             default:
   4819                 return BCM_E_PARAM;
   4820         }
   4821         BCM_IF_ERROR_RETURN(_bcm_esw_vlan_xlate_key_type_value_get(unit,
   4822                    key_type, &key_type_value));
   4823         soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
   4824         if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
   4825             soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value);
   4826         }
   4827     
   4828         niv_port.niv_port_id = niv_port_id;
   4829         BCM_IF_ERROR_RETURN(bcm_esw_niv_port_get(unit,&niv_port));
   4830         if (niv_port.flags & BCM_NIV_PORT_MATCH_NONE) {
   4831             bcm_niv_egress_t_init(&niv_egress);
   4832             rv = bcm_trident_niv_egress_get(unit, niv_port.niv_port_id,
   4833                                             1, &niv_egress, &count);
   4834             if (BCM_FAILURE(rv)) {
   4835                 return BCM_E_PARAM;
   4836             }
   4837 
   4838             if (niv_egress.flags & BCM_NIV_EGRESS_MULTICAST) {
   4839                 return BCM_E_PARAM;
   4840             } else {
   4841                 virtual_interface_id = niv_egress.virtual_interface_id;
   4842                 gport                = niv_egress.port;
   4843             }
   4844         } else {
   4845             virtual_interface_id = niv_port.virtual_interface_id;
   4846             gport                = niv_port.port;
   4847         }
   4848     
   4849         soc_mem_field32_set(unit, mem, vent, VIF__SRC_VIFf,
   4850                                     virtual_interface_id);
   4851     
   4852         if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) {
   4853             soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1);
   4854         }
   4855         BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, gport, 
   4856                       &mod_out, &port_out, &trunk_out, &tmp_id));
   4857         if (BCM_GPORT_IS_TRUNK(gport)) {
   4858             soc_mem_field32_set(unit, mem, vent, VIF__Tf, 1);
   4859             soc_mem_field32_set(unit, mem, vent, VIF__TGIDf, trunk_out);
   4860         } else {
   4861             soc_mem_field32_set(unit, mem, vent, VIF__MODULE_IDf, mod_out);
   4862             soc_mem_field32_set(unit, mem, vent, VIF__PORT_NUMf, port_out);
   4863         }
   4864         return BCM_E_NONE;
   4865     }
   4866 #endif   /* defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) */
   4867     return BCM_E_UNAVAIL;
   4868 }
   4869 
   4870 /*
   4871  * Function:
   4872  *      _bcm_trx_lltag_vlan_translate_entry_assemble
   4873  * Purpose:
   4874  *      Constructs lltag vlan translate entry from given key_type, lltag vlan and other vlans
   4875  * Parameters:
   4876  *      unit            (IN) BCM unit number
   4877  *      vent            (IN/OUT) vlan translate entry to construct
   4878  *      key_type        (IN) Key Type : bcmVlanTranslateKey*
   4879  *      lltag_vlan      (IN) LLTAG VLAN ID
   4880  *      other_vlan      (IN) other VLAN ID denpends on the key_type
   4881  * Returns:
   4882  *      BCM_E_XXX
   4883  */
   4884 int
   4885 _bcm_trx_lltag_vlan_translate_entry_assemble(int unit, void *vent,
   4886                                       bcm_gport_t port,
   4887                                       bcm_vlan_translate_key_t key_type,
   4888                                       bcm_vlan_t lltag_vlan,
   4889                                       bcm_vlan_t other_vlan)
   4890 {
   4891 #if defined(BCM_KATANA2_SUPPORT) && defined(INCLUDE_L3)
   4892     if (soc_feature(unit, soc_feature_lltag)) {
   4893         int             use_glp = 1;    /* By default incoming port used in lookup key */
   4894         int             tmp_id;
   4895         bcm_module_t    mod_out;
   4896         bcm_port_t      port_out;
   4897         bcm_trunk_t     trunk_out;
   4898         int key_type_value;
   4899         soc_mem_t       mem = VLAN_XLATEm;
   4900 
   4901         if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
   4902             mem = VLAN_XLATE_1_DOUBLEm;
   4903         }
   4904 
   4905         switch (key_type) {
   4906             case bcmVlanTranslateKeyPortPonTunnel:
   4907                 use_glp = 1;
   4908                 VLAN_CHK_ID(unit, lltag_vlan);
   4909                 BCM_IF_ERROR_RETURN
   4910                     (_bcm_esw_vlan_xlate_key_type_value_get(unit,
   4911                            VLXLT_HASH_KEY_TYPE_LLVID,
   4912                            &key_type_value));
   4913                 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
   4914                 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
   4915                     soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value);
   4916                 }
   4917                 soc_mem_field32_set(unit, mem, vent, LLTAG__LLVIDf, lltag_vlan);
   4918                 break;
   4919             case bcmVlanTranslateKeyPortPonTunnelOuter:
   4920                 use_glp = 1;      
   4921                 VLAN_CHK_ID(unit, lltag_vlan);
   4922                 VLAN_CHK_ID(unit, other_vlan);
   4923                 BCM_IF_ERROR_RETURN
   4924                     (_bcm_esw_vlan_xlate_key_type_value_get(unit,
   4925                            VLXLT_HASH_KEY_TYPE_LLVID_OVID,
   4926                            &key_type_value));
   4927                 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
   4928                 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
   4929                     soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value);
   4930                 }
   4931                 soc_mem_field32_set(unit, mem, vent, LLTAG__LLVIDf, lltag_vlan);
   4932                 soc_mem_field32_set(unit, mem, vent, LLTAG__OVIDf, other_vlan);
   4933                 break;
   4934             case bcmVlanTranslateKeyPortPonTunnelInner:
   4935                 use_glp = 1;      
   4936                 VLAN_CHK_ID(unit, lltag_vlan);
   4937                 VLAN_CHK_ID(unit, other_vlan);
   4938                 BCM_IF_ERROR_RETURN
   4939                     (_bcm_esw_vlan_xlate_key_type_value_get(unit,
   4940                            VLXLT_HASK_KEY_TYPE_LLVID_IVID,
   4941                            &key_type_value));
   4942                 soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
   4943                 if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
   4944                     soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value);
   4945                 }
   4946                 soc_mem_field32_set(unit, mem, vent, LLTAG__LLVIDf, lltag_vlan);
   4947                 soc_mem_field32_set(unit, mem, vent, LLTAG__IVIDf, other_vlan);
   4948                 break;
   4949             default:
   4950                 return BCM_E_PARAM;
   4951         }
   4952 
   4953         if (use_glp) {
   4954             if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) {
   4955                 soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1);
   4956             }
   4957             BCM_IF_ERROR_RETURN
   4958                 (_bcm_esw_gport_resolve(unit, port, &mod_out, &port_out,
   4959                                         &trunk_out, &tmp_id));
   4960             if (BCM_GPORT_IS_TRUNK(port)) {
   4961                 soc_mem_field32_set(unit, mem, vent, LLTAG__Tf, 1);
   4962                 soc_mem_field32_set(unit, mem, vent, LLTAG__TGIDf, trunk_out);
   4963             } else {
   4964                 soc_mem_field32_set(unit, mem, vent, LLTAG__MODULE_IDf, mod_out);
   4965                 soc_mem_field32_set(unit, mem, vent, LLTAG__PORT_NUMf, port_out);
   4966             }
   4967         } else {
   4968             /* SOURCE_TYPE field in vent is 0 */
   4969 
   4970             /* incoming port not used in lookup key, set field to all 1's */
   4971             /* coverity[dead_error_line : FALSE] */
   4972             soc_mem_field32_set(unit, mem, vent, LLTAG__GLPf,
   4973                                         SOC_VLAN_XLATE_GLP_WILDCARD(unit));
   4974         }
   4975         return BCM_E_NONE;
   4976     } 
   4977 #endif
   4978     return BCM_E_UNAVAIL;
   4979 }
   4980 
   4981 #define PORT_GROUP_MAX  0xffff
   4982 
   4983 /*
   4984  * Function:
   4985  *      _bcm_trx_vlan_translate_entry_assemble
   4986  * Purpose:
   4987  *      Constructs vlan translate entry from given key_type, inner and outer vlans
   4988  * Parameters:
   4989  *      unit            (IN) BCM unit number
   4990  *      vent            (IN/OUT) vlan translate entry to construct
   4991  *      key_type        (IN) Key Type : bcmVlanTranslateKey*
   4992  *      inner_vlan      (IN) inner VLAN ID
   4993  *      outer_vlan      (IN) outer VLAN ID
   4994  * Returns:
   4995  *      BCM_E_XXX
   4996  */
   4997 int 
   4998 _bcm_trx_vlan_translate_entry_assemble(int unit, void *vent,
   4999                                       bcm_gport_t port,
   5000                                       bcm_vlan_translate_key_t key_type,
   5001                                       bcm_vlan_t inner_vlan, 
   5002                                       bcm_vlan_t outer_vlan)
   5003 {
   5004     int             use_glp = 1;    /* By default incoming port used in lookup key */
   5005     int             tmp_id;
   5006     bcm_module_t    mod_out;
   5007     bcm_port_t      port_out;
   5008     bcm_trunk_t     trunk_out = -1;
   5009     int key_type_value;
   5010     soc_mem_t       mem = VLAN_XLATEm;
   5011 
   5012 #if defined(BCM_TRIDENT2_SUPPORT)
   5013     int             use_port_group = 0;
   5014     uint32          port_group;
   5015 #endif
   5016     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
   5017         mem = VLAN_XLATE_1_DOUBLEm;
   5018     }
   5019 
   5020     switch (key_type) {
   5021 #if defined(BCM_TRIDENT2_SUPPORT)
   5022         case bcmVlanTranslateKeyPortGroupDouble:
   5023             use_port_group = 1;
   5024             /* Fall through */
   5025 #endif
   5026         case bcmVlanTranslateKeyDouble:
   5027             use_glp = 0;
   5028             /* Fall through */
   5029         case bcmVlanTranslateKeyPortDouble:
   5030             VLAN_CHK_ID(unit, inner_vlan);
   5031             VLAN_CHK_ID(unit, outer_vlan);
   5032             BCM_IF_ERROR_RETURN
   5033                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
   5034                        VLXLT_HASH_KEY_TYPE_IVID_OVID,
   5035                        &key_type_value));
   5036             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
   5037             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
   5038                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value);
   5039             }
   5040             soc_mem_field32_set(unit, mem, vent, OVIDf, outer_vlan);
   5041             soc_mem_field32_set(unit, mem, vent, IVIDf, inner_vlan);
   5042             break;
   5043 #if defined(BCM_TRIDENT2_SUPPORT)
   5044         case bcmVlanTranslateKeyPortGroupOuterTag:
   5045             use_port_group = 1;
   5046             /* Fall through */
   5047 #endif
   5048         case bcmVlanTranslateKeyOuterTag:
   5049             use_glp = 0;
   5050             /* Fall through */
   5051         case bcmVlanTranslateKeyPortOuterTag:
   5052             /* allow 16 bit VLAN id */
   5053             BCM_IF_ERROR_RETURN
   5054                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
   5055                        VLXLT_HASH_KEY_TYPE_OTAG,
   5056                        &key_type_value));
   5057             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
   5058             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
   5059                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value);
   5060             }
   5061             soc_mem_field32_set(unit, mem, vent, OTAGf, outer_vlan);
   5062             break;
   5063 #if defined(BCM_TRIDENT2_SUPPORT)
   5064         case bcmVlanTranslateKeyPortGroupInnerTag:
   5065             use_port_group = 1;
   5066             /* Fall through */
   5067 #endif
   5068         case bcmVlanTranslateKeyInnerTag:
   5069             use_glp = 0;
   5070             /* Fall through */
   5071         case bcmVlanTranslateKeyPortInnerTag:
   5072             /* Allow 16 bit VLAN id */
   5073             BCM_IF_ERROR_RETURN
   5074                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
   5075                        VLXLT_HASH_KEY_TYPE_ITAG,
   5076                        &key_type_value));
   5077             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
   5078             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
   5079                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value);
   5080             }
   5081             soc_mem_field32_set(unit, mem, vent, ITAGf, inner_vlan);
   5082             break;
   5083 #if defined(BCM_TRIDENT2_SUPPORT)
   5084         case bcmVlanTranslateKeyPortGroupOuter:
   5085             use_port_group = 1;
   5086             /* Fall through */
   5087 #endif
   5088         case bcmVlanTranslateKeyOuter:
   5089             use_glp = 0;
   5090             /* Fall through */
   5091         case bcmVlanTranslateKeyPortOuter:
   5092             VLAN_CHK_ID(unit, outer_vlan);
   5093             BCM_IF_ERROR_RETURN
   5094                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
   5095                        VLXLT_HASH_KEY_TYPE_OVID,
   5096                        &key_type_value));
   5097             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
   5098             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
   5099                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value);
   5100             }
   5101             soc_mem_field32_set(unit, mem, vent, OVIDf, outer_vlan);
   5102             break;
   5103 #if defined(BCM_TRIDENT2_SUPPORT)
   5104         case bcmVlanTranslateKeyPortGroupInner:
   5105             use_port_group = 1;
   5106             /* Fall through */
   5107 #endif
   5108         case bcmVlanTranslateKeyInner:
   5109             use_glp = 0;
   5110             /* Fall through */
   5111         case bcmVlanTranslateKeyPortInner:
   5112             VLAN_CHK_ID(unit, inner_vlan);
   5113             BCM_IF_ERROR_RETURN
   5114                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
   5115                        VLXLT_HASH_KEY_TYPE_IVID,
   5116                        &key_type_value));
   5117             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
   5118             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
   5119                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value);
   5120             }
   5121             soc_mem_field32_set(unit, mem, vent, IVIDf, inner_vlan);
   5122             break;
   5123 #if defined(BCM_TRIDENT2_SUPPORT)
   5124         case bcmVlanTranslateKeyPortGroupOuterPri:
   5125             use_port_group = 1;
   5126             /* Fall through */
   5127 #endif
   5128         case bcmVlanTranslateKeyOuterPri:
   5129             use_glp = 0;
   5130             /* Fall through */
   5131         case bcmVlanTranslateKeyPortOuterPri:
   5132             /* Allow Hi 4 bits in 16 bit VLAN tag */
   5133             BCM_IF_ERROR_RETURN
   5134                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
   5135                        VLXLT_HASH_KEY_TYPE_PRI_CFI,
   5136                        &key_type_value));
   5137             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
   5138             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
   5139                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value);
   5140             }
   5141             /* outer_vlan: Bits 12-15 contains VLAN_PRI + CFI, vlan=BCM_VLAN_NONE */
   5142             soc_mem_field32_set(unit, mem, vent, OTAGf, outer_vlan);
   5143             break;
   5144         case bcmVlanTranslateKeyCapwapPayloadDouble:
   5145             use_glp = 0;
   5146             /* Fall through */
   5147         case bcmVlanTranslateKeyPortCapwapPayloadDouble:
   5148             VLAN_CHK_ID(unit, inner_vlan);
   5149             VLAN_CHK_ID(unit, outer_vlan);
   5150             BCM_IF_ERROR_RETURN
   5151                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
   5152                        VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID,
   5153                        &key_type_value));
   5154             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
   5155             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
   5156                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value);
   5157             }
   5158             soc_mem_field32_set(unit, mem, vent, OVIDf, outer_vlan);
   5159             soc_mem_field32_set(unit, mem, vent, IVIDf, inner_vlan);
   5160             break;
   5161         case bcmVlanTranslateKeyCapwapPayloadOuter:
   5162             use_glp = 0;
   5163             /* Fall through */
   5164         case bcmVlanTranslateKeyPortCapwapPayloadOuter:
   5165             VLAN_CHK_ID(unit, outer_vlan);
   5166             BCM_IF_ERROR_RETURN
   5167                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
   5168                        VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID,
   5169                        &key_type_value));
   5170             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
   5171             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
   5172                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value);
   5173             }
   5174             soc_mem_field32_set(unit, mem, vent, OVIDf, outer_vlan);
   5175             break;
   5176         case bcmVlanTranslateKeyCapwapPayloadInner:
   5177             use_glp = 0;
   5178             /* Fall through */
   5179         case bcmVlanTranslateKeyPortCapwapPayloadInner:
   5180             VLAN_CHK_ID(unit, inner_vlan);
   5181             BCM_IF_ERROR_RETURN
   5182                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
   5183                        VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID,
   5184                        &key_type_value));
   5185             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
   5186             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
   5187                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value);
   5188             }
   5189             soc_mem_field32_set(unit, mem, vent, IVIDf, inner_vlan);
   5190             break;
   5191         case bcmVlanTranslateKeyCapwapPayloadOuterTag:
   5192             use_glp = 0;
   5193             /* Fall through */
   5194         case bcmVlanTranslateKeyPortCapwapPayloadOuterTag:
   5195             /* allow 16 bit VLAN id */
   5196             BCM_IF_ERROR_RETURN
   5197                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
   5198                        VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG,
   5199                        &key_type_value));
   5200             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
   5201             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
   5202                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value);
   5203             }
   5204             soc_mem_field32_set(unit, mem, vent, OTAGf, outer_vlan);
   5205             break;
   5206         case bcmVlanTranslateKeyCapwapPayloadInnerTag:
   5207             use_glp = 0;
   5208             /* Fall through */
   5209         case bcmVlanTranslateKeyPortCapwapPayloadInnerTag:
   5210             /* Allow 16 bit VLAN id */
   5211             BCM_IF_ERROR_RETURN
   5212                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
   5213                        VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG,
   5214                        &key_type_value));
   5215             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
   5216             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
   5217                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, key_type_value);
   5218             }
   5219             soc_mem_field32_set(unit, mem, vent, ITAGf, inner_vlan);
   5220             break;
   5221         default:
   5222             return BCM_E_PARAM;
   5223     }
   5224 
   5225 #if defined(BCM_TRIDENT2_SUPPORT)
   5226     if (use_port_group) {
   5227         if (!soc_feature(unit, soc_feature_port_group_for_ivxlt)) {
   5228             return BCM_E_UNAVAIL;
   5229         }
   5230         soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 3);
   5231         if((port < 0) || (port > PORT_GROUP_MAX)) {
   5232             return BCM_E_PARAM;
   5233         }
   5234         port_group = port;
   5235         soc_mem_field32_set(unit, mem, vent, SOURCE_FIELDf, port_group);
   5236     } else
   5237 #endif /* BCM_TRIDENT2_SUPPORT */
   5238     if (use_glp) {
   5239 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT)        
   5240         if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) {
   5241             soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1);
   5242         }
   5243 #endif
   5244         BCM_IF_ERROR_RETURN
   5245             (_bcm_esw_gport_resolve(unit, port, &mod_out, &port_out,
   5246                                     &trunk_out, &tmp_id));
   5247         /* In case of extended queuing on KTX, tgid_out gets updated with
   5248          * extended queue value. So set it to invalid value.
   5249          */
   5250 #ifdef BCM_KATANA_SUPPORT
   5251        if (soc_feature(unit, soc_feature_extended_queueing)) {
   5252            if ((BCM_GPORT_IS_UCAST_QUEUE_GROUP(port)) ||
   5253                (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(port)) ||
   5254                (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(port))) {
   5255                trunk_out = BCM_TRUNK_INVALID;
   5256            }
   5257        }
   5258 #endif
   5259         if (trunk_out >= 0) {
   5260             soc_mem_field32_set(unit, mem, vent, Tf, 1);
   5261             soc_mem_field32_set(unit, mem, vent, TGIDf, trunk_out);
   5262         } else {
   5263             soc_mem_field32_set(unit, mem, vent, MODULE_IDf, mod_out);
   5264             soc_mem_field32_set(unit, mem, vent, PORT_NUMf, port_out);
   5265         }
   5266     } else {
   5267         /* SOURCE_TYPE field in vent is 0 */
   5268 
   5269         /* incoming port not used in lookup key, set field to all 1's */
   5270         soc_mem_field32_set(unit, mem, vent, GLPf,
   5271                                     SOC_VLAN_XLATE_GLP_WILDCARD(unit));
   5272     }
   5273     return BCM_E_NONE;
   5274 }
   5275 
   5276 /*
   5277  * Function:
   5278  *		_bcm_trx_vlan_translate_action_entry_update
   5279  * Purpose:
   5280  *		Update Vlan_xlate Entry.
   5281  *              Currently it only updates the fields by the actions
   5282  *              specified in bcm_vlan_action_set_t.
   5283  * Parameters:
   5284  *  IN :  Unit
   5285  *  IN :  vlan_xlate_entry
   5286  *  OUT :  vlan_xlate_entry
   5287 
   5288  */
   5289 
   5290 STATIC int
   5291 _bcm_trx_vlan_translate_action_entry_update(int unit, void *vent,
   5292                                             void *return_ent)
   5293 {
   5294     uint32  key_type, value;
   5295     uint32 l3_iif_valid  = 0;
   5296     uint32 ret_svp_valid = 0;
   5297 #if defined(BCM_TRIDENT2_SUPPORT)
   5298     uint32 svp_valid     = 0;
   5299     uint32 ret_svp       = 0;
   5300     uint32 svp           = 0;
   5301     uint32 dummy_svp_chk = 0;
   5302     uint32 svp_dummy     = 0;
   5303 #endif /* BCM_TRIDENT2_SUPPORT */
   5304 
   5305     bcm_vlan_t outer_vlan, inner_vlan;
   5306 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_APACHE_SUPPORT) || \
   5307     defined(BCM_GREYHOUND2_SUPPORT)
   5308     bcm_policer_t  current_policer = 0;
   5309     int rv = BCM_E_NONE;
   5310 #endif /* BCM_KATANA_SUPPORT || BCM_APACHE_SUPPORT ||
   5311           BCM_GREYHOUND2_SUPPORT */
   5312 
   5313     soc_mem_t mem = VLAN_XLATEm;
   5314     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
   5315         mem = VLAN_XLATE_1_DOUBLEm;
   5316     }
   5317 
   5318     /* Check if Key_Type identical */
   5319     key_type = soc_mem_field32_get(unit, mem, vent, KEY_TYPEf);
   5320     value = soc_mem_field32_get(unit, mem, return_ent, KEY_TYPEf);
   5321     if (key_type != value) {
   5322          return BCM_E_PARAM;
   5323     }
   5324 
   5325     /* Retain original Keys -- Update data only */
   5326     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   5327         value = soc_mem_field32_get(unit, mem, vent, NEW_OPRIf);
   5328         soc_mem_field32_set(unit, mem, return_ent, NEW_OPRIf, value);
   5329         value = soc_mem_field32_get(unit, mem, vent, NEW_OCFIf);
   5330         soc_mem_field32_set(unit, mem, return_ent, NEW_OCFIf, value);
   5331         value = soc_mem_field32_get(unit, mem, vent, NEW_IPRIf);
   5332         soc_mem_field32_set(unit, mem, return_ent, NEW_IPRIf, value);
   5333         value = soc_mem_field32_get(unit, mem, vent, NEW_ICFIf);
   5334         soc_mem_field32_set(unit, mem, return_ent, NEW_ICFIf, value);
   5335     } else {
   5336         value = soc_mem_field32_get(unit, mem, vent, RPEf);
   5337         soc_mem_field32_set(unit, mem, return_ent, RPEf, value);
   5338         if (value) {
   5339             value = soc_mem_field32_get(unit, mem, vent, PRIf);
   5340             soc_mem_field32_set(unit, mem, return_ent, PRIf, value);
   5341         } 
   5342     }
   5343 
   5344     value = soc_mem_field32_get(unit, mem, vent, TAG_ACTION_PROFILE_PTRf);
   5345     soc_mem_field32_set(unit, mem, return_ent, TAG_ACTION_PROFILE_PTRf, value);
   5346     if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_ACTION_VALIDf)) {
   5347         value = soc_mem_field32_get(unit, mem, vent, VLAN_ACTION_VALIDf);
   5348         soc_mem_field32_set(unit, mem, return_ent, VLAN_ACTION_VALIDf,value);
   5349     }
   5350 
   5351     if (SOC_MEM_FIELD_VALID(unit, mem, DISABLE_VLAN_CHECKSf)) {  
   5352         value = soc_mem_field32_get(unit, mem, vent, DISABLE_VLAN_CHECKSf);
   5353         soc_mem_field32_set(unit, mem, return_ent,
   5354                                     DISABLE_VLAN_CHECKSf, value);
   5355     }
   5356 
   5357     inner_vlan = soc_mem_field32_get(unit, mem, vent, NEW_IVIDf);
   5358     soc_mem_field32_set(unit, mem, return_ent, NEW_IVIDf, inner_vlan);
   5359     outer_vlan = soc_mem_field32_get(unit, mem, vent, NEW_OVIDf);
   5360     soc_mem_field32_set(unit, mem, return_ent, NEW_OVIDf, outer_vlan);
   5361 
   5362 #if defined(BCM_TRIDENT2_SUPPORT)
   5363     if (soc_feature(unit, soc_feature_vlan_xlate_iif_with_dummy_vp) &&
   5364         soc_property_get(unit, spn_VLAN_ACTION_DUMMY_VP_RESERVED, 0)) {
   5365         svp = soc_mem_field32_get(unit, mem, vent, SOURCE_VPf);
   5366         ret_svp = soc_mem_field32_get(unit, mem, return_ent, SOURCE_VPf);
   5367         if (svp ==  _BCM_VLAN_XLATE_DUMMY_PORT ||
   5368             ret_svp == _BCM_VLAN_XLATE_DUMMY_PORT) {
   5369             dummy_svp_chk = 1;
   5370         }
   5371     }
   5372 #endif /* defined(BCM_TRIDENT2_SUPPORT) */
   5373 
   5374     if (SOC_MEM_FIELD_VALID(unit, mem, MPLS_ACTIONf)) {
   5375         /* Only carry forward the L3_IIF encoding and leave L2_SVP as is */
   5376         l3_iif_valid = soc_mem_field32_get(unit, mem, vent, MPLS_ACTIONf) & 0x2;
   5377         ret_svp_valid = 0x1 &
   5378             soc_mem_field32_get(unit, mem, return_ent, MPLS_ACTIONf);
   5379 
   5380         /* If the device supports MPLS_ACTION value 0x3 i.e. both L3_IIF and
   5381          * L2_SVP simultaneously then retain the SVP_VALID bit. To check if
   5382          * the device supports both actions simultaneously, use existence
   5383          * of L3_IIF_VALID field as this field is only present in chips which
   5384          * has the support.
   5385          */
   5386         if (SOC_MEM_FIELD_VALID(unit, mem, L3_IIF_VALIDf)) {
   5387 #if defined(BCM_TRIDENT2_SUPPORT)
   5388             if (soc_feature(unit, soc_feature_vlan_xlate_iif_with_dummy_vp) &&
   5389                 soc_property_get(unit, spn_VLAN_ACTION_DUMMY_VP_RESERVED, 0) &&
   5390                 dummy_svp_chk) {
   5391 
   5392                 svp_valid =
   5393                        soc_mem_field32_get(unit, mem, vent, MPLS_ACTIONf) & 0x1;
   5394                 if ((svp_valid == 1) && (svp == _BCM_VLAN_XLATE_DUMMY_PORT)) {
   5395                     /* svp is either invalid or a dummy VP */
   5396                     svp_dummy = 1;
   5397                 }
   5398 
   5399                 if (svp_dummy &&
   5400                    (ret_svp_valid && ret_svp != _BCM_VLAN_XLATE_DUMMY_PORT)) {
   5401                     /* svp information conflicts */
   5402                     return BCM_E_PARAM;
   5403                 }
   5404 
   5405                 if (!ret_svp_valid || (ret_svp == _BCM_VLAN_XLATE_DUMMY_PORT)) {
   5406                     /*
   5407                      * In this case, the ret_svp is either invalid or a dummy vp
   5408                      * configured with L3 IIF, it should be updated.
   5409                      */
   5410                     value = l3_iif_valid | svp_valid;
   5411                     soc_mem_field32_set(unit, mem, return_ent, SOURCE_VPf, svp);
   5412                 }
   5413             } else
   5414 #endif /* defined(BCM_TRIDENT2_SUPPORT) */
   5415             {
   5416                 value = l3_iif_valid | ret_svp_valid;
   5417             }
   5418         } else if (l3_iif_valid) {
   5419             /* The device does not support setting simultaneously L3_IIF and
   5420              * L2_SVP, and if L3_IIF_VALID bit is set then it takes precedence
   5421              * over L2_SVP.
   5422              */
   5423             value = l3_iif_valid;
   5424         } else {
   5425             /* If L3_IIF_VALID bit is not set then retain the SVP_VALID */
   5426             value = ret_svp_valid;
   5427         }
   5428 
   5429         soc_mem_field32_set(unit, mem, return_ent, MPLS_ACTIONf, value);
   5430     }
   5431 
   5432     /* Retreive the resolved L3_IIF_VALID field status */
   5433     if (SOC_MEM_FIELD_VALID(unit, mem, MPLS_ACTIONf)) {
   5434         /* The second bit as it corresponds to L3_IIF_VALID */
   5435         l3_iif_valid =
   5436             0x2 & soc_mem_field32_get(unit, mem, return_ent, MPLS_ACTIONf);
   5437     } else {
   5438         /* L3_IIF_VALID bit couldnt be retrieved hence assume not valid */
   5439         l3_iif_valid = 0;
   5440     }
   5441 
   5442 
   5443     if (l3_iif_valid) {
   5444         if (SOC_MEM_FIELD_VALID(unit, mem, L3_IIFf)) {
   5445             /* Update the L3_IIF field if the corresponding valid bit is set */
   5446             value = soc_mem_field32_get(unit, mem, vent, L3_IIFf);
   5447             soc_mem_field32_set(unit, mem, return_ent, L3_IIFf, value);
   5448         }
   5449     }
   5450 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   5451     else if (SOC_MEM_FIELD_VALID(unit, mem, CLASS_IDf)) {
   5452         /* If the L3_IIF is not valid and CLASS_ID field exists, though
   5453          * overlaid on L3_IIF field, then perform update on CLASS_ID field.
   5454          */
   5455         value = soc_mem_field32_get(unit, mem, vent, CLASS_IDf);
   5456         soc_mem_field32_set(unit, mem, return_ent, CLASS_IDf, value);
   5457     }
   5458 #endif
   5459 
   5460 #if defined(BCM_GREYHOUND2_SUPPORT)
   5461     if (soc_feature(unit, soc_feature_global_meter) &&
   5462         SOC_IS_GREYHOUND2(unit)) {
   5463         rv = _bcm_esw_get_policer_from_table(unit, mem, 0, return_ent,
   5464                                              &current_policer, 1);
   5465         BCM_IF_ERROR_RETURN(rv);
   5466 
   5467         /* decrement current policer ref count - if any */
   5468         rv = _bcm_esw_policer_validate(unit, &current_policer);
   5469         if (BCM_SUCCESS(rv)) {
   5470             rv = _bcm_esw_policer_decrement_ref_count(unit, current_policer);
   5471             BCM_IF_ERROR_RETURN(rv);
   5472         }
   5473 
   5474         value = soc_mem_field32_get(unit, mem, vent, SVC_METER_OFFSET_MODEf);
   5475         soc_mem_field32_set(unit, mem, return_ent,
   5476                             SVC_METER_OFFSET_MODEf, value);
   5477         value = soc_mem_field32_get(unit, mem, vent, SVC_METER_INDEXf);
   5478         soc_mem_field32_set(unit, mem, return_ent, SVC_METER_INDEXf, value);
   5479     }
   5480 #endif /* BCM_GREYHOUND2_SUPPORT */
   5481 
   5482 #if defined(BCM_GREYHOUND2_SUPPORT)
   5483     if (soc_feature(unit, soc_feature_global_meter) &&
   5484         SOC_IS_GREYHOUND2(unit)) {
   5485         rv = _bcm_esw_get_policer_from_table(unit, mem, 0, return_ent,
   5486                                              &current_policer, 1);
   5487         BCM_IF_ERROR_RETURN(rv);
   5488 
   5489         /* decrement current policer ref count - if any */
   5490         rv = _bcm_esw_policer_validate(unit, &current_policer);
   5491         if (BCM_SUCCESS(rv)) {
   5492             rv = _bcm_esw_policer_decrement_ref_count(unit, current_policer);
   5493             BCM_IF_ERROR_RETURN(rv);
   5494         }
   5495 
   5496         value = soc_mem_field32_get(unit, mem, vent, SVC_METER_OFFSET_MODEf);
   5497         soc_mem_field32_set(unit, mem, return_ent,
   5498                             SVC_METER_OFFSET_MODEf, value);
   5499         value = soc_mem_field32_get(unit, mem, vent, SVC_METER_INDEXf);
   5500         soc_mem_field32_set(unit, mem, return_ent, SVC_METER_INDEXf, value);
   5501     }
   5502 #endif /* BCM_GREYHOUND2_SUPPORT */
   5503 
   5504 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   5505     if (soc_feature(unit, soc_feature_global_meter) &&
   5506         (SOC_IS_KATANAX(unit) || (SOC_IS_APACHE(unit)
   5507                                   && !SOC_IS_MONTEREY(unit)))) {
   5508         rv = _bcm_esw_get_policer_from_table(unit, mem, 0, return_ent,
   5509                                              &current_policer, 1);
   5510         BCM_IF_ERROR_RETURN(rv);
   5511         /* decrement current policer ref count - if any */
   5512         if ((current_policer & BCM_POLICER_GLOBAL_METER_INDEX_MASK) > 0) {
   5513             rv = _bcm_esw_policer_decrement_ref_count(unit, current_policer);
   5514             BCM_IF_ERROR_RETURN(rv);
   5515         }
   5516         value = soc_mem_field32_get(unit, mem, vent, SVC_METER_OFFSET_MODEf);
   5517         soc_mem_field32_set(unit, mem, return_ent,
   5518                                                 SVC_METER_OFFSET_MODEf, value);
   5519         value = soc_mem_field32_get(unit, mem, vent, SVC_METER_INDEXf);
   5520         soc_mem_field32_set(unit, mem, return_ent, SVC_METER_INDEXf, value);
   5521     }
   5522 #endif /* BCM_KATANA_SUPPORT || BCM_APACHE_SUPPORT */
   5523 
   5524 #if defined(BCM_TSN_SUPPORT)
   5525 #if defined(BCM_TSN_SR_SUPPORT)
   5526     if (soc_feature(unit, soc_feature_tsn_sr)) {
   5527         value = soc_mem_field32_get(unit, mem, vent, SR_ENABLEf);
   5528         soc_mem_field32_set(unit, mem, return_ent, SR_ENABLEf, value);
   5529         value = soc_mem_field32_get(unit, mem, vent, SR_LAN_ID_VALIDf);
   5530         soc_mem_field32_set(unit, mem, return_ent, SR_LAN_ID_VALIDf, value);
   5531         value = soc_mem_field32_get(unit, mem, vent, SR_LAN_IDf);
   5532         soc_mem_field32_set(unit, mem, return_ent, SR_LAN_IDf, value);
   5533     }
   5534 #endif /* BCM_TSN_SR_SUPPORT*/
   5535     if (soc_feature(unit, soc_feature_tsn_taf) &&
   5536         SOC_MEM_FIELD_VALID(unit, mem, TAF_GATE_ID_PROFILEf)) {
   5537         value = soc_mem_field32_get(unit, mem, vent, TAF_GATE_ID_PROFILEf);
   5538         soc_mem_field32_set(unit, mem, return_ent, TAF_GATE_ID_PROFILEf, value);
   5539     }
   5540 #endif /* BCM_TSN_SUPPORT */
   5541    return BCM_E_NONE;
   5542 }
   5543 
   5544 #if defined(BCM_TRIUMPH3_SUPPORT)
   5545 STATIC int
   5546 _bcm_tr3_vxlate_extd_action_entry_update(int unit,
   5547                vlan_xlate_entry_t *vent_in,  /* update entry */
   5548                void *ctxt,
   5549                vlan_xlate_entry_t *vent_out, /* entry read from mem */
   5550                vlan_xlate_extd_entry_t *vxent_out, /* entry read from mem or
   5551                                    converted from vent_out if not null */
   5552                int *use_extd_tbl) 
   5553 {
   5554     vlan_xlate_entry_t vent_new;
   5555     bcm_vlan_action_set_t *action;
   5556 #ifdef INCLUDE_L3
   5557     int intf_map_mode = 0;
   5558     int min_l3_iif;
   5559     int max_l3_iif;
   5560 #endif
   5561 
   5562     *use_extd_tbl = FALSE;
   5563     action = (bcm_vlan_action_set_t *)ctxt;
   5564     sal_memset(&vent_new, 0, sizeof(vent_new));
   5565 
   5566     /* if a regular entry from memory table is given, then update it */
   5567     if (vent_out) {
   5568         BCM_IF_ERROR_RETURN(
   5569             _bcm_trx_vlan_translate_action_entry_update (unit,
   5570                     vent_in, vent_out));
   5571 
   5572         BCM_IF_ERROR_RETURN
   5573             (_bcm_tr3_vxlate2vxlate_extd(unit,vent_out,vxent_out));
   5574     } else {
   5575         /* if a regular entry isn't given instead a extd entry, then
   5576          * first convert to a regular entry, update it and convert back
   5577          * to a extd entry. This is to utilize the existing regular entry
   5578          * update function 
   5579          */
   5580         BCM_IF_ERROR_RETURN
   5581             (_bcm_tr3_vxlate_extd2vxlate(unit,vxent_out,&vent_new,0));
   5582         BCM_IF_ERROR_RETURN(
   5583             _bcm_trx_vlan_translate_action_entry_update (unit,
   5584                     vent_in, &vent_new));
   5585         BCM_IF_ERROR_RETURN
   5586             (_bcm_tr3_vxlate2vxlate_extd(unit,&vent_new,vxent_out));
   5587     }
   5588 #ifdef INCLUDE_L3
   5589     max_l3_iif = BCM_XGS3_L3_ING_IF_TBL_SIZE(unit);
   5590 
   5591 #if defined(BCM_TRIUMPH_SUPPORT)
   5592     if (soc_feature(unit, soc_feature_l3_ingress_interface)) {
   5593         BCM_IF_ERROR_RETURN (bcm_xgs3_l3_ingress_intf_map_get(unit,
   5594                            &intf_map_mode));
   5595     }
   5596 #endif
   5597 
   5598     if (intf_map_mode) {
   5599         min_l3_iif = 0;
   5600     } else {
   5601         min_l3_iif = BCM_VLAN_MAX + 1;
   5602     }
   5603 
   5604     if ((action->ingress_if >= min_l3_iif) &&
   5605                       (action->ingress_if < max_l3_iif)) {
   5606         *use_extd_tbl = TRUE;
   5607         soc_VLAN_XLATE_EXTDm_field32_set(unit, vxent_out,
   5608                                     XLATE__MPLS_ACTIONf, 0x2); /* L3_IIF */
   5609         soc_VLAN_XLATE_EXTDm_field32_set(unit, vxent_out, XLATE__L3_IIFf,
   5610                                     action->ingress_if);
   5611     }
   5612 #endif  /* INCLUDE_L3 */
   5613 
   5614     if (SOC_IS_TRIUMPH3(unit) && action->policer_id) {
   5615         BCM_IF_ERROR_RETURN(
   5616             _bcm_esw_add_policer_to_table(unit, action->policer_id,
   5617                                      VLAN_XLATE_EXTDm, 0, vxent_out));
   5618         *use_extd_tbl = TRUE;
   5619     } 
   5620     return BCM_E_NONE;
   5621 }
   5622 
   5623 /*
   5624  * Function:
   5625  *		_bcm_tr3_vlan_translate_action_entry_set
   5626  * Purpose:
   5627  *		Set Vlan Translate Entry 
   5628  * Parameters:
   5629  *  IN :  Unit
   5630  *  IN :  vlan_xlate_entry
   5631  * Returns:
   5632  *		BCM_E_XXX
   5633  */
   5634 
   5635 STATIC int
   5636 _bcm_tr3_vlan_translate_action_entry_set(int unit, vlan_xlate_entry_t *vent,
   5637                             bcm_vlan_action_set_t *action)
   5638 {
   5639 
   5640     BCM_IF_ERROR_RETURN(
   5641          _bcm_tr3_vxlate_entry_add(unit, vent,(void *)action,
   5642                 _bcm_tr3_vxlate_extd_action_entry_update, NULL));
   5643     return BCM_E_NONE;
   5644 }
   5645 #endif /* BCM_TRIUMPH3_SUPPORT */
   5646 
   5647 /*
   5648  * Function:
   5649  *		_bcm_trx_vlan_translate_action_entry_set
   5650  * Purpose:
   5651  *		Set Vlan Translate Entry 
   5652  * Parameters:
   5653  *  IN :  Unit
   5654  *  IN :  vlan_xlate_entry
   5655  * Returns:
   5656  *		BCM_E_XXX
   5657  */
   5658 
   5659 STATIC int
   5660 _bcm_trx_vlan_translate_action_entry_set(int unit, void *vent)
   5661 {
   5662     vlan_xlate_entry_t return_vxent;
   5663     vlan_xlate_1_double_entry_t return_vx1dent;
   5664     int rv = BCM_E_UNAVAIL;
   5665     int index;
   5666     uint32 old_profile_idx = 0;
   5667     soc_mem_t mem = VLAN_XLATEm;
   5668     void *return_ent = &return_vxent;
   5669 
   5670     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
   5671         mem = VLAN_XLATE_1_DOUBLEm;
   5672         return_ent = &return_vx1dent;
   5673     }
   5674 
   5675     rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index,
   5676                         vent, return_ent, 0);
   5677 	
   5678     if (rv == SOC_E_NONE) {
   5679          /* Keep the old vlan translate profile index */
   5680          old_profile_idx = soc_mem_field32_get(unit, mem, return_ent,
   5681                                                   TAG_ACTION_PROFILE_PTRf);
   5682          BCM_IF_ERROR_RETURN(
   5683              _bcm_trx_vlan_translate_action_entry_update (unit, 
   5684                      vent, return_ent));
   5685          rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, return_ent);
   5686 
   5687          /* Delete the old vlan translate profile entry */
   5688          if ((rv == SOC_E_NONE) &&
   5689              (old_profile_idx != ing_action_profile_def[unit])) {
   5690              rv = _bcm_trx_vlan_action_profile_entry_delete(unit, old_profile_idx);
   5691 
   5692              if (BCM_FAILURE(rv)) {
   5693                  /* ignore if the non-used hardware default value */
   5694                  if ((!old_profile_idx) && (rv == SOC_E_PARAM ||
   5695                                             rv == SOC_E_NOT_FOUND)) {
   5696                      rv = BCM_E_NONE;
   5697                  } else {
   5698                      BCM_IF_ERROR_RETURN(rv);
   5699                  }
   5700              }
   5701          }
   5702     } else if (rv != SOC_E_NOT_FOUND) {
   5703         return rv;
   5704     } else {
   5705          rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, vent);
   5706     }
   5707 
   5708     return rv;
   5709 }
   5710 
   5711 
   5712 /*
   5713  * Function   :
   5714  *      _bcm_trx_vif_vlan_translate_action_add
   5715  * Description   :
   5716  *      Add an entry to ingress VLAN translation table.
   5717  * Parameters   :
   5718  *      unit            (IN) BCM unit number
   5719  *      port            (IN) Ingress generic port
   5720  *      key_type        (IN) Key Type : bcmVlanTranslateKey*
   5721  *      outer_vlan      (IN) Packet outer VLAN ID
   5722  *      inner_vlan      (IN) Packet inner VLAN ID
   5723  *      action          (IN) Action for outer and inner tag
   5724  */
   5725 STATIC int 
   5726 _bcm_trx_vif_vlan_translate_action_add(int unit,
   5727                                   bcm_gport_t port,
   5728                                   bcm_vlan_translate_key_t key_type,
   5729                                   bcm_vlan_t outer_vlan,
   5730                                   bcm_vlan_t inner_vlan,
   5731                                   bcm_vlan_action_set_t *action)
   5732 {
   5733 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
   5734     if (soc_feature(unit, soc_feature_niv)) {
   5735         uint32 profile_idx; 
   5736         int rv = BCM_E_NONE;
   5737         int search_rv;
   5738         vlan_xlate_entry_t vx_ent;
   5739         vlan_xlate_entry_t search_vx_ent;
   5740         vlan_xlate_1_double_entry_t vx1d_ent;
   5741         vlan_xlate_1_double_entry_t search_vx1d_ent;
   5742         int key_type_value;
   5743         int old_profile_idx = 0;
   5744         int index;
   5745     
   5746         soc_mem_t mem = VLAN_XLATEm;
   5747         soc_field_t vf = VALIDf;
   5748         void *vent = &vx_ent;
   5749         void *search_vent = &search_vx_ent;
   5750         uint32 ent_sz = sizeof(vlan_xlate_entry_t);
   5751 
   5752         if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
   5753             mem = VLAN_XLATE_1_DOUBLEm;
   5754             vf = BASE_VALID_0f; /* TD3TBD */
   5755             vent = &vx1d_ent;
   5756             search_vent= &search_vx1d_ent;
   5757             ent_sz = sizeof(vlan_xlate_1_double_entry_t);
   5758         }
   5759 
   5760         BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action));
   5761     
   5762         sal_memset(vent, 0, ent_sz);
   5763         BCM_IF_ERROR_RETURN(_bcm_trx_vif_vlan_translate_entry_assemble(unit, 
   5764                 vent, port, key_type, inner_vlan, outer_vlan));
   5765     
   5766         sal_memcpy(search_vent, vent, ent_sz);
   5767      
   5768         /* NIV port vxlate key type */
   5769         BCM_IF_ERROR_RETURN(_bcm_esw_vlan_xlate_key_type_value_get(unit,
   5770                        VLXLT_HASH_KEY_TYPE_VIF, &key_type_value));
   5771         soc_mem_field32_set(unit, mem, search_vent, KEY_TYPEf,
   5772                                           key_type_value);
   5773         if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
   5774             soc_mem_field32_set(unit, mem, search_vent, DATA_TYPEf, key_type_value);
   5775         }
   5776         soc_mem_field32_set(unit, mem, search_vent, VIF__VLANf, 0);
   5777     
   5778         search_rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index,
   5779                             search_vent, vent, 0);
   5780     
   5781         /* an entry should already exist */
   5782         if (search_rv != SOC_E_NONE) {
   5783             return search_rv;
   5784         }
   5785     
   5786         /* re-initialize the key */
   5787         BCM_IF_ERROR_RETURN(_bcm_trx_vif_vlan_translate_entry_assemble(unit, 
   5788                vent, port, key_type, inner_vlan, outer_vlan));
   5789         sal_memcpy(search_vent, vent, ent_sz);
   5790         search_rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index,
   5791                             search_vent, vent, 0);
   5792     
   5793         if (!(search_rv == SOC_E_NONE || search_rv == SOC_E_NOT_FOUND)) {
   5794             return search_rv;
   5795         }
   5796         if (search_rv == SOC_E_NONE) {
   5797             old_profile_idx = soc_mem_field32_get(unit, mem, vent,
   5798                                    VIF__TAG_ACTION_PROFILE_PTRf);
   5799         }
   5800     
   5801         /* update or fill in the vlan xlate entry*/
   5802         BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_profile_entry_add(unit, 
   5803                        action, &profile_idx));
   5804         soc_mem_field32_set(unit, mem, vent, VIF__TAG_ACTION_PROFILE_PTRf,
   5805                                     profile_idx);
   5806         if (SOC_MEM_FIELD_VALID(unit, mem, VIF__VLAN_ACTION_VALIDf)) {
   5807             soc_mem_field32_set(unit, mem, vent, VIF__VLAN_ACTION_VALIDf, 1);
   5808         }
   5809     
   5810         soc_mem_field32_set(unit, mem, vent, VIF__NEW_IVIDf,
   5811                                     action->new_inner_vlan);
   5812         soc_mem_field32_set(unit, mem, vent, VIF__NEW_OVIDf,
   5813                                     action->new_outer_vlan);
   5814         if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   5815             if (action->priority >= BCM_PRIO_MIN &&
   5816                 action->priority <= BCM_PRIO_MAX) {
   5817                 soc_mem_field32_set(unit, mem, vent, VIF__NEW_OPRIf,
   5818                           action->priority);
   5819             }
   5820             soc_mem_field32_set(unit, mem, vent, VIF__NEW_OCFIf,
   5821                                         action->new_outer_cfi);
   5822             soc_mem_field32_set(unit, mem, vent, VIF__NEW_IPRIf,
   5823                                         action->new_inner_pkt_prio);
   5824             soc_mem_field32_set(unit, mem, vent, VIF__NEW_ICFIf,
   5825                                         action->new_inner_cfi);
   5826         } 
   5827         if (mem == VLAN_XLATEm) {
   5828             soc_mem_field32_set(unit, mem, vent, vf, 1);
   5829         } else {
   5830             soc_mem_field32_set(unit, mem, vent, vf, 3);
   5831             soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7);
   5832         }
   5833 
   5834         /* Program L3_IIF */
   5835         if (SOC_MEM_FIELD_VALID(unit, VLAN_XLATEm, VIF__L3_IIF_VALIDf)) {
   5836             int intf_map_mode = 0;
   5837             int min_l3_iif;
   5838             int max_l3_iif;
   5839             max_l3_iif = BCM_XGS3_L3_ING_IF_TBL_SIZE(unit) - 1;
   5840             if (soc_feature(unit, soc_feature_l3_ingress_interface)) {
   5841                 BCM_IF_ERROR_RETURN(
   5842                     bcm_xgs3_l3_ingress_intf_map_get(unit, &intf_map_mode));
   5843             }
   5844 
   5845             if (intf_map_mode) {
   5846                 if (soc_feature(unit, soc_feature_l3_iif_zero_invalid)){
   5847                     min_l3_iif = 1;
   5848                 } else {
   5849                     min_l3_iif = 0;
   5850                 }
   5851             } else {
   5852                 min_l3_iif = BCM_VLAN_MAX + 1;
   5853             }
   5854             if ((action->ingress_if >= min_l3_iif) &&
   5855                 (action->ingress_if <= max_l3_iif)) {
   5856                 soc_mem_field32_set(unit, mem, vent, VIF__L3_IIF_VALIDf, 1);
   5857                 soc_mem_field32_set(unit, mem, vent, VIF__L3_IIFf,
   5858                                             action->ingress_if);
   5859             }
   5860         }
   5861     
   5862         if (search_rv == SOC_E_NONE) {
   5863             /* overrides existing one */
   5864             rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, vent);
   5865         } else { /* case search_rv == SOC_E_NOT_FOUND */
   5866            rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, vent);
   5867         }
   5868     
   5869         if (BCM_FAILURE(rv)) {
   5870             /* Delete the allocated vlan translate profile entry */
   5871             profile_idx = soc_mem_field32_get(unit, mem, vent,
   5872                                              VIF__TAG_ACTION_PROFILE_PTRf);
   5873             (void) _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx);
   5874         } else {
   5875             /* delete t the old profile entry */
   5876             if ((search_rv == SOC_E_NONE) &&
   5877                 (old_profile_idx != ing_action_profile_def[unit])) {
   5878                 rv = _bcm_trx_vlan_action_profile_entry_delete(unit,
   5879                          old_profile_idx);
   5880             }
   5881         }
   5882         return rv;
   5883     }
   5884 #endif   /* defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) */
   5885     return BCM_E_UNAVAIL;
   5886 
   5887 }
   5888 
   5889 
   5890 /*
   5891  * Function   :
   5892  *      _bcm_trx_lltag_vlan_translate_action_add
   5893  * Description   :
   5894  *      Add an entry to ingress VLAN translation table for LLTAG based VLAN port.
   5895  * Parameters   :
   5896  *      unit            (IN) BCM unit number
   5897  *      port            (IN) Ingress generic port
   5898  *      key_type        (IN) Key Type : bcmVlanTranslateKey*
   5899  *      outer_vlan      (IN) Packet outer VLAN ID
   5900  *      inner_vlan      (IN) Packet inner VLAN ID
   5901  *      action          (IN) Action for outer and inner tag
   5902  */
   5903 int 
   5904 _bcm_trx_lltag_vlan_translate_action_add(int unit,
   5905                                   bcm_gport_t port,
   5906                                   bcm_vlan_translate_key_t key_type,
   5907                                   bcm_vlan_t outer_vlan,
   5908                                   bcm_vlan_t inner_vlan,
   5909                                   bcm_vlan_action_set_t *action)
   5910 {
   5911     uint32 profile_idx; 
   5912     int rv;
   5913     vlan_xlate_entry_t vx_ent;
   5914     vlan_xlate_1_double_entry_t vx1d_ent;
   5915     ing_dvp_table_entry_t dvp_entry;
   5916     egr_l3_next_hop_entry_t egr_nh;
   5917     uint16 llvid, other_vlan;
   5918     int vp, nh_index;
   5919     soc_mem_t mem = VLAN_XLATEm;
   5920     soc_field_t vf = VALIDf;
   5921     void *vent = &vx_ent;
   5922     uint32 ent_sz = sizeof(vlan_xlate_entry_t);
   5923 
   5924     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
   5925         mem = VLAN_XLATE_1_DOUBLEm;
   5926         vf = BASE_VALID_0f; /* TD3TBD */
   5927         vent = &vx1d_ent;
   5928         ent_sz = sizeof(vlan_xlate_1_double_entry_t);
   5929     }
   5930 
   5931     BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action));
   5932 
   5933     if (!BCM_GPORT_IS_VLAN_PORT(port)) {
   5934         return BCM_E_PARAM;
   5935     }
   5936 
   5937     vp = BCM_GPORT_VLAN_PORT_ID_GET(port);
   5938 
   5939     if (vp >= soc_mem_index_count(unit, SOURCE_VPm)) {
   5940         return BCM_E_PARAM;
   5941     }
   5942 
   5943     /* For existing vlan vp, NH entry already exists */
   5944     BCM_IF_ERROR_RETURN
   5945         (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp_entry));
   5946 
   5947     nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp_entry,
   5948            NEXT_HOP_INDEXf);
   5949 
   5950     BCM_IF_ERROR_RETURN
   5951         (READ_EGR_L3_NEXT_HOPm(unit, MEM_BLOCK_ANY, nh_index, &egr_nh));
   5952 
   5953     llvid = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh,
   5954            SD_TAG__LLTAG_VIDf);
   5955 
   5956     sal_memset(vent, 0, ent_sz);
   5957 
   5958     switch (key_type) {
   5959         case bcmVlanTranslateKeyPortPonTunnel:
   5960             other_vlan = 0;
   5961             break;
   5962         case bcmVlanTranslateKeyPortPonTunnelOuter:
   5963             other_vlan = outer_vlan;
   5964             break;
   5965         case  bcmVlanTranslateKeyPortPonTunnelInner:
   5966             other_vlan = inner_vlan;
   5967             break;
   5968         default:
   5969             return BCM_E_PARAM;
   5970             break;
   5971     }
   5972     
   5973     BCM_IF_ERROR_RETURN(
   5974         _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, port, key_type,
   5975                                                llvid, other_vlan));
   5976 
   5977     BCM_IF_ERROR_RETURN
   5978         (_bcm_trx_vlan_action_profile_entry_add(unit, action, &profile_idx));
   5979     soc_mem_field32_set(unit, mem, vent, TAG_ACTION_PROFILE_PTRf, profile_idx);
   5980     if (SOC_MEM_FIELD_VALID(unit, VLAN_XLATEm, VLAN_ACTION_VALIDf)) {
   5981         soc_mem_field32_set(unit, mem, vent, VLAN_ACTION_VALIDf, 1);
   5982     }
   5983 
   5984     soc_mem_field32_set(unit, mem, vent, NEW_IVIDf, action->new_inner_vlan);
   5985     soc_mem_field32_set(unit, mem, vent, NEW_OVIDf, action->new_outer_vlan);
   5986     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   5987         if (action->priority >= BCM_PRIO_MIN &&
   5988             action->priority <= BCM_PRIO_MAX) {
   5989             soc_mem_field32_set(unit, mem, vent, NEW_OPRIf, action->priority);
   5990         }
   5991         soc_mem_field32_set(unit, mem, vent, NEW_OCFIf, action->new_outer_cfi);
   5992         soc_mem_field32_set(unit, mem, vent, NEW_IPRIf, action->new_inner_pkt_prio);
   5993         soc_mem_field32_set(unit, mem, vent, NEW_ICFIf, action->new_inner_cfi);
   5994     } else {
   5995         if (action->priority >= BCM_PRIO_MIN &&
   5996             action->priority <= BCM_PRIO_MAX) {
   5997             soc_mem_field32_set(unit, mem, vent, RPEf, 1);
   5998             soc_mem_field32_set(unit, mem, vent, PRIf, action->priority);
   5999         }
   6000     }
   6001 
   6002     if (mem == VLAN_XLATEm) {
   6003         soc_mem_field32_set(unit, mem, vent, vf, 1);
   6004     } else {
   6005         soc_mem_field32_set(unit, mem, vent, vf, 3);
   6006         soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7);
   6007     }
   6008 
   6009 #ifdef INCLUDE_L3
   6010     if (SOC_IS_TR_VL(unit) && (!SOC_IS_HURRICANEX(unit))) {
   6011 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   6012         if (SOC_MEM_FIELD_VALID(unit, mem, CLASS_IDf) &&
   6013                 (action->class_id)) {
   6014             soc_mem_field32_set(unit, mem, vent, CLASS_IDf, action->class_id);
   6015         } else
   6016 #endif
   6017             if (SOC_MEM_FIELD_VALID(unit, mem, MPLS_ACTIONf)) {
   6018             int intf_map_mode = 0; 
   6019             int min_l3_iif; 
   6020             int max_l3_iif; 
   6021 
   6022             max_l3_iif = BCM_XGS3_L3_ING_IF_TBL_SIZE(unit); 
   6023 #if defined(BCM_TRIUMPH_SUPPORT)
   6024             if (soc_feature(unit, soc_feature_l3_ingress_interface)) {
   6025                 BCM_IF_ERROR_RETURN (bcm_xgs3_l3_ingress_intf_map_get(unit,
   6026                                    &intf_map_mode));
   6027     }
   6028 #endif
   6029 
   6030             if (intf_map_mode) { 
   6031                 min_l3_iif = 0;
   6032             } else {
   6033                 min_l3_iif = BCM_VLAN_MAX + 1;
   6034             }
   6035             
   6036             if ((action->ingress_if >= min_l3_iif) && 
   6037                       (action->ingress_if < max_l3_iif)) {
   6038                 /* L3_IIF */
   6039                 soc_mem_field32_set(unit, mem, vent, MPLS_ACTIONf, 0x2);
   6040                 soc_mem_field32_set(unit, mem, vent, L3_IIFf, action->ingress_if);
   6041             } 
   6042         }
   6043     }
   6044 #endif /* INCLUDE_L3 */
   6045 
   6046 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   6047     if (SOC_IS_KATANAX(unit)) {
   6048         rv = _bcm_esw_add_policer_to_table(unit, action->policer_id,
   6049                                            mem, 0, vent);
   6050         BCM_IF_ERROR_RETURN(rv);
   6051     }
   6052 #endif /* BCM_KATANA_SUPPORT || BCM_APACHE_SUPPORT */
   6053     rv = _bcm_trx_vlan_translate_action_entry_set(unit, vent);
   6054 
   6055     if (BCM_FAILURE(rv)) {
   6056         /* Delete the old vlan translate profile entry */
   6057         profile_idx = soc_mem_field32_get(unit, mem, vent,
   6058                                                   TAG_ACTION_PROFILE_PTRf);
   6059         (void) _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx);
   6060     }
   6061    
   6062     return rv;
   6063 }
   6064 
   6065 /*
   6066  * Function   :
   6067  *      _bcm_trx_vlan_translate_action_add
   6068  * Description   :
   6069  *      Add an entry to ingress VLAN translation table.
   6070  * Parameters   :
   6071  *      unit            (IN) BCM unit number
   6072  *      port            (IN) Ingress generic port
   6073  *      key_type        (IN) Key Type : bcmVlanTranslateKey*
   6074  *      outer_vlan      (IN) Packet outer VLAN ID
   6075  *      inner_vlan      (IN) Packet inner VLAN ID
   6076  *      action          (IN) Action for outer and inner tag
   6077  */
   6078 int 
   6079 _bcm_trx_vlan_translate_action_add(int unit,
   6080                                   bcm_gport_t port,
   6081                                   bcm_vlan_translate_key_t key_type,
   6082                                   bcm_vlan_t outer_vlan,
   6083                                   bcm_vlan_t inner_vlan,
   6084                                   bcm_vlan_action_set_t *action)
   6085 {
   6086     uint32 profile_idx; 
   6087     int rv, vp = 0;
   6088     vlan_xlate_entry_t vx_ent;
   6089     vlan_xlate_1_double_entry_t vx1d_ent;
   6090     uint16 llvid = 0;
   6091     soc_mem_t mem = VLAN_XLATEm;
   6092     soc_field_t vf = VALIDf;
   6093     void *vent = &vx_ent;
   6094     uint32 ent_sz = sizeof(vlan_xlate_entry_t);
   6095 
   6096     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
   6097         mem = VLAN_XLATE_1_DOUBLEm;
   6098         vf = BASE_VALID_0f; /* TD3TBD */
   6099         vent = &vx1d_ent;
   6100         ent_sz = sizeof(vlan_xlate_1_double_entry_t);
   6101     }
   6102 
   6103     if ((key_type == bcmVlanTranslateKeyPortPonTunnel || 
   6104         key_type == bcmVlanTranslateKeyPortPonTunnelOuter || 
   6105         key_type == bcmVlanTranslateKeyPortPonTunnelInner) && 
   6106         !soc_feature(unit, soc_feature_lltag)) {
   6107         return BCM_E_UNAVAIL;
   6108     }
   6109 
   6110 #if defined(BCM_TRIDENT2_SUPPORT)
   6111     if ((!soc_feature(unit, soc_feature_vlan_xlate_iif_with_dummy_vp) ||
   6112          !soc_property_get(unit, spn_VLAN_ACTION_DUMMY_VP_RESERVED, 0)) &&
   6113          (action->flags & BCM_VLAN_ACTION_SET_DUMMY_VP)) {
   6114         return BCM_E_UNAVAIL;
   6115     }
   6116 #endif /* BCM_TRIDENT2_SUPPORT */
   6117 
   6118     /* process the NIV type of gport */
   6119     if (BCM_GPORT_IS_NIV_PORT(port)) {
   6120         int rv;
   6121         rv = _bcm_trx_vif_vlan_translate_action_add(unit,
   6122              port,key_type,outer_vlan,inner_vlan,action);
   6123         return rv;
   6124     } else if (BCM_GPORT_IS_VLAN_PORT(port)) {
   6125         if (key_type == bcmVlanTranslateKeyPortPonTunnel || 
   6126             key_type == bcmVlanTranslateKeyPortPonTunnelOuter || 
   6127             key_type == bcmVlanTranslateKeyPortPonTunnelInner) {
   6128             ing_dvp_table_entry_t dvp_entry;
   6129             egr_l3_next_hop_entry_t egr_nh;
   6130             int nh_index;
   6131 
   6132             if (!soc_feature(unit, soc_feature_lltag)) {
   6133                 return BCM_E_UNAVAIL;
   6134             }
   6135 
   6136             vp = BCM_GPORT_VLAN_PORT_ID_GET(port);
   6137             /* For existing vlan vp, NH entry already exists */
   6138             BCM_IF_ERROR_RETURN
   6139                     (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp_entry));
   6140 
   6141             nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp_entry,
   6142                     NEXT_HOP_INDEXf);
   6143 
   6144             BCM_IF_ERROR_RETURN
   6145                     (READ_EGR_L3_NEXT_HOPm(unit, MEM_BLOCK_ANY, nh_index, &egr_nh));
   6146 
   6147             llvid = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh,
   6148                     SD_TAG__LLTAG_VIDf);
   6149         }
   6150     }
   6151 
   6152     BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action));
   6153 
   6154     sal_memset(vent, 0, ent_sz);
   6155     switch (key_type) {
   6156         case bcmVlanTranslateKeyPortPonTunnel:
   6157             rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, port, key_type,
   6158                                                llvid, 0); 
   6159             break;
   6160         case bcmVlanTranslateKeyPortPonTunnelOuter:
   6161             rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, port, key_type,
   6162                                                llvid, outer_vlan);
   6163             break;
   6164         case bcmVlanTranslateKeyPortPonTunnelInner:
   6165             rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, port, key_type,
   6166                                                llvid, inner_vlan);
   6167             break;
   6168         default:
   6169             rv = _bcm_trx_vlan_translate_entry_assemble(unit, vent, port, key_type,
   6170                                                inner_vlan, outer_vlan);
   6171             break;        
   6172     }
   6173     
   6174     BCM_IF_ERROR_RETURN(rv);
   6175 	    
   6176     if (key_type == bcmVlanTranslateKeyPortPonTunnel ||
   6177         key_type == bcmVlanTranslateKeyPortPonTunnelOuter ||
   6178         key_type == bcmVlanTranslateKeyPortPonTunnelInner) {
   6179         soc_mem_field32_set(unit, mem, vent, LLTAG__SOURCE_VPf, vp);
   6180         if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) {
   6181             soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1);
   6182         } 
   6183         if (SOC_MEM_FIELD_VALID(unit, mem, MPLS_ACTIONf)) {
   6184             soc_mem_field32_set(unit, mem, vent, MPLS_ACTIONf, 1);
   6185         }
   6186     }
   6187     BCM_IF_ERROR_RETURN
   6188         (_bcm_trx_vlan_action_profile_entry_add(unit, action, &profile_idx));
   6189     soc_mem_field32_set(unit, mem, vent, TAG_ACTION_PROFILE_PTRf,
   6190                                 profile_idx);
   6191     if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_ACTION_VALIDf)) {
   6192         soc_mem_field32_set(unit, mem, vent, VLAN_ACTION_VALIDf, 1);
   6193     }
   6194 
   6195     if (SOC_MEM_FIELD_VALID(unit, mem, DISABLE_VLAN_CHECKSf)) {
   6196         if (action->flags & BCM_VLAN_ACTION_SET_VLAN_CHECKS_DISABLE) {
   6197             soc_mem_field32_set(unit, mem, vent, DISABLE_VLAN_CHECKSf, 1);
   6198         }
   6199     }
   6200 #if defined(BCM_TSN_SR_SUPPORT)
   6201     if (soc_feature(unit, soc_feature_tsn_sr)) {
   6202         if ((!(action->flags & BCM_VLAN_ACTION_SET_SR_ENABLE)) &&
   6203               (action->flags & BCM_VLAN_ACTION_SET_SR_LAN_ID)) {
   6204            return BCM_E_PARAM;
   6205         }
   6206 
   6207         if (action->flags & BCM_VLAN_ACTION_SET_SR_ENABLE) {
   6208             soc_mem_field32_set(unit, mem, vent, SR_ENABLEf, 1);
   6209             soc_mem_field32_set(unit, mem, vent, SR_LAN_ID_VALIDf, 1);
   6210             if (action->flags & BCM_VLAN_ACTION_SET_SR_LAN_ID) {
   6211                 soc_mem_field32_set(unit, mem, vent, SR_LAN_IDf, 1);
   6212             }
   6213         }
   6214     }
   6215 #endif /* BCM_TSN_SR_SUPPORT*/
   6216 
   6217 #if defined(BCM_TSN_SUPPORT)
   6218     if (soc_feature(unit, soc_feature_tsn_taf) &&
   6219         SOC_MEM_FIELD_VALID(unit, mem, TAF_GATE_ID_PROFILEf)) {
   6220         uint32 hw_index;
   6221 
   6222         if (BCM_TSN_PRI_MAP_INVALID != action->taf_gate_primap) {
   6223             bcm_tsn_pri_map_type_t map;
   6224 
   6225             BCM_IF_ERROR_RETURN(
   6226                 bcmi_esw_tsn_pri_map_hw_index_get(unit, action->taf_gate_primap,
   6227                                                   &map, &hw_index));
   6228 
   6229             if (map != bcmTsnPriMapTypeTafGate) {
   6230                 return BCM_E_PARAM;
   6231             }
   6232         } else {
   6233             hw_index = 0;
   6234         }
   6235         soc_mem_field32_set(unit, mem, vent,
   6236                             TAF_GATE_ID_PROFILEf, hw_index);
   6237     }
   6238 #endif /* BCM_TSN_SUPPORT */
   6239 
   6240     soc_mem_field32_set(unit, mem, vent, NEW_IVIDf, action->new_inner_vlan);
   6241     soc_mem_field32_set(unit, mem, vent, NEW_OVIDf, action->new_outer_vlan);
   6242     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   6243         if (action->priority >= BCM_PRIO_MIN &&
   6244             action->priority <= BCM_PRIO_MAX) {
   6245             soc_mem_field32_set(unit, mem, vent, NEW_OPRIf, action->priority);
   6246         }
   6247         soc_mem_field32_set(unit, mem, vent, NEW_OCFIf, action->new_outer_cfi);
   6248         soc_mem_field32_set(unit, mem, vent, NEW_IPRIf,
   6249                                     action->new_inner_pkt_prio);
   6250         soc_mem_field32_set(unit, mem, vent, NEW_ICFIf, action->new_inner_cfi);
   6251     } else {
   6252         if (action->priority >= BCM_PRIO_MIN &&
   6253             action->priority <= BCM_PRIO_MAX) {
   6254             soc_mem_field32_set(unit, mem, vent, RPEf, 1);
   6255             soc_mem_field32_set(unit, mem, vent, PRIf, action->priority);
   6256         }
   6257     }
   6258     if (mem == VLAN_XLATEm) {
   6259         soc_mem_field32_set(unit, mem, vent, vf, 1);
   6260     } else {
   6261         soc_mem_field32_set(unit, mem, vent, vf, 3);
   6262         soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7);
   6263     }
   6264 
   6265 #if defined(BCM_TRIUMPH3_SUPPORT)
   6266     if (SOC_IS_TRIUMPH3(unit)) {
   6267         rv = _bcm_tr3_vlan_translate_action_entry_set(unit, vent, action);
   6268         if (BCM_FAILURE(rv)) {
   6269             /* Delete the old vlan translate profile entry */
   6270             profile_idx = soc_mem_field32_get(unit, mem, vent,
   6271                                                   TAG_ACTION_PROFILE_PTRf);
   6272             (void) _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx);
   6273         }
   6274     } else
   6275 #endif /* BCM_TRIUMPH3_SUPPORT */
   6276     {
   6277 #ifdef INCLUDE_L3
   6278         if (SOC_IS_TR_VL(unit) &&
   6279             (!SOC_IS_HURRICANE(unit) || !SOC_IS_HURRICANE2(unit))) {
   6280 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   6281             if (SOC_MEM_FIELD_VALID(unit, mem, CLASS_IDf) && action->class_id) {
   6282                 soc_mem_field32_set(
   6283                     unit, mem, vent, CLASS_IDf, action->class_id);
   6284             } else
   6285 #endif
   6286             if (SOC_MEM_FIELD_VALID(unit, mem, MPLS_ACTIONf)) {
   6287                 int intf_map_mode = 0;
   6288                 int min_l3_iif;   /* the minimum valid l3_iif index */
   6289                 int max_l3_iif;   /* the maximum valid l3_iif index */
   6290 
   6291                 max_l3_iif = BCM_XGS3_L3_ING_IF_TBL_SIZE(unit) - 1;
   6292 #if defined(BCM_TRIUMPH_SUPPORT)
   6293                 if (soc_feature(unit, soc_feature_l3_ingress_interface)) {
   6294                     BCM_IF_ERROR_RETURN (
   6295                         bcm_xgs3_l3_ingress_intf_map_get(unit, &intf_map_mode));
   6296                 }
   6297 #endif
   6298 
   6299                 if (intf_map_mode) {
   6300                     if (soc_feature(unit, soc_feature_l3_iif_zero_invalid)){
   6301                         min_l3_iif = 1;
   6302                     } else {
   6303                         min_l3_iif = 0;
   6304                     }
   6305                 } else {
   6306                     min_l3_iif = BCM_VLAN_MAX + 1;
   6307                 }
   6308 
   6309                 if ((action->ingress_if >= min_l3_iif) &&
   6310                       (action->ingress_if <= max_l3_iif)) {
   6311                     /* L3_IIF */
   6312 #if defined(BCM_TRIDENT2_SUPPORT)
   6313                     if ((action->flags & BCM_VLAN_ACTION_SET_DUMMY_VP) &&
   6314                         soc_feature(unit,
   6315                             soc_feature_vlan_xlate_iif_with_dummy_vp) &&
   6316                         soc_property_get(
   6317                             unit, spn_VLAN_ACTION_DUMMY_VP_RESERVED, 0)) {
   6318                         soc_mem_field32_set(unit, mem, vent, MPLS_ACTIONf, 0x3);
   6319                         soc_mem_field32_set(unit, mem, vent, L3_IIFf,
   6320                                             action->ingress_if);
   6321                         soc_mem_field32_set(unit, mem, vent, SOURCE_VPf,
   6322                                             _BCM_VLAN_XLATE_DUMMY_PORT);
   6323                     } else
   6324 #endif /* BCM_TRIDENT2_SUPPORT */
   6325                     {
   6326                         soc_mem_field32_set(unit, mem, vent, MPLS_ACTIONf, 0x2);
   6327                         soc_mem_field32_set(unit, mem, vent, L3_IIFf,
   6328                                             action->ingress_if);
   6329                     }
   6330                 }
   6331             }
   6332         }
   6333 #endif /* INCLUDE_L3 */
   6334 
   6335 #if defined(BCM_GREYHOUND2_SUPPORT)
   6336         if (soc_feature(unit, soc_feature_global_meter) &&
   6337             SOC_IS_GREYHOUND2(unit)) {
   6338             rv = _bcm_esw_policer_validate(unit, &action->policer_id);
   6339             if (BCM_SUCCESS(rv)) {
   6340                 rv = _bcm_esw_add_policer_to_table(
   6341                         unit, action->policer_id,
   6342                         mem, 0, vent);
   6343                 BCM_IF_ERROR_RETURN(rv);
   6344             }
   6345         }
   6346 #endif /* BCM_GREYHOUND2_SUPPORT */
   6347 
   6348 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   6349         if (soc_feature(unit, soc_feature_global_meter) &&
   6350             (SOC_IS_KATANAX(unit) || SOC_IS_APACHE(unit))) {
   6351             rv = _bcm_esw_add_policer_to_table(unit, action->policer_id,
   6352                                                mem, 0, vent);
   6353             BCM_IF_ERROR_RETURN(rv);
   6354         }
   6355 #endif /* BCM_KATANA_SUPPORT || BCM_APACHE_SUPPORT */
   6356         rv = _bcm_trx_vlan_translate_action_entry_set(unit, vent);
   6357 
   6358         if (BCM_FAILURE(rv)) {
   6359             /* Delete the old vlan translate profile entry */
   6360             profile_idx = soc_mem_field32_get(unit, mem, vent,
   6361                                                       TAG_ACTION_PROFILE_PTRf);
   6362             (void) _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx);
   6363         }
   6364     }
   6365     return rv;
   6366 }
   6367 
   6368 /*
   6369  * Function:
   6370  *      _bcm_trx_vlan_translate_get
   6371  * Purpose:
   6372  *      Gets a vlan translate entry.
   6373  * Parameters:
   6374  *      unit            (IN) BCM unit number
   6375  *      port            (IN) Ingress generic port
   6376  *      key_type        (IN) Key Type : bcmVlanTranslateKey*
   6377  *      old_vlan        (IN) Packet old VLAN ID
   6378  *      new_vlan        (OUT) Packet new VLAN ID
   6379  *      prio            (OUT) Packet prio
   6380  */
   6381 int 
   6382 _bcm_trx_vlan_translate_action_get (int unit, 
   6383                                    bcm_gport_t port, 
   6384                                    bcm_vlan_translate_key_t key_type, 
   6385                                    bcm_vlan_t outer_vid,
   6386                                    bcm_vlan_t inner_vid,
   6387                                    bcm_vlan_action_set_t *action)
   6388 {
   6389     vlan_xlate_entry_t  vx_ent, res_vx_ent;
   6390     vlan_xlate_1_double_entry_t  vx1d_ent, res_vx1d_ent;
   6391     int                 rv;
   6392     int                 idx = 0;
   6393     uint32              profile_idx = 0;
   6394     uint16 llvid = 0;
   6395     
   6396     soc_mem_t mem = VLAN_XLATEm;
   6397     void *vent = &vx_ent;
   6398     void *res_vent = &res_vx_ent;
   6399     uint32 ent_sz = sizeof(vlan_xlate_entry_t);
   6400 
   6401     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
   6402         mem = VLAN_XLATE_1_DOUBLEm;
   6403         vent = &vx1d_ent;
   6404         res_vent = &res_vx1d_ent;
   6405         ent_sz = sizeof(vlan_xlate_1_double_entry_t);
   6406     }
   6407 
   6408     if ((key_type == bcmVlanTranslateKeyPortPonTunnel || 
   6409        key_type == bcmVlanTranslateKeyPortPonTunnelOuter || 
   6410        key_type == bcmVlanTranslateKeyPortPonTunnelInner) &&
   6411        !soc_feature(unit, soc_feature_lltag)) {
   6412         return BCM_E_PARAM;
   6413     }
   6414 
   6415     sal_memset(vent, 0, ent_sz);
   6416     sal_memset(res_vent, 0, ent_sz);
   6417     if (BCM_GPORT_IS_NIV_PORT(port)) {
   6418         BCM_IF_ERROR_RETURN(
   6419             _bcm_trx_vif_vlan_translate_entry_assemble(unit, vent, port,
   6420                          key_type,inner_vid, outer_vid));
   6421 
   6422         rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, &idx,
   6423                             vent, res_vent, 0);
   6424         BCM_IF_ERROR_RETURN(rv);
   6425         profile_idx = soc_mem_field32_get(unit, mem, res_vent,
   6426                                       VIF__TAG_ACTION_PROFILE_PTRf);       
   6427         _bcm_trx_vlan_action_profile_entry_get(unit, action, profile_idx);
   6428         return _bcm_trx_vif_vlan_translate_entry_parse(unit, mem,
   6429                                                (uint32 *)res_vent, action);
   6430     } else if (BCM_GPORT_IS_VLAN_PORT(port)) {
   6431         if (key_type == bcmVlanTranslateKeyPortPonTunnel || 
   6432             key_type == bcmVlanTranslateKeyPortPonTunnelOuter || 
   6433             key_type == bcmVlanTranslateKeyPortPonTunnelInner) {
   6434             ing_dvp_table_entry_t dvp_entry;
   6435             egr_l3_next_hop_entry_t egr_nh;
   6436             int vp, nh_index;
   6437 
   6438             if (!soc_feature(unit, soc_feature_lltag)) {
   6439                 return BCM_E_UNAVAIL;
   6440             }
   6441 
   6442             vp = BCM_GPORT_VLAN_PORT_ID_GET(port);;
   6443             /* For existing vlan vp, NH entry already exists */
   6444             BCM_IF_ERROR_RETURN
   6445                     (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp_entry));
   6446 
   6447             nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp_entry,
   6448                     NEXT_HOP_INDEXf);
   6449 
   6450             BCM_IF_ERROR_RETURN
   6451                     (READ_EGR_L3_NEXT_HOPm(unit, MEM_BLOCK_ANY, nh_index, &egr_nh));
   6452 
   6453             llvid = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh,
   6454                     SD_TAG__LLTAG_VIDf);
   6455         }
   6456     }
   6457 
   6458     switch (key_type) {
   6459         case bcmVlanTranslateKeyPortPonTunnel:
   6460             rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, port, key_type,
   6461                                                llvid, 0); 
   6462             break;
   6463         case bcmVlanTranslateKeyPortPonTunnelOuter:
   6464             rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, port, key_type,
   6465                                                llvid, outer_vid);
   6466             break;
   6467         case bcmVlanTranslateKeyPortPonTunnelInner:
   6468             rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, port, key_type,
   6469                                                llvid, inner_vid);
   6470             break;
   6471         default:
   6472             rv = _bcm_trx_vlan_translate_entry_assemble(unit, vent, port, key_type,
   6473                                                inner_vid, outer_vid);
   6474             break;        
   6475     }
   6476     
   6477     BCM_IF_ERROR_RETURN(rv);
   6478     
   6479     soc_mem_lock(unit, mem);
   6480     rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, &idx, vent, res_vent, 0);
   6481     soc_mem_unlock(unit, mem);
   6482 
   6483 #if defined(BCM_TRIUMPH3_SUPPORT)
   6484     if (SOC_IS_TRIUMPH3(unit)) {
   6485         vlan_xlate_extd_entry_t vxent;
   6486         vlan_xlate_extd_entry_t res_vxent;
   6487 
   6488         /* check the extd table */
   6489         if (rv == SOC_E_NOT_FOUND) {
   6490             BCM_IF_ERROR_RETURN
   6491                 (_bcm_tr3_vxlate2vxlate_extd(unit, vent, &vxent));
   6492 
   6493             soc_mem_lock(unit, VLAN_XLATE_EXTDm);
   6494             rv = soc_mem_search(unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ALL, &idx, 
   6495                             &vxent, &res_vxent, 0);
   6496             soc_mem_unlock(unit, VLAN_XLATE_EXTDm);
   6497             BCM_IF_ERROR_RETURN(rv);
   6498             profile_idx = soc_VLAN_XLATE_EXTDm_field32_get(unit, &res_vxent,
   6499                                           TAG_ACTION_PROFILE_PTRf);       
   6500             _bcm_trx_vlan_action_profile_entry_get(unit, action, profile_idx);
   6501 
   6502              return _bcm_trx_vlan_translate_entry_parse(unit, VLAN_XLATE_EXTDm,
   6503                                                (uint32 *)&res_vxent, action);  
   6504             
   6505         }
   6506     } 
   6507 #endif
   6508     BCM_IF_ERROR_RETURN(rv);
   6509     profile_idx = soc_mem_field32_get(unit, mem, res_vent,
   6510                                               TAG_ACTION_PROFILE_PTRf);       
   6511     _bcm_trx_vlan_action_profile_entry_get(unit, action, profile_idx);
   6512 
   6513     return _bcm_trx_vlan_translate_entry_parse(unit, mem,
   6514                                                res_vent, action);
   6515 }
   6516 
   6517 
   6518 /*
   6519  * Function:
   6520  *      bcm_vlan_translate_action_delete
   6521  * Purpose:
   6522  *      Delete a vlan translate lookup entry.
   6523  * Parameters:
   6524  *      unit            (IN) BCM unit number
   6525  *      port            (IN) Ingress generic port
   6526  *      key_type        (IN) Key Type : bcmVlanTranslateKey*
   6527  *      outer_vlan      (IN) Packet outer VLAN ID
   6528  *      inner_vlan      (IN) Packet inner VLAN ID
   6529  */
   6530 int 
   6531 _bcm_trx_vlan_translate_action_delete(int unit,
   6532                                      bcm_gport_t port,
   6533                                      bcm_vlan_translate_key_t key_type,
   6534                                      bcm_vlan_t outer_vlan,
   6535                                      bcm_vlan_t inner_vlan)
   6536 {
   6537     vlan_xlate_entry_t vx_ent;
   6538     vlan_xlate_1_double_entry_t vx1d_ent;
   6539     uint32 profile_idx;
   6540     int rv;
   6541 #if defined(BCM_TRIUMPH3_SUPPORT)
   6542     int rv_vxlate_delete;
   6543 #endif
   6544     uint16 llvid = 0;
   6545 
   6546     soc_mem_t mem = VLAN_XLATEm;
   6547     soc_field_t vf = VALIDf;
   6548     void *vent = &vx_ent;
   6549     uint32 ent_sz = sizeof(vx_ent);
   6550 
   6551 #if defined(BCM_TRIUMPH2_SUPPORT)
   6552     _bcm_flex_stat_handle_t handle;
   6553     _BCM_FLEX_STAT_HANDLE_CLEAR(handle);
   6554 #endif
   6555 
   6556 
   6557     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
   6558         mem = VLAN_XLATE_1_DOUBLEm;
   6559         vf = BASE_VALID_0f; /* TD3TBD */
   6560         vent = &vx1d_ent;
   6561         ent_sz = sizeof(vx1d_ent);
   6562     }
   6563 
   6564     if ((key_type == bcmVlanTranslateKeyPortPonTunnel || 
   6565        key_type == bcmVlanTranslateKeyPortPonTunnelOuter || 
   6566        key_type == bcmVlanTranslateKeyPortPonTunnelInner) &&
   6567        !soc_feature(unit, soc_feature_lltag)) {
   6568         return BCM_E_PARAM;
   6569     }
   6570         
   6571     sal_memset(vent, 0, ent_sz);
   6572 
   6573     if (BCM_GPORT_IS_NIV_PORT(port)) {
   6574         BCM_IF_ERROR_RETURN(
   6575             _bcm_trx_vif_vlan_translate_entry_assemble(unit, vent, port,
   6576                          key_type,inner_vlan, outer_vlan));
   6577         rv = soc_mem_delete_return_old(unit, mem, MEM_BLOCK_ALL,
   6578                                        vent, vent);
   6579         if ((rv == SOC_E_NONE) && 
   6580             (soc_mem_field32_get(unit, mem, vent, vf) == 3) &&
   6581             (soc_mem_field32_get(unit, mem, vent, BASE_VALID_1f) == 7)) {
   6582             profile_idx = soc_mem_field32_get(unit, mem, vent,
   6583                                         VIF__TAG_ACTION_PROFILE_PTRf);       
   6584             /* Delete the old vlan action profile entry */
   6585             if (profile_idx != ing_action_profile_def[unit]) {
   6586                 rv = _bcm_trx_vlan_action_profile_entry_delete(unit,
   6587                                                                profile_idx);
   6588             }
   6589         }
   6590         return rv;
   6591     } else if (BCM_GPORT_IS_VLAN_PORT(port)) {
   6592         if (key_type == bcmVlanTranslateKeyPortPonTunnel || 
   6593             key_type == bcmVlanTranslateKeyPortPonTunnelOuter || 
   6594             key_type == bcmVlanTranslateKeyPortPonTunnelInner) {
   6595             ing_dvp_table_entry_t dvp_entry;
   6596             egr_l3_next_hop_entry_t egr_nh;
   6597             int vp, nh_index;
   6598 
   6599             if (!soc_feature(unit, soc_feature_lltag)) {
   6600                 return BCM_E_UNAVAIL;
   6601             }
   6602 
   6603             vp = BCM_GPORT_VLAN_PORT_ID_GET(port);
   6604             /* For existing vlan vp, NH entry already exists */
   6605             BCM_IF_ERROR_RETURN
   6606                     (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp_entry));
   6607 
   6608             nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp_entry,
   6609                     NEXT_HOP_INDEXf);
   6610 
   6611             BCM_IF_ERROR_RETURN
   6612                     (READ_EGR_L3_NEXT_HOPm(unit, MEM_BLOCK_ANY, nh_index, &egr_nh));
   6613 
   6614             llvid = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_nh,
   6615                     SD_TAG__LLTAG_VIDf);
   6616         }
   6617     }
   6618 
   6619     switch (key_type) {
   6620         case bcmVlanTranslateKeyPortPonTunnel:
   6621             rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, port, key_type,
   6622                                                llvid, 0); 
   6623             break;
   6624         case bcmVlanTranslateKeyPortPonTunnelOuter:
   6625             rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, port, key_type,
   6626                                                llvid, outer_vlan);
   6627             break;
   6628         case bcmVlanTranslateKeyPortPonTunnelInner:
   6629             rv = _bcm_trx_lltag_vlan_translate_entry_assemble(unit, vent, port, key_type,
   6630                                                llvid, inner_vlan);
   6631             break;
   6632         default:
   6633             rv = _bcm_trx_vlan_translate_entry_assemble(unit, vent, port, key_type,
   6634                                                inner_vlan, outer_vlan);
   6635             break;        
   6636     }
   6637     
   6638     BCM_IF_ERROR_RETURN(rv);
   6639 
   6640 
   6641 #if defined(BCM_TRIUMPH2_SUPPORT)
   6642         if (soc_feature(unit, soc_feature_gport_service_counters)) {
   6643             /* Record flex stat info before the returned entry
   6644              * includes non-key info. */
   6645 
   6646             /* _BCM_FLEX_STAT_HANDLE_COPY(handle, vent); */
   6647             memcpy(&handle, vent, sizeof(_bcm_flex_stat_handle_t));
   6648         }
   6649 #endif
   6650 
   6651     rv = soc_mem_delete_return_old(unit, mem, MEM_BLOCK_ALL, vent, vent);
   6652 #if defined(BCM_TRIUMPH3_SUPPORT)
   6653     rv_vxlate_delete = rv;
   6654 #endif
   6655     if ((rv == SOC_E_NONE) && soc_mem_field32_get(unit, mem, vent, vf)) {
   6656         profile_idx = soc_mem_field32_get(unit, mem, vent,
   6657                                                   TAG_ACTION_PROFILE_PTRf);       
   6658         /* Delete the old vlan action profile entry */
   6659         if (profile_idx != ing_action_profile_def[unit]) {
   6660             rv = _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx);
   6661         }
   6662 
   6663 #if defined(BCM_TRIUMPH2_SUPPORT)
   6664         if (soc_feature(unit, soc_feature_gport_service_counters) &&
   6665             (0 != soc_mem_field32_get(unit, mem, vent, VINTF_CTR_IDXf))) {
   6666             /* Release Service counter */
   6667             _bcm_esw_flex_stat_ext_handle_free(unit, _bcmFlexStatTypeVxlt,
   6668                                                handle);
   6669         }
   6670 #endif
   6671     }
   6672 #if defined(BCM_GREYHOUND2_SUPPORT)
   6673     if (soc_feature(unit, soc_feature_global_meter) &&
   6674         SOC_IS_GREYHOUND2(unit)) {
   6675         bcm_policer_t current_policer_id;
   6676         int policer_rv = 0;
   6677         policer_rv = _bcm_esw_get_policer_from_table(unit, VLAN_XLATEm, 0, vent,
   6678                                              &current_policer_id, 1);
   6679         BCM_IF_ERROR_RETURN(policer_rv);
   6680         policer_rv = _bcm_esw_policer_validate(unit, &current_policer_id);
   6681         if (BCM_SUCCESS(policer_rv)) {
   6682             policer_rv = _bcm_esw_policer_decrement_ref_count(
   6683                     unit, current_policer_id);
   6684             BCM_IF_ERROR_RETURN(policer_rv);
   6685         }
   6686     }
   6687 #endif /* BCM_GREYHOUND2_SUPPORT */
   6688 
   6689 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_APACHE_SUPPORT)
   6690     if (soc_feature(unit, soc_feature_global_meter) &&
   6691        (SOC_IS_KATANAX(unit) || SOC_IS_APACHE(unit))) {
   6692         bcm_policer_t current_policer;
   6693         int policer_rv = 0;
   6694         policer_rv = _bcm_esw_get_policer_from_table(unit, VLAN_XLATEm, 0, vent,
   6695                                              &current_policer, 1);
   6696         if (current_policer != 0) {
   6697             if ((current_policer & BCM_POLICER_GLOBAL_METER_INDEX_MASK) > 0) {
   6698                 policer_rv = _bcm_esw_policer_decrement_ref_count(unit, current_policer);
   6699                 BCM_IF_ERROR_RETURN(policer_rv);
   6700             }
   6701         }
   6702     }
   6703 #endif /* BCM_KATANA_SUPPORT || BCM_APACHE_SUPPORT */
   6704 
   6705 #if defined(BCM_TRIUMPH3_SUPPORT)
   6706     if (SOC_IS_TRIUMPH3(unit)) {
   6707         vlan_xlate_extd_entry_t vxent;
   6708 
   6709         /* check the extend table */
   6710         sal_memset(&vxent, 0, sizeof(vxent));
   6711         BCM_IF_ERROR_RETURN
   6712             (_bcm_tr3_vxlate2vxlate_extd(unit, vent, &vxent));
   6713         rv = soc_mem_delete_return_old(unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ALL,
   6714                      &vxent, &vxent);
   6715         if ((rv == SOC_E_NONE) && soc_VLAN_XLATE_EXTDm_field32_get(unit, 
   6716                         &vxent, VALID_0f)) {
   6717             profile_idx = soc_VLAN_XLATE_EXTDm_field32_get(unit, &vxent,
   6718                                                   TAG_ACTION_PROFILE_PTRf); 
   6719             /* Delete the old vlan action profile entry */
   6720             if (profile_idx != ing_action_profile_def[unit]) {
   6721                 rv = _bcm_trx_vlan_action_profile_entry_delete(unit,
   6722                                                                profile_idx);
   6723             }
   6724         } else {
   6725             /* if an entry is already found in regular table, then reset ret code*/
   6726             if (rv == BCM_E_NOT_FOUND) {
   6727                 if (rv_vxlate_delete == BCM_E_NONE) {
   6728                     rv = BCM_E_NONE;
   6729                 }
   6730             }
   6731         }
   6732     }
   6733 #endif
   6734 
   6735     return rv;
   6736 }
   6737 
   6738 #if defined(BCM_TRIUMPH3_SUPPORT)
   6739 /*
   6740  * Function:
   6741  *      _bcm_tr3_vxlate_action_delete_extd_tbl
   6742  * Purpose:
   6743  *      Delete all vlan translate lookup entries.
   6744  * Parameters:
   6745  *      unit      (IN) BCM unit number
   6746  * Returns:
   6747  *      BCM_E_XXX
   6748  */
   6749 STATIC int
   6750 _bcm_tr3_vxlate_action_delete_extd_tbl(int unit) 
   6751 {
   6752     int i, imin, imax, nent, vbytes, rv, mpls;
   6753     vlan_xlate_extd_entry_t * vtab, * vnull,  *vtabp;
   6754     
   6755     imin = soc_mem_index_min(unit, VLAN_XLATE_EXTDm);
   6756     imax = soc_mem_index_max(unit, VLAN_XLATE_EXTDm);
   6757     nent = soc_mem_index_count(unit, VLAN_XLATE_EXTDm);
   6758     vbytes = soc_mem_entry_words(unit, VLAN_XLATE_EXTDm);
   6759     vbytes = WORDS2BYTES(vbytes);
   6760     vtab = soc_cm_salloc(unit, nent * sizeof(*vtab), "vlan_xlate_extd");
   6761 
   6762     if (vtab == NULL) {
   6763         return BCM_E_MEMORY;
   6764     }
   6765     
   6766     vnull = soc_mem_entry_null(unit, VLAN_XLATE_EXTDm);
   6767 
   6768     soc_mem_lock(unit, VLAN_XLATE_EXTDm);
   6769     rv = soc_mem_read_range(unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ANY,
   6770                             imin, imax, vtab);
   6771     if (rv < 0) {
   6772         soc_mem_unlock(unit, VLAN_XLATE_EXTDm);
   6773         soc_cm_sfree(unit, vtab);
   6774         return rv; 
   6775     }
   6776     
   6777     for(i = 0; i < nent; i++) {
   6778         vtabp = soc_mem_table_idx_to_pointer(unit, VLAN_XLATE_EXTDm,
   6779                                      vlan_xlate_extd_entry_t *, vtab, i);
   6780 
   6781         mpls = soc_VLAN_XLATE_EXTDm_field32_get(unit, vtabp, 
   6782                             XLATE__MPLS_ACTIONf);
   6783 
   6784         if (!soc_VLAN_XLATE_EXTDm_field32_get(unit, vtabp, VALID_0f) ||
   6785             (mpls != 0)) {
   6786             continue;
   6787         }
   6788 
   6789         rv = WRITE_VLAN_XLATE_EXTDm(unit, MEM_BLOCK_ANY, i, vnull);
   6790     }
   6791     
   6792     soc_mem_unlock(unit, VLAN_XLATE_EXTDm);
   6793     soc_cm_sfree(unit, vtab);
   6794     return rv;
   6795 }
   6796 #endif   /*BCM_TRIUMPH3_SUPPORT */
   6797 
   6798 /*
   6799  * Function:
   6800  *      _bcm_trx_vlan_translate_action_delete_all
   6801  * Purpose:
   6802  *      Delete all vlan translate lookup entries.
   6803  * Parameters:
   6804  *      unit      (IN) BCM unit number
   6805  * Returns:
   6806  *      BCM_E_XXX
   6807  */
   6808 int
   6809 _bcm_trx_vlan_translate_action_delete_all(int unit) 
   6810 {
   6811     int i, imin, imax, nent, vbytes, rv, mpls;
   6812     uint32 old_profile_idx;
   6813     void * vtab, * vnull,  *vtabp;
   6814     int vx_key_type;
   6815     int vx_key_value;
   6816 #if defined(BCM_TRIUMPH2_SUPPORT)
   6817     _bcm_flex_stat_handle_t handle;
   6818     vlan_xlate_entry_t vent;
   6819     uint32 key[2];
   6820 #endif
   6821     soc_mem_t mem = VLAN_XLATEm;
   6822     soc_field_t vf = VALIDf;
   6823     uint32 ent_sz = sizeof(vlan_xlate_entry_t);
   6824     
   6825     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
   6826         mem = VLAN_XLATE_1_DOUBLEm;
   6827         vf = BASE_VALID_0f; /* TD3TBD */
   6828         ent_sz = sizeof(vlan_xlate_1_double_entry_t);
   6829     }
   6830 
   6831     imin = soc_mem_index_min(unit, mem);
   6832     imax = soc_mem_index_max(unit, mem);
   6833     nent = soc_mem_index_count(unit, mem);
   6834     vbytes = soc_mem_entry_words(unit, mem);
   6835     vbytes = WORDS2BYTES(vbytes);
   6836     vtab = soc_cm_salloc(unit, nent * ent_sz, "vlan_xlate");
   6837 
   6838     if (vtab == NULL) {
   6839         return BCM_E_MEMORY;
   6840     }
   6841     
   6842     vnull = soc_mem_entry_null(unit, mem);
   6843 
   6844     soc_mem_lock(unit, mem);
   6845     rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY,
   6846                             imin, imax, vtab);
   6847     if (rv < 0) {
   6848         soc_mem_unlock(unit, mem);
   6849         soc_cm_sfree(unit, vtab);
   6850         return rv; 
   6851     }
   6852     
   6853     for(i = 0; i < nent; i++) {
   6854         if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
   6855             vtabp = soc_mem_table_idx_to_pointer(unit, mem,
   6856                         vlan_xlate_1_double_entry_t *, vtab, i);
   6857         } else {
   6858             vtabp = soc_mem_table_idx_to_pointer(unit, mem,
   6859                                              vlan_xlate_entry_t *, vtab, i);
   6860         }
   6861 
   6862 #if defined(BCM_TRIUMPH3_SUPPORT)
   6863         if (SOC_IS_TRIUMPH3(unit)) {
   6864             mpls = 0;
   6865         } else
   6866 #endif
   6867         {
   6868             if (SOC_IS_TR_VL(unit) && (!(SOC_IS_HURRICANE(unit) || 
   6869                 SOC_IS_HURRICANE2(unit))) &&
   6870                 SOC_MEM_FIELD_VALID(unit, mem, MPLS_ACTIONf)) {
   6871                 mpls = soc_mem_field32_get(unit, mem, vtabp, MPLS_ACTIONf);
   6872             } else {
   6873                 mpls = 0;
   6874             }
   6875         }
   6876 
   6877         vx_key_value = soc_mem_field32_get(unit, mem, vtabp, KEY_TYPEf);
   6878         rv =  _bcm_esw_vlan_xlate_key_type_get(unit,vx_key_value,&vx_key_type);
   6879         if (rv != BCM_E_NONE) {
   6880             /* not valid key type, must be for extend entry */
   6881             continue;
   6882         }
   6883 
   6884         if (!soc_mem_field32_get(unit, mem, vtabp, vf) ||
   6885             (mpls != 0) ||
   6886             (vx_key_type == VLXLT_HASH_KEY_TYPE_VLAN_MAC) ||
   6887             (vx_key_type == VLXLT_HASH_KEY_TYPE_LLVID) ||
   6888             (vx_key_type == VLXLT_HASH_KEY_TYPE_LLVID_OVID) ||
   6889             (vx_key_type == VLXLT_HASK_KEY_TYPE_LLVID_IVID)) {
   6890             continue;
   6891         }
   6892 
   6893         old_profile_idx = soc_mem_field32_get(unit, mem, vtabp,
   6894                                                       TAG_ACTION_PROFILE_PTRf);
   6895 
   6896         rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, i, vnull);
   6897 
   6898         if ((rv >= 0) && (old_profile_idx != ing_action_profile_def[unit])) {
   6899             /* Delete the old vlan action profile entry */
   6900             rv = _bcm_trx_vlan_action_profile_entry_delete(unit, old_profile_idx);
   6901         }
   6902 
   6903 #if defined(BCM_TRIUMPH2_SUPPORT)
   6904         if (soc_feature(unit, soc_feature_gport_service_counters) &&
   6905             (0 != soc_mem_field32_get(unit, mem, vtabp, VINTF_CTR_IDXf))) {
   6906             sal_memset(&vent, 0, sizeof(vent));
   6907             /* Construct key-only entry, copy to FS handle */
   6908             soc_mem_field32_set(unit, mem, &vent, KEY_TYPEf,
   6909                      soc_mem_field32_get(unit, mem, vtabp, KEY_TYPEf));
   6910             soc_mem_field_get(unit, mem, (uint32 *) vtabp,
   6911                                KEYf, (uint32 *) key);
   6912             soc_mem_field_set(unit, mem, (uint32 *) &vent,
   6913                                KEYf, (uint32 *) key);
   6914 
   6915             _BCM_FLEX_STAT_HANDLE_CLEAR(handle);
   6916             _BCM_FLEX_STAT_HANDLE_COPY(handle, vent);
   6917 
   6918             /* Release Service counter */
   6919             _bcm_esw_flex_stat_ext_handle_free(unit, _bcmFlexStatTypeVxlt,
   6920                                                handle);
   6921         }
   6922 #endif
   6923     }
   6924     
   6925     soc_mem_unlock(unit, mem);
   6926     soc_cm_sfree(unit, vtab);
   6927 
   6928 #if defined(BCM_TRIUMPH3_SUPPORT)
   6929     if (SOC_IS_TRIUMPH3(unit)) {
   6930         BCM_IF_ERROR_RETURN
   6931             (_bcm_tr3_vxlate_action_delete_extd_tbl(unit));
   6932     }
   6933 #endif
   6934     return rv;
   6935 }
   6936 
   6937 /*
   6938  * Function   :
   6939  *      _bcm_trx_vlan_translate_action_range_add
   6940  * Description   :
   6941  *      Add a range of VLANs and an entry to ingress VLAN translation table.
   6942  * Parameters   :
   6943  *      unit            (IN) BCM unit number
   6944  *      port            (IN) Ingress generic port
   6945  *      outer_vlan_low  (IN) Packet outer VLAN ID low 
   6946  *      outer_vlan_high (IN) Packet outer VLAN ID high
   6947  *      inner_vlan_low  (IN) Packet inner VLAN ID low 
   6948  *      inner_vlan_high (IN) Packet inner VLAN ID high
   6949  *      action          (IN) Action for outer and inner tag
   6950  */
   6951 int
   6952 _bcm_trx_vlan_translate_action_range_add(int unit,
   6953                                         bcm_gport_t port,
   6954                                         bcm_vlan_t outer_vlan_low,
   6955                                         bcm_vlan_t outer_vlan_high,
   6956                                         bcm_vlan_t inner_vlan_low,
   6957                                         bcm_vlan_t inner_vlan_high,
   6958                                         bcm_vlan_action_set_t *action)
   6959 {
   6960     int i, key_type = 0, rv, gport_id, old_idx = 0, stm_idx = 0;
   6961     uint32 new_idx = 0;
   6962     source_trunk_map_table_entry_t stm_entry;
   6963     bcm_module_t mod_out;
   6964     bcm_port_t   port_out;
   6965     bcm_trunk_t  trunk_id, tid;
   6966     bcm_vlan_t min_vlan[8], max_vlan[8];
   6967     bcm_vlan_t min_inner_vlan[8], max_inner_vlan[8];
   6968     int port_count;
   6969     bcm_trunk_member_t *member_array = NULL;
   6970     bcm_module_t *mod_array = NULL;
   6971     bcm_port_t   *port_array = NULL;
   6972     int trunk128;
   6973     soc_field_t field;
   6974     int old_inner_idx = 0;
   6975     uint32 new_inner_idx = 0;
   6976 #if defined(BCM_KATANA2_SUPPORT) && defined(INCLUDE_L3)
   6977     int pon_tunnel = FALSE;
   6978     int nh_index, vp;
   6979     ing_l3_next_hop_entry_t ing_nh;
   6980     ing_dvp_table_entry_t dvp;
   6981 #endif
   6982 
   6983     if ((outer_vlan_low != BCM_VLAN_INVALID) &&
   6984         (inner_vlan_low != BCM_VLAN_INVALID)) {
   6985         if (soc_feature (unit, soc_feature_vlan_double_tag_range_compress)) {
   6986             key_type = bcmVlanTranslateKeyPortDouble;
   6987             VLAN_CHK_ID(unit, inner_vlan_low);
   6988             VLAN_CHK_ID(unit, inner_vlan_high);
   6989             VLAN_CHK_ID(unit, outer_vlan_low);
   6990             VLAN_CHK_ID(unit, outer_vlan_high);
   6991         } else {
   6992             /* For an incoming double tagged packet, hardware currently supports
   6993              * VLAN range matching for outer VLAN ID only, not for inner VLAN ID
   6994              * Hence, outer VLAN range and inner VLAN range cannot be specified
   6995              * simultaneously.
   6996              */
   6997             return BCM_E_PARAM;
   6998         }
   6999     } else if (outer_vlan_low != BCM_VLAN_INVALID) {
   7000         key_type = bcmVlanTranslateKeyPortOuter;
   7001         VLAN_CHK_ID(unit, outer_vlan_low);
   7002         VLAN_CHK_ID(unit, outer_vlan_high);
   7003     } else if (inner_vlan_low != BCM_VLAN_INVALID) {
   7004         key_type = bcmVlanTranslateKeyPortInner;
   7005         VLAN_CHK_ID(unit, inner_vlan_low);
   7006         VLAN_CHK_ID(unit, inner_vlan_high);
   7007     } else {
   7008         return BCM_E_PARAM;
   7009     }
   7010 
   7011 #if defined(BCM_KATANA2_SUPPORT) && defined(INCLUDE_L3)
   7012     if (soc_feature(unit, soc_feature_lltag)) {
   7013         if (BCM_GPORT_IS_VLAN_PORT(port)) {
   7014             vp = BCM_GPORT_VLAN_PORT_ID_GET(port);
   7015             if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) {
   7016                 return BCM_E_NOT_FOUND;
   7017             }
   7018             BCM_IF_ERROR_RETURN (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY,
   7019                         vp, &dvp));
   7020             nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp,
   7021                     NEXT_HOP_INDEXf);
   7022             BCM_IF_ERROR_RETURN (READ_ING_L3_NEXT_HOPm(unit, MEM_BLOCK_ANY,
   7023                         nh_index, &ing_nh));
   7024 
   7025             if ((soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, ENTRY_TYPEf)
   7026                         == 0x3)) {
   7027                 pon_tunnel = TRUE;
   7028             }
   7029         }
   7030     }
   7031 
   7032     if (pon_tunnel == TRUE) {
   7033         if (inner_vlan_low != BCM_VLAN_INVALID) {
   7034             key_type = bcmVlanTranslateKeyPortPonTunnelInner;
   7035             VLAN_CHK_ID(unit, inner_vlan_low);
   7036             VLAN_CHK_ID(unit, inner_vlan_high);
   7037         } else if (outer_vlan_low != BCM_VLAN_INVALID) {
   7038             key_type = bcmVlanTranslateKeyPortPonTunnelOuter;
   7039             VLAN_CHK_ID(unit, outer_vlan_low);
   7040             VLAN_CHK_ID(unit, outer_vlan_high);
   7041         }
   7042     }
   7043 #endif
   7044 
   7045     BCM_IF_ERROR_RETURN(
   7046         _bcm_trx_vlan_action_verify(unit, action));
   7047 
   7048     BCM_IF_ERROR_RETURN
   7049         (_bcm_esw_gport_resolve(unit, port, &mod_out, &port_out, &trunk_id,
   7050                                 &gport_id));
   7051 
   7052     if (BCM_GPORT_IS_TRUNK(port)) {
   7053         if (BCM_TRUNK_INVALID == trunk_id) {
   7054             return BCM_E_PORT;
   7055         }
   7056 
   7057         BCM_IF_ERROR_RETURN
   7058             (bcm_esw_trunk_get(unit, trunk_id, NULL, 0, NULL,
   7059                                &port_count));
   7060 
   7061         if (port_count <= 0) {
   7062             return BCM_E_PORT;
   7063         }
   7064 
   7065         member_array = sal_alloc(sizeof(bcm_trunk_member_t) * port_count,
   7066                 "trunk member array");
   7067         if (member_array == NULL) {
   7068             rv = BCM_E_MEMORY;
   7069             goto cleanup;
   7070         }
   7071         sal_memset(member_array, 0, sizeof(bcm_trunk_member_t) * port_count);
   7072 
   7073         rv = bcm_esw_trunk_get(unit, trunk_id, NULL, port_count,
   7074                 member_array, &port_count);
   7075         if (BCM_FAILURE(rv)) {
   7076             goto cleanup;
   7077         }
   7078 
   7079         mod_array = sal_alloc(sizeof(bcm_module_t) * port_count,
   7080                 "module ID array");
   7081         if (mod_array == NULL) {
   7082             rv = BCM_E_MEMORY;
   7083             goto cleanup;
   7084         }
   7085         sal_memset(mod_array, 0, sizeof(bcm_module_t) * port_count);
   7086 
   7087         port_array = sal_alloc(sizeof(bcm_port_t) * port_count,
   7088                 "port ID array");
   7089         if (port_array == NULL) {
   7090             rv = BCM_E_MEMORY;
   7091             goto cleanup;
   7092         }
   7093         sal_memset(port_array, 0, sizeof(bcm_port_t) * port_count);
   7094 
   7095         for (i = 0; i < port_count; i++) {
   7096             rv = _bcm_esw_gport_resolve(unit, member_array[i].gport,
   7097                     &mod_array[i], &port_array[i], &tid, &gport_id);
   7098             if (BCM_FAILURE(rv)) {
   7099                 goto cleanup;
   7100             }
   7101         }
   7102     } else {
   7103         if ((-1 == mod_out) || (-1 == port_out)) {
   7104             return BCM_E_PORT;
   7105         }
   7106 
   7107         port_count = 1;
   7108 
   7109         mod_array = sal_alloc(sizeof(bcm_module_t) * port_count,
   7110                 "module ID array");
   7111         if (mod_array == NULL) {
   7112             rv = BCM_E_MEMORY;
   7113             goto cleanup;
   7114         }
   7115         mod_array[0] = mod_out;
   7116 
   7117         port_array = sal_alloc(sizeof(bcm_port_t) * port_count,
   7118                 "port ID array");
   7119         if (port_array == NULL) {
   7120             rv = BCM_E_MEMORY;
   7121             goto cleanup;
   7122         }
   7123         port_array[0] = port_out;
   7124     }
   7125 
   7126     rv = _bcm_esw_src_mod_port_table_index_get(unit, mod_array[0],
   7127             port_array[0], &stm_idx);
   7128     if (BCM_FAILURE(rv)) {
   7129         goto cleanup;
   7130     }
   7131 
   7132     soc_mem_lock(unit, ING_VLAN_RANGEm);
   7133 
   7134     rv = READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, stm_idx, &stm_entry);
   7135     if (rv < 0) {
   7136         soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7137         goto cleanup;
   7138     }
   7139 
   7140     /* For devices supporting vlan double tag range compression
   7141      * and if inner_vlan_low is valid
   7142      */
   7143     if (inner_vlan_low != BCM_VLAN_INVALID) {
   7144         if (soc_feature (unit, soc_feature_vlan_double_tag_range_compress)) {
   7145             field = INNER_VLAN_RANGE_IDXf;
   7146         } else {
   7147             field = VLAN_RANGE_IDXf;
   7148         } 
   7149         old_inner_idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm,
   7150                                   &stm_entry, field);
   7151 
   7152         /* Get the profile table entry for this port/trunk */
   7153         _bcm_trx_vlan_range_profile_entry_get(unit,
   7154                                 min_inner_vlan, max_inner_vlan, old_inner_idx);
   7155     
   7156         /* Find the first unused min/max range. Unused ranges are
   7157          * identified by { min == 1, max == 0 }
   7158          */
   7159         for (i = 0 ; i < 8 ; i++) {
   7160             if ((min_inner_vlan[i] == 1) && (max_inner_vlan[i] == 0)) {
   7161                 break;
   7162             } else if (min_inner_vlan[i] == inner_vlan_low) {
   7163                 /* Can't have multiple ranges with the same min */
   7164                 rv = BCM_E_EXISTS;
   7165                 soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7166                 goto cleanup;
   7167             }
   7168         }
   7169         if (i == 8) {
   7170             /* All ranges are taken */
   7171             rv = BCM_E_FULL;
   7172             soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7173             goto cleanup;
   7174         }
   7175 
   7176         /* Insert the new range into the table entry sorted by min VID */
   7177         for ( ; i > 0 ; i--) {
   7178             if (min_inner_vlan[i - 1] > inner_vlan_low) {
   7179                 /* Move existing min/max down */
   7180                 min_inner_vlan[i] = min_inner_vlan[i - 1];
   7181                 max_inner_vlan[i] = max_inner_vlan[i - 1];
   7182             } else {
   7183                 break;
   7184             }
   7185         }
   7186         min_inner_vlan[i] = inner_vlan_low;
   7187         max_inner_vlan[i] = inner_vlan_high;
   7188 
   7189         /* Adding the new profile table entry and update profile pointer */
   7190         for (i = 0; i < port_count; i++) {
   7191             rv = _bcm_trx_vlan_range_profile_entry_add(unit, 
   7192                             min_inner_vlan, max_inner_vlan, &new_inner_idx);
   7193             if (BCM_FAILURE(rv)) {
   7194                 soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7195                 goto cleanup;
   7196             }
   7197             rv = _bcm_esw_src_mod_port_table_index_get(unit, mod_array[i],
   7198                     port_array[i], &stm_idx);
   7199             if (BCM_SUCCESS(rv)) {
   7200                 rv = soc_mem_field32_modify(unit,
   7201                         SOURCE_TRUNK_MAP_TABLEm, stm_idx, field, new_inner_idx);
   7202             }
   7203             if (BCM_FAILURE(rv)) {
   7204                 _bcm_trx_vlan_range_profile_entry_delete(unit, new_inner_idx);
   7205                 soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7206                 goto cleanup;
   7207             }
   7208         }
   7209     }
   7210 
   7211     /* For devices supporting vlan double tag range compression
   7212      * and entry is for outer tag or double tag vlan range compression
   7213      * OR
   7214      * Other devices not supporting double tag range compression feature
   7215      */
   7216     if (outer_vlan_low != BCM_VLAN_INVALID) {
   7217         field = VLAN_RANGE_IDXf;
   7218         if (soc_feature (unit, soc_feature_vlan_double_tag_range_compress)) {
   7219             if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 
   7220                               OUTER_VLAN_RANGE_IDXf)) {  
   7221                 field = OUTER_VLAN_RANGE_IDXf;
   7222             }
   7223         }
   7224 
   7225         old_idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm,
   7226                                   &stm_entry, field);
   7227 
   7228         /* Get the profile table entry for this port/trunk */
   7229         _bcm_trx_vlan_range_profile_entry_get(unit,
   7230                                           min_vlan, max_vlan, old_idx);
   7231         
   7232         /* Find the first unused min/max range. Unused ranges are
   7233          * identified by { min == 1, max == 0 }
   7234          */
   7235         for (i = 0 ; i < 8 ; i++) {
   7236             if ((min_vlan[i] == 1) && (max_vlan[i] == 0)) {
   7237                 break;
   7238             } else if (min_vlan[i] == outer_vlan_low) {
   7239                 /* Can't have multiple ranges with the same min */
   7240                 rv = BCM_E_EXISTS;
   7241                 soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7242                 goto cleanup;
   7243             }
   7244         }
   7245         if (i == 8) {
   7246             /* All ranges are taken */
   7247             rv = BCM_E_FULL;
   7248             soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7249             goto cleanup;
   7250         }
   7251        
   7252         /* Insert the new range into the table entry sorted by min VID */
   7253         for ( ; i > 0 ; i--) {
   7254             if (min_vlan[i - 1] > outer_vlan_low) {
   7255                 /* Move existing min/max down */
   7256                 min_vlan[i] = min_vlan[i - 1];
   7257                 max_vlan[i] = max_vlan[i - 1];
   7258             } else {
   7259                 break;
   7260             }
   7261         }
   7262         min_vlan[i] = outer_vlan_low;
   7263         max_vlan[i] = outer_vlan_high;
   7264         
   7265         /* Adding the new profile table entry and update profile pointer */
   7266         for (i = 0; i < port_count; i++) {
   7267             rv = _bcm_trx_vlan_range_profile_entry_add(unit, min_vlan, max_vlan,
   7268                     &new_idx);
   7269             if (BCM_FAILURE(rv)) {
   7270                 soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7271                 goto cleanup;
   7272             }
   7273             rv = _bcm_esw_src_mod_port_table_index_get(unit, mod_array[i],
   7274                     port_array[i], &stm_idx);
   7275             if (BCM_SUCCESS(rv)) {
   7276                 rv = soc_mem_field32_modify(unit,
   7277                         SOURCE_TRUNK_MAP_TABLEm, stm_idx, field, new_idx);
   7278             }
   7279             if (BCM_FAILURE(rv)) {
   7280                 _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx);
   7281                 soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7282                 goto cleanup;
   7283             }
   7284         }
   7285     }
   7286 
   7287     /* Add an entry in the vlan translate table for the low VID */
   7288     rv = _bcm_trx_vlan_translate_action_add(unit, port, key_type,
   7289                                            outer_vlan_low, inner_vlan_low,
   7290                                            action);
   7291     if (rv != BCM_E_NONE) {
   7292         for (i = 0; i < port_count; i++) {
   7293             if (outer_vlan_low != BCM_VLAN_INVALID) {
   7294                 _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx);
   7295             }
   7296             if (inner_vlan_low != BCM_VLAN_INVALID) {
   7297                 _bcm_trx_vlan_range_profile_entry_delete(unit, new_inner_idx);
   7298             }
   7299         }
   7300         soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7301         goto cleanup;
   7302     }
   7303 
   7304     /* Delete the old profile entry */
   7305     for (i = 0; i < port_count; i++) {
   7306         if (outer_vlan_low != BCM_VLAN_INVALID) {
   7307             rv = _bcm_trx_vlan_range_profile_entry_delete(unit, old_idx);
   7308             if (BCM_FAILURE(rv)) {
   7309                 soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7310                 goto cleanup;
   7311             }
   7312         }
   7313         if (inner_vlan_low != BCM_VLAN_INVALID) {
   7314             rv = _bcm_trx_vlan_range_profile_entry_delete(unit, old_inner_idx);
   7315             if (BCM_FAILURE(rv)) {
   7316                 soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7317                 goto cleanup;
   7318             }
   7319         }
   7320     }
   7321 
   7322     if (BCM_GPORT_IS_TRUNK(port)) {
   7323         if (SOC_MEM_FIELD_VALID(unit, TRUNK32_PORT_TABLEm, VLAN_RANGE_IDXf)) {
   7324             trunk128 = soc_property_get(unit, spn_TRUNK_EXTEND, 1);
   7325             if (!trunk128) {
   7326                 rv = _bcm_trx_vlan_range_profile_entry_add(unit,
   7327                         min_vlan, max_vlan, &new_idx);
   7328                 if (BCM_FAILURE(rv)) {
   7329                     soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7330                     goto cleanup;
   7331                 }
   7332                 rv = soc_mem_field32_modify(unit,
   7333                         TRUNK32_PORT_TABLEm, trunk_id,
   7334                         VLAN_RANGE_IDXf, new_idx);
   7335                 if (BCM_FAILURE(rv)) {
   7336                     _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx);
   7337                     soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7338                     goto cleanup;
   7339                 }
   7340                 if (outer_vlan_low != BCM_VLAN_INVALID) {
   7341                     rv = _bcm_trx_vlan_range_profile_entry_delete(unit,
   7342                             old_idx);
   7343                     if (BCM_FAILURE(rv)) {
   7344                         soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7345                         goto cleanup;
   7346                     }
   7347                 }
   7348                 if (inner_vlan_low != BCM_VLAN_INVALID) {
   7349                     rv = _bcm_trx_vlan_range_profile_entry_delete(unit,
   7350                             old_inner_idx);
   7351                     if (BCM_FAILURE(rv)) {
   7352                         soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7353                         goto cleanup;
   7354                     }
   7355                 }
   7356             }
   7357         }
   7358     }
   7359     
   7360     soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7361 
   7362 cleanup:
   7363     if (NULL != member_array) {
   7364         sal_free(member_array);
   7365     }
   7366     if (NULL != mod_array) {
   7367         sal_free(mod_array);
   7368     }
   7369     if (NULL != port_array) {
   7370         sal_free(port_array);
   7371     }
   7372 
   7373     return rv;
   7374 }
   7375 
   7376 /*
   7377  * Function   :
   7378  *      _bcm_trx_vlan_range_profile_index_get
   7379  * Description   :
   7380  *      Get the index for profile entry in the ING_VLAN_RANGE memory.
   7381  * Parameters   :
   7382  *      unit        (IN) BCM unit number
   7383  *      gport       (IN) Ingress generic port
   7384  *      profile_idx (OUT) index to profile entry
   7385  */
   7386 int 
   7387 _bcm_trx_vlan_range_profile_index_get(int unit, bcm_gport_t gport, 
   7388                                      int *profile_idx)
   7389 {
   7390     int                             idx = 0, gport_id = 0;
   7391     bcm_port_t                      port_out;
   7392     bcm_module_t                    mod_out;
   7393     bcm_trunk_t                     trunk_id;
   7394     int                             stm_idx;     /* Source Trunk Map index */
   7395     source_trunk_map_table_entry_t  stm_entry;
   7396     bcm_trunk_member_t              trunk_member;
   7397     int                             port_count;
   7398 
   7399     BCM_IF_ERROR_RETURN
   7400         (_bcm_esw_gport_resolve(unit, gport, &mod_out, &port_out, &trunk_id,
   7401                                 &gport_id));
   7402 
   7403     if (BCM_GPORT_IS_TRUNK(gport)) {
   7404         if (BCM_TRUNK_INVALID == trunk_id) {
   7405             return BCM_E_PORT;
   7406         }
   7407 
   7408         BCM_IF_ERROR_RETURN
   7409             (bcm_esw_trunk_get(unit, trunk_id, NULL, 1, &trunk_member,
   7410                                       &port_count));
   7411         BCM_IF_ERROR_RETURN
   7412             (_bcm_esw_gport_resolve(unit, trunk_member.gport,
   7413                                     &mod_out, &port_out, &trunk_id, &gport_id));
   7414     } else {
   7415         if ((-1 == mod_out) || (-1 == port_out)) {
   7416             return BCM_E_PORT;
   7417         }
   7418     }
   7419 
   7420     BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, mod_out,
   7421             port_out, &stm_idx));
   7422 
   7423     BCM_IF_ERROR_RETURN(
   7424        READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, stm_idx, &stm_entry));
   7425 
   7426     if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
   7427                                           OUTER_VLAN_RANGE_IDXf)) {
   7428         idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm,
   7429                               &stm_entry, OUTER_VLAN_RANGE_IDXf);
   7430     } else {
   7431         idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm,
   7432                               &stm_entry, VLAN_RANGE_IDXf);
   7433     }
   7434         *profile_idx = idx;
   7435     return BCM_E_NONE;
   7436     }
   7437 
   7438 /*
   7439  * Function   :
   7440  *      _bcm_trx_vlan_range_profile_inner_index_get
   7441  * Description   :
   7442  *      Get the inner index for profile entry in the ING_VLAN_RANGE memory.
   7443  * Parameters   :
   7444  *      unit        (IN) BCM unit number
   7445  *      gport       (IN) Ingress generic port
   7446  *      profile_idx (OUT) inner vlan range index to profile entry
   7447  */
   7448 int 
   7449 _bcm_trx_vlan_range_profile_inner_index_get(int unit, bcm_gport_t gport, 
   7450                                      int *profile_idx)
   7451 {
   7452     int                             idx = 0, gport_id = 0;
   7453     bcm_port_t                      port_out;
   7454     bcm_module_t                    mod_out;
   7455     bcm_trunk_t                     trunk_id;
   7456     int                             stm_idx;     /* Source Trunk Map index */
   7457     source_trunk_map_table_entry_t  stm_entry;
   7458     bcm_trunk_info_t                tinfo;
   7459     bcm_trunk_member_t              trunk_member;
   7460     int                             port_count;
   7461 
   7462     BCM_IF_ERROR_RETURN
   7463         (_bcm_esw_gport_resolve(unit, gport, &mod_out, &port_out, &trunk_id,
   7464                                 &gport_id));
   7465 
   7466     if (BCM_GPORT_IS_TRUNK(gport)) {
   7467         if (BCM_TRUNK_INVALID == trunk_id) {
   7468             return BCM_E_PORT;
   7469         }
   7470         BCM_IF_ERROR_RETURN(bcm_esw_trunk_get(unit, trunk_id, &tinfo, 1,
   7471                     &trunk_member, &port_count));
   7472         BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, trunk_member.gport,
   7473                     &mod_out, &port_out, &trunk_id, &gport_id));
   7474     } else {
   7475         if ((-1 == mod_out) || (-1 == port_out)) {
   7476             return BCM_E_PORT;
   7477         }
   7478     }
   7479 
   7480     BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, mod_out,
   7481             port_out, &stm_idx));
   7482 
   7483     BCM_IF_ERROR_RETURN(
   7484        READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, stm_idx, &stm_entry));
   7485 
   7486     if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
   7487                         INNER_VLAN_RANGE_IDXf)) {
   7488         idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm,
   7489                           &stm_entry, INNER_VLAN_RANGE_IDXf);
   7490         *profile_idx = idx;
   7491     }
   7492     return BCM_E_NONE;
   7493 }
   7494 
   7495 /*
   7496  * Function   :
   7497  *      _bcm_trx_vlan_translate_action_range_get
   7498  * Description   :
   7499  *      Get a range of VLANs and an entry to ingress VLAN translation table.
   7500  *      for Triumph
   7501  * Parameters   :
   7502  *      unit            (IN) BCM unit number
   7503  *      port            (IN) Ingress generic port
   7504  *      outer_vlan_low  (IN) Packet outer VLAN ID low 
   7505  *      outer_vlan_high (IN) Packet outer VLAN ID high
   7506  *      inner_vlan_low  (IN) Packet inner VLAN ID low 
   7507  *      inner_vlan_high (IN) Packet inner VLAN ID high
   7508  *      action          (OUT) Action for outer and inner tag
   7509  */
   7510 int
   7511 _bcm_trx_vlan_translate_action_range_get(int unit,
   7512                                         bcm_gport_t port,
   7513                                         bcm_vlan_t outer_vlan_low,
   7514                                         bcm_vlan_t outer_vlan_high,
   7515                                         bcm_vlan_t inner_vlan_low,
   7516                                         bcm_vlan_t inner_vlan_high,
   7517                                         bcm_vlan_action_set_t *action)
   7518 {
   7519     int         key_type = 0, profile_idx, i;
   7520     bcm_vlan_t  min_vlan[8], max_vlan[8];
   7521     int rv;
   7522 #if defined(BCM_KATANA2_SUPPORT) && defined(INCLUDE_L3)
   7523     int pon_tunnel = FALSE;
   7524     int nh_index, vp;
   7525     ing_l3_next_hop_entry_t ing_nh;
   7526     ing_dvp_table_entry_t dvp;
   7527 #endif
   7528     
   7529     if ((outer_vlan_low != BCM_VLAN_INVALID) &&
   7530         (inner_vlan_low != BCM_VLAN_INVALID)) {
   7531         if (soc_feature (unit, soc_feature_vlan_double_tag_range_compress)) {
   7532             key_type = bcmVlanTranslateKeyPortDouble;
   7533             VLAN_CHK_ID(unit, inner_vlan_low);
   7534             VLAN_CHK_ID(unit, inner_vlan_high);
   7535             VLAN_CHK_ID(unit, outer_vlan_low);
   7536             VLAN_CHK_ID(unit, outer_vlan_high);
   7537         } else {
   7538             /* For an incoming double tagged packet, hardware currently supports
   7539              * VLAN range matching for outer VLAN ID only, not for inner VLAN ID
   7540              * Hence, outer VLAN range and inner VLAN range cannot be specified
   7541              * simultaneously.
   7542              */
   7543             return BCM_E_PARAM;
   7544         }
   7545     } else if (outer_vlan_low != BCM_VLAN_INVALID) {
   7546         key_type = bcmVlanTranslateKeyPortOuter;
   7547         VLAN_CHK_ID(unit, outer_vlan_low);
   7548         VLAN_CHK_ID(unit, outer_vlan_high);
   7549     } else if (inner_vlan_low != BCM_VLAN_INVALID) {
   7550         key_type = bcmVlanTranslateKeyPortInner;
   7551         VLAN_CHK_ID(unit, inner_vlan_low);
   7552         VLAN_CHK_ID(unit, inner_vlan_high);
   7553     } else {
   7554         return BCM_E_PARAM;
   7555     }
   7556 
   7557 #if defined(BCM_KATANA2_SUPPORT) && defined(INCLUDE_L3)
   7558     if (soc_feature(unit, soc_feature_lltag)) {
   7559         if (BCM_GPORT_IS_VLAN_PORT(port)) {
   7560             vp = BCM_GPORT_VLAN_PORT_ID_GET(port);
   7561             if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) {
   7562                 return BCM_E_NOT_FOUND;
   7563             }
   7564             BCM_IF_ERROR_RETURN (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY,
   7565                         vp, &dvp));
   7566             nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp,
   7567                     NEXT_HOP_INDEXf);
   7568             BCM_IF_ERROR_RETURN (READ_ING_L3_NEXT_HOPm(unit, MEM_BLOCK_ANY,
   7569                         nh_index, &ing_nh));
   7570 
   7571             if ((soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, ENTRY_TYPEf)
   7572                         == 0x3)) {
   7573                 pon_tunnel = TRUE;
   7574             }
   7575         }
   7576     }
   7577 
   7578     if (pon_tunnel == TRUE) {
   7579         if (inner_vlan_low != BCM_VLAN_INVALID) {
   7580             key_type = bcmVlanTranslateKeyPortPonTunnelInner;
   7581             VLAN_CHK_ID(unit, inner_vlan_low);
   7582             VLAN_CHK_ID(unit, inner_vlan_high);
   7583         } else if (outer_vlan_low != BCM_VLAN_INVALID) {
   7584             key_type = bcmVlanTranslateKeyPortPonTunnelOuter;
   7585             VLAN_CHK_ID(unit, outer_vlan_low);
   7586             VLAN_CHK_ID(unit, outer_vlan_high);
   7587         }
   7588     }
   7589 #endif
   7590 
   7591     /* For devices supporting vlan double tag range compression
   7592      * and if inner_vlan_low is valid
   7593      */
   7594     if (inner_vlan_low != BCM_VLAN_INVALID) {
   7595         if (soc_feature (unit, soc_feature_vlan_double_tag_range_compress)) {
   7596             rv = _bcm_trx_vlan_range_profile_inner_index_get(unit,
   7597                 port, &profile_idx);
   7598         } else {
   7599             rv = _bcm_trx_vlan_range_profile_index_get(unit, port, &profile_idx);
   7600         }
   7601         BCM_IF_ERROR_RETURN(rv);
   7602 
   7603         /* Get the profile table entry for this port/trunk */
   7604         _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, 
   7605                 max_vlan, profile_idx);
   7606         /* Find range match */
   7607         for (i = 0 ; i < 8 ; i++) {
   7608             if ((min_vlan[i] == inner_vlan_low) &&
   7609                 (max_vlan[i] == inner_vlan_high)) {
   7610                 break;
   7611             }
   7612         }
   7613         if (i == 8) {
   7614             return BCM_E_NOT_FOUND;
   7615         }
   7616     }
   7617 
   7618     /* For devices supporting vlan double tag range compression
   7619      * and entry is for outer tag or double tag range compression
   7620      * OR
   7621      * Other devices not supporting double tag range compression feature 
   7622      */
   7623     if (outer_vlan_low != BCM_VLAN_INVALID) {
   7624         rv = _bcm_trx_vlan_range_profile_index_get(unit, port, &profile_idx);
   7625         BCM_IF_ERROR_RETURN(rv);
   7626         
   7627         /* Get the profile table entry for this port/trunk */
   7628         _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, 
   7629                 max_vlan, profile_idx);
   7630         /* Find range match */
   7631         for (i = 0 ; i < 8 ; i++) {
   7632             if ((min_vlan[i] == outer_vlan_low) &&
   7633                 (max_vlan[i] == outer_vlan_high)) {
   7634                 break;
   7635             }
   7636         }
   7637         if (i == 8) {
   7638             return BCM_E_NOT_FOUND;
   7639         }
   7640     }
   7641     /* Get an entry in the vlan translate table for the low VID */
   7642     rv = _bcm_trx_vlan_translate_action_get(unit,port, key_type,
   7643                                 outer_vlan_low, inner_vlan_low, action);  
   7644     if (rv == BCM_E_NOT_FOUND) {
   7645         int mod_out;
   7646         int port_out;
   7647         int trunk_id;
   7648         int gport_id;
   7649         int    stm_idx = 0;
   7650         source_trunk_map_table_entry_t  stm_entry;
   7651         int port_type;
   7652         soc_mem_t mem = VLAN_XLATEm;
   7653         soc_field_t tgid_fld = TGIDf;
   7654         if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
   7655             mem = VLAN_XLATE_1_DOUBLEm;
   7656         }
   7657 
   7658         /* check if the port belongs to a trunk group and whether 
   7659          * a xlat entry for that TGID exist
   7660          */
   7661         if (SOC_MEM_FIELD_VALID(unit, mem, Tf)) {
   7662             if (BCM_GPORT_IS_MODPORT(port)) {
   7663                 BCM_IF_ERROR_RETURN
   7664                     (_bcm_esw_gport_resolve(unit, port, &mod_out, 
   7665                           &port_out, &trunk_id, &gport_id));
   7666 
   7667                 /* Get index to source trunk map table */
   7668                 BCM_IF_ERROR_RETURN
   7669                     (_bcm_esw_src_mod_port_table_index_get(unit, 
   7670                         mod_out, port_out, &stm_idx));
   7671 
   7672                 /* read the entry */
   7673                 BCM_IF_ERROR_RETURN(
   7674                    READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, 
   7675                                 stm_idx, &stm_entry));
   7676 
   7677                 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
   7678                                         SRC_TGIDf)) {
   7679                     tgid_fld = SRC_TGIDf;
   7680                 }
   7681 
   7682                 trunk_id = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm,
   7683                                          &stm_entry, tgid_fld);
   7684                 port_type = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm,
   7685                                          &stm_entry, PORT_TYPEf);
   7686 
   7687                 if (port_type == 1) {
   7688                     BCM_GPORT_TRUNK_SET(gport_id, trunk_id);
   7689                     rv = _bcm_trx_vlan_translate_action_get(unit,gport_id,
   7690                          key_type,outer_vlan_low, inner_vlan_low, action);
   7691                 }
   7692             } 
   7693         }
   7694     } 
   7695     return (rv);
   7696 }
   7697 
   7698 /*
   7699  * Function   :
   7700  *      _bcm_trx_vlan_translate_action_range_delete
   7701  * Description   :
   7702  *      Delete a range of VLANs and an entry from ingress VLAN translation table
   7703  * Parameters   :
   7704  *      unit            (IN) BCM unit number
   7705  *      port            (IN) Ingress generic port
   7706  *      outer_vlan_low  (IN) Packet outer VLAN ID low 
   7707  *      outer_vlan_high (IN) Packet outer VLAN ID high
   7708  *      inner_vlan_low  (IN) Packet inner VLAN ID low 
   7709  *      inner_vlan_high (IN) Packet inner VLAN ID high
   7710  */
   7711 int
   7712 _bcm_trx_vlan_translate_action_range_delete(int unit,
   7713                                            bcm_gport_t port,
   7714                                            bcm_vlan_t outer_vlan_low,
   7715                                            bcm_vlan_t outer_vlan_high,
   7716                                            bcm_vlan_t inner_vlan_low,
   7717                                            bcm_vlan_t inner_vlan_high)
   7718 {
   7719     int i, key_type = 0, rv, gport_id, old_idx = 0, stm_idx = 0;
   7720     uint32 new_idx = 0;
   7721     source_trunk_map_table_entry_t stm_entry;
   7722     bcm_module_t mod_out;
   7723     bcm_port_t   port_out;
   7724     bcm_trunk_t  trunk_id, tid;
   7725     bcm_vlan_t min_vlan[8], max_vlan[8];
   7726     bcm_vlan_t min_inner_vlan[8], max_inner_vlan[8];
   7727     int port_count;
   7728     bcm_trunk_member_t *member_array = NULL;
   7729     bcm_module_t *mod_array = NULL;
   7730     bcm_port_t   *port_array = NULL;
   7731     int trunk128;
   7732     soc_field_t field;
   7733     int old_inner_idx = 0;
   7734     uint32 new_inner_idx = 0;
   7735 #if defined(BCM_KATANA2_SUPPORT) && defined(INCLUDE_L3)
   7736     int pon_tunnel = FALSE;
   7737     int nh_index, vp;
   7738     ing_l3_next_hop_entry_t ing_nh;
   7739     ing_dvp_table_entry_t dvp;
   7740 #endif
   7741 
   7742     if ((outer_vlan_low != BCM_VLAN_INVALID) &&
   7743         (inner_vlan_low != BCM_VLAN_INVALID)) {
   7744         if (soc_feature (unit, soc_feature_vlan_double_tag_range_compress)) {
   7745             key_type = bcmVlanTranslateKeyPortDouble;
   7746             VLAN_CHK_ID(unit, outer_vlan_low);
   7747             VLAN_CHK_ID(unit, outer_vlan_high);
   7748             VLAN_CHK_ID(unit, inner_vlan_low);
   7749             VLAN_CHK_ID(unit, inner_vlan_high);
   7750         } else {
   7751             /* For an incoming double tagged packet, hardware currently supports
   7752              * VLAN range matching for outer VLAN ID only, not for inner VLAN ID
   7753              * Hence, outer VLAN range and inner VLAN range cannot be specified
   7754              * simultaneously.
   7755              */
   7756             return BCM_E_PARAM;
   7757         }
   7758     } else if (outer_vlan_low != BCM_VLAN_INVALID) {
   7759         key_type = bcmVlanTranslateKeyPortOuter;
   7760         VLAN_CHK_ID(unit, outer_vlan_low);
   7761         VLAN_CHK_ID(unit, outer_vlan_high);
   7762     } else if (inner_vlan_low != BCM_VLAN_INVALID) {
   7763         key_type = bcmVlanTranslateKeyPortInner;
   7764         VLAN_CHK_ID(unit, inner_vlan_low);
   7765         VLAN_CHK_ID(unit, inner_vlan_high);
   7766     } else {
   7767         return BCM_E_PARAM;
   7768     }
   7769 
   7770 #if defined(BCM_KATANA2_SUPPORT) && defined(INCLUDE_L3)
   7771     if (soc_feature(unit, soc_feature_lltag)) {
   7772         if (BCM_GPORT_IS_VLAN_PORT(port)) {
   7773             vp = BCM_GPORT_VLAN_PORT_ID_GET(port);
   7774             if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) {
   7775                 return BCM_E_NOT_FOUND;
   7776             }
   7777             BCM_IF_ERROR_RETURN (READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY,
   7778                         vp, &dvp));
   7779             nh_index = soc_ING_DVP_TABLEm_field32_get(unit, &dvp,
   7780                     NEXT_HOP_INDEXf);
   7781             BCM_IF_ERROR_RETURN (READ_ING_L3_NEXT_HOPm(unit, MEM_BLOCK_ANY,
   7782                         nh_index, &ing_nh));
   7783 
   7784             if ((soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, ENTRY_TYPEf)
   7785                         == 0x3)) {
   7786                 pon_tunnel = TRUE;
   7787             }
   7788         }
   7789     }
   7790 
   7791     if (pon_tunnel == TRUE) {
   7792         if (inner_vlan_low != BCM_VLAN_INVALID) {
   7793             key_type = bcmVlanTranslateKeyPortPonTunnelInner;
   7794             VLAN_CHK_ID(unit, inner_vlan_low);
   7795             VLAN_CHK_ID(unit, inner_vlan_high);
   7796         } else if (outer_vlan_low != BCM_VLAN_INVALID) {
   7797             key_type = bcmVlanTranslateKeyPortPonTunnelOuter;
   7798             VLAN_CHK_ID(unit, outer_vlan_low);
   7799             VLAN_CHK_ID(unit, outer_vlan_high);
   7800         }
   7801     }
   7802 #endif
   7803 
   7804     BCM_IF_ERROR_RETURN
   7805         (_bcm_esw_gport_resolve(unit, port, &mod_out, &port_out, &trunk_id,
   7806                                 &gport_id));
   7807 
   7808     if (BCM_GPORT_IS_TRUNK(port)) {
   7809        if (BCM_TRUNK_INVALID == trunk_id) {
   7810             return BCM_E_PORT;
   7811         }
   7812 
   7813         BCM_IF_ERROR_RETURN
   7814             (bcm_esw_trunk_get(unit, trunk_id, NULL, 0, NULL, &port_count));
   7815 
   7816         if (port_count > 0) {
   7817         member_array = sal_alloc(sizeof(bcm_trunk_member_t) * port_count,
   7818                 "trunk member array");
   7819         if (member_array == NULL) {
   7820             rv = BCM_E_MEMORY;
   7821             goto cleanup;
   7822         }
   7823         sal_memset(member_array, 0, sizeof(bcm_trunk_member_t) * port_count);
   7824 
   7825         rv = bcm_esw_trunk_get(unit, trunk_id, NULL, port_count,
   7826                 member_array, &port_count);
   7827         if (BCM_FAILURE(rv)) {
   7828             goto cleanup;
   7829         }
   7830 
   7831         mod_array = sal_alloc(sizeof(bcm_module_t) * port_count,
   7832                 "module ID array");
   7833         if (mod_array == NULL) {
   7834             rv = BCM_E_MEMORY;
   7835             goto cleanup;
   7836         }
   7837         sal_memset(mod_array, 0, sizeof(bcm_module_t) * port_count);
   7838 
   7839         port_array = sal_alloc(sizeof(bcm_port_t) * port_count,
   7840                 "port ID array");
   7841         if (port_array == NULL) {
   7842             rv = BCM_E_MEMORY;
   7843             goto cleanup;
   7844         }
   7845         sal_memset(port_array, 0, sizeof(bcm_port_t) * port_count);
   7846         }
   7847 
   7848         for (i = 0; i < port_count; i++) {
   7849             rv = _bcm_esw_gport_resolve(unit, member_array[i].gport,
   7850                     &mod_array[i], &port_array[i], &tid, &gport_id);
   7851             if (BCM_FAILURE(rv)) {
   7852                 goto cleanup;
   7853             }
   7854         }
   7855     } else {
   7856         if ((-1 == mod_out) || (-1 == port_out)) {
   7857             return BCM_E_PORT;
   7858         }
   7859 
   7860         port_count = 1;
   7861 
   7862         mod_array = sal_alloc(sizeof(bcm_module_t) * port_count,
   7863                 "module ID array");
   7864         if (mod_array == NULL) {
   7865             rv = BCM_E_MEMORY;
   7866             goto cleanup;
   7867         }
   7868         mod_array[0] = mod_out;
   7869 
   7870         port_array = sal_alloc(sizeof(bcm_port_t) * port_count,
   7871                 "port ID array");
   7872         if (port_array == NULL) {
   7873             rv = BCM_E_MEMORY;
   7874             goto cleanup;
   7875         }
   7876         port_array[0] = port_out;
   7877     }
   7878 
   7879     if (port_count > 0) {
   7880     rv = _bcm_esw_src_mod_port_table_index_get(unit, mod_array[0],
   7881             port_array[0], &stm_idx);
   7882     if (BCM_FAILURE(rv)) {
   7883         goto cleanup;
   7884     }
   7885 
   7886     soc_mem_lock(unit, ING_VLAN_RANGEm);
   7887     rv = READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, stm_idx, &stm_entry);
   7888     if (rv < 0) {
   7889         soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7890         goto cleanup;
   7891     }
   7892 
   7893     /* If vlan double tag range compression feature is supported and
   7894      * entry type is for inner tag range translation */
   7895     if (inner_vlan_low != BCM_VLAN_INVALID) {
   7896         if (soc_feature (unit, soc_feature_vlan_double_tag_range_compress)) {
   7897             field = INNER_VLAN_RANGE_IDXf;
   7898         } else {
   7899             field = VLAN_RANGE_IDXf;
   7900         }
   7901 
   7902         old_inner_idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm,
   7903                                   &stm_entry, field);
   7904 
   7905         /* Get the profile table entry for this port/trunk */
   7906         _bcm_trx_vlan_range_profile_entry_get(unit,
   7907                                 min_inner_vlan, max_inner_vlan, old_inner_idx);
   7908     
   7909         /* Find the min/max range. */
   7910         for (i = 0 ; i < 8 ; i++) {
   7911             if ((min_inner_vlan[i] == inner_vlan_low) &&
   7912                 (max_inner_vlan[i] == inner_vlan_high)) {
   7913                 break;
   7914             }
   7915         }
   7916         if (i == 8) {
   7917             rv = BCM_E_NOT_FOUND;
   7918             soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7919             goto cleanup;
   7920         }
   7921 
   7922         /* Remove the range from the table entry and fill in the gap */
   7923         for ( ; i < 7 ; i++) {
   7924             /* Move existing min/max UP */
   7925             min_inner_vlan[i] = min_inner_vlan[i + 1];
   7926             max_inner_vlan[i] = max_inner_vlan[i + 1];
   7927         }
   7928         /* Mark last min/max range as unused. Unused ranges are
   7929          * identified by { min == 1, max == 0 }
   7930          */
   7931         min_inner_vlan[i] = 1;
   7932         max_inner_vlan[i] = 0;
   7933     
   7934         /* Adding the new profile table entry and update profile pointer */
   7935         for (i = 0; i < port_count; i++) {
   7936             rv = _bcm_trx_vlan_range_profile_entry_add(unit,
   7937                     min_inner_vlan, max_inner_vlan, &new_inner_idx);
   7938             if (BCM_FAILURE(rv)) {
   7939                 soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7940                 goto cleanup;
   7941             }
   7942             rv = _bcm_esw_src_mod_port_table_index_get(unit, mod_array[i],
   7943                     port_array[i], &stm_idx);
   7944             if (BCM_SUCCESS(rv)) {
   7945                 rv = soc_mem_field32_modify(unit,
   7946                         SOURCE_TRUNK_MAP_TABLEm, stm_idx,
   7947                         field, new_inner_idx);
   7948             }
   7949             if (BCM_FAILURE(rv)) {
   7950                 _bcm_trx_vlan_range_profile_entry_delete(unit, new_inner_idx);
   7951                 soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7952                 goto cleanup;
   7953             }
   7954         }
   7955     }
   7956     
   7957     /* If vlan double tag range compression feature is supported and
   7958      * entry type is for double tag range compression */
   7959     if (outer_vlan_low != BCM_VLAN_INVALID) {
   7960         field = VLAN_RANGE_IDXf;
   7961         if (soc_feature (unit, soc_feature_vlan_double_tag_range_compress)) {
   7962             if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 
   7963                               OUTER_VLAN_RANGE_IDXf)) {  
   7964                 field = OUTER_VLAN_RANGE_IDXf;
   7965             }
   7966         }
   7967 
   7968         old_idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm,
   7969                 &stm_entry, field);
   7970 
   7971         /* Get the profile table entry for this port/trunk */
   7972         _bcm_trx_vlan_range_profile_entry_get(unit,
   7973                                               min_vlan, max_vlan, old_idx);
   7974 
   7975 
   7976         /* Find the min/max range. */
   7977         for (i = 0 ; i < 8 ; i++) {
   7978             if ((min_vlan[i] == outer_vlan_low) &&
   7979                 (max_vlan[i] == outer_vlan_high)) {
   7980                         break;
   7981             }
   7982         }
   7983         if (i == 8) {
   7984             rv = BCM_E_NOT_FOUND;
   7985             soc_mem_unlock(unit, ING_VLAN_RANGEm);
   7986             goto cleanup;
   7987         }
   7988 
   7989         /* Remove the range from the table entry and fill in the gap */
   7990         for ( ; i < 7 ; i++) {
   7991             /* Move existing min/max UP */
   7992             min_vlan[i] = min_vlan[i + 1];
   7993             max_vlan[i] = max_vlan[i + 1];
   7994         }
   7995         /* Mark last min/max range as unused. Unused ranges are
   7996          * identified by { min == 1, max == 0 }
   7997          */
   7998         min_vlan[i] = 1;
   7999         max_vlan[i] = 0;
   8000 
   8001         /* Adding the new profile table entry and update profile pointer */
   8002         for (i = 0; i < port_count; i++) {
   8003             rv = _bcm_trx_vlan_range_profile_entry_add(unit,
   8004                     min_vlan, max_vlan, &new_idx);
   8005             if (BCM_FAILURE(rv)) {
   8006                 soc_mem_unlock(unit, ING_VLAN_RANGEm);
   8007                 goto cleanup;
   8008             }
   8009             rv = _bcm_esw_src_mod_port_table_index_get(unit, mod_array[i],
   8010                     port_array[i], &stm_idx);
   8011             if (BCM_SUCCESS(rv)) {
   8012                 rv = soc_mem_field32_modify(unit,
   8013                         SOURCE_TRUNK_MAP_TABLEm, stm_idx,
   8014                         field, new_idx);
   8015             }
   8016             if (BCM_FAILURE(rv)) {
   8017                 _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx);
   8018                 soc_mem_unlock(unit, ING_VLAN_RANGEm);
   8019                 goto cleanup;
   8020             }
   8021         }
   8022     }
   8023     }
   8024 
   8025     /* Delete the entry from the vlan translate table for the low VID */
   8026     rv = _bcm_trx_vlan_translate_action_delete(unit, port, key_type,
   8027                                                outer_vlan_low, inner_vlan_low);
   8028     if ((rv != BCM_E_NONE) && (rv != BCM_E_NOT_FOUND)){
   8029         for (i = 0; i < port_count; i++) {
   8030             if (outer_vlan_low != BCM_VLAN_INVALID) {
   8031                 _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx);
   8032             }
   8033             if (inner_vlan_low != BCM_VLAN_INVALID) {
   8034                 _bcm_trx_vlan_range_profile_entry_delete(unit, new_inner_idx);
   8035             }
   8036         }
   8037         if (port_count > 0) {
   8038         soc_mem_unlock(unit, ING_VLAN_RANGEm);
   8039         }
   8040         goto cleanup;
   8041     }
   8042 
   8043     /* Delete the old profile entry */
   8044     for (i = 0; i < port_count; i++) {
   8045         if (outer_vlan_low != BCM_VLAN_INVALID) {
   8046             _bcm_trx_vlan_range_profile_entry_delete(unit, old_idx);
   8047         }
   8048         if (inner_vlan_low != BCM_VLAN_INVALID) {
   8049             _bcm_trx_vlan_range_profile_entry_delete(unit, old_inner_idx);
   8050         }
   8051     }
   8052 
   8053     if (BCM_GPORT_IS_TRUNK(port)) {
   8054         if (SOC_MEM_FIELD_VALID(unit, TRUNK32_PORT_TABLEm, VLAN_RANGE_IDXf)) {
   8055             trunk128 = soc_property_get(unit, spn_TRUNK_EXTEND, 1);
   8056             if (!trunk128) {
   8057                 rv = _bcm_trx_vlan_range_profile_entry_add(unit,
   8058                         min_vlan, max_vlan, &new_idx);
   8059                 if (BCM_FAILURE(rv)) {
   8060                     soc_mem_unlock(unit, ING_VLAN_RANGEm);
   8061                     goto cleanup;
   8062                 }
   8063                 rv = soc_mem_field32_modify(unit, TRUNK32_PORT_TABLEm, trunk_id,
   8064                         VLAN_RANGE_IDXf, new_idx);
   8065                 if (BCM_FAILURE(rv)) {
   8066                     _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx);
   8067                     soc_mem_unlock(unit, ING_VLAN_RANGEm);
   8068                     goto cleanup;
   8069                 }
   8070                 if (outer_vlan_low != BCM_VLAN_INVALID) {
   8071                     _bcm_trx_vlan_range_profile_entry_delete(unit, old_idx);
   8072                 }
   8073                 if (inner_vlan_low != BCM_VLAN_INVALID) {
   8074                     _bcm_trx_vlan_range_profile_entry_delete(unit, old_inner_idx);
   8075                 }
   8076             }
   8077         }
   8078     }
   8079     if (port_count > 0) {
   8080     soc_mem_unlock(unit, ING_VLAN_RANGEm);
   8081     }
   8082     
   8083 cleanup:
   8084     if (NULL != member_array) {
   8085         sal_free(member_array);
   8086     }
   8087     if (NULL != mod_array) {
   8088         sal_free(mod_array);
   8089     }
   8090     if (NULL != port_array) {
   8091         sal_free(port_array);
   8092     }
   8093 
   8094     return rv;
   8095 }
   8096 
   8097 /*
   8098  * Function   :
   8099  *      bcm_vlan_translate_action_range_delete_all
   8100  * Description   :
   8101  *      Delete all ranges of VLANs and entries from ingress 
   8102  *      VLAN translation table.
   8103  * Parameters   :
   8104  *      unit            (IN) BCM unit number
   8105  */
   8106 int
   8107 _bcm_trx_vlan_translate_action_range_delete_all(int unit)
   8108 {
   8109     int rv;
   8110 
   8111     rv = _bcm_trx_vlan_range_profile_init(unit);
   8112     if (rv == BCM_E_NONE) {
   8113         rv = _bcm_trx_vlan_translate_action_delete_all(unit);
   8114     }
   8115     return rv;
   8116 }
   8117 
   8118 /*
   8119  * Function:
   8120  *     _bcm_trx_vlan_translate_stm_index_to_gport
   8121  * Description:
   8122  *      Translate index of SOURCE_TRUNK_MAP_TABLE into gport
   8123  * Parameters:
   8124  *      unit         device number
   8125  *      stm_index    Index to SOURCE_TRUNK_MAP_TABLE
   8126  *      gport       (OUT) gport
   8127  * Return:
   8128  *     BCM_E_XXX
   8129  */
   8130 STATIC int  
   8131 _bcm_trx_vlan_translate_stm_index_to_gport(int unit, int stm_index, 
   8132                                           bcm_gport_t *gport)
   8133 {
   8134     bcm_module_t    modid;
   8135     bcm_port_t      port;
   8136     _bcm_gport_dest_t   gport_dest;
   8137 
   8138     if (NULL == gport) {
   8139         return BCM_E_PARAM;
   8140     }
   8141 
   8142 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT)
   8143     if (soc_feature(unit, soc_feature_src_modid_base_index)) {
   8144         BCM_IF_ERROR_RETURN
   8145             (_bcm_esw_src_modid_port_get(unit, stm_index, 
   8146                                                  &modid,&port));
   8147     } else
   8148 #endif
   8149     {
   8150         modid = stm_index / (SOC_PORT_ADDR_MAX(unit) + 1) ; 
   8151         port = stm_index - modid * (SOC_PORT_ADDR_MAX(unit) + 1);
   8152     }
   8153 
   8154     if (!SOC_MODID_ADDRESSABLE(unit, modid)) {
   8155         return BCM_E_PARAM;
   8156     }
   8157 
   8158     if (!SOC_PORT_ADDRESSABLE(unit, port)) {
   8159         return BCM_E_PARAM;
   8160     }
   8161 
   8162     gport_dest.port = port;
   8163     gport_dest.modid = modid;
   8164     gport_dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
   8165     BCM_IF_ERROR_RETURN(_bcm_esw_gport_construct(unit, &gport_dest, gport));
   8166 
   8167     return BCM_E_NONE;
   8168 }
   8169 
   8170 /*
   8171  * Function   :
   8172  *      _bcm_trx_vlan_translate_action_range_traverse
   8173  * Description   :
   8174  *      Traverses over range of ingress VLAN translation table.
   8175  * Parameters   :
   8176  *      unit            (IN) BCM unit number
   8177  *      trvs_info       (IN/OUT) Traverse Structure to opertae on
   8178  */
   8179 int
   8180 _bcm_trx_vlan_translate_action_range_traverse(int unit, 
   8181                                     _bcm_vlan_translate_traverse_t *trvs_info)
   8182 {
   8183     /* Indexes to iterate over memories, chunks and entries */
   8184     int                           chnk_idx, ent_idx, chnk_idx_max, mem_idx_max;
   8185     int                             buf_size, chunksize, chnk_end;
   8186     /* Buffer to store chunks of memory table we currently work on */
   8187     uint32                          *stm_tbl_chnk;
   8188     source_trunk_map_table_entry_t  *stm_ent;
   8189     soc_mem_t                       mem;
   8190     int                             stop, rv = BCM_E_NONE;
   8191     /* Index to point to table of vlan ranges. */
   8192     int                             range_idx, stm_index, i;
   8193     bcm_gport_t                     gport;
   8194     bcm_vlan_t                      min_vlan[8], max_vlan[8];
   8195     soc_field_t                    field;
   8196     bcm_vlan_t                     min_inner_vlan[8], max_inner_vlan[8];
   8197     int                            range_inner_idx, j;
   8198 
   8199     mem = SOURCE_TRUNK_MAP_TABLEm;
   8200     if (!soc_mem_index_count(unit, mem)) {
   8201         return BCM_E_NONE;
   8202     }
   8203 
   8204     chunksize = soc_property_get(unit, spn_VLANDELETE_CHUNKS,
   8205                                  VLAN_MEM_CHUNKS_DEFAULT);
   8206 
   8207     buf_size = 4 * SOC_MAX_MEM_FIELD_WORDS * chunksize;
   8208     stm_tbl_chnk = soc_cm_salloc(unit, buf_size, 
   8209                                  "vlan translate range traverse");
   8210     if (NULL == stm_tbl_chnk) {
   8211         return BCM_E_MEMORY;
   8212     }
   8213 
   8214     mem_idx_max = soc_mem_index_max(unit, mem);
   8215     for (chnk_idx = soc_mem_index_min(unit, mem); 
   8216          chnk_idx <= mem_idx_max; 
   8217          chnk_idx += chunksize) {
   8218         sal_memset((void *)stm_tbl_chnk, 0, buf_size);
   8219 
   8220         chnk_idx_max = 
   8221             ((chnk_idx + chunksize) <= mem_idx_max) ? 
   8222             chnk_idx + chunksize - 1: mem_idx_max;
   8223 
   8224         rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY,
   8225                                 chnk_idx, chnk_idx_max, stm_tbl_chnk);
   8226         if (SOC_FAILURE(rv)) {
   8227             break;
   8228         }
   8229         chnk_end = (chnk_idx_max - chnk_idx);
   8230 
   8231         if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
   8232                     OUTER_VLAN_RANGE_IDXf)) {
   8233             field = OUTER_VLAN_RANGE_IDXf;
   8234         } else {
   8235             field = VLAN_RANGE_IDXf;
   8236         }
   8237 
   8238         for (ent_idx = 0 ; ent_idx <= chnk_end; ent_idx ++) {
   8239             stm_ent = soc_mem_table_idx_to_pointer(unit, mem, 
   8240                                              source_trunk_map_table_entry_t *, 
   8241                                              stm_tbl_chnk, ent_idx);
   8242 
   8243             if (soc_feature(unit, soc_feature_vlan_double_tag_range_compress)) {
   8244                 range_idx = soc_mem_field32_get(unit, mem, stm_ent, field);
   8245                 _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, max_vlan,
   8246                         range_idx);
   8247 
   8248                 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
   8249                             INNER_VLAN_RANGE_IDXf)) {
   8250                     range_inner_idx = soc_mem_field32_get(unit, mem, stm_ent, 
   8251                             INNER_VLAN_RANGE_IDXf);
   8252                     _bcm_trx_vlan_range_profile_entry_get(unit, min_inner_vlan,
   8253                             max_inner_vlan, range_inner_idx);
   8254                     if ((1 == min_vlan[0]) && (0 == max_vlan[0]) &&
   8255                         (1 == min_inner_vlan[0]) && (0 == max_inner_vlan[0])) {
   8256                         continue;
   8257                     }
   8258                 } else {
   8259                     if ((1 == min_vlan[0]) && (0 == max_vlan[0])) {
   8260                         continue;
   8261                     }
   8262                 }
   8263                 stm_index = chnk_idx + ent_idx; 
   8264                 rv = _bcm_trx_vlan_translate_stm_index_to_gport(unit, stm_index,
   8265                         &gport);
   8266                 if (BCM_FAILURE(rv)) {
   8267                     break;
   8268                 }
   8269                 trvs_info->gport = gport;
   8270 
   8271                 for (i = 0; i < 8; i++) {
   8272                     if ((1 == min_vlan[i]) && (0 == max_vlan[i])) {
   8273                         continue;
   8274                     }
   8275                     trvs_info->inner_vlan = BCM_VLAN_INVALID;
   8276                     trvs_info->inner_vlan_high = BCM_VLAN_INVALID;
   8277                     trvs_info->outer_vlan = BCM_VLAN_INVALID;
   8278                     trvs_info->outer_vlan_high = BCM_VLAN_INVALID;
   8279                     /* check if entry key_type is 
   8280                        bcmVlanTranslateKeyPortOuter */
   8281                     rv = _bcm_trx_vlan_translate_action_range_get(
   8282                             unit, gport,
   8283                             min_vlan[i], max_vlan[i],
   8284                             BCM_VLAN_INVALID, BCM_VLAN_INVALID,
   8285                             trvs_info->action);
   8286                     if (BCM_SUCCESS (rv)) {
   8287                         trvs_info->key_type = bcmVlanTranslateKeyPortOuter;
   8288                         trvs_info->outer_vlan = min_vlan[i];
   8289                         trvs_info->outer_vlan_high = max_vlan[i];
   8290                         rv = trvs_info->int_cb(unit, trvs_info, &stop);
   8291                         if (BCM_FAILURE(rv) || TRUE == stop) {
   8292                             break;
   8293                         }
   8294                     } else {
   8295                         if (BCM_E_NOT_FOUND == rv) {
   8296                             if (SOC_MEM_FIELD_VALID(unit,
   8297                                         SOURCE_TRUNK_MAP_TABLEm,
   8298                                         INNER_VLAN_RANGE_IDXf)) {
   8299                                 for (j = 0; j < 8; j++) {
   8300                                     if ((1 == min_inner_vlan[j]) && 
   8301                                         (0 == max_inner_vlan[j])) {
   8302                                         continue;
   8303                                     }
   8304                                     trvs_info->inner_vlan = BCM_VLAN_INVALID;
   8305                                     trvs_info->inner_vlan_high =
   8306                                         BCM_VLAN_INVALID;
   8307                                     trvs_info->outer_vlan = BCM_VLAN_INVALID;
   8308                                     trvs_info->outer_vlan_high =
   8309                                         BCM_VLAN_INVALID;
   8310                                     /* check if entry key_type is 
   8311                                      * bcmVlanTranslateKeyPortDouble */
   8312                                     rv =
   8313                                     _bcm_trx_vlan_translate_action_range_get(
   8314                                             unit, gport,
   8315                                             min_vlan[i], max_vlan[i],
   8316                                             min_inner_vlan[j],
   8317                                             max_inner_vlan[j],
   8318                                             trvs_info->action);
   8319                                     if (BCM_SUCCESS (rv)) {
   8320                                         trvs_info->key_type =
   8321                                             bcmVlanTranslateKeyPortDouble;
   8322                                         trvs_info->outer_vlan = min_vlan[i];
   8323                                         trvs_info->outer_vlan_high =
   8324                                             max_vlan[i];
   8325                                         trvs_info->inner_vlan =
   8326                                             min_inner_vlan[j];
   8327                                         trvs_info->inner_vlan_high =
   8328                                             max_inner_vlan[j];
   8329                                         rv = trvs_info->int_cb(unit,
   8330                                                 trvs_info, &stop);
   8331                                         if (BCM_FAILURE(rv) || TRUE == stop) {
   8332                                             break;
   8333                                         }
   8334                                     } else {
   8335                                         if (BCM_E_NOT_FOUND != rv) {
   8336                                             soc_cm_sfree(unit, stm_tbl_chnk);
   8337                                             return rv;
   8338                                         }
   8339                                     }
   8340                                 } /*endof for j=0;j<8;j++*/
   8341                             }
   8342                         } else {
   8343                             soc_cm_sfree(unit, stm_tbl_chnk);
   8344                             return rv;
   8345                         }
   8346                     }
   8347                 } /*endof for i=0;i<8;i++ */
   8348                 
   8349                 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
   8350                             INNER_VLAN_RANGE_IDXf)) {
   8351                     for (j = 0; j < 8; j++) {
   8352                         if ((1 == min_inner_vlan[j]) && 
   8353                             (0 == max_inner_vlan[j])) {
   8354                             continue;
   8355                         }
   8356                         trvs_info->inner_vlan = BCM_VLAN_INVALID;
   8357                         trvs_info->inner_vlan_high = BCM_VLAN_INVALID;
   8358                         trvs_info->outer_vlan = BCM_VLAN_INVALID;
   8359                         trvs_info->outer_vlan_high = BCM_VLAN_INVALID;
   8360                         /* check if entry key_type is
   8361                            bcmVlanTranslateKeyPortInner */
   8362                         rv = _bcm_trx_vlan_translate_action_range_get(
   8363                                 unit, gport, 
   8364                                 BCM_VLAN_INVALID, BCM_VLAN_INVALID,
   8365                                 min_inner_vlan[j], max_inner_vlan[j], 
   8366                                 trvs_info->action);
   8367                         if (BCM_SUCCESS (rv)) {
   8368                             trvs_info->key_type = bcmVlanTranslateKeyPortInner;
   8369                             trvs_info->inner_vlan = min_inner_vlan[j];
   8370                             trvs_info->inner_vlan_high = max_inner_vlan[j];
   8371                             rv = trvs_info->int_cb(unit, trvs_info, &stop);
   8372                             if (BCM_FAILURE(rv) || TRUE == stop) {
   8373                                 break;
   8374                             }
   8375                         } else {
   8376                             if (BCM_E_NOT_FOUND != rv) {
   8377                                 soc_cm_sfree(unit, stm_tbl_chnk);
   8378                                 return rv;
   8379                             }
   8380                         }
   8381                     }
   8382                 }
   8383             } else {
   8384                 range_idx = soc_mem_field32_get(unit, mem, stm_ent, field);
   8385                 _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, max_vlan,
   8386                         range_idx);
   8387 
   8388                 if ((1 == min_vlan[0]) && (0 == max_vlan[0])) {
   8389                     continue;
   8390                 }
   8391 
   8392                 stm_index = chnk_idx + ent_idx; 
   8393                 rv = _bcm_trx_vlan_translate_stm_index_to_gport(unit, stm_index,
   8394                         &gport);
   8395                 if (BCM_FAILURE(rv)) {
   8396                     break;
   8397                 }
   8398                 trvs_info->gport = gport;
   8399 
   8400                 for (i = 0; i < 8; i++) {
   8401                     if ((1 == min_vlan[i]) && (0 == max_vlan[i])) {
   8402                         continue;
   8403                     }
   8404                     trvs_info->inner_vlan = BCM_VLAN_INVALID;
   8405                     trvs_info->inner_vlan_high = BCM_VLAN_INVALID;
   8406                     trvs_info->outer_vlan = BCM_VLAN_INVALID;
   8407                     trvs_info->outer_vlan_high = BCM_VLAN_INVALID;
   8408 
   8409                     /* check if entry key_type is
   8410                      * bcmVlanTranslateKeyPortOuter */
   8411                     rv = _bcm_trx_vlan_translate_action_range_get(unit, 
   8412                             gport, 
   8413                             min_vlan[i], 
   8414                             max_vlan[i], 
   8415                             BCM_VLAN_INVALID,
   8416                             BCM_VLAN_INVALID,
   8417                             trvs_info->action);
   8418                     if (BCM_SUCCESS (rv)) {
   8419                         trvs_info->key_type = bcmVlanTranslateKeyPortOuter;
   8420                         trvs_info->outer_vlan = min_vlan[i];
   8421                         trvs_info->outer_vlan_high = max_vlan[i];
   8422                     } else {
   8423                         if (BCM_E_NOT_FOUND == rv) {
   8424                             /* check if entry key_type is
   8425                                bcmVlanTranslateKeyPortInner */
   8426                             rv = _bcm_trx_vlan_translate_action_range_get(unit, 
   8427                                     gport, 
   8428                                     BCM_VLAN_INVALID,
   8429                                     BCM_VLAN_INVALID,
   8430                                     min_vlan[i], 
   8431                                     max_vlan[i], 
   8432                                     trvs_info->action);
   8433                             if (BCM_FAILURE(rv)) {
   8434                                 soc_cm_sfree(unit, stm_tbl_chnk);
   8435                                 return rv;
   8436                             }
   8437                             trvs_info->key_type = bcmVlanTranslateKeyPortInner;
   8438                             trvs_info->inner_vlan = min_vlan[i];
   8439                             trvs_info->inner_vlan_high = max_vlan[i];
   8440                         } else {
   8441                             soc_cm_sfree(unit, stm_tbl_chnk);
   8442                             return rv;
   8443                         }
   8444                     }
   8445 
   8446                     rv = trvs_info->int_cb(unit, trvs_info, &stop);
   8447                     if (BCM_FAILURE(rv) || TRUE == stop) {
   8448                         break;
   8449                     }
   8450                 }
   8451             }
   8452         }
   8453     }
   8454     soc_cm_sfree(unit, stm_tbl_chnk);
   8455     return rv;        
   8456 
   8457 }
   8458 
   8459 /*
   8460  * Function:
   8461  *      _bcm_trx_vlan_translate_egress_entry_assemble
   8462  * Purpose:
   8463  *      Constructs vlan translate egress entry from given port class,
   8464  *      inner and outer vlans
   8465  * Parameters:
   8466  *      unit            (IN) BCM unit number
   8467  *      vent            (IN/OUT) vlan translate egress entry to construct
   8468  *      port_class      (IN) Group ID of ingress port
   8469  *      outer_vlan      (IN) Packet outer VLAN ID
   8470  *      inner_vlan      (IN) Packet inner VLAN ID
   8471  * Returns:
   8472  *      BCM_E_XXX
   8473  */
   8474 int 
   8475 _bcm_trx_vlan_translate_egress_entry_assemble(int unit,
   8476                                               void *vent,
   8477                                               int port_class,
   8478                                               bcm_vlan_t outer_vlan,
   8479                                               bcm_vlan_t inner_vlan)
   8480 {
   8481 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
   8482     int id = -1;
   8483     bcm_module_t modid = -1;
   8484     bcm_trunk_t tgid = -1;
   8485 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   8486 
   8487 #ifdef BCM_TRIUMPH2_SUPPORT
   8488     int tunnel_id = 0;
   8489     int dvp_id = BCM_GPORT_INVALID;
   8490 #endif
   8491 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   8492     int vfi_index = 0;
   8493 #endif /* BCM_TRIDENT2PLUS_SUPPORT &&  INCLUDE_L3 */
   8494 #if defined(BCM_GREYHOUND2_SUPPORT) && defined(INCLUDE_L3)
   8495     int rv = BCM_E_NONE;
   8496     int ecmp = -1, nh_ecmp_index = -1;
   8497 #endif /* BCM_GREYHOUND2_SUPPORT && INCLUDE_L3 */
   8498 
   8499     soc_mem_t egr_mem = EGR_VLAN_XLATEm;
   8500     uint32 ent_sz = sizeof(egr_vlan_xlate_entry_t);
   8501 
   8502 #ifdef BCM_TRIUMPH2_SUPPORT
   8503     soc_field_t kt_fld = ENTRY_TYPEf;
   8504     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) {
   8505         egr_mem = EGR_VLAN_XLATE_1_DOUBLEm;
   8506         ent_sz = sizeof(egr_vlan_xlate_1_double_entry_t);
   8507         kt_fld = KEY_TYPEf;
   8508     }
   8509 #endif
   8510 
   8511 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   8512     if (soc_feature(unit, soc_feature_vp_sharing)) {
   8513         if (_BCM_VPN_VFI_IS_SET(outer_vlan)) 
   8514         {   
   8515             /* only invalid inner VLAN is allowed for VFI case */
   8516             if (inner_vlan == BCM_VLAN_INVALID) {             
   8517                 _BCM_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, outer_vlan);
   8518                 if (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeAny)) {
   8519                     return BCM_E_NOT_FOUND;
   8520                 } 
   8521             } else {
   8522                 return BCM_E_PARAM;
   8523             } 
   8524         } else {         
   8525             VLAN_CHK_ID(unit, outer_vlan);
   8526             VLAN_CHK_ID(unit, inner_vlan);
   8527         }
   8528     } else 
   8529 #endif
   8530     {
   8531         VLAN_CHK_ID(unit, outer_vlan);
   8532         VLAN_CHK_ID(unit, inner_vlan);
   8533     }
   8534 #ifdef BCM_TRIUMPH2_SUPPORT
   8535 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) 
   8536     if (inner_vlan == BCM_VLAN_INVALID) {
   8537         if (BCM_GPORT_IS_VXLAN_PORT(port_class)) {
   8538             if (soc_feature(unit, soc_feature_vxlan)) {
   8539                 dvp_id = BCM_GPORT_VXLAN_PORT_ID_GET(port_class);
   8540             } else {
   8541                 return BCM_E_PORT;                
   8542             }
   8543         } else if (BCM_GPORT_IS_MIM_PORT(port_class)) {
   8544             if (soc_feature(unit, soc_feature_mim)) {
   8545                 dvp_id = BCM_GPORT_MIM_PORT_ID_GET(port_class);
   8546             } else {
   8547                 return BCM_E_PORT;
   8548             }
   8549         } else if (BCM_GPORT_IS_MPLS_PORT(port_class)) {
   8550             if (soc_feature(unit, soc_feature_mpls)) {
   8551                 dvp_id = BCM_GPORT_MPLS_PORT_ID_GET(port_class);
   8552             } else {
   8553                 return BCM_E_PORT;
   8554             }
   8555         } else if (BCM_GPORT_IS_L2GRE_PORT(port_class)) {
   8556             if (soc_feature(unit, soc_feature_l2gre)) {
   8557                 dvp_id = BCM_GPORT_L2GRE_PORT_ID_GET(port_class);
   8558             } else {
   8559                 return BCM_E_PORT;
   8560             }
   8561         } else if (BCM_GPORT_IS_TUNNEL(port_class) || 
   8562                    BCM_GPORT_IS_SUBPORT_PORT(port_class) || 
   8563                    BCM_GPORT_IS_WLAN_PORT(port_class) ||
   8564                    BCM_GPORT_IS_VLAN_PORT(port_class) ||
   8565                    BCM_GPORT_IS_NIV_PORT(port_class)){
   8566             return BCM_E_PORT; 
   8567         }
   8568     } else
   8569 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */
   8570     if (BCM_GPORT_IS_TUNNEL(port_class)) {
   8571         if (soc_feature(unit, soc_feature_wlan)) {
   8572             tunnel_id = BCM_GPORT_TUNNEL_ID_GET(port_class);
   8573         } else {
   8574             return BCM_E_PORT;
   8575         }
   8576     } else if (BCM_GPORT_IS_SUBPORT_PORT(port_class)) {
   8577         if (soc_feature(unit, soc_feature_subport)) {
   8578             bcm_module_t modid = -1;
   8579             bcm_trunk_t tgid = -1;
   8580             int port = -1;
   8581             BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port_class,
   8582                                 &modid, &port, &tgid, &dvp_id));
   8583         } else {
   8584             return BCM_E_PORT;
   8585         }
   8586     } else if (BCM_GPORT_IS_MIM_PORT(port_class)) {
   8587         if (soc_feature(unit, soc_feature_mim)) {
   8588             dvp_id = BCM_GPORT_MIM_PORT_ID_GET(port_class);
   8589         } else {
   8590             return BCM_E_PORT;
   8591         }
   8592         
   8593     } else if (BCM_GPORT_IS_WLAN_PORT(port_class)) {
   8594         if (soc_feature(unit, soc_feature_wlan)) {
   8595             dvp_id = BCM_GPORT_WLAN_PORT_ID_GET(port_class);
   8596         } else {
   8597             return BCM_E_PORT;
   8598         }
   8599     } else if (BCM_GPORT_IS_VLAN_PORT(port_class)) {
   8600         if (soc_feature(unit, soc_feature_vlan_vp)) {
   8601             dvp_id = BCM_GPORT_VLAN_PORT_ID_GET(port_class);
   8602         } else {
   8603             return BCM_E_PORT;
   8604         }
   8605     } else if (BCM_GPORT_IS_NIV_PORT(port_class)) {
   8606         if (soc_feature(unit, soc_feature_niv)) {
   8607             dvp_id = BCM_GPORT_NIV_PORT_ID_GET(port_class);
   8608         } else {
   8609             return BCM_E_PORT;
   8610         }
   8611     } else if (BCM_GPORT_IS_EXTENDER_PORT(port_class)) {
   8612         if (soc_feature(unit, soc_feature_port_extension)) {
   8613             dvp_id = BCM_GPORT_EXTENDER_PORT_ID_GET(port_class);
   8614         } else {
   8615             return BCM_E_PORT;
   8616         } 
   8617     } else if (BCM_GPORT_IS_MPLS_PORT(port_class)) {
   8618         if (soc_feature(unit, soc_feature_mpls)) {
   8619             dvp_id = BCM_GPORT_MPLS_PORT_ID_GET(port_class);
   8620         } else {
   8621             return BCM_E_PORT;
   8622         }
   8623     } else if (BCM_GPORT_IS_VXLAN_PORT(port_class)) {
   8624 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
   8625         if (soc_feature(unit, soc_feature_vxlan)) {
   8626             ing_dvp_table_entry_t dvp;
   8627             dvp_id = BCM_GPORT_VXLAN_PORT_ID_GET(port_class);
   8628             BCM_IF_ERROR_RETURN(
   8629                 READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, dvp_id, &dvp));
   8630             if (soc_ING_DVP_TABLEm_field32_get(unit, &dvp, VP_TYPEf) == 0x3) {
   8631                 return BCM_E_PORT;
   8632             }
   8633         } else
   8634 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */
   8635 #if defined(BCM_GREYHOUND2_SUPPORT) && defined(INCLUDE_L3)
   8636         if (soc_feature(unit, soc_feature_vxlan_lite)) {
   8637             dvp_id = BCM_GPORT_VXLAN_PORT_ID_GET(port_class);
   8638             rv = bcmi_gh2_vxlan_port_to_nh_ecmp_index(unit, dvp_id,
   8639                                                       &ecmp, &nh_ecmp_index);
   8640             if (BCM_FAILURE(rv) || (ecmp)) {
   8641                 return BCM_E_PORT;
   8642             }
   8643         } else
   8644 #endif /* BCM_GREYHOUND2_SUPPORT && INCLUDE_L3 */
   8645         {
   8646             return BCM_E_PORT;
   8647         }
   8648     } else if (BCM_GPORT_IS_L2GRE_PORT(port_class)) {
   8649 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
   8650         if (soc_feature(unit, soc_feature_l2gre)) {
   8651             ing_dvp_table_entry_t dvp;
   8652             dvp_id = BCM_GPORT_L2GRE_PORT_ID_GET(port_class);
   8653             BCM_IF_ERROR_RETURN(
   8654                 READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, dvp_id, &dvp));
   8655             if (soc_ING_DVP_TABLEm_field32_get(unit, &dvp, VP_TYPEf) == 0x2) {
   8656                 return BCM_E_PORT;
   8657             }
   8658         } else
   8659 #endif
   8660         {
   8661             return BCM_E_PORT;
   8662         }
   8663     }
   8664 #endif /* BCM_TRIUMPH2_SUPPORT */
   8665 
   8666     sal_memset(vent, 0, ent_sz);
   8667 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   8668     if (inner_vlan == BCM_VLAN_INVALID) {
   8669         soc_mem_field32_set(unit, egr_mem, vent,
   8670                            VLAN_XLATE_VFI__VFIf, vfi_index);   
   8671 
   8672     } else
   8673 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */
   8674     {
   8675         soc_mem_field32_set(unit, egr_mem, vent, OVIDf, outer_vlan);
   8676         soc_mem_field32_set(unit, egr_mem, vent, IVIDf, inner_vlan);
   8677     }
   8678 #ifdef BCM_TRIUMPH2_SUPPORT
   8679     if (BCM_GPORT_IS_TUNNEL(port_class)) {
   8680         soc_mem_field32_set(unit, egr_mem, vent, kt_fld, 2); /* WLAN */
   8681         if (soc_mem_field_valid(unit, egr_mem, DATA_TYPEf)) {
   8682             soc_mem_field32_set(unit, egr_mem, vent, DATA_TYPEf, 2);
   8683         }
   8684         soc_mem_field32_set(unit, egr_mem, vent, TUNNEL_IDf, tunnel_id);
   8685     } else if (BCM_GPORT_INVALID != dvp_id) {
   8686 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   8687         if (inner_vlan == BCM_VLAN_INVALID) {
   8688             soc_mem_field32_set(unit, egr_mem, vent, kt_fld,
   8689                            TD2PLUS_EVLXLT_HASH_KEY_TYPE_VLAN_XLATE_VFI); /* VFI + DVP */
   8690 #ifdef BCM_TRIDENT3_SUPPORT
   8691             if (soc_mem_field_valid(unit, egr_mem, DATA_TYPEf)) {
   8692                 soc_mem_field32_set(unit, egr_mem, vent, DATA_TYPEf, 
   8693                     TD2PLUS_EVLXLT_HASH_KEY_TYPE_VLAN_XLATE_VFI);
   8694             }
   8695 #endif
   8696             soc_mem_field32_set(unit, egr_mem, vent,
   8697                                VLAN_XLATE_VFI__DVPf, dvp_id);                               
   8698         } else
   8699 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 
   8700 #if defined(BCM_GREYHOUND2_SUPPORT) && defined(INCLUDE_L3)
   8701         if (soc_feature(unit, soc_feature_vxlan_lite)) {
   8702             /* ENTRY_TYPEf: NHI */
   8703             soc_mem_field32_set(unit, egr_mem, vent, ENTRY_TYPEf, 0x7);
   8704             /* NHI for NHI view */
   8705             soc_mem_field32_set(unit, egr_mem, vent, NHI__NHIf, nh_ecmp_index);
   8706         } else
   8707 #endif /* BCM_GREYHOUND2_SUPPORT && INCLUDE_L3 */
   8708         {
   8709 #ifdef BCM_TRIUMPH3_SUPPORT
   8710             if(SOC_IS_TRIUMPH3(unit)) {
   8711                 soc_mem_field32_set(unit, egr_mem, vent, KEY_TYPEf, 1); /* DVP */
   8712             } else
   8713 #endif /* BCM_TRIUMPH3_SUPPORT */
   8714             {
   8715                 soc_mem_field32_set(unit, egr_mem, vent, kt_fld, 1); /* DVP */
   8716                 if (soc_mem_field_valid(unit, egr_mem, DATA_TYPEf)) {
   8717                     soc_mem_field32_set(unit, egr_mem, vent, DATA_TYPEf, 1);
   8718             }
   8719             }
   8720             soc_mem_field32_set(unit, egr_mem, vent, DVPf, dvp_id);
   8721         }
   8722     } else 
   8723 #endif
   8724     {
   8725 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   8726         if (inner_vlan == BCM_VLAN_INVALID) {             
   8727             soc_mem_field32_set(unit, egr_mem, vent, kt_fld, /* VFI + DVP Group*/
   8728                                 TD2PLUS_EVLXLT_HASH_KEY_TYPE_VFI_DVP_GROUP);
   8729             if (soc_mem_field_valid(unit, egr_mem, DATA_TYPEf)) {
   8730                 soc_mem_field32_set(unit, egr_mem, vent, DATA_TYPEf,
   8731                         TD2PLUS_EVLXLT_HASH_KEY_TYPE_VFI_DVP_GROUP);
   8732             }
   8733             soc_mem_field32_set(unit, egr_mem, vent,
   8734                         VFI_DVP_GROUP__VT_DVP_GROUP_IDf, port_class);
   8735 
   8736             if (soc_mem_field_valid(unit, egr_mem,
   8737                         VFI_DVP_GROUP__DATA_OVERLAY_TYPEf)) {
   8738                 soc_mem_field32_set(unit, egr_mem, vent,
   8739                         VFI_DVP_GROUP__DATA_OVERLAY_TYPEf, 1);
   8740             } else if (soc_mem_field_valid(unit, egr_mem,
   8741                         VFI_DVP_GROUP__DATA_TYPEf)) {
   8742             soc_mem_field32_set(unit, egr_mem, vent,
   8743                         VFI_DVP_GROUP__DATA_TYPEf, 1);  
   8744             }
   8745         } else
   8746 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 
   8747         {
   8748 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
   8749             if ((BCM_GPORT_IS_MODPORT(port_class) ||
   8750                 BCM_GPORT_IS_SUBPORT_PORT(port_class)) &&
   8751                 soc_feature(unit, soc_feature_egr_vxlate_supports_dgpp)) {
   8752                 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port_class,
   8753                             &modid, &port_class, &tgid, &id));
   8754                 if (modid != -1 && port_class != -1) {
   8755                     soc_mem_field32_set(unit, egr_mem, vent, DST_MODIDf,
   8756                             modid);
   8757                     soc_mem_field32_set(unit, egr_mem, vent, DST_PORTf,
   8758                             port_class);
   8759                     if (SOC_MEM_FIELD_VALID(unit, egr_mem,
   8760                             PORT_TYPE_DGPPf)) {
   8761                         soc_mem_field32_set(unit, egr_mem, vent,
   8762                             PORT_TYPE_DGPPf, TRUE);
   8763                     }
   8764                 } else {
   8765                     return BCM_E_PORT;
   8766                 }
   8767             } else
   8768 #endif
   8769             {
   8770                 soc_mem_field32_set(unit, egr_mem, vent, PORT_GROUP_IDf,
   8771                         port_class);
   8772             }
   8773         }
   8774     }
   8775     return BCM_E_NONE;
   8776 }
   8777 
   8778 /*
   8779  * Function   :
   8780  *      bcm_vlan_translate_egress_action_add
   8781  * Description   :
   8782  *      Add an entry to egress VLAN translation table.
   8783  * Parameters   :
   8784  *      unit            (IN) BCM unit number
   8785  *      port_class      (IN) Group ID of ingress port
   8786  *      outer_vlan      (IN) Packet outer VLAN ID
   8787  *      inner_vlan      (IN) Packet inner VLAN ID
   8788  *      action          (IN) Action for outer and inner tag
   8789  */
   8790 int 
   8791 _bcm_trx_vlan_translate_egress_action_add(int unit, int port_class,
   8792                                          bcm_vlan_t outer_vlan,
   8793                                          bcm_vlan_t inner_vlan,
   8794                                          bcm_vlan_action_set_t *action)
   8795 {
   8796     int rv;
   8797     uint32 profile_idx;
   8798     uint32 old_profile_idx = 0;
   8799     egr_vlan_xlate_entry_t evx_ent;
   8800     egr_vlan_xlate_entry_t evx_ent_old;
   8801 
   8802     egr_vlan_xlate_1_double_entry_t evx1d_ent;
   8803     egr_vlan_xlate_1_double_entry_t evx1d_ent_old;
   8804 
   8805     void *vent = &evx_ent, *vent_old = &evx_ent_old;
   8806 
   8807     void *vent_ptr;
   8808 
   8809     int index;
   8810 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   8811     uint32 entry[SOC_MAX_MEM_WORDS];
   8812     soc_field_info_t *field_info = NULL, *field_info_1 = NULL;
   8813     void *vent_tmp_p = NULL;
   8814     egr_vlan_xlate_entry_t evx_ent_tmp;
   8815     egr_vlan_xlate_1_double_entry_t evx1d_ent_tmp;
   8816     void *vent_tmp = &evx_ent_tmp;
   8817     uint32 ent_sz = sizeof(egr_vlan_xlate_entry_t);
   8818 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */ 
   8819     
   8820     soc_mem_t mem = EGR_VLAN_XLATEm;
   8821     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) {
   8822         mem = EGR_VLAN_XLATE_1_DOUBLEm;
   8823         vent = &evx1d_ent;
   8824         vent_old = &evx1d_ent_old;
   8825 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   8826         vent_tmp = &evx1d_ent_tmp;
   8827         ent_sz = sizeof(egr_vlan_xlate_1_double_entry_t);
   8828 #endif
   8829     }
   8830 
   8831     BCM_IF_ERROR_RETURN(_bcm_trx_egr_vlan_action_verify(unit, action));
   8832 
   8833     vent_ptr = vent;
   8834     BCM_IF_ERROR_RETURN
   8835         (_bcm_trx_vlan_translate_egress_entry_assemble(unit, vent_ptr,
   8836                                                        port_class,
   8837                                                        outer_vlan,
   8838                                                        inner_vlan));
   8839 
   8840     soc_mem_lock(unit, mem);
   8841     /* check if the entry with same key already exists */
   8842     rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index,
   8843                         vent_ptr, vent_old, 0);
   8844 
   8845     if (rv == SOC_E_NONE) {
   8846         /* alredy exists, update on the existing one, so the flex
   8847          * counter related fields in TR3/Katana can be preserved.
   8848          */
   8849         vent_ptr = vent_old;
   8850         old_profile_idx = soc_mem_field32_get(unit, mem, vent_ptr,
   8851                                                TAG_ACTION_PROFILE_PTRf); 
   8852     } else if (rv != SOC_E_NOT_FOUND) {
   8853         soc_mem_unlock(unit, mem);
   8854         return rv;  /* error condition */
   8855     } else {
   8856         /* doesn't exist, update the new entry */
   8857         vent_ptr = vent;
   8858     }
   8859 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   8860     if (inner_vlan == BCM_VLAN_INVALID) {     
   8861         sal_memset(entry, 0, SOC_MAX_MEM_WORDS * sizeof(uint32));
   8862         if (BCM_GPORT_IS_SET(port_class) &&
   8863             !BCM_GPORT_IS_MODPORT(port_class)) {
   8864             field_info = soc_mem_fieldinfo_get(unit, mem, 
   8865                                           VLAN_XLATE_VFI__XLATE_DATAf);
   8866         } else {             
   8867             field_info = soc_mem_fieldinfo_get(unit, mem,
   8868                                           VFI_DVP_GROUP__XLATE_DATAf);
   8869         }             
   8870         if (!field_info) {
   8871                 return BCM_E_UNAVAIL;        
   8872         }
   8873         SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_GET(unit, mem, vent_ptr,
   8874                                          field_info, entry);
   8875         /* Reuse the format of field XLATE_DATA in XLATE view
   8876             * for VLAN_XLATE_VFI and VFI_DVP view. 
   8877             */                                 
   8878         vent_tmp_p = vent_ptr;
   8879         field_info_1 = soc_mem_fieldinfo_get(unit, mem,
   8880                                              XLATE_DATAf);         
   8881         if (!field_info_1) {
   8882             return BCM_E_UNAVAIL;        
   8883         }         
   8884         sal_memset(vent_tmp, 0, ent_sz);
   8885         vent_ptr = vent_tmp;
   8886         SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_SET(unit, mem, vent_ptr,
   8887                                          field_info_1, entry); 
   8888         if ( rv == SOC_E_NONE) {
   8889             old_profile_idx = soc_mem_field32_get(unit, mem, vent_ptr,
   8890                                               TAG_ACTION_PROFILE_PTRf);
   8891         }
   8892     }
   8893 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */
   8894     soc_mem_field32_set(unit, mem, vent_ptr, NEW_IVIDf,
   8895                                     action->new_inner_vlan);
   8896     soc_mem_field32_set(unit, mem, vent_ptr, NEW_OVIDf,
   8897                                     action->new_outer_vlan);
   8898 
   8899     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
   8900         bcm_vlan_action_set_t action1;
   8901         sal_memcpy(&action1, action, sizeof(bcm_vlan_action_set_t));
   8902         if (action->priority == -1) {
   8903             /* point to the default mapping table(0) for default priority action */
   8904             PKT_VLAN_OUTER_ACTION_SET(unit, mem, vent_ptr, action);
   8905             PKT_VLAN_INNER_ACTION_SET(unit, mem, vent_ptr, action);
   8906 
   8907 #define PKT_PRI_DFLT_ACTION(_action_tag) \
   8908    do { \
   8909       if (((_action_tag) == bcmVlanActionReplace) || \
   8910                 ((_action_tag) == bcmVlanActionAdd) ) { \
   8911                 _action_tag ## _pkt_prio = _action_tag; \
   8912       } \
   8913    } while(0)
   8914             PKT_PRI_DFLT_ACTION(action1.dt_outer);
   8915             PKT_PRI_DFLT_ACTION(action1.dt_inner);
   8916             PKT_PRI_DFLT_ACTION(action1.ot_outer);
   8917             PKT_PRI_DFLT_ACTION(action1.ot_inner);
   8918             PKT_PRI_DFLT_ACTION(action1.it_outer);
   8919             PKT_PRI_DFLT_ACTION(action1.it_inner);
   8920             PKT_PRI_DFLT_ACTION(action1.ut_outer);
   8921             PKT_PRI_DFLT_ACTION(action1.ut_inner);
   8922 #undef PKT_PRI_DFLT_ACTION
   8923         } else {
   8924             soc_mem_field32_set(unit, mem, vent_ptr, NEW_OPRIf,
   8925                                         action->priority);
   8926             soc_mem_field32_set(unit, mem, vent_ptr, NEW_OCFIf,
   8927                                         action->new_outer_cfi);
   8928             soc_mem_field32_set(unit, mem, vent_ptr, NEW_IPRIf,
   8929                                         action->new_inner_pkt_prio);
   8930             soc_mem_field32_set(unit, mem, vent_ptr, NEW_ICFIf,
   8931                                         action->new_inner_cfi);
   8932         }
   8933         BCM_IF_ERROR_RETURN
   8934             (_bcm_trx_egr_vlan_action_profile_entry_add(unit, &action1,
   8935                                                     &profile_idx));
   8936     } else {
   8937         if (action->priority >= BCM_PRIO_MIN &&
   8938             action->priority <= BCM_PRIO_MAX) {
   8939             soc_mem_field32_set(unit, mem, vent_ptr, RPEf, 1);
   8940             soc_mem_field32_set(unit, mem, vent_ptr, PRIf,
   8941                                             action->priority);
   8942             if (bcmVlanActionNone != action->it_inner_prio ||
   8943                 bcmVlanActionNone != action->dt_inner_prio) {                                           
   8944                 soc_mem_field32_set(unit, mem, vent_ptr, NEW_IRPEf, 1);
   8945                 soc_mem_field32_set(unit, mem, vent_ptr, NEW_IPRIf,
   8946                                             action->priority);
   8947             }
   8948         }
   8949         BCM_IF_ERROR_RETURN
   8950             (_bcm_trx_egr_vlan_action_profile_entry_add(unit, action,
   8951                                                     &profile_idx));
   8952     }
   8953     soc_mem_field32_set(unit, mem, vent_ptr, TAG_ACTION_PROFILE_PTRf,
   8954                                     profile_idx);
   8955     soc_mem_field32_set(unit, mem, vent_ptr, NEW_OTAG_VPTAG_SELf, 0);
   8956 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   8957     if (SOC_MEM_FIELD_VALID(unit, mem, CLASS_IDf) &&
   8958             (action->class_id)) {
   8959         soc_mem_field32_set(unit, mem, vent_ptr, CLASS_IDf, action->class_id);
   8960         soc_mem_field32_set(unit, mem, vent_ptr, CLASS_ID_VALIDf,1);
   8961     }
   8962 #endif
   8963     if (soc_feature(unit, soc_feature_base_valid)) {
   8964         soc_mem_field32_set(unit, mem, vent_ptr, BASE_VALID_0f, 3);
   8965         soc_mem_field32_set(unit, mem, vent_ptr, BASE_VALID_1f, 7);
   8966     } else {
   8967         soc_mem_field32_set(unit, mem, vent_ptr, VALIDf, 1);
   8968     }
   8969 
   8970 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   8971     if (inner_vlan == BCM_VLAN_INVALID) {         
   8972         SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_GET(unit, mem, vent_ptr,
   8973                                          field_info_1, entry);            
   8974         /* Restore the old pointer */
   8975         vent_ptr = vent_tmp_p;
   8976         /* Update the whole XLATE_DATAf for VLAN_XLATE_VFI and VFI_DVP view. */
   8977         SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_SET(unit, mem, vent_ptr,
   8978                                          field_info, entry);                                 
   8979         if (soc_feature(unit, soc_feature_base_valid)) {
   8980             soc_mem_field32_set(unit, mem, vent_ptr, BASE_VALID_0f, 3);
   8981             soc_mem_field32_set(unit, mem, vent_ptr, BASE_VALID_1f, 7);
   8982         } else {
   8983             soc_mem_field32_set(unit, mem, vent_ptr, VALIDf, 1);
   8984         }
   8985     }
   8986 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */
   8987 #if defined(BCM_TSN_SR_SUPPORT)
   8988     if (soc_feature(unit, soc_feature_tsn_sr)) {
   8989         if ((!(action->flags & BCM_VLAN_ACTION_SET_SR_ENABLE)) &&
   8990               (action->flags & BCM_VLAN_ACTION_SET_SR_LAN_ID)) {
   8991            return BCM_E_PARAM;
   8992         }
   8993 
   8994         if (action->flags & BCM_VLAN_ACTION_SET_SR_ENABLE) {
   8995             soc_mem_field32_set(unit, mem, vent_ptr, SR_ENABLEf, 1);
   8996             soc_mem_field32_set(unit, mem, vent_ptr, SR_LAN_ID_VALIDf, 1);
   8997             if (action->flags & BCM_VLAN_ACTION_SET_SR_LAN_ID) {
   8998                 soc_mem_field32_set(unit, mem, vent_ptr, SR_LAN_IDf, 1);
   8999             }
   9000         } else {
   9001             soc_mem_field32_set(unit, mem, vent_ptr, SR_ENABLEf, 0);
   9002             soc_mem_field32_set(unit, mem, vent_ptr, SR_LAN_ID_VALIDf, 0);
   9003         }
   9004     }
   9005 #endif /* BCM_TSN_SR_SUPPORT*/
   9006     if (rv == SOC_E_NONE) { 
   9007         /* write back the existing one */
   9008         rv = soc_mem_write(unit, mem,
   9009                              MEM_BLOCK_ALL, index, vent_ptr);
   9010         if (rv == SOC_E_NONE) {
   9011             /* Preserve ref_count for default profile in case deleting old profile */
   9012             if (old_profile_idx == EGR_ACTION_PROFILE_DEFAULT) {
   9013                 soc_profile_mem_reference(unit, egr_action_profile[unit],
   9014                                           EGR_ACTION_PROFILE_DEFAULT, 1);
   9015             }
   9016             rv = _bcm_trx_egr_vlan_action_profile_entry_delete(unit,
   9017                            old_profile_idx);
   9018         }
   9019     } else {
   9020         /* insert new one */
   9021         rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, vent_ptr);
   9022     }
   9023     soc_mem_unlock(unit, mem);
   9024 
   9025     return rv;
   9026 }
   9027 
   9028 /*
   9029  * Function:
   9030  *      _bcm_trx_vlan_translate_egress_action_get
   9031  * Purpose:
   9032  *      Get an egress vlan translate entry.
   9033  * Parameters:
   9034  *      unit            (IN) BCM unit number
   9035  *      port_class      (IN) Group ID of ingress port
   9036  *      old_vid         (IN) Packet old VLAN ID to match
   9037  *      new_vid         (OUT) Packet new VLAN ID
   9038  *      prio            (OUT) Translation priority
   9039  */
   9040 extern int 
   9041 _bcm_trx_vlan_translate_egress_action_get(int unit, int port_class,
   9042                                          bcm_vlan_t outer_vlan,
   9043                                          bcm_vlan_t inner_vlan,
   9044                                          bcm_vlan_action_set_t *action)
   9045 {
   9046     egr_vlan_xlate_entry_t  evx_ent;
   9047     egr_vlan_xlate_entry_t  res_evx_ent;
   9048 
   9049     egr_vlan_xlate_1_double_entry_t evx1d_ent;
   9050     egr_vlan_xlate_1_double_entry_t res_evx1d_ent;
   9051 
   9052     int                     rv;
   9053     int                     idx = 0, profile_idx; 
   9054 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   9055     uint32 entry[SOC_MAX_MEM_WORDS];
   9056     soc_field_info_t *field_info = NULL, *field_info_1 = NULL;
   9057 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */
   9058 
   9059     void *vent = &evx_ent;
   9060     void *res_vent = &res_evx_ent;
   9061     soc_mem_t mem = EGR_VLAN_XLATEm;
   9062     uint32 ent_sz = sizeof(egr_vlan_xlate_entry_t);
   9063     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) {
   9064         mem = EGR_VLAN_XLATE_1_DOUBLEm;
   9065         ent_sz = sizeof(egr_vlan_xlate_1_double_entry_t);
   9066         vent = &evx1d_ent;
   9067         res_vent = &res_evx1d_ent;
   9068     }
   9069 
   9070     BCM_IF_ERROR_RETURN
   9071         (_bcm_trx_vlan_translate_egress_entry_assemble(unit, vent,
   9072                                                        port_class,
   9073                                                        outer_vlan,
   9074                                                        inner_vlan));
   9075 
   9076     sal_memset(res_vent, 0, ent_sz);
   9077     soc_mem_lock(unit, mem);
   9078     rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, &idx,
   9079                         vent, res_vent, 0);
   9080     soc_mem_unlock(unit, mem);
   9081     BCM_IF_ERROR_RETURN(rv);
   9082 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   9083     if (inner_vlan == BCM_VLAN_INVALID) { 
   9084         sal_memset(entry, 0, SOC_MAX_MEM_WORDS * sizeof(uint32));        
   9085         if (BCM_GPORT_IS_SET(port_class) &&
   9086             !BCM_GPORT_IS_MODPORT(port_class)) {
   9087             field_info = soc_mem_fieldinfo_get(unit, mem, 
   9088                                           VLAN_XLATE_VFI__XLATE_DATAf);
   9089         } else {             
   9090             field_info = soc_mem_fieldinfo_get(unit, mem,
   9091                                           VFI_DVP_GROUP__XLATE_DATAf);
   9092         }        
   9093         if (!field_info) {
   9094             return BCM_E_UNAVAIL;        
   9095         }          
   9096         SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_GET(unit, mem, res_vent,
   9097                                          field_info, entry);
   9098         field_info_1 = soc_mem_fieldinfo_get(unit, mem,
   9099                                              XLATE_DATAf);         
   9100         if (!field_info_1) {
   9101             return BCM_E_UNAVAIL;        
   9102         }         
   9103         SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_SET(unit, mem, res_vent,
   9104                                          field_info_1, entry); 
   9105     }
   9106 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */
   9107     profile_idx = soc_mem_field32_get(unit, mem, res_vent,
   9108                                               TAG_ACTION_PROFILE_PTRf);       
   9109     _bcm_trx_egr_vlan_action_profile_entry_get(unit, action, profile_idx);
   9110    
   9111     BCM_IF_ERROR_RETURN(
   9112         _bcm_trx_vlan_translate_entry_parse(unit, mem,
   9113                                             (uint32 *)res_vent, action));
   9114     return BCM_E_NONE;
   9115 }
   9116 
   9117 /*
   9118  * Function:
   9119  *      bcm_vlan_translate_egress_action_delete
   9120  * Purpose:
   9121  *      Delete an egress vlan translate lookup entry.
   9122  * Parameters:
   9123  *      unit            (IN) BCM unit number
   9124  *      port_class      (IN) Group ID of ingress port
   9125  *      outer_vlan      (IN) Packet outer VLAN ID
   9126  *      inner_vlan      (IN) Packet inner VLAN ID
   9127  */
   9128 int 
   9129 _bcm_trx_vlan_translate_egress_action_delete(int unit, int port_class,
   9130                                             bcm_vlan_t outer_vlan,
   9131                                             bcm_vlan_t inner_vlan)
   9132 {
   9133     egr_vlan_xlate_entry_t evx_ent;
   9134     egr_vlan_xlate_1_double_entry_t evx1d_ent;
   9135     int rv; 
   9136     uint32 profile_idx;
   9137     void *vent = (void *)&evx_ent;
   9138     soc_mem_t mem = EGR_VLAN_XLATEm;
   9139     soc_field_t vld_fld = VALIDf;
   9140 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   9141     uint32 entry[SOC_MAX_MEM_WORDS];
   9142     soc_field_info_t *field_info = NULL, *field_info_1 = NULL;
   9143 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */
   9144 
   9145 #if defined(BCM_TRIUMPH2_SUPPORT)
   9146     _bcm_flex_stat_handle_t handle;
   9147     _BCM_FLEX_STAT_HANDLE_CLEAR(handle);
   9148 #endif
   9149 
   9150     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) {
   9151         mem = EGR_VLAN_XLATE_1_DOUBLEm;
   9152         vld_fld = BASE_VALID_0f;
   9153         vent = (void *)&evx1d_ent;
   9154     }
   9155 
   9156     BCM_IF_ERROR_RETURN
   9157         (_bcm_trx_vlan_translate_egress_entry_assemble(unit, vent,
   9158                                                        port_class,
   9159                                                        outer_vlan,
   9160                                                        inner_vlan));
   9161 
   9162 #if defined(BCM_TRIUMPH2_SUPPORT)
   9163     if (soc_feature(unit, soc_feature_gport_service_counters)) {
   9164         /* Record flex stat info before the returned entry
   9165          * includes non-key info. */
   9166 
   9167         memcpy(&handle, vent, sizeof(_bcm_flex_stat_handle_t));
   9168     }
   9169 #endif
   9170 
   9171     rv = soc_mem_delete_return_old(unit, mem, MEM_BLOCK_ALL, vent, vent);
   9172     if ((rv == SOC_E_NONE) && soc_mem_field32_get(unit, mem, vent, vld_fld)) {
   9173 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   9174         if (inner_vlan == BCM_VLAN_INVALID) {
   9175             sal_memset(entry, 0, SOC_MAX_MEM_WORDS * sizeof(uint32));
   9176             if (BCM_GPORT_IS_SET(port_class) &&
   9177                 !BCM_GPORT_IS_MODPORT(port_class)) {
   9178                 field_info = soc_mem_fieldinfo_get(unit, mem,
   9179                                               VLAN_XLATE_VFI__XLATE_DATAf);
   9180             } else {
   9181                 field_info = soc_mem_fieldinfo_get(unit, mem,
   9182                                               VFI_DVP_GROUP__XLATE_DATAf);
   9183             }
   9184             if (!field_info) {
   9185                 return BCM_E_UNAVAIL;
   9186             }
   9187             SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_GET(unit, mem, vent,
   9188                                                   field_info, entry);
   9189             field_info_1 = soc_mem_fieldinfo_get(unit, mem,
   9190                                                  XLATE_DATAf);
   9191             if (!field_info_1) {
   9192                 return BCM_E_UNAVAIL;
   9193             }
   9194             SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_SET(unit, mem, vent,
   9195                                                   field_info_1, entry);
   9196         }
   9197 #endif
   9198         profile_idx = soc_mem_field32_get(unit, mem, vent,
   9199                                                       TAG_ACTION_PROFILE_PTRf);       
   9200         /* Preserve ref_count for default profile in case deleting old profile */
   9201         if (profile_idx == EGR_ACTION_PROFILE_DEFAULT) {
   9202             soc_profile_mem_reference(unit, egr_action_profile[unit],
   9203                                       EGR_ACTION_PROFILE_DEFAULT, 1);
   9204         }
   9205         /* Delete the old vlan action profile entry */
   9206         rv = _bcm_trx_egr_vlan_action_profile_entry_delete(unit, profile_idx);
   9207 
   9208 #if defined(BCM_TRIUMPH2_SUPPORT)
   9209         if (soc_feature(unit, soc_feature_gport_service_counters) &&
   9210             (0 != soc_mem_field32_get(unit, mem, vent, VINTF_CTR_IDXf))) {
   9211             /* Release Service counter */
   9212             _bcm_esw_flex_stat_ext_handle_free(unit, _bcmFlexStatTypeVxlt,
   9213                                                handle);
   9214         }
   9215 #endif
   9216     }
   9217     return rv;
   9218 }
   9219 
   9220 /*
   9221  * Function:
   9222  *      bcm_vlan_translate_egress_action_delete_all
   9223  * Purpose:
   9224  *      Delete all egress vlan translate lookup entries.
   9225  * Parameters:
   9226  *      unit      (IN) BCM unit number
   9227  * Returns:
   9228  *      BCM_E_XXX
   9229  */
   9230 int
   9231 _bcm_trx_vlan_translate_egress_action_delete_all(int unit) 
   9232 {
   9233     int i, imin, imax, nent, vbytes, rv;
   9234     uint32 old_profile_idx;
   9235     void *vtab, *vtabp, *vnull;
   9236 #if defined(BCM_TRIUMPH2_SUPPORT)
   9237     _bcm_flex_stat_handle_t handle;
   9238     egr_vlan_xlate_entry_t vent;
   9239     uint32 key[2];
   9240 #endif
   9241 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   9242     uint32 entry[SOC_MAX_MEM_WORDS];
   9243     soc_field_info_t *field_info = NULL, *field_info_1 = NULL;
   9244     int type;
   9245     soc_field_t type_fld = ENTRY_TYPEf;
   9246 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */
   9247     int rv1 = BCM_E_NONE; /* To capture first failure in loop */
   9248     soc_mem_t mem = EGR_VLAN_XLATEm;
   9249     soc_field_t vld_fld = VALIDf;
   9250     uint32 ent_sz = sizeof(egr_vlan_xlate_entry_t);
   9251     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) {
   9252         mem = EGR_VLAN_XLATE_1_DOUBLEm;
   9253         vld_fld = BASE_VALID_0f;
   9254 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   9255         type_fld = KEY_TYPEf;
   9256 #endif
   9257         ent_sz = sizeof(egr_vlan_xlate_1_double_entry_t);
   9258     }
   9259     imin = soc_mem_index_min(unit, mem);
   9260     imax = soc_mem_index_max(unit, mem);
   9261     nent = soc_mem_index_count(unit, mem);
   9262     vbytes = soc_mem_entry_words(unit, mem);
   9263     
   9264     vbytes = WORDS2BYTES(vbytes);
   9265     vtab = soc_cm_salloc(unit, nent * ent_sz, "egr_vlan_xlate");
   9266 
   9267     if (vtab == NULL) {
   9268         return BCM_E_MEMORY;
   9269     }
   9270     
   9271     vnull = soc_mem_entry_null(unit, mem);
   9272 
   9273     soc_mem_lock(unit, mem);
   9274     rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY,
   9275                             imin, imax, vtab);
   9276     if (rv < 0) {
   9277         soc_mem_unlock(unit, mem);
   9278         soc_cm_sfree(unit, vtab);
   9279         return rv; 
   9280     }
   9281     
   9282     for(i = 0; i < nent; i++) {
   9283 
   9284         if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) {
   9285             vtabp = soc_mem_table_idx_to_pointer(unit, mem,
   9286                         egr_vlan_xlate_1_double_entry_t *, vtab, i);
   9287         } else {
   9288             vtabp = soc_mem_table_idx_to_pointer(unit, mem,
   9289                         egr_vlan_xlate_entry_t *, vtab, i);
   9290         }
   9291 
   9292         if (!soc_mem_field32_get(unit, mem, vtabp, vld_fld)) {
   9293             continue;
   9294         }
   9295 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   9296         type = soc_mem_field32_get(unit, mem, vtabp, type_fld);
   9297         if (type == TD2PLUS_EVLXLT_HASH_KEY_TYPE_VFI_DVP_GROUP) {
   9298             field_info = soc_mem_fieldinfo_get(unit, mem,
   9299                                               VFI_DVP_GROUP__XLATE_DATAf);
   9300         } else if (type == TD2PLUS_EVLXLT_HASH_KEY_TYPE_VLAN_XLATE_VFI) {
   9301             field_info = soc_mem_fieldinfo_get(unit, mem,
   9302                                               VLAN_XLATE_VFI__XLATE_DATAf);
   9303         }
   9304 
   9305         if (field_info) {
   9306             sal_memset(entry, 0, SOC_MAX_MEM_WORDS * sizeof(uint32));
   9307             SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_GET(unit, mem, vtabp,
   9308                                                   field_info, entry);
   9309             field_info_1 = soc_mem_fieldinfo_get(unit, mem,
   9310                                                  XLATE_DATAf);
   9311             if (!field_info_1) {
   9312                 return BCM_E_UNAVAIL;
   9313             }
   9314             SOC_MEM_EGR_VLAN_XLATE_FIELD_INFO_SET(unit, mem, vtabp,
   9315                                                   field_info_1, entry);
   9316         }
   9317 #endif
   9318         old_profile_idx =
   9319             soc_mem_field32_get(unit, mem, vtabp,
   9320                                             TAG_ACTION_PROFILE_PTRf);
   9321 
   9322         rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, i, vnull);
   9323 
   9324         /* Delete the old vlan action profile entry */
   9325         if (rv == SOC_E_NONE) {
   9326             /* Preserve ref_count for default profile in case deleting old profile*/
   9327             if (old_profile_idx == EGR_ACTION_PROFILE_DEFAULT) {
   9328                 soc_profile_mem_reference(unit, egr_action_profile[unit],
   9329                                           EGR_ACTION_PROFILE_DEFAULT, 1);
   9330             }
   9331             rv = _bcm_trx_egr_vlan_action_profile_entry_delete(unit, 
   9332                                                         old_profile_idx);
   9333             if (BCM_FAILURE(rv) && BCM_SUCCESS(rv1)) {
   9334                 rv1 = rv;
   9335             }
   9336 #if defined(BCM_TRIUMPH2_SUPPORT)
   9337         if (soc_feature(unit, soc_feature_gport_service_counters) &&
   9338             (0 != soc_mem_field32_get(unit, mem, vtabp, VINTF_CTR_IDXf))) {
   9339             sal_memset(&vent, 0, sizeof(vent));
   9340             /* Construct key-only entry, copy to FS handle */
   9341             soc_mem_field32_set(unit, mem, &vent, ENTRY_TYPEf,
   9342                 soc_mem_field32_get(unit, mem, vtabp, ENTRY_TYPEf));
   9343             soc_mem_field_get(unit, mem, (uint32 *) vtabp,
   9344                                KEYf, (uint32 *) key);
   9345             soc_mem_field_set(unit, mem, (uint32 *) &vent,
   9346                                KEYf, (uint32 *) key);
   9347 
   9348             _BCM_FLEX_STAT_HANDLE_CLEAR(handle);
   9349             _BCM_FLEX_STAT_HANDLE_COPY(handle, vent);
   9350 
   9351             /* Release Service counter */
   9352             _bcm_esw_flex_stat_ext_handle_free(unit, _bcmFlexStatTypeVxlt,
   9353                                                handle);
   9354         }
   9355 #endif
   9356         } else if (BCM_SUCCESS(rv1)) {
   9357             rv1 = rv;
   9358         }
   9359     }
   9360     
   9361     soc_mem_unlock(unit, mem);
   9362     soc_cm_sfree(unit, vtab);
   9363     return rv1;
   9364 }
   9365 
   9366 /*
   9367  * Function   :
   9368  *      _bcm_trx_vlan_translate_old_vlan_get
   9369  * Description   :
   9370  *      Helper function to get an old vid from vlan translate entry 
   9371  * Parameters   :
   9372  *      unit            (IN) BCM unit number
   9373  *      mem             (IN) Vlan translate memory id.
   9374  *      vent            (IN) Vlan translate entry
   9375  *      key_type        (IN) Key type to determine which old vid to get
   9376  *      outer_vlan      (OUT) outer vlan to retrieve
   9377  *      inner_vlan      (OUT) inner vlan to retrieve
   9378  */
   9379 
   9380 STATIC int 
   9381 _bcm_trx_vlan_translate_old_vlan_get(int unit, soc_mem_t mem, 
   9382                                      uint32 *vent, uint32 key_type,
   9383                                      bcm_vlan_t *outer_vlan, 
   9384                                      bcm_vlan_t *inner_vlan)
   9385 {
   9386     bcm_vlan_t  tmp_o_vlan = BCM_VLAN_INVALID;
   9387     bcm_vlan_t  tmp_i_vlan = BCM_VLAN_INVALID;
   9388 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   9389     soc_field_t type_field = ENTRY_TYPEf;
   9390     soc_mem_t egr_mem = EGR_VLAN_XLATEm;
   9391     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) {
   9392         egr_mem = EGR_VLAN_XLATE_1_DOUBLEm;
   9393         type_field = KEY_TYPEf;
   9394     }
   9395 #endif
   9396 
   9397     /* Input parameters check. */ 
   9398     if ((NULL  == vent) || (NULL == outer_vlan) || 
   9399         (INVALIDm == mem) || (NULL == inner_vlan)) {
   9400         return (BCM_E_PARAM);
   9401     }
   9402 
   9403     switch (key_type) {
   9404       case bcmVlanTranslateKeyDouble:
   9405       case bcmVlanTranslateKeyPortDouble:
   9406       case bcmVlanTranslateKeyPortGroupDouble:
   9407       case bcmVlanTranslateKeyCapwapPayloadDouble:
   9408       case bcmVlanTranslateKeyPortCapwapPayloadDouble:
   9409 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   9410           if ((mem == egr_mem) && soc_feature(unit, soc_feature_vp_sharing) &&
   9411              (soc_mem_field32_get_def(unit, mem, vent, type_field, FALSE) ==
   9412                              TD2PLUS_EVLXLT_HASH_KEY_TYPE_VLAN_XLATE_VFI)) {
   9413               _BCM_VPN_SET(tmp_o_vlan, _BCM_VPN_TYPE_VFI,
   9414                            soc_mem_field32_get(unit, mem, vent, VLAN_XLATE_VFI__VFIf));
   9415               tmp_i_vlan = BCM_VLAN_INVALID;
   9416           } else
   9417 #endif
   9418           {
   9419               tmp_o_vlan = soc_mem_field32_get(unit, mem, vent, OVIDf);
   9420               tmp_i_vlan = soc_mem_field32_get(unit, mem, vent, IVIDf);
   9421           }
   9422           break;
   9423       case bcmVlanTranslateKeyOuterTag:
   9424       case bcmVlanTranslateKeyPortOuterTag:
   9425       case bcmVlanTranslateKeyPortGroupOuterTag:
   9426       case bcmVlanTranslateKeyCapwapPayloadOuterTag:
   9427       case bcmVlanTranslateKeyPortCapwapPayloadOuterTag:
   9428           tmp_o_vlan = soc_mem_field32_get(unit, mem, vent, OTAGf);
   9429           break;
   9430       case bcmVlanTranslateKeyInnerTag:
   9431       case bcmVlanTranslateKeyPortInnerTag:
   9432       case bcmVlanTranslateKeyPortGroupInnerTag:
   9433       case bcmVlanTranslateKeyCapwapPayloadInnerTag:
   9434       case bcmVlanTranslateKeyPortCapwapPayloadInnerTag:
   9435           tmp_i_vlan = soc_mem_field32_get(unit, mem, vent, ITAGf);
   9436           break;
   9437       case bcmVlanTranslateKeyOuter:
   9438       case bcmVlanTranslateKeyPortOuter:
   9439       case bcmVlanTranslateKeyPortGroupOuter:
   9440       case bcmVlanTranslateKeyCapwapPayloadOuter:
   9441       case bcmVlanTranslateKeyPortCapwapPayloadOuter:
   9442           tmp_o_vlan = soc_mem_field32_get(unit, mem, vent, OVIDf);
   9443           break;
   9444       case bcmVlanTranslateKeyInner:
   9445       case bcmVlanTranslateKeyPortInner:
   9446       case bcmVlanTranslateKeyPortGroupInner:
   9447       case bcmVlanTranslateKeyCapwapPayloadInner:
   9448       case bcmVlanTranslateKeyPortCapwapPayloadInner:
   9449           tmp_i_vlan = soc_mem_field32_get(unit, mem, vent, IVIDf);
   9450           break;    
   9451       case bcmVlanTranslateKeyPortPonTunnel:
   9452       case bcmVlanTranslateKeyPortPonTunnelOuter:
   9453       case bcmVlanTranslateKeyPortPonTunnelInner:
   9454           if (!soc_feature(unit, soc_feature_lltag)) {
   9455               return BCM_E_PARAM;
   9456           }
   9457           tmp_o_vlan = soc_mem_field32_get(unit, mem, vent, LLTAG__LLVIDf);
   9458           if (key_type == bcmVlanTranslateKeyPortPonTunnelOuter) {
   9459               tmp_i_vlan = soc_mem_field32_get(unit, mem, vent, LLTAG__OVIDf);
   9460           } else if (key_type == bcmVlanTranslateKeyPortPonTunnelInner) {
   9461               tmp_i_vlan = soc_mem_field32_get(unit, mem, vent, LLTAG__IVIDf);
   9462           }     
   9463           break;
   9464       default:
   9465           return BCM_E_PARAM;
   9466     }
   9467 
   9468     *outer_vlan = tmp_o_vlan;
   9469     *inner_vlan = tmp_i_vlan;
   9470 
   9471     return BCM_E_NONE;
   9472 }
   9473 
   9474 /*
   9475  * Function   :
   9476  *      _bcm_trx_vlan_translate_gport_get
   9477  * Description   :
   9478  *      Helper function to get a gport from vlan translate entry 
   9479  * Parameters   :
   9480  *      unit            (IN) BCM unit number
   9481  *      mem             (IN) Vlan translate memory id.
   9482  *      vent            (IN) Vlan translate entry
   9483  *      gport           (OUT) gport to retrieve
   9484  */
   9485 
   9486 STATIC int
   9487 _bcm_trx_vlan_translate_gport_get(int unit, soc_mem_t mem,
   9488                                   uint32 *vent, bcm_gport_t *gport)
   9489 {
   9490     bcm_gport_t     tmp_gport = 0;
   9491     uint32          modid;
   9492     uint32          port;
   9493     int             glp_wildcard;
   9494 
   9495 
   9496     /* Input parameters check. */
   9497     if ((NULL == vent) || (NULL == gport) || (INVALIDm == mem)) {
   9498         return (BCM_E_PARAM);
   9499     }
   9500 
   9501     glp_wildcard = (soc_mem_field32_get(unit, mem, vent, GLPf) == 
   9502                     SOC_VLAN_XLATE_GLP_WILDCARD(unit));
   9503     if (glp_wildcard) {
   9504         tmp_gport = BCM_GPORT_INVALID;
   9505     } else {
   9506         if (soc_mem_field32_get(unit, mem, vent, Tf)) {
   9507             port = soc_mem_field32_get(unit, mem, vent, TGIDf); 
   9508             BCM_GPORT_TRUNK_SET(tmp_gport, port); 
   9509         } else {
   9510             port = soc_mem_field32_get(unit, mem, vent, PORT_NUMf); 
   9511             modid = soc_mem_field32_get(unit, mem, vent, MODULE_IDf); 
   9512             BCM_GPORT_MODPORT_SET(tmp_gport, modid, port); 
   9513         }
   9514     }
   9515 
   9516     *gport = tmp_gport;
   9517     return BCM_E_NONE;
   9518 }
   9519 
   9520 /*
   9521  * Function   :
   9522  *      _bcm_trx_vlan_translate_key_type_get
   9523  * Description   :
   9524  *      Helper function to get a key_type from vlan translate entry 
   9525  * Parameters   :
   9526  *      unit            (IN) BCM unit number
   9527  *      mem             (IN) Vlan translate memory id.
   9528  *      vent            (IN) Vlan translate entry
   9529  *      key_type        (OUT) Key type to retrieve
   9530  */
   9531 
   9532 STATIC int 
   9533 _bcm_trx_vlan_translate_key_type_get(int unit, soc_mem_t mem, 
   9534                                      uint32 *vent, uint32 *key_type)
   9535 {
   9536     uint32 key_val, glp_wildcard;
   9537     int vt_key;
   9538     uint32 source_type = 0;
   9539 
   9540     /* Input parameters check. */
   9541     if ((NULL == vent) || (NULL == key_type) || (INVALIDm == mem)) {
   9542         return (BCM_E_PARAM);
   9543     }
   9544 
   9545 #ifdef BCM_TRIUMPH3_SUPPORT
   9546     if (SOC_IS_TRIUMPH3(unit)) {
   9547         if (mem ==  VLAN_XLATE_EXTDm) {
   9548             key_val = soc_mem_field32_get(unit, mem, vent, KEY_TYPE_0f);
   9549             key_val &= ~1; /*remove extd entry indication */ 
   9550         } else {
   9551             key_val = soc_mem_field32_get(unit, mem, vent, KEY_TYPEf); 
   9552         }
   9553     } else
   9554 #endif /* BCM_TRIUMPH3_SUPPORT */
   9555     {
   9556         key_val = soc_mem_field32_get(unit, mem, vent, KEY_TYPEf);
   9557     } 
   9558     glp_wildcard = (soc_mem_field32_get(unit, mem, vent, GLPf) == 
   9559                     SOC_VLAN_XLATE_GLP_WILDCARD(unit));
   9560     if ((mem == VLAN_XLATEm) && SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) {
   9561         source_type = soc_mem_field32_get(unit, mem, vent, SOURCE_TYPEf);
   9562     }
   9563     BCM_IF_ERROR_RETURN
   9564         (_bcm_esw_vlan_xlate_key_type_get(unit,key_val,&vt_key));
   9565     switch (vt_key) {
   9566       case VLXLT_HASH_KEY_TYPE_IVID_OVID:
   9567           {
   9568               if (source_type == 3) {
   9569                   *key_type = bcmVlanTranslateKeyPortGroupDouble;
   9570               } else if (glp_wildcard) {
   9571                   *key_type = bcmVlanTranslateKeyDouble;
   9572               } else {
   9573                   *key_type = bcmVlanTranslateKeyPortDouble;
   9574               }
   9575               break;
   9576           }
   9577       case VLXLT_HASH_KEY_TYPE_OTAG:
   9578           {
   9579               if (source_type == 3) {
   9580                   *key_type = bcmVlanTranslateKeyPortGroupOuterTag;
   9581               } else if (glp_wildcard) {
   9582                   *key_type = bcmVlanTranslateKeyOuterTag;
   9583               } else {
   9584                   *key_type = bcmVlanTranslateKeyPortOuterTag;
   9585               }
   9586               break;
   9587           }
   9588       case VLXLT_HASH_KEY_TYPE_ITAG:
   9589           {
   9590               if (source_type == 3) {
   9591                   *key_type = bcmVlanTranslateKeyPortGroupInnerTag;
   9592               } else if (glp_wildcard) {
   9593                   *key_type = bcmVlanTranslateKeyInnerTag;
   9594               } else {
   9595                   *key_type = bcmVlanTranslateKeyPortInnerTag;
   9596               }
   9597               break;
   9598           }
   9599       case VLXLT_HASH_KEY_TYPE_OVID:
   9600           {
   9601               if (source_type == 3) {
   9602                   *key_type = bcmVlanTranslateKeyPortGroupOuter;
   9603               } else if (glp_wildcard) {
   9604                   *key_type = bcmVlanTranslateKeyOuter;
   9605               } else {
   9606                   *key_type = bcmVlanTranslateKeyPortOuter;
   9607               }
   9608               break;
   9609           }
   9610       case VLXLT_HASH_KEY_TYPE_IVID: 
   9611           {
   9612               if (source_type == 3) {
   9613                   *key_type = bcmVlanTranslateKeyPortGroupInner;
   9614               } else if (glp_wildcard) {
   9615                   *key_type = bcmVlanTranslateKeyInner;
   9616               } else {
   9617                   *key_type = bcmVlanTranslateKeyPortInner;
   9618               }
   9619               break;
   9620           }
   9621       case VLXLT_HASH_KEY_TYPE_LLVID:
   9622           {
   9623               if (glp_wildcard) {
   9624                   return BCM_E_NOT_FOUND;
   9625               } else {
   9626               *key_type = bcmVlanTranslateKeyPortPonTunnel;
   9627               }
   9628               break;
   9629           }
   9630       case VLXLT_HASH_KEY_TYPE_LLVID_OVID:
   9631           {
   9632               if (glp_wildcard) {
   9633                   return BCM_E_NOT_FOUND;
   9634               } else {
   9635                   *key_type = bcmVlanTranslateKeyPortPonTunnelOuter;
   9636               }
   9637               break;
   9638           }
   9639       case VLXLT_HASK_KEY_TYPE_LLVID_IVID:
   9640           {
   9641               if (glp_wildcard) {
   9642                   return BCM_E_NOT_FOUND;
   9643               } else {
   9644                   *key_type = bcmVlanTranslateKeyPortPonTunnelInner;
   9645               }
   9646               break;
   9647           }
   9648           break;
   9649       case VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID:
   9650           {
   9651               if (glp_wildcard) {
   9652                   *key_type = bcmVlanTranslateKeyCapwapPayloadDouble;
   9653               } else {
   9654                   *key_type = bcmVlanTranslateKeyPortCapwapPayloadDouble;
   9655               }
   9656               break;
   9657           }
   9658           break;
   9659       case VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG:
   9660           {
   9661               if (glp_wildcard) {
   9662                   *key_type = bcmVlanTranslateKeyCapwapPayloadOuterTag;
   9663               } else {
   9664                   *key_type = bcmVlanTranslateKeyPortCapwapPayloadOuterTag;
   9665               }
   9666               break;
   9667           }
   9668           break;
   9669       case VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG:
   9670           {
   9671               if (glp_wildcard) {
   9672                   *key_type = bcmVlanTranslateKeyCapwapPayloadInnerTag;
   9673               } else {
   9674                   *key_type = bcmVlanTranslateKeyPortCapwapPayloadInnerTag;
   9675               }
   9676               break;
   9677           }
   9678           break;
   9679       case VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID:
   9680           {
   9681               if (glp_wildcard) {
   9682                   *key_type = bcmVlanTranslateKeyCapwapPayloadOuter;
   9683               } else {
   9684                   *key_type = bcmVlanTranslateKeyPortCapwapPayloadOuter;
   9685               }
   9686               break;
   9687           }
   9688           break;
   9689       case VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID:
   9690           {
   9691               if (glp_wildcard) {
   9692                   *key_type = bcmVlanTranslateKeyCapwapPayloadInner;
   9693               } else {
   9694                   *key_type = bcmVlanTranslateKeyPortCapwapPayloadInner;
   9695               }
   9696               break;
   9697           }
   9698           break;
   9699       default:
   9700           return BCM_E_NOT_FOUND;
   9701           break;
   9702     }
   9703 
   9704     return BCM_E_NONE;
   9705 }
   9706 
   9707 /*
   9708  * Function   :
   9709  *      _bcm_trx_vlan_translate_parse
   9710  * Description   :
   9711  *      Helper function for an API to parse a vlan translate 
   9712  *      entry for Triumph and call given call back.
   9713  * Parameters   :
   9714  *      unit            (IN) BCM unit number
   9715  *      mem             (IN) Vlan translation memory id.
   9716  *      vent            (IN) HW entry.
   9717  *      trvs_info       (IN/OUT) Traverse structure that contain all relevant info
   9718  */
   9719 int 
   9720 _bcm_trx_vlan_translate_parse(int unit, soc_mem_t mem, uint32 *vent,
   9721                              _bcm_vlan_translate_traverse_t *trvs_info)
   9722 {
   9723     uint32          profile_idx = 0;     /* Vlan profile index.      */
   9724     soc_mem_t egr_mem = EGR_VLAN_XLATEm;
   9725 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   9726     soc_field_t type_field = ENTRY_TYPEf;
   9727 #endif
   9728 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
   9729     soc_mem_t ing_mem = VLAN_XLATEm;
   9730     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
   9731         ing_mem = VLAN_XLATE_1_DOUBLEm;
   9732     }
   9733 
   9734     if (soc_feature(unit, soc_feature_niv) && (mem == ing_mem)) {
   9735         uint32 key_val;
   9736         int vt_key;
   9737         int vif_hit = TRUE;
   9738         int niv_port_id;
   9739         int vp;
   9740 
   9741         key_val = soc_mem_field32_get(unit, mem, vent, KEY_TYPEf);
   9742         BCM_IF_ERROR_RETURN(_bcm_esw_vlan_xlate_key_type_get(unit,
   9743               key_val,&vt_key));
   9744         switch (vt_key) {
   9745             case VLXLT_HASH_KEY_TYPE_VIF_OTAG:
   9746                 trvs_info->key_type = bcmVlanTranslateKeyPortOuterTag;
   9747                 trvs_info->outer_vlan = soc_mem_field32_get(unit, mem, 
   9748                            vent, VIF__OTAGf);
   9749                 break;
   9750 
   9751             case VLXLT_HASH_KEY_TYPE_VIF_ITAG:
   9752                 trvs_info->key_type = bcmVlanTranslateKeyPortInnerTag;
   9753                 trvs_info->inner_vlan = soc_mem_field32_get(unit, mem, 
   9754                            vent, VIF__ITAGf);
   9755                 break;
   9756 
   9757             case VLXLT_HASH_KEY_TYPE_VIF_VLAN:
   9758                 trvs_info->key_type = bcmVlanTranslateKeyPortOuter;
   9759                 trvs_info->outer_vlan = soc_mem_field32_get(unit, mem, 
   9760                            vent, VIF__VLANf);
   9761                 break;
   9762 
   9763             case VLXLT_HASH_KEY_TYPE_VIF_CVLAN:
   9764                 trvs_info->key_type = bcmVlanTranslateKeyPortInner;
   9765                 trvs_info->inner_vlan = soc_mem_field32_get(unit, mem, 
   9766                            vent, VIF__CVLANf);
   9767                 break;
   9768             default:
   9769                 vif_hit = FALSE;
   9770                 break;
   9771         }
   9772         if (vif_hit == TRUE) {
   9773             vp = soc_mem_field32_get(unit, mem, vent, VIF__SOURCE_VPf);
   9774             BCM_GPORT_NIV_PORT_ID_SET(niv_port_id, vp);
   9775             profile_idx = soc_mem_field32_get(unit, mem, vent,
   9776                                       VIF__TAG_ACTION_PROFILE_PTRf); 
   9777             _bcm_trx_vlan_action_profile_entry_get(unit, trvs_info->action,
   9778                                                profile_idx);
   9779             trvs_info->gport = niv_port_id;
   9780             BCM_IF_ERROR_RETURN(_bcm_trx_vif_vlan_translate_entry_parse(unit, 
   9781                      mem, vent, trvs_info->action));
   9782             return BCM_E_NONE;
   9783         }
   9784     }
   9785 #endif   /* defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) */
   9786  
   9787     profile_idx = soc_mem_field32_get(unit, mem, vent,
   9788                                       TAG_ACTION_PROFILE_PTRf); 
   9789 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   9790     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_XLATE_1_DOUBLEm)) {
   9791         egr_mem = EGR_VLAN_XLATE_1_DOUBLEm;
   9792         type_field = KEY_TYPEf;
   9793     }
   9794 #endif
   9795     if (mem == egr_mem) {
   9796         _bcm_trx_egr_vlan_action_profile_entry_get(unit, 
   9797                                                    trvs_info->action, 
   9798                                                    profile_idx);
   9799 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   9800         if (soc_feature(unit, soc_feature_vp_sharing) &&
   9801            (soc_mem_field32_get_def(unit, mem, vent, type_field, FALSE) ==
   9802                              TD2PLUS_EVLXLT_HASH_KEY_TYPE_VLAN_XLATE_VFI)) {
   9803             int dvp = 0;
   9804             dvp = soc_mem_field32_get(unit, mem, vent, VLAN_XLATE_VFI__DVPf);
   9805             if (_bcm_vp_used_get(unit, dvp, _bcmVpTypeVxlan)) {
   9806                 BCM_GPORT_VXLAN_PORT_ID_SET(trvs_info->port_class, dvp);
   9807             }
   9808         } else
   9809 #endif
   9810         {
   9811 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   9812             if (soc_feature(unit, soc_feature_egr_vxlate_supports_dgpp)) {
   9813                 if (soc_mem_field32_get(unit, mem, vent, PORT_TYPE_DGPPf)) {
   9814                     bcm_module_t modid =
   9815                         soc_mem_field32_get(unit, mem, vent, DST_MODIDf);
   9816                     bcm_port_t port =
   9817                         soc_mem_field32_get(unit, mem, vent, DST_PORTf);
   9818 
   9819                     BCM_GPORT_MODPORT_SET(trvs_info->port_class, modid, port);
   9820                 } else {
   9821                     trvs_info->port_class =
   9822                         soc_mem_field32_get(unit, mem, vent, PORT_GROUP_IDf);
   9823                 }
   9824             } else
   9825 #endif
   9826             {
   9827                 trvs_info->port_class = 
   9828                     soc_mem_field32_get(unit, mem, vent, PORT_GROUP_IDf);
   9829             }
   9830         }
   9831         trvs_info->gport = BCM_GPORT_INVALID;
   9832 
   9833         trvs_info->key_type = bcmVlanTranslateKeyPortDouble;
   9834     } else {
   9835         _bcm_trx_vlan_action_profile_entry_get(unit, trvs_info->action, 
   9836                                                profile_idx);
   9837 
   9838         BCM_IF_ERROR_RETURN(
   9839              _bcm_trx_vlan_translate_key_type_get(unit, mem, vent,
   9840                                                   &(trvs_info->key_type)));
   9841         BCM_IF_ERROR_RETURN(
   9842             _bcm_trx_vlan_translate_gport_get(unit, mem, vent, 
   9843                                               &(trvs_info->gport)));
   9844         trvs_info->port_class = BCM_GPORT_INVALID;
   9845     }
   9846 
   9847     BCM_IF_ERROR_RETURN(
   9848         _bcm_trx_vlan_translate_entry_parse(unit, mem, vent,
   9849                                             trvs_info->action));
   9850 
   9851     return _bcm_trx_vlan_translate_old_vlan_get(unit, mem, vent, 
   9852                                               trvs_info->key_type,
   9853                                               &(trvs_info->outer_vlan), 
   9854                                               &(trvs_info->inner_vlan));
   9855 }
   9856 
   9857 /*
   9858 *       VLAN PORT PROTOCOL 
   9859 */
   9860 
   9861 /*
   9862  * Function:
   9863  *      _bcm_trx_vlan_port_protocol_entry_parse
   9864  * Purpose:
   9865  *      Parses VLAN protocol entry and extracts frame type and ethertype
   9866  * Parameters:
   9867  *      unit        -     (IN) BCM Device unit
   9868  *      vpe         -     (IN) VLAN protocol entry to parse
   9869  *      frame       -     (OUT) Frame type from the entry
   9870  *      ether       -     (IN) Ethertype from the entry
   9871  * Returns:
   9872  *      None
   9873  */
   9874 STATIC void
   9875 _bcm_trx_vlan_port_protocol_entry_parse(int unit, vlan_protocol_entry_t *vpe,
   9876                                         bcm_port_frametype_t *frame,
   9877                                         bcm_port_ethertype_t *ether)
   9878 {
   9879     *frame = 0;
   9880     if (soc_VLAN_PROTOCOLm_field32_get(unit, vpe, ETHERIIf)) {
   9881         *frame |= BCM_PORT_FRAMETYPE_ETHER2;
   9882     }
   9883     if (soc_VLAN_PROTOCOLm_field32_get(unit, vpe, SNAPf)) {
   9884         *frame |= BCM_PORT_FRAMETYPE_8023;
   9885     }
   9886     if (soc_VLAN_PROTOCOLm_field32_get(unit, vpe, LLCf)) {
   9887         *frame |= BCM_PORT_FRAMETYPE_LLC;
   9888     }
   9889     *ether = soc_VLAN_PROTOCOLm_field32_get(unit, vpe, ETHERTYPEf);
   9890 }
   9891 
   9892 /*
   9893  * Function:
   9894  *      _bcm_trx_vlan_port_prot_match_get
   9895  * Purpose:
   9896  *      Get index into table with settings matching to port protocol
   9897  * Parameters:
   9898  *      unit        -     (IN) BCM Device unit
   9899  *      frame       -     (IN) Frmae to match
   9900  *      ether       -     (IN) Ethertype to match
   9901  *      match_idx   -     (OUT) index to the table entry if match, -1 otherwise
   9902  * Returns:
   9903  *      BCM_E_XXX
   9904  */
   9905 int 
   9906 _bcm_trx_vlan_port_prot_match_get(int unit, bcm_port_frametype_t frame, 
   9907                                   bcm_port_ethertype_t ether, int *match_idx)
   9908 {
   9909     int                         i, idxmin, idxmax;
   9910     vlan_protocol_entry_t       vpe;
   9911     bcm_port_frametype_t        ft;
   9912     bcm_port_ethertype_t        et;
   9913 
   9914     idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm);
   9915     idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm);
   9916     
   9917     *match_idx = -1;
   9918 
   9919     for (i = idxmin; i <= idxmax; i++) {
   9920         SOC_IF_ERROR_RETURN
   9921             (READ_VLAN_PROTOCOLm(unit, MEM_BLOCK_ANY, i, &vpe));
   9922         _bcm_trx_vlan_port_protocol_entry_parse(unit, &vpe, &ft, &et);
   9923         if (ft == frame && et == ether) {
   9924             *match_idx = i;
   9925             break;
   9926         }
   9927     }
   9928 
   9929     return (*match_idx < 0) ?  BCM_E_NOT_FOUND : BCM_E_NONE ;
   9930 }
   9931 
   9932 /*
   9933  * Function:
   9934  *      _bcm_trx_vlan_port_prot_match_get
   9935  * Purpose:
   9936  *      Get index into first empty entry in the table 
   9937  * Parameters:
   9938  *      unit        -     (IN) BCM Device unit
   9939  *      empty_idx   -     (OUT) index to the table entry if match, -1 otherwise
   9940  * Returns:
   9941  *      BCM_E_XXX
   9942  */
   9943 int 
   9944 _bcm_trx_vlan_port_prot_empty_get(int unit, int *empty_idx)
   9945 {
   9946     int                         i, idxmin, idxmax;
   9947     vlan_protocol_entry_t       vpe;
   9948     bcm_port_frametype_t        ft;
   9949     
   9950     idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm);
   9951     idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm);
   9952     
   9953     *empty_idx = -1;
   9954 
   9955     for (i = idxmin; i <= idxmax; i++) {
   9956         SOC_IF_ERROR_RETURN
   9957             (READ_VLAN_PROTOCOLm(unit, MEM_BLOCK_ANY, i, &vpe));
   9958         ft = 0;
   9959         if (soc_VLAN_PROTOCOLm_field32_get(unit, &vpe, ETHERIIf)) {
   9960             ft |= BCM_PORT_FRAMETYPE_ETHER2;
   9961         }
   9962         if (soc_VLAN_PROTOCOLm_field32_get(unit, &vpe, SNAPf)) {
   9963             ft |= BCM_PORT_FRAMETYPE_8023;
   9964         }
   9965         if (soc_VLAN_PROTOCOLm_field32_get(unit, &vpe, LLCf)) {
   9966             ft |= BCM_PORT_FRAMETYPE_LLC;
   9967         }
   9968         if (0 == ft) {
   9969             *empty_idx = i;
   9970             break;
   9971         }
   9972     }
   9973 
   9974     return (*empty_idx < 0) ?  BCM_E_FULL : BCM_E_NONE ;
   9975 }
   9976 
   9977 /*
   9978  * Function   :
   9979  *      _bcm_trx_vlan_protocol_data_entry_set
   9980  * Description   :
   9981  *      Helper function to set vlan_protocol_data entry
   9982  * Parameters   :
   9983  *      unit            (IN) BCM unit number
   9984  *      ventry          (IN / OUT) Entry to setup
   9985  *      action          (IN) vlan action to be used
   9986  *      profile_idx     (IN) profile index to set
   9987  */
   9988 STATIC void 
   9989 _bcm_trx_vlan_protocol_data_entry_set(int unit, 
   9990                                       vlan_protocol_data_entry_t *ventry, 
   9991                                       bcm_vlan_action_set_t *action,
   9992                                       int profile_idx)
   9993 {
   9994     soc_VLAN_PROTOCOL_DATAm_field32_set(unit, ventry, OVIDf, 
   9995                                         action->new_outer_vlan);
   9996     soc_VLAN_PROTOCOL_DATAm_field32_set(unit, ventry, IVIDf, 
   9997                                         action->new_inner_vlan);
   9998 
   9999     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
  10000         soc_VLAN_PROTOCOL_DATAm_field32_set(unit, ventry, OPRIf,
  10001                                             action->priority);
  10002         soc_VLAN_PROTOCOL_DATAm_field32_set(unit, ventry, OCFIf,
  10003                                             action->new_outer_cfi);
  10004         soc_VLAN_PROTOCOL_DATAm_field32_set(unit, ventry, IPRIf,
  10005                                             action->new_inner_pkt_prio);
  10006         soc_VLAN_PROTOCOL_DATAm_field32_set(unit, ventry, ICFIf,
  10007                                             action->new_inner_cfi);
  10008     } else {
  10009         soc_VLAN_PROTOCOL_DATAm_field32_set(unit, ventry, PRIf,
  10010                                             action->priority);
  10011     }
  10012     soc_VLAN_PROTOCOL_DATAm_field32_set(unit, ventry, TAG_ACTION_PROFILE_PTRf,
  10013                                         profile_idx);
  10014 }
  10015 
  10016 /*
  10017  * Function   :
  10018  *      _bcm_trx_vlan_protocol_data_entry_parse
  10019  * Description   :
  10020  *      Helper function to parse vlan_protocol_data entry into action
  10021  * Parameters   :
  10022  *      unit            (IN) BCM unit number
  10023  *      ventry          (IN) Entry to setup
  10024  *      action          (OUT) vlan action to be used
  10025  *      profile_idx     (OUT) profile index 
  10026  */
  10027 STATIC void 
  10028 _bcm_trx_vlan_protocol_data_entry_parse(int unit, 
  10029                                         vlan_protocol_data_entry_t *ventry, 
  10030                                         bcm_vlan_action_set_t *action,
  10031                                         int *profile_idx)
  10032 {
  10033     action->new_outer_vlan = 
  10034         soc_VLAN_PROTOCOL_DATAm_field32_get(unit, ventry, OVIDf);
  10035 
  10036     action->new_inner_vlan = 
  10037         soc_VLAN_PROTOCOL_DATAm_field32_get(unit, ventry, IVIDf); 
  10038 
  10039     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
  10040         action->priority =
  10041             soc_VLAN_PROTOCOL_DATAm_field32_get(unit, ventry, OPRIf);
  10042         action->new_outer_cfi =
  10043             soc_VLAN_PROTOCOL_DATAm_field32_get(unit, ventry, OCFIf);
  10044         action->new_inner_pkt_prio =
  10045             soc_VLAN_PROTOCOL_DATAm_field32_get(unit, ventry, IPRIf);
  10046         action->new_inner_cfi =
  10047             soc_VLAN_PROTOCOL_DATAm_field32_get(unit, ventry, ICFIf);
  10048     } else {
  10049         action->priority =
  10050             soc_VLAN_PROTOCOL_DATAm_field32_get(unit, ventry, PRIf);
  10051     }
  10052     *profile_idx = 
  10053         soc_VLAN_PROTOCOL_DATAm_field32_get(unit, ventry, 
  10054                                             TAG_ACTION_PROFILE_PTRf);
  10055 }
  10056 
  10057 #ifdef BCM_WARM_BOOT_SUPPORT
  10058 /*
  10059  * Function:
  10060  *      _bcm_trx_vlan_port_protocol_action_reinit
  10061  * Description:
  10062  *      Recover data for 'vd_pbvl' in port_info structure.
  10063  * Parameters:
  10064  *      unit            (IN) BCM unit number
  10065  * Notes:
  10066  *      Assumes:
  10067  *      - 'vd_pbvl' data in port_info structure is clear
  10068  *      - 'vlan_prot_ptr' in port_info structure is initialized
  10069  */
  10070 STATIC int
  10071 _bcm_trx_vlan_port_protocol_action_reinit(int unit)
  10072 {
  10073     int                         idxmin, idxmax, i, data_idx;
  10074     vlan_protocol_entry_t       vpe;
  10075     vlan_protocol_data_entry_t  vde;
  10076     bcm_port_frametype_t        ft;
  10077     bcm_port_ethertype_t        et;
  10078     bcm_pbmp_t                  pbmp;
  10079     bcm_port_t                  port;
  10080     bcm_vlan_action_set_t       def_action;
  10081     bcm_vlan_t                  def_ovid, def_ivid;
  10082     bcm_port_config_t           pconf;
  10083     _bcm_port_info_t            *pinfo;
  10084 
  10085 #ifdef BCM_KATANA2_SUPPORT
  10086     if (SOC_IS_KATANA2(unit)) {
  10087         /* KT2 devices recovery happens from scache in _bcm_esw_port_wb_recover */
  10088         return BCM_E_NONE;
  10089     }
  10090 #endif
  10091     idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm);
  10092     idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm);
  10093 
  10094     BCM_IF_ERROR_RETURN(bcm_esw_port_config_get(unit, &pconf));
  10095     pbmp = pconf.e; 
  10096     if (soc_feature(unit, soc_feature_cpuport_switched)) {
  10097         BCM_PBMP_OR(pbmp, pconf.cpu);
  10098     }
  10099 
  10100     for (i = idxmin; i <= idxmax; i++) {
  10101         SOC_IF_ERROR_RETURN
  10102             (READ_VLAN_PROTOCOLm(unit, MEM_BLOCK_ANY, i, &vpe));
  10103         _bcm_trx_vlan_port_protocol_entry_parse(unit, &vpe, &ft, &et);
  10104         if (0 == ft) {
  10105             continue;
  10106         }
  10107 
  10108         PBMP_ITER(pbmp, port) {
  10109             BCM_IF_ERROR_RETURN(
  10110                 bcm_esw_vlan_port_default_action_get(unit, port, &def_action));
  10111             BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
  10112             data_idx = pinfo->vlan_prot_ptr + i;
  10113             SOC_IF_ERROR_RETURN(
  10114                 READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY, data_idx, &vde));
  10115             def_ovid = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, OVIDf);
  10116             def_ivid = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, IVIDf);
  10117             if (def_ivid == def_action.new_inner_vlan &&
  10118                 def_ovid == def_action.new_outer_vlan) {
  10119                 continue;
  10120             }
  10121 
  10122             _BCM_PORT_VD_PBVL_SET(pinfo, i);
  10123         }
  10124     }
  10125 
  10126     return BCM_E_NONE;
  10127 }
  10128 #endif /* BCM_WARM_BOOT_SUPPORT */
  10129 
  10130 
  10131 /*
  10132  * Function   :
  10133  *      _bcm_trx_vlan_protocol_data_update
  10134  * Description   :
  10135  *      Helper function for an API to update lan port protocol data memory
  10136  *      for specific ports.
  10137  * Parameters   :
  10138  *      unit            (IN) BCM unit number
  10139  *      update_pbm      (IN) BCM port bitmap to update
  10140  *      prot_idx        (IN) Index to Port Protocol table
  10141  *      action          (IN) VLAN action to be used to update all ports in pbmp
  10142  */
  10143 STATIC int
  10144 _bcm_trx_vlan_protocol_data_update(int unit, bcm_pbmp_t update_pbm, int prot_idx,
  10145                                   bcm_vlan_action_set_t *action)
  10146 {
  10147     bcm_port_t                  p;
  10148     vlan_protocol_data_entry_t  vde;
  10149     int                         data_idx, profile_idx;
  10150     int                         c_profile_idx, use_default = 0;
  10151     bcm_vlan_action_set_t       def_action, *action_p;
  10152     _bcm_port_info_t            *pinfo;
  10153     
  10154 
  10155     /* if action is NULL then default action should be used for each port */
  10156     if (NULL == action) {
  10157         use_default = 1;
  10158         action_p = &def_action;
  10159     } else {
  10160         BCM_IF_ERROR_RETURN(
  10161             _bcm_trx_vlan_action_verify(unit, action));
  10162         action_p = action;
  10163     }
  10164 
  10165     BCM_PBMP_ITER(update_pbm, p) {
  10166         BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, p, &pinfo));
  10167         data_idx = pinfo->vlan_prot_ptr + prot_idx;
  10168 
  10169         if (use_default) {
  10170         BCM_IF_ERROR_RETURN(
  10171                 bcm_esw_vlan_port_default_action_get(unit, p, action_p));
  10172         }
  10173         BCM_IF_ERROR_RETURN(
  10174             _bcm_trx_vlan_action_profile_entry_add(unit, action_p, 
  10175                                                    (uint32 *)&profile_idx));
  10176         BCM_IF_ERROR_RETURN(
  10177             READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY, data_idx, &vde));
  10178 
  10179         c_profile_idx =
  10180             soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde,
  10181                                                 TAG_ACTION_PROFILE_PTRf);
  10182         sal_memset(&vde, 0, sizeof(vde));
  10183         _bcm_trx_vlan_protocol_data_entry_set(unit, &vde, action_p, 
  10184                                               profile_idx);
  10185         BCM_IF_ERROR_RETURN(
  10186             WRITE_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ALL, data_idx, &vde));
  10187         BCM_IF_ERROR_RETURN(
  10188             _bcm_trx_vlan_action_profile_entry_delete(unit, c_profile_idx));
  10189     }
  10190     return BCM_E_NONE;
  10191 }
  10192 
  10193 /*
  10194  * Function   :
  10195  *      _bcm_trx_vlan_protocol_data_entry_delete_by_idx
  10196  * Description   :
  10197  *      Helper function to delete a vlan_protocol_data entry from memory by 
  10198  *      protocol index
  10199  * Parameters   :
  10200  *      unit            (IN) BCM unit number
  10201  *      port            (IN) Port
  10202  *      vp_idx          (IN) Index to protcol id
  10203  */
  10204 STATIC int 
  10205 _bcm_trx_vlan_protocol_data_entry_delete_by_idx(int unit, bcm_port_t port, 
  10206                                                 int vp_idx) 
  10207 {
  10208     bcm_pbmp_t                  switched_pbm, update_pbm;
  10209     bcm_port_config_t           pconf;
  10210     _bcm_port_info_t            *pinfo;
  10211     bcm_port_t                  p;
  10212     int                         in_use = 0;
  10213     vlan_protocol_entry_t       *vpnull;
  10214 
  10215     BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
  10216     BCM_IF_ERROR_RETURN(bcm_esw_port_config_get(unit, &pconf));
  10217 
  10218     BCM_PBMP_CLEAR(update_pbm);
  10219     BCM_PBMP_PORT_ADD(update_pbm, port);
  10220     
  10221     switched_pbm = pconf.e; 
  10222     if (soc_feature(unit, soc_feature_cpuport_switched)) {
  10223         BCM_PBMP_OR(switched_pbm, pconf.cpu);
  10224     }
  10225 #ifdef BCM_KATANA2_SUPPORT
  10226     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  10227         BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &switched_pbm));
  10228     }
  10229     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  10230         soc_feature(unit, soc_feature_subtag_coe)) {
  10231         _bcm_kt2_subport_pbmp_update(unit, &switched_pbm);
  10232     }
  10233 #endif
  10234 
  10235     BCM_PBMP_ITER(switched_pbm, p) {
  10236         if (p == port) {    /* skip the port we just added */
  10237             continue;
  10238         }
  10239         BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, p, &pinfo));
  10240         /* Check for explicit VID entry */
  10241         if (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, vp_idx)) {
  10242             BCM_PBMP_PORT_ADD(update_pbm, p);
  10243         } else {
  10244             in_use = 1;
  10245         }
  10246     }
  10247 
  10248 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
  10249     if (SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
  10250         BCM_IF_ERROR_RETURN(
  10251             _bcm_trx_vlan_protocol_data_profile_update(unit, update_pbm, vp_idx, NULL));
  10252     } else
  10253 #endif
  10254     {
  10255         BCM_IF_ERROR_RETURN(
  10256             _bcm_trx_vlan_protocol_data_update(unit, update_pbm, vp_idx, NULL));
  10257     }
  10258     if (!in_use) {
  10259         vpnull = soc_mem_entry_null(unit, VLAN_PROTOCOLm); 
  10260         WRITE_VLAN_PROTOCOLm(unit, MEM_BLOCK_ALL, vp_idx, vpnull);
  10261     }
  10262 
  10263     return BCM_E_NONE;
  10264 }
  10265 
  10266 /*
  10267  * Function   :
  10268  *      _bcm_trx_vlan_port_protocol_action_add
  10269  * Description   :
  10270  *      Helper function for an API to add vlan port protocol action
  10271  *      For TRX 
  10272  * Parameters   :
  10273  *      unit            (IN) BCM unit number
  10274  *      port            (IN) BCM port number
  10275  *      frame           (IN) Frame type
  10276  *      ethr            (IN) Ethertype 
  10277  *      action          (IN) vlan action to be used
  10278  */
  10279 int
  10280 _bcm_trx_vlan_port_protocol_action_add(int unit,
  10281                                       bcm_port_t port,
  10282                                       bcm_port_frametype_t frame,
  10283                                       bcm_port_ethertype_t ether,
  10284                                       bcm_vlan_action_set_t *action)
  10285 {
  10286     
  10287     bcm_port_t                  p;
  10288     vlan_protocol_entry_t       vpe;
  10289     int                         vpentry, empty, rv_m, rv_e;
  10290     bcm_pbmp_t                  switched_pbm, update_pbm, clear_pbm;
  10291     _bcm_port_info_t            *pinfo;
  10292     bcm_port_config_t           pconf;
  10293 
  10294     BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action));
  10295     
  10296     /* Verifying supported frame types */
  10297     if ((0 == frame) || (BCM_PORT_FRAMETYPE_SNAP_PRIVATE < frame) ||
  10298             (frame & (frame - 1))) {
  10299         return BCM_E_PARAM;
  10300     }
  10301     rv_m = _bcm_trx_vlan_port_prot_match_get(unit, frame, ether, &vpentry);
  10302     rv_e = _bcm_trx_vlan_port_prot_empty_get(unit, &empty);
  10303 
  10304     if ((BCM_E_NOT_FOUND == rv_m)  && (BCM_E_FULL == rv_e)) {
  10305         return BCM_E_FULL;
  10306     }
  10307     if (BCM_E_NOT_FOUND == rv_m) {
  10308         sal_memset(&vpe, 0, sizeof(vpe));
  10309         soc_VLAN_PROTOCOLm_field32_set(unit, &vpe, ETHERTYPEf, ether);
  10310         if (frame & BCM_PORT_FRAMETYPE_ETHER2) {
  10311             soc_VLAN_PROTOCOLm_field32_set(unit, &vpe, ETHERIIf, 1);
  10312         }
  10313         if (frame & BCM_PORT_FRAMETYPE_8023) {
  10314             soc_VLAN_PROTOCOLm_field32_set(unit, &vpe, SNAPf, 1);
  10315         }
  10316         if (frame & BCM_PORT_FRAMETYPE_LLC) {
  10317             soc_VLAN_PROTOCOLm_field32_set(unit, &vpe, LLCf, 1);
  10318         }
  10319         soc_VLAN_PROTOCOLm_field32_set(unit, &vpe, MATCHUPPERf, 1);
  10320         soc_VLAN_PROTOCOLm_field32_set(unit, &vpe, MATCHLOWERf, 1);
  10321         /* Actual writing into the memory will be last in this routine */
  10322         vpentry = empty;
  10323     }
  10324 
  10325     /*
  10326      * Set VLAN ID for target port. For all other ethernet ports,
  10327      * make sure entries indexed by the matched entry in VLAN_PROTOCOL
  10328      * have initialized values (either default or explicit VID).
  10329      */
  10330     BCM_PBMP_CLEAR(update_pbm);
  10331     BCM_PBMP_CLEAR(clear_pbm);
  10332     BCM_IF_ERROR_RETURN(
  10333         bcm_esw_port_config_get(unit, &pconf));
  10334     switched_pbm = pconf.e;
  10335     if (soc_feature(unit, soc_feature_cpuport_switched)) {
  10336         BCM_PBMP_OR(switched_pbm, pconf.cpu);
  10337     }
  10338 #ifdef BCM_KATANA2_SUPPORT
  10339     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  10340         BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &switched_pbm));
  10341     }
  10342     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  10343         soc_feature(unit, soc_feature_subtag_coe)) {
  10344         _bcm_kt2_subport_pbmp_update(unit, &switched_pbm);
  10345     }
  10346 #endif
  10347 
  10348     BCM_PBMP_ITER(switched_pbm, p) {
  10349         BCM_IF_ERROR_RETURN(
  10350             _bcm_port_info_get(unit, p, &pinfo));
  10351         if (p == port) {
  10352             if (_BCM_PORT_VD_PBVL_IS_SET(pinfo, vpentry)) {
  10353                 return BCM_E_EXISTS;
  10354             }
  10355             /* Set as explicit VID */
  10356             _BCM_PORT_VD_PBVL_SET(pinfo, vpentry);
  10357             BCM_PBMP_PORT_ADD(update_pbm, p);
  10358         } else {
  10359             if (_BCM_PORT_VD_PBVL_IS_SET(pinfo, vpentry)) {
  10360                 continue;
  10361             }
  10362             /* Set to default VLAN ID and vlan actions */
  10363             BCM_PBMP_PORT_ADD(clear_pbm, p);
  10364         }
  10365     }
  10366 
  10367 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
  10368     if (SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
  10369         BCM_IF_ERROR_RETURN(_bcm_trx_vlan_protocol_data_profile_update(unit,
  10370             clear_pbm, vpentry, NULL));
  10371         BCM_IF_ERROR_RETURN(_bcm_trx_vlan_protocol_data_profile_update(unit,
  10372             update_pbm, vpentry, action));
  10373     } else
  10374 #endif
  10375     {
  10376         BCM_IF_ERROR_RETURN(_bcm_trx_vlan_protocol_data_update(unit,
  10377             clear_pbm, vpentry, NULL));
  10378         BCM_IF_ERROR_RETURN(_bcm_trx_vlan_protocol_data_update(unit,
  10379             update_pbm, vpentry, action));
  10380     }
  10381 
  10382     if (BCM_E_NOT_FOUND == rv_m) {
  10383         BCM_IF_ERROR_RETURN(
  10384             WRITE_VLAN_PROTOCOLm(unit, MEM_BLOCK_ALL, vpentry, &vpe));
  10385 }
  10386 
  10387     return BCM_E_NONE;
  10388 }
  10389 
  10390 /*
  10391  * Function   :
  10392  *      _bcm_trx_vlan_port_protocol_action_get
  10393  * Description   :
  10394  *      Helper function for an API to get vlan port protocol action
  10395  *      For TRX 
  10396  * Parameters   :
  10397  *      unit            (IN) BCM unit number
  10398  *      port            (IN) BCM port number
  10399  *      frame           (IN) Frame type
  10400  *      ethr            (IN) Ethertype 
  10401  *      action          (OUT) vlan action to get
  10402  */
  10403 int
  10404 _bcm_trx_vlan_port_protocol_action_get(int unit, bcm_port_t port, 
  10405                                       bcm_port_frametype_t frame,
  10406                                       bcm_port_ethertype_t ether,
  10407                                       bcm_vlan_action_set_t *action)
  10408 {
  10409     int                             match_prot_idx, match_data_idx, profile_idx; 
  10410     vlan_protocol_data_entry_t      vde;
  10411     _bcm_port_info_t                *pinfo;
  10412 
  10413     if (NULL == action) {
  10414         return (BCM_E_PARAM);
  10415     }
  10416 
  10417     BCM_IF_ERROR_RETURN(
  10418         _bcm_trx_vlan_port_prot_match_get(unit, frame, ether, &match_prot_idx));
  10419 
  10420     BCM_IF_ERROR_RETURN(
  10421         _bcm_port_info_get(unit, port, &pinfo));
  10422 
  10423     if (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, match_prot_idx)) {
  10424         return BCM_E_NOT_FOUND;
  10425     }
  10426 
  10427     match_data_idx = pinfo->vlan_prot_ptr + match_prot_idx;
  10428     
  10429     BCM_IF_ERROR_RETURN(
  10430         READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY, match_data_idx, &vde));
  10431 
  10432     _bcm_trx_vlan_protocol_data_entry_parse(unit, &vde, action, &profile_idx);
  10433     _bcm_trx_vlan_action_profile_entry_get(unit, action, profile_idx); 
  10434 
  10435     return BCM_E_NONE;
  10436 }
  10437 
  10438 /*
  10439  * Function   :
  10440  *      _bcm_trx_vlan_port_protocol_delete
  10441  * Description   :
  10442  *      Helper function for an API to delete vlan port protocol action
  10443  *      For TRX 
  10444  * Parameters   :
  10445  *      unit            (IN) BCM unit number
  10446  *      port            (IN) BCM port number
  10447  *      frame           (IN) Frame type
  10448  *      ethr            (IN) Ethertype 
  10449  */
  10450 
  10451 int
  10452 _bcm_trx_vlan_port_protocol_delete(int unit, bcm_port_t port,
  10453                                   bcm_port_frametype_t frame,
  10454                                   bcm_port_ethertype_t ether)
  10455 {
  10456     int                 vpentry, rv;
  10457     _bcm_port_info_t    *pinfo;
  10458 
  10459     BCM_IF_ERROR_RETURN(
  10460         _bcm_trx_vlan_port_prot_match_get(unit, frame, ether, &vpentry));
  10461 
  10462     BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
  10463 
  10464     if (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, vpentry)) {
  10465         return BCM_E_NOT_FOUND;
  10466     }
  10467 
  10468     rv = _bcm_trx_vlan_protocol_data_entry_delete_by_idx(unit, port, vpentry);
  10469     if (BCM_SUCCESS(rv)) {
  10470         _BCM_PORT_VD_PBVL_CLEAR(pinfo, vpentry);
  10471     }
  10472 
  10473     return rv;
  10474 }
  10475 
  10476 
  10477 /*
  10478  * Function   :
  10479  *      _bcm_trx_vlan_port_protocol_delete_all
  10480  * Description   :
  10481  *      Helper function for an API to delete all actions for all 
  10482  *      vlan port protocols for TRX 
  10483  * Parameters   :
  10484  *      unit            (IN) BCM unit number
  10485  *      port            (IN) BCM port number
  10486  */
  10487 int
  10488 _bcm_trx_vlan_port_protocol_delete_all(int unit, bcm_port_t port)
  10489 {
  10490     int      i, idxmin, idxmax, rv;
  10491     _bcm_port_info_t    *pinfo;
  10492 
  10493     idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm);
  10494     idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm);
  10495 
  10496     BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
  10497     
  10498     rv = BCM_E_NONE;
  10499     
  10500     for (i = idxmin; i <= idxmax; i++) {
  10501         if (_BCM_PORT_VD_PBVL_IS_SET(pinfo, i)) {
  10502             rv = _bcm_trx_vlan_protocol_data_entry_delete_by_idx(unit, port, i);
  10503             if (BCM_FAILURE(rv)) {
  10504                 break;
  10505             } else {
  10506                 _BCM_PORT_VD_PBVL_CLEAR(pinfo, i);
  10507             }
  10508         }
  10509     }
  10510 
  10511     return rv;
  10512 }
  10513 
  10514 
  10515 /*
  10516  * Function   :
  10517  *      _bcm_trx_vlan_port_protocol_action_traverse
  10518  * Description   :
  10519  *      Helper function for an API to traverse over all  
  10520  *      vlan port protocols and call given callback routine for TRX 
  10521  * Parameters   :
  10522  *      unit            (IN) BCM unit number
  10523  *      cb              (IN) user callback function
  10524  *      user_data       (IN) pointer to user data
  10525  */
  10526 int 
  10527 _bcm_trx_vlan_port_protocol_action_traverse(int unit,
  10528                                    bcm_vlan_port_protocol_action_traverse_cb cb,
  10529                                            void *user_data)
  10530 {
  10531     int                         idxmin, idxmax, i, data_idx, profile_idx;
  10532     vlan_protocol_entry_t       vpe;
  10533     vlan_protocol_data_entry_t  vde;
  10534     bcm_port_frametype_t        ft;
  10535     bcm_port_ethertype_t        et;
  10536     bcm_pbmp_t                  pbmp;
  10537     bcm_port_t                  port;
  10538     bcm_vlan_action_set_t       action;
  10539     bcm_port_config_t           pconf;
  10540     _bcm_port_info_t            *pinfo;
  10541 
  10542     idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm);
  10543     idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm);
  10544 
  10545     BCM_IF_ERROR_RETURN(bcm_esw_port_config_get(unit, &pconf));
  10546     pbmp = pconf.e; 
  10547     if (soc_feature(unit, soc_feature_cpuport_switched)) {
  10548         BCM_PBMP_OR(pbmp, pconf.cpu);
  10549     }
  10550 #ifdef BCM_KATANA2_SUPPORT
  10551     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  10552         BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &pbmp));
  10553     }
  10554     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  10555         soc_feature(unit, soc_feature_subtag_coe)) {
  10556         _bcm_kt2_subport_pbmp_update(unit, &pbmp);
  10557     }
  10558 #endif
  10559 
  10560     for (i = idxmin; i <= idxmax; i++) {
  10561         SOC_IF_ERROR_RETURN(
  10562             READ_VLAN_PROTOCOLm(unit, MEM_BLOCK_ANY, i, &vpe));
  10563         _bcm_trx_vlan_port_protocol_entry_parse(unit, &vpe, &ft, &et);
  10564         if (0 == ft) {
  10565             continue;
  10566         }
  10567         PBMP_ITER(pbmp, port) {
  10568             BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
  10569             if (_BCM_PORT_VD_PBVL_IS_SET(pinfo, i)) {
  10570                 data_idx = pinfo->vlan_prot_ptr + i;
  10571                 SOC_IF_ERROR_RETURN(READ_VLAN_PROTOCOL_DATAm(unit,
  10572                             MEM_BLOCK_ANY, data_idx, &vde));
  10573                 profile_idx = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde,
  10574                         TAG_ACTION_PROFILE_PTRf);
  10575                 action.new_inner_vlan =
  10576                     soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, IVIDf);
  10577                 action.new_outer_vlan =
  10578                     soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, OVIDf);
  10579                 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
  10580                     action.priority =
  10581                         soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, OPRIf);
  10582                     action.new_outer_cfi =
  10583                         soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, OCFIf);
  10584                     action.new_inner_pkt_prio =
  10585                         soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, IPRIf);
  10586                     action.new_inner_cfi =
  10587                         soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, ICFIf);
  10588                 } else {
  10589                     action.priority =
  10590                         soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, PRIf);
  10591                 }
  10592                 /* Read action profile data. */
  10593                 _bcm_trx_vlan_action_profile_entry_get(unit, &action, profile_idx);
  10594                 BCM_IF_ERROR_RETURN(cb(unit, port, ft, et, &action, user_data));
  10595             }
  10596         }
  10597     }
  10598 
  10599     return (BCM_E_NONE);
  10600 }
  10601 
  10602 /*
  10603  * Function:
  10604  *      _bcm_trx_vlan_port_default_action_set
  10605  * Purpose:
  10606  *      Set the port's default vlan tag actions
  10607  * Parameters:
  10608  *      unit       - (IN) BCM unit.
  10609  *      port       - (IN) Port number.
  10610  *      action     - (IN) Vlan tag actions
  10611  * Returns:
  10612  *      BCM_E_XXX
  10613  */
  10614 int
  10615 _bcm_trx_vlan_port_default_action_set(int unit, bcm_port_t port,
  10616                                      bcm_vlan_action_set_t *action)
  10617 {
  10618     uint32 profile_idx, old_profile_idx, vp_profile_idx;
  10619     bcm_port_cfg_t pcfg;
  10620     vlan_protocol_data_entry_t vde;
  10621     int vlan_prot_entries, vlan_data_prot_start, i;
  10622     _bcm_port_info_t *pinfo;
  10623 #ifdef BCM_HGPROXY_COE_SUPPORT
  10624     int rv = BCM_E_NONE;
  10625 #endif
  10626 
  10627     BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action));
  10628     BCM_IF_ERROR_RETURN
  10629         (_bcm_trx_vlan_action_profile_entry_add(unit, action, &profile_idx));
  10630 
  10631 #ifdef BCM_HGPROXY_COE_SUPPORT
  10632     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  10633         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  10634         uint32 values[5];
  10635         soc_field_t fields[] = {
  10636             TAG_ACTION_PROFILE_PTRf,
  10637             PORT_PRIf,
  10638             OCFIf,
  10639             IPRIf,
  10640             ICFIf
  10641         };
  10642 
  10643         PORT_LOCK(unit);
  10644         rv = bcm_esw_port_lport_fields_get(unit, port, LPORT_PROFILE_LPORT_TAB,
  10645                                            5, fields, values);
  10646         PORT_UNLOCK(unit);
  10647         if (BCM_FAILURE(rv)) {
  10648             return rv;
  10649         }
  10650 
  10651         old_profile_idx = values[0];
  10652         pcfg.pc_new_opri = values[1];
  10653         pcfg.pc_new_ocfi = values[2];
  10654         pcfg.pc_new_ipri = values[3];
  10655         pcfg.pc_new_icfi = values[4];
  10656     } else
  10657 #endif
  10658     {
  10659         BCM_IF_ERROR_RETURN
  10660             (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg));
  10661         old_profile_idx = pcfg.pc_vlan_action;
  10662     }
  10663 
  10664     pcfg.pc_vlan = action->new_outer_vlan;
  10665     pcfg.pc_ivlan = action->new_inner_vlan;
  10666     pcfg.pc_vlan_action = profile_idx;
  10667     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
  10668         if (action->priority >= BCM_PRIO_MIN &&
  10669             action->priority <= BCM_PRIO_MAX) {
  10670             pcfg.pc_new_opri = action->priority;
  10671         }
  10672         pcfg.pc_new_ocfi = action->new_outer_cfi;
  10673         pcfg.pc_new_ipri = action->new_inner_pkt_prio;
  10674         pcfg.pc_new_icfi = action->new_inner_cfi;
  10675     } else {
  10676         if (action->priority >= BCM_PRIO_MIN &&
  10677             action->priority <= BCM_PRIO_MAX) {
  10678             pcfg.pc_new_opri = action->priority;
  10679         }
  10680     }
  10681 
  10682 #ifdef BCM_HGPROXY_COE_SUPPORT
  10683     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  10684         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  10685         uint32 values[7];
  10686         soc_field_t fields[] = {
  10687             PORT_VIDf,
  10688             IVIDf,
  10689             TAG_ACTION_PROFILE_PTRf,
  10690             PORT_PRIf,
  10691             OCFIf,
  10692             IPRIf,
  10693             ICFIf
  10694         };
  10695 
  10696         values[0] = pcfg.pc_vlan;
  10697         values[1] = pcfg.pc_ivlan;
  10698         values[2] = pcfg.pc_vlan_action;
  10699         values[3] = pcfg.pc_new_opri;
  10700         values[4] = pcfg.pc_new_ocfi;
  10701         values[5] = pcfg.pc_new_ipri;
  10702         values[6] = pcfg.pc_new_icfi;
  10703 
  10704         PORT_LOCK(unit);
  10705         rv = bcm_esw_port_lport_fields_set(unit, port, LPORT_PROFILE_LPORT_TAB,
  10706                                            7, fields, values);
  10707         PORT_UNLOCK(unit);
  10708         if (BCM_FAILURE(rv)) {
  10709             return rv;
  10710         }
  10711     }else
  10712 #endif
  10713     {
  10714         BCM_IF_ERROR_RETURN
  10715             (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg));
  10716     }
  10717 
  10718     SOC_IF_ERROR_RETURN
  10719         (_bcm_trx_vlan_action_profile_entry_delete(unit, old_profile_idx));
  10720 
  10721     BCM_IF_ERROR_RETURN(
  10722         _bcm_esw_port_gport_validate(unit, port, &port));
  10723 
  10724     /*
  10725      * Update default VLAN ID in VLAN_PROTOCOL_DATA
  10726      */
  10727     vlan_prot_entries = soc_mem_index_count(unit, VLAN_PROTOCOLm);
  10728     BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
  10729     vlan_data_prot_start = pinfo->vlan_prot_ptr;
  10730 
  10731     if (pinfo->p_vd_pbvl == 0) {
  10732         /* Avoid one crash in kt2 tr 18 test case in linux environment */
  10733         return (BCM_E_NONE);
  10734     }
  10735 
  10736     
  10737     for (i = 0; i < vlan_prot_entries; i++) {
  10738 
  10739         BCM_IF_ERROR_RETURN(
  10740             READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY,
  10741                                      vlan_data_prot_start + i, &vde));
  10742         vp_profile_idx = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde,
  10743                              TAG_ACTION_PROFILE_PTRf);
  10744 
  10745         if (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, i)) { 
  10746 
  10747             BCM_IF_ERROR_RETURN(
  10748                 _bcm_trx_vlan_action_profile_entry_add(unit, action, 
  10749                                                        &profile_idx));
  10750             _bcm_trx_vlan_protocol_data_entry_set(unit, &vde, action, 
  10751                                                   profile_idx);
  10752 
  10753             BCM_IF_ERROR_RETURN(
  10754                 WRITE_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ALL,
  10755                                            vlan_data_prot_start + i, &vde));
  10756             BCM_IF_ERROR_RETURN(
  10757                 _bcm_trx_vlan_action_profile_entry_delete(unit, 
  10758                                                           vp_profile_idx));
  10759         }
  10760     }
  10761     
  10762     return (BCM_E_NONE);
  10763 }
  10764 
  10765 /*
  10766  * Function:
  10767  *      _bcm_trx_vlan_port_default_action_get
  10768  * Purpose:
  10769  *      Get the port's default vlan tag actions
  10770  * Parameters:
  10771  *      unit       - (IN) BCM unit.
  10772  *      port       - (IN) Port number.
  10773  *      action     - (IN) Vlan tag actions
  10774  * Returns:
  10775  *      BCM_E_XXX
  10776  */ 
  10777 int 
  10778 _bcm_trx_vlan_port_default_action_get(int unit, bcm_port_t port,
  10779                                      bcm_vlan_action_set_t *action)
  10780 {
  10781     uint32 profile_idx;
  10782     bcm_port_cfg_t pcfg;
  10783     int vid;
  10784     int ivid;
  10785 #ifdef BCM_HGPROXY_COE_SUPPORT
  10786     int rv = BCM_E_NONE;
  10787 #endif
  10788 
  10789     bcm_vlan_action_set_t_init(action);
  10790 
  10791 #ifdef BCM_HGPROXY_COE_SUPPORT
  10792     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  10793         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  10794         uint32 values[7];
  10795         soc_field_t fields[] = {
  10796             PORT_VIDf,
  10797             IVIDf,
  10798             TAG_ACTION_PROFILE_PTRf,
  10799             PORT_PRIf,
  10800             OCFIf,
  10801             IPRIf,
  10802             ICFIf
  10803         };
  10804 
  10805         PORT_LOCK(unit);
  10806         rv = bcm_esw_port_lport_fields_get(unit, port, LPORT_PROFILE_LPORT_TAB,
  10807                                            7, fields, values);
  10808         PORT_UNLOCK(unit);
  10809         if (BCM_FAILURE(rv)) {
  10810             return rv;
  10811         }
  10812 
  10813         vid = values[0];
  10814         ivid = values[1];
  10815         profile_idx = values[2];
  10816         pcfg.pc_new_opri = values[3];
  10817         pcfg.pc_new_ocfi = values[4];
  10818         pcfg.pc_new_ipri = values[5];
  10819         pcfg.pc_new_icfi = values[6];
  10820     } else
  10821 #endif
  10822     {
  10823         BCM_IF_ERROR_RETURN
  10824             (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg));
  10825         profile_idx = pcfg.pc_vlan_action;
  10826         vid = pcfg.pc_vlan;
  10827         ivid = pcfg.pc_ivlan;
  10828     }
  10829 
  10830     _bcm_trx_vlan_action_profile_entry_get(unit, action, profile_idx);
  10831 
  10832     action->new_outer_vlan = vid;
  10833     action->new_inner_vlan = ivid;
  10834     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
  10835         action->priority = pcfg.pc_new_opri; 
  10836         action->new_outer_cfi = pcfg.pc_new_ocfi;
  10837         action->new_inner_pkt_prio = pcfg.pc_new_ipri;
  10838         action->new_inner_cfi = pcfg.pc_new_icfi;
  10839     } else {
  10840         action->priority = pcfg.pc_new_opri;
  10841     }
  10842 
  10843     return BCM_E_NONE;
  10844 }
  10845 
  10846 
  10847 /*
  10848  * Function:
  10849  *      _bcm_tr_vlan_port_default_action_delete
  10850  * Purpose:
  10851  *      Deletes the port's default vlan tag actions
  10852  * Parameters:
  10853  *      unit       - (IN) BCM unit.
  10854  *      port       - (IN) Port number.
  10855  * Returns:
  10856  *      BCM_E_XXX
  10857  */ 
  10858 int 
  10859 _bcm_trx_vlan_port_default_action_delete(int unit, bcm_port_t port)
  10860 {
  10861     uint32                      old_profile_idx;
  10862     uint32                      vp_profile_idx;
  10863     bcm_port_cfg_t              pcfg;
  10864     _bcm_port_info_t            *pinfo;
  10865     int                         num_ent, start, i;
  10866     vlan_protocol_data_entry_t  vde;
  10867 
  10868     BCM_IF_ERROR_RETURN
  10869         (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg));
  10870     old_profile_idx = pcfg.pc_vlan_action;
  10871 
  10872     pcfg.pc_vlan = BCM_VLAN_DEFAULT;
  10873     pcfg.pc_ivlan = 0;
  10874     pcfg.pc_vlan_action = ing_action_profile_def[unit];
  10875     BCM_IF_ERROR_RETURN
  10876         (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg));
  10877 
  10878     _bcm_trx_vlan_action_profile_entry_increment(unit,
  10879             ing_action_profile_def[unit]);
  10880     BCM_IF_ERROR_RETURN
  10881         (_bcm_trx_vlan_action_profile_entry_delete(unit, old_profile_idx));
  10882     
  10883     BCM_IF_ERROR_RETURN(
  10884         _bcm_port_info_get(unit,port, &pinfo));
  10885 
  10886     num_ent = soc_mem_index_count(unit, VLAN_PROTOCOLm);
  10887     start = pinfo->vlan_prot_ptr;
  10888     for (i = 0; i < num_ent; i++) {
  10889         if (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, i)) { 
  10890             BCM_IF_ERROR_RETURN(READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY,
  10891                         start + i, &vde));
  10892             vp_profile_idx = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde,
  10893                     TAG_ACTION_PROFILE_PTRf);
  10894 
  10895             sal_memset(&vde, 0, sizeof(vlan_protocol_data_entry_t));
  10896             soc_VLAN_PROTOCOL_DATAm_field32_set(unit, &vde, OVIDf,
  10897                     BCM_VLAN_DEFAULT); 
  10898             soc_VLAN_PROTOCOL_DATAm_field32_set(unit, &vde,
  10899                     TAG_ACTION_PROFILE_PTRf, ing_action_profile_def[unit]);
  10900             BCM_IF_ERROR_RETURN(WRITE_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ALL,
  10901                         start + i, &vde));
  10902 
  10903             _bcm_trx_vlan_action_profile_entry_increment(unit,
  10904                     ing_action_profile_def[unit]);
  10905             BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_profile_entry_delete(unit, 
  10906                         vp_profile_idx));
  10907         }
  10908     }
  10909     return (BCM_E_NONE);
  10910 }
  10911 
  10912 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  10913 /*
  10914  * Function:
  10915  *      _bcm_td2p_vlan_port_egress_default_action_set
  10916  * Purpose:
  10917  *      Set the egress port's default vlan tag actions
  10918  * Parameters:
  10919  *      unit       - (IN) BCM unit.
  10920  *      port       - (IN) Port number.
  10921  *      action     - (IN) Vlan tag actions
  10922  * Returns:
  10923  *      BCM_E_XXX
  10924  */
  10925 STATIC int
  10926 _bcm_td2p_vlan_port_egress_default_action_set(int unit, bcm_port_t port,
  10927                                             bcm_vlan_action_set_t *action,
  10928                                             uint32 profile_idx)
  10929 {
  10930     int rv;
  10931     uint32 old_profile_idx;
  10932     egr_vlan_control_3_entry_t entry_3;
  10933     egr_vlan_control_2_entry_t entry_2;
  10934 
  10935     if (soc_feature(unit, soc_feature_egr_all_profile)) {
  10936         int field_cnt = 0;
  10937         soc_field_t fields[6];
  10938         uint32 values[6];
  10939 
  10940         if (-1 == action->priority) {
  10941             fields[field_cnt] = OPRI_CFI_SELf;
  10942             values[field_cnt++] = 1;
  10943         } else {
  10944             fields[field_cnt] = OPRI_CFI_SELf;
  10945             values[field_cnt++] = 0;
  10946             fields[field_cnt] = OPRIf;
  10947             values[field_cnt++] = action->priority;
  10948             fields[field_cnt] = OCFIf;
  10949             values[field_cnt++] = action->new_outer_cfi;
  10950         }
  10951         fields[field_cnt] = OVIDf;
  10952         values[field_cnt++] = action->new_outer_vlan;
  10953         rv = bcm_esw_port_egr_lport_fields_set(unit, port, EGR_VLAN_CONTROL_2m,
  10954                 field_cnt, fields, values);
  10955         if (rv < 0) {
  10956             goto error;
  10957         }
  10958 
  10959         /* EGR_VLAN_CONTROL_3m */
  10960         field_cnt = 0;
  10961         rv = bcm_esw_port_egr_lport_field_get(unit, port, EGR_VLAN_CONTROL_3m,
  10962                 TAG_ACTION_PROFILE_PTRf, &old_profile_idx);
  10963         if (rv < 0) {
  10964             goto error;
  10965         }
  10966         fields[field_cnt] = TAG_ACTION_PROFILE_PTRf;
  10967         values[field_cnt++] = profile_idx;
  10968         fields[field_cnt] = IVIDf;
  10969         values[field_cnt++] = action->new_inner_vlan;
  10970         if (-1 == action->priority) {
  10971             fields[field_cnt] = IPRI_CFI_SELf;
  10972             values[field_cnt++] = 1;
  10973         } else {
  10974             fields[field_cnt] = IPRI_CFI_SELf;
  10975             values[field_cnt++] = 0;
  10976             fields[field_cnt] = IPRIf;
  10977             values[field_cnt++] = action->new_inner_pkt_prio;
  10978             fields[field_cnt] = ICFIf;
  10979             values[field_cnt++] = action->new_inner_cfi;
  10980         }
  10981         rv = bcm_esw_port_egr_lport_fields_set(unit, port, EGR_VLAN_CONTROL_3m,
  10982                 field_cnt, fields, values);
  10983         if (rv < 0) {
  10984             goto error;
  10985         }
  10986         /* Delete the old profile only if it is different the a new one. */
  10987         if (profile_idx != old_profile_idx) {
  10988             rv = _bcm_trx_egr_vlan_action_profile_entry_delete(unit,
  10989                     old_profile_idx);
  10990             if (rv < 0) {
  10991                 goto error;
  10992             }
  10993         }
  10994 
  10995         return BCM_E_NONE;
  10996     }
  10997 
  10998     rv = READ_EGR_VLAN_CONTROL_2m(unit, MEM_BLOCK_ANY, port, &entry_2);
  10999     if (rv < 0) {
  11000         goto error;
  11001     }
  11002     if (-1 == action->priority) {
  11003         /* point to default map profile(0) for default priority action */
  11004         soc_mem_field32_set(unit, EGR_VLAN_CONTROL_2m, 
  11005                 &entry_2, OPRI_CFI_SELf, 1);
  11006     } else {
  11007         soc_mem_field32_set(unit, EGR_VLAN_CONTROL_2m, 
  11008                 &entry_2, OPRI_CFI_SELf, 0);
  11009         soc_mem_field32_set(unit, EGR_VLAN_CONTROL_2m, 
  11010                 &entry_2, OPRIf, action->priority);
  11011         soc_mem_field32_set(unit, EGR_VLAN_CONTROL_2m, &entry_2, OCFIf,
  11012                 action->new_outer_cfi);
  11013     }
  11014     soc_mem_field32_set(unit, EGR_VLAN_CONTROL_2m, &entry_2,
  11015             OVIDf, action->new_outer_vlan);
  11016     rv = WRITE_EGR_VLAN_CONTROL_2m(unit, MEM_BLOCK_ANY, port, &entry_2);
  11017     if (rv < 0) {
  11018         goto error;
  11019     }
  11020 
  11021     rv = READ_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry_3);
  11022     if (rv < 0) {
  11023         goto error;
  11024     }   
  11025     old_profile_idx = soc_mem_field32_get(unit, EGR_VLAN_CONTROL_3m,
  11026             &entry_3, TAG_ACTION_PROFILE_PTRf);
  11027     soc_mem_field32_set(unit, EGR_VLAN_CONTROL_3m, &entry_3,
  11028             TAG_ACTION_PROFILE_PTRf, profile_idx);
  11029     soc_mem_field32_set(unit, EGR_VLAN_CONTROL_3m, &entry_3,
  11030             IVIDf, action->new_inner_vlan);
  11031 
  11032     if ( -1 == action->priority) {
  11033         /* point to default map profile(0) for default priority action */
  11034         soc_mem_field32_set(unit, EGR_VLAN_CONTROL_3m,
  11035                 &entry_3, IPRI_CFI_SELf, 1);
  11036     } else {
  11037         soc_mem_field32_set(unit, EGR_VLAN_CONTROL_3m,
  11038                 &entry_3, IPRI_CFI_SELf, 0);
  11039         soc_mem_field32_set(unit, EGR_VLAN_CONTROL_3m, &entry_3, IPRIf,
  11040                 action->new_inner_pkt_prio);
  11041         soc_mem_field32_set(unit, EGR_VLAN_CONTROL_3m, &entry_3, ICFIf,
  11042                 action->new_inner_cfi);
  11043     }
  11044     rv = WRITE_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry_3);
  11045     if (rv < 0) {
  11046         goto error;
  11047     }
  11048 
  11049     /* Delete the old profile only if it is different the a new one. */
  11050     if (profile_idx != old_profile_idx) {
  11051         rv = _bcm_trx_egr_vlan_action_profile_entry_delete(unit,
  11052                 old_profile_idx);
  11053         if (rv < 0) {
  11054             goto error;
  11055         }
  11056     }
  11057 
  11058     return BCM_E_NONE;
  11059 
  11060 error:
  11061     /* Undo action profile entry addition */
  11062     if (_bcm_trx_egr_vlan_action_profile_entry_delete(unit, profile_idx) != BCM_E_NONE) {
  11063         LOG_INFO(BSL_LS_SOC_VLAN,
  11064                 (BSL_META_U(unit,
  11065                             "Failed to undo profile entry addition\n")));
  11066     }
  11067     return rv;
  11068 }
  11069 
  11070 /*
  11071  * Function:
  11072  *      _bcm_td2pvlan_port_egress_default_action_get
  11073  * Purpose:
  11074  *      Get the egress port's default vlan tag actions
  11075  * Parameters:
  11076  *      unit       - (IN) BCM unit.
  11077  *      port       - (IN) Port number.
  11078  *      action     - (IN) Vlan tag actions
  11079  * Returns:
  11080  *      BCM_E_XXX
  11081  */
  11082 STATIC int
  11083 _bcm_td2p_vlan_port_egress_default_action_get(int unit, bcm_port_t port,
  11084                                             bcm_vlan_action_set_t *action)
  11085 {
  11086     uint32 profile_idx;
  11087     egr_vlan_control_3_entry_t entry_3;
  11088     egr_vlan_control_2_entry_t entry_2;
  11089 
  11090     if (soc_feature(unit, soc_feature_egr_all_profile)) {
  11091         int field_count = 5;
  11092         soc_field_t fields[5] = {
  11093             TAG_ACTION_PROFILE_PTRf,
  11094             IVIDf,
  11095             IPRI_CFI_SELf,
  11096             IPRIf,
  11097             ICFIf
  11098         };
  11099         uint32 values[5];
  11100         BCM_IF_ERROR_RETURN(
  11101             bcm_esw_port_egr_lport_fields_get(unit, port, EGR_VLAN_CONTROL_3m,
  11102             field_count, fields, values));
  11103         profile_idx = values[0];
  11104         _bcm_trx_egr_vlan_action_profile_entry_get(unit, action, profile_idx);
  11105         action->new_inner_vlan = values[1];
  11106         if (!values[2]) {
  11107             action->new_inner_pkt_prio = values[3];
  11108             action->new_inner_cfi = values[4];
  11109         }
  11110 
  11111         /* EGR_VLAN_CONTROL_2m */
  11112         field_count = 4;
  11113         fields[0] = OVIDf;
  11114         fields[1] = OPRI_CFI_SELf;
  11115         fields[2] = OPRIf;
  11116         fields[3] = OCFIf;
  11117         BCM_IF_ERROR_RETURN(
  11118             bcm_esw_port_egr_lport_fields_get(unit, port, EGR_VLAN_CONTROL_2m,
  11119             field_count, fields, values));
  11120         action->new_outer_vlan = values[0];
  11121         if (!values[1]) {
  11122             action->priority = values[2];
  11123             action->new_outer_cfi = values[3];
  11124         }
  11125 
  11126         return BCM_E_NONE;
  11127     }
  11128     BCM_IF_ERROR_RETURN
  11129         (READ_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry_3));
  11130     profile_idx = soc_mem_field32_get(unit, EGR_VLAN_CONTROL_3m,
  11131             &entry_3, TAG_ACTION_PROFILE_PTRf);
  11132     _bcm_trx_egr_vlan_action_profile_entry_get(unit, action, profile_idx);
  11133     action->new_inner_vlan = soc_mem_field32_get(unit, EGR_VLAN_CONTROL_3m,
  11134             &entry_3, IVIDf);
  11135     if (!soc_mem_field32_get(unit, EGR_VLAN_CONTROL_3m, &entry_3,
  11136                 IPRI_CFI_SELf)) {
  11137         action->new_inner_pkt_prio =
  11138             soc_mem_field32_get(unit, EGR_VLAN_CONTROL_3m, &entry_3, IPRIf);
  11139         action->new_inner_cfi =
  11140             soc_mem_field32_get(unit, EGR_VLAN_CONTROL_3m, &entry_3, ICFIf);
  11141     }
  11142 
  11143     BCM_IF_ERROR_RETURN
  11144         (READ_EGR_VLAN_CONTROL_2m(unit, MEM_BLOCK_ANY, port, &entry_2));
  11145     action->new_outer_vlan = soc_mem_field32_get(unit, EGR_VLAN_CONTROL_2m,
  11146             &entry_2, OVIDf);
  11147     if (!soc_mem_field32_get(unit, EGR_VLAN_CONTROL_2m, &entry_2,
  11148                 OPRI_CFI_SELf)) {
  11149         action->priority =
  11150             soc_mem_field32_get(unit, EGR_VLAN_CONTROL_2m, &entry_2, OPRIf);
  11151         action->new_outer_cfi =
  11152             soc_mem_field32_get(unit, EGR_VLAN_CONTROL_2m, &entry_2, OCFIf);
  11153     }
  11154 
  11155     return BCM_E_NONE;
  11156 }
  11157 
  11158 /*
  11159  * Function:
  11160  *      _bcm_td2p_vlan_port_egress_default_action_delete
  11161  * Purpose:
  11162  *      Deletes the egress port's default vlan tag actions
  11163  * Parameters:
  11164  *      unit       - (IN) BCM unit.
  11165  *      port       - (IN) Port number.
  11166  * Returns:
  11167  *      BCM_E_XXX
  11168  */
  11169 STATIC int
  11170 _bcm_td2p_vlan_port_egress_default_action_delete(int unit, bcm_port_t port)
  11171 {
  11172     uint32 profile_idx;
  11173     egr_vlan_control_3_entry_t entry_3;
  11174     egr_vlan_control_2_entry_t entry_2;
  11175 
  11176     if (soc_feature(unit, soc_feature_egr_all_profile)) {
  11177         BCM_IF_ERROR_RETURN(
  11178             bcm_esw_port_egr_lport_field_get(unit, port, EGR_VLAN_CONTROL_3m,
  11179             TAG_ACTION_PROFILE_PTRf, &profile_idx));
  11180     } else {
  11181     BCM_IF_ERROR_RETURN
  11182         (READ_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry_3));
  11183     profile_idx = soc_EGR_VLAN_CONTROL_3m_field32_get(unit, &entry_3,
  11184             TAG_ACTION_PROFILE_PTRf);
  11185     }
  11186 
  11187     if (!SOC_IS_TRIDENT3X(unit)) {
  11188         BCM_IF_ERROR_RETURN(
  11189             _bcm_trx_egr_vlan_action_profile_entry_delete(unit, profile_idx));
  11190     }
  11191 
  11192     if (soc_feature(unit, soc_feature_egr_all_profile)) {
  11193         BCM_IF_ERROR_RETURN(
  11194             bcm_esw_port_egr_lport_fields_clear(unit, port, EGR_VLAN_CONTROL_2m));
  11195         BCM_IF_ERROR_RETURN(
  11196             bcm_esw_port_egr_lport_fields_clear(unit, port, EGR_VLAN_CONTROL_3m));
  11197     } else {
  11198     sal_memset(&entry_3, 0, sizeof(entry_3));
  11199     sal_memset(&entry_2, 0, sizeof(entry_2));
  11200     BCM_IF_ERROR_RETURN(
  11201             WRITE_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry_3));
  11202     BCM_IF_ERROR_RETURN(
  11203             WRITE_EGR_VLAN_CONTROL_2m(unit, MEM_BLOCK_ANY, port, &entry_2));
  11204     }
  11205     return BCM_E_NONE;
  11206 }
  11207 
  11208 /*
  11209  * Function:
  11210  *      _bcm_td2p_vlan_port_egress_action_profile_clear
  11211  * Purpose:
  11212  *      Clear the egress port's default vlan tag profile pointer
  11213  * Parameters:
  11214  *      unit       - (IN) BCM unit.
  11215  *      port       - (IN) Port number.
  11216  * Returns:
  11217  *      BCM_E_XXX
  11218  */
  11219 STATIC int
  11220 _bcm_td2p_vlan_port_egress_action_profile_clear(int unit, bcm_port_t port)
  11221 {
  11222     if (soc_feature(unit, soc_feature_egr_all_profile)) {
  11223         BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_field_set(unit,
  11224             port, EGR_VLAN_CONTROL_3m, TAG_ACTION_PROFILE_PTRf, 0));
  11225     } else {
  11226     egr_vlan_control_3_entry_t entry_3;
  11227 
  11228     BCM_IF_ERROR_RETURN
  11229         (READ_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry_3));
  11230     soc_EGR_VLAN_CONTROL_3m_field32_set(unit, &entry_3,
  11231                                         TAG_ACTION_PROFILE_PTRf, 0);
  11232     BCM_IF_ERROR_RETURN(
  11233             WRITE_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry_3));
  11234     }
  11235     return BCM_E_NONE;
  11236 }
  11237 #endif
  11238 
  11239 /*
  11240  * Function:
  11241  *      _bcm_tr_vlan_port_egress_default_action_set
  11242  * Purpose:
  11243  *      Set the egress port's default vlan tag actions
  11244  * Parameters:
  11245  *      unit       - (IN) BCM unit.
  11246  *      port       - (IN) Port number.
  11247  *      action     - (IN) Vlan tag actions
  11248  * Returns:
  11249  *      BCM_E_XXX
  11250  */
  11251 int
  11252 _bcm_trx_vlan_port_egress_default_action_set(int unit, bcm_port_t port,
  11253                                             bcm_vlan_action_set_t *action)
  11254 {
  11255     int rv;
  11256     uint32 rval, profile_idx, old_profile_idx;
  11257 
  11258 #if defined(BCM_TOMAHAWK3_SUPPORT)
  11259     if (SOC_IS_TOMAHAWK3(unit)) {
  11260         return(
  11261             _bcm_th3_vlan_port_egress_default_action_set(unit, port, action));
  11262     }
  11263 #endif/* BCM_TOMAHAWK3_SUPPORT */
  11264 
  11265 #if defined(BCM_TOMAHAWK_SUPPORT)
  11266     /* Tomahawk low latency mode */
  11267     if (soc_feature(unit, soc_feature_fast_egr_vlan_action)) {
  11268         rval = _bcm_fast_egr_vlan_port_egress_default_action_set(unit,
  11269                                                                port, action);
  11270         return rval;
  11271     }
  11272 #endif
  11273 
  11274     BCM_IF_ERROR_RETURN(_bcm_trx_egr_vlan_action_verify(unit, action));
  11275     BCM_IF_ERROR_RETURN(
  11276         _bcm_trx_egr_vlan_action_profile_entry_add(unit, action, &profile_idx));
  11277 
  11278 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  11279     if(soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
  11280         return _bcm_td2p_vlan_port_egress_default_action_set(unit, port,
  11281                 action, profile_idx);
  11282     } else
  11283 #endif
  11284     {
  11285         rv = READ_EGR_VLAN_CONTROL_2r(unit, port, &rval);
  11286         if (rv < 0) {
  11287             goto error;
  11288         }
  11289 
  11290         if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
  11291             if (-1 == action->priority) {
  11292                 /* point to default map profile(0) for default priority action */
  11293                 soc_reg_field_set(unit, EGR_VLAN_CONTROL_2r, &rval, OPRI_CFI_SELf, 1);
  11294             } else {
  11295                 soc_reg_field_set(unit, EGR_VLAN_CONTROL_2r, &rval, OPRI_CFI_SELf, 0);
  11296                 soc_reg_field_set(unit, EGR_VLAN_CONTROL_2r, &rval, OPRIf,
  11297                           action->priority);
  11298                 soc_reg_field_set(unit, EGR_VLAN_CONTROL_2r, &rval, OCFIf,
  11299                           action->new_outer_cfi);
  11300             }
  11301         } else {
  11302             /* -1 reserved value */
  11303             if (-1 == action->priority) {
  11304                 soc_reg_field_set(unit, EGR_VLAN_CONTROL_2r, &rval, ORPEf, 0);
  11305                 soc_reg_field_set(unit, EGR_VLAN_CONTROL_2r, &rval, OPRIf, 0);
  11306             } else if (action->priority <= BCM_PRIO_MAX){
  11307                 soc_reg_field_set(unit, EGR_VLAN_CONTROL_2r, &rval, ORPEf, 1);
  11308                 soc_reg_field_set(unit, EGR_VLAN_CONTROL_2r, &rval, OPRIf,
  11309                               action->priority);
  11310             } else {
  11311                 rv = BCM_E_PARAM;
  11312                 goto error;
  11313             }
  11314         }
  11315     
  11316         soc_reg_field_set(unit, EGR_VLAN_CONTROL_2r, &rval,
  11317                       OVIDf, action->new_outer_vlan);
  11318         rv = WRITE_EGR_VLAN_CONTROL_2r(unit, port, rval);
  11319         if (rv < 0) {
  11320             goto error;
  11321         }
  11322 
  11323         rv = READ_EGR_VLAN_CONTROL_3r(unit, port, &rval);
  11324         if (rv < 0) {
  11325             goto error;
  11326         }   
  11327         old_profile_idx = soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r,
  11328                                         rval, TAG_ACTION_PROFILE_PTRf);
  11329         soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval,
  11330                       TAG_ACTION_PROFILE_PTRf, profile_idx);
  11331         soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval,
  11332                       IVIDf, action->new_inner_vlan);
  11333 
  11334         if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
  11335             if ( -1 == action->priority) {
  11336                 /* point to default map profile(0) for default priority action */
  11337                 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, IPRI_CFI_SELf, 1);
  11338             } else {
  11339                 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, IPRI_CFI_SELf, 0);
  11340                 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, IPRIf,
  11341                           action->new_inner_pkt_prio);
  11342                 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, ICFIf,
  11343                           action->new_inner_cfi);
  11344             }
  11345         } else {
  11346             if ( -1 == action->priority) {
  11347                 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, IRPEf, 0);
  11348                 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, IPRIf, 0);
  11349             } else if (action->priority <= BCM_PRIO_MAX){
  11350                 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, IRPEf, 1);
  11351                 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, IPRIf,
  11352                               action->priority);
  11353             } else {
  11354                 rv = BCM_E_PARAM;
  11355                 goto error;
  11356             }
  11357         }
  11358     
  11359         rv = WRITE_EGR_VLAN_CONTROL_3r(unit, port, rval);
  11360         if (rv < 0) {
  11361             goto error;
  11362         }
  11363         /* Delete the old profile only if it is different the a new one. */
  11364         if (profile_idx != old_profile_idx) {
  11365             BCM_IF_ERROR_RETURN
  11366                 (_bcm_trx_egr_vlan_action_profile_entry_delete(unit, old_profile_idx));
  11367         }
  11368 
  11369         return BCM_E_NONE;
  11370 
  11371 error:
  11372         /* Undo action profile entry addition */
  11373         BCM_IF_ERROR_RETURN
  11374             (_bcm_trx_egr_vlan_action_profile_entry_delete(unit, profile_idx));
  11375         return rv;
  11376     }
  11377 }
  11378 
  11379 /*
  11380  * Function:
  11381  *      _bcm_tr_vlan_port_egress_default_action_get
  11382  * Purpose:
  11383  *      Get the egress port's default vlan tag actions
  11384  * Parameters:
  11385  *      unit       - (IN) BCM unit.
  11386  *      port       - (IN) Port number.
  11387  *      action     - (IN) Vlan tag actions
  11388  * Returns:
  11389  *      BCM_E_XXX
  11390  */
  11391 int
  11392 _bcm_trx_vlan_port_egress_default_action_get(int unit, bcm_port_t port,
  11393                                             bcm_vlan_action_set_t *action)
  11394 {
  11395     uint32 profile_idx, rval;
  11396 
  11397 #if defined(BCM_TOMAHAWK3_SUPPORT)
  11398     if (SOC_IS_TOMAHAWK3(unit)) {
  11399         return(
  11400             _bcm_th3_vlan_port_egress_default_action_get(unit, port, action));
  11401     }
  11402 #endif/* BCM_TOMAHAWK3_SUPPORT */
  11403 
  11404     bcm_vlan_action_set_t_init(action);
  11405 #if defined(BCM_TOMAHAWK_SUPPORT)
  11406     /* Tomahawk low latency mode */
  11407     if (soc_feature(unit, soc_feature_fast_egr_vlan_action)) {
  11408         rval = _bcm_fast_egr_vlan_port_egress_default_action_get(unit,
  11409                                                                port, action);
  11410         return rval;
  11411     }
  11412 #endif
  11413 
  11414 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  11415     if(soc_feature(unit, soc_feature_egr_vlan_control_is_memory)){
  11416         return _bcm_td2p_vlan_port_egress_default_action_get(unit, port,
  11417                 action);
  11418     } else
  11419 #endif
  11420     {
  11421         BCM_IF_ERROR_RETURN
  11422             (READ_EGR_VLAN_CONTROL_3r(unit, port, &rval));
  11423         profile_idx = soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r,
  11424                                     rval, TAG_ACTION_PROFILE_PTRf);
  11425         _bcm_trx_egr_vlan_action_profile_entry_get(unit, action, profile_idx);
  11426         action->new_inner_vlan = soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r,
  11427                                                rval, IVIDf);
  11428         if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
  11429             if (!soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r, rval,
  11430                                IPRI_CFI_SELf)) {
  11431                 action->new_inner_pkt_prio =
  11432                     soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r, rval, IPRIf);
  11433                 action->new_inner_cfi =
  11434                     soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r, rval, ICFIf);
  11435             }
  11436         }
  11437 
  11438         BCM_IF_ERROR_RETURN
  11439             (READ_EGR_VLAN_CONTROL_2r(unit, port, &rval));
  11440         action->new_outer_vlan = soc_reg_field_get(unit, EGR_VLAN_CONTROL_2r,
  11441                                                rval, OVIDf);
  11442         if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
  11443             if (!soc_reg_field_get(unit, EGR_VLAN_CONTROL_2r, rval,
  11444                                OPRI_CFI_SELf)) {
  11445                 action->priority =
  11446                     soc_reg_field_get(unit, EGR_VLAN_CONTROL_2r, rval, OPRIf);
  11447                 action->new_outer_cfi =
  11448                     soc_reg_field_get(unit, EGR_VLAN_CONTROL_2r, rval, OCFIf);
  11449             }
  11450         } else {
  11451             if (soc_reg_field_get(unit, EGR_VLAN_CONTROL_2r, rval, ORPEf)) {
  11452                 action->priority = soc_reg_field_get(unit, EGR_VLAN_CONTROL_2r,
  11453                                                  rval, OPRIf);
  11454             } else {
  11455                 action->priority = -1;
  11456             }
  11457         }
  11458     }
  11459 
  11460     return BCM_E_NONE;
  11461 }
  11462 
  11463 /*
  11464  * Function:
  11465  *      _bcm_tr_vlan_port_egress_default_action_delete
  11466  * Purpose:
  11467  *      Deletes the egress port's default vlan tag actions
  11468  * Parameters:
  11469  *      unit       - (IN) BCM unit.
  11470  *      port       - (IN) Port number.
  11471  * Returns:
  11472  *      BCM_E_XXX
  11473  */
  11474 int
  11475 _bcm_trx_vlan_port_egress_default_action_delete(int unit, bcm_port_t port)
  11476 {
  11477     uint32                  profile_idx, rval;
  11478 
  11479 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  11480     if(soc_feature(unit, soc_feature_egr_vlan_control_is_memory)){
  11481         return _bcm_td2p_vlan_port_egress_default_action_delete(unit, port);
  11482     } else
  11483 #endif
  11484 #if defined(BCM_TOMAHAWK3_SUPPORT)
  11485     if (SOC_IS_TOMAHAWK3(unit)) {
  11486         return(_bcm_th3_vlan_port_egress_default_action_delete(unit, port));
  11487     } else
  11488 #endif/* BCM_TOMAHAWK3_SUPPORT */
  11489     {
  11490         BCM_IF_ERROR_RETURN(
  11491                 READ_EGR_VLAN_CONTROL_3r(unit, port, &rval));
  11492         profile_idx = soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r,
  11493                 rval, TAG_ACTION_PROFILE_PTRf);
  11494 
  11495         if (!SOC_IS_TRIDENT3X(unit)) {
  11496             BCM_IF_ERROR_RETURN(
  11497                     _bcm_trx_egr_vlan_action_profile_entry_delete(unit, profile_idx));
  11498         }
  11499         sal_memset(&rval, 0, sizeof(uint32));
  11500         BCM_IF_ERROR_RETURN(
  11501                 WRITE_EGR_VLAN_CONTROL_3r(unit, port, rval));
  11502         BCM_IF_ERROR_RETURN(
  11503                 WRITE_EGR_VLAN_CONTROL_2r(unit, port, rval));
  11504     }
  11505 
  11506     return BCM_E_NONE;
  11507 }
  11508 
  11509 int
  11510 _bcm_trx_vlan_port_egress_action_profile_clear(int unit, bcm_port_t port)
  11511 {
  11512     uint32                  rval;
  11513 
  11514 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  11515     if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
  11516         return _bcm_td2p_vlan_port_egress_action_profile_clear(unit, port);
  11517     } else
  11518 #endif
  11519     {
  11520         BCM_IF_ERROR_RETURN(
  11521                 READ_EGR_VLAN_CONTROL_3r(unit, port, &rval));
  11522         soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r,
  11523                 &rval, TAG_ACTION_PROFILE_PTRf, 0);
  11524 
  11525         BCM_IF_ERROR_RETURN(
  11526                 WRITE_EGR_VLAN_CONTROL_3r(unit, port, rval));
  11527     }
  11528 
  11529     return BCM_E_NONE;
  11530 }
  11531 
  11532 #if defined(BCM_TOMAHAWK_SUPPORT)
  11533 /*
  11534  * Function:
  11535  *      _bcm_fast_egr_vlan_port_egress_default_action_set
  11536  * Purpose:
  11537  *      Set the egress port's default vlan tag actions in Low latency mode
  11538  * Parameters:
  11539  *      unit       - (IN) BCM unit.
  11540  *      port       - (IN) Port number.
  11541  *      action     - (IN) Vlan tag actions
  11542  * Returns:
  11543  *      BCM_E_XXX
  11544  */
  11545 STATIC int
  11546 _bcm_fast_egr_vlan_port_egress_default_action_set(
  11547             int unit,
  11548             bcm_port_t port,
  11549             bcm_vlan_action_set_t *action)
  11550 {
  11551     uint32 rval;
  11552 
  11553     /* Verify vlan_action */
  11554     if (NULL == action)
  11555         return BCM_E_PARAM;
  11556 
  11557     switch(action->ot_outer) {
  11558     case bcmVlanActionNone:
  11559     case bcmVlanActionDelete:
  11560         break;
  11561     default:
  11562         return BCM_E_PARAM;
  11563     }
  11564     switch(action->ot_outer_prio) {
  11565     case bcmVlanActionNone:
  11566     case bcmVlanActionDelete:
  11567         break;
  11568     default:
  11569         return BCM_E_PARAM;
  11570     }
  11571     switch(action->ut_outer) {
  11572     case bcmVlanActionNone:
  11573         break;
  11574     default:
  11575         return BCM_E_PARAM;
  11576     }
  11577 
  11578     /* Check for non-zero value on other fields */
  11579     if ((action->new_outer_vlan) | (action->new_inner_vlan) | (action->new_inner_pkt_prio)
  11580         | (action->new_outer_cfi) | (action->new_inner_cfi) | (action->ingress_if)
  11581         | (action->priority) | (action->dt_outer) | (action->dt_outer_prio)
  11582         | (action->dt_outer_pkt_prio) | (action->dt_outer_cfi) | (action->dt_inner)) {
  11583         return BCM_E_UNAVAIL;
  11584     }
  11585     if ((action->dt_inner_prio) | (action->dt_inner_pkt_prio) | (action->dt_inner_cfi)
  11586         | (action->ot_outer_pkt_prio) | (action->ot_outer_cfi) | (action->ot_inner)
  11587         | (action->ot_inner_pkt_prio) | (action->ot_inner_cfi) | (action->it_outer)
  11588         | (action->it_outer_pkt_prio) | (action->it_outer_cfi) | (action->it_inner)
  11589         | (action->it_inner_prio) | (action->it_inner_pkt_prio) | (action->it_inner_cfi)) {
  11590         return BCM_E_UNAVAIL;
  11591     }
  11592     if ((action->ut_outer_pkt_prio) | (action->ut_outer_cfi) | (action->ut_inner)
  11593         | (action->ut_inner_pkt_prio) | (action->ut_inner_cfi) | (action->outer_pcp)
  11594         | (action->inner_pcp) | (action->policer_id) | (action->outer_tpid)
  11595         | (action->inner_tpid) | (action->outer_tpid_action) | (action->inner_tpid_action)
  11596         | (action->action_id) | (action->class_id) | (action->flags)) {
  11597         return BCM_E_UNAVAIL;
  11598     }
  11599 
  11600     SOC_IF_ERROR_RETURN(
  11601         READ_EGR_VLAN_TAG_ACTION_FOR_BYPASSr(unit, port, &rval));
  11602 
  11603     soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr, &rval,
  11604         SOT_OTAG_ACTIONf, _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_outer));
  11605     soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr, &rval,
  11606         SOT_POTAG_ACTIONf, _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ot_outer_prio));
  11607     soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr, &rval,
  11608         UT_OTAG_ACTIONf, _BCM_TRX_PRI_CFI_ACTION_ENCODE(action->ut_outer));
  11609 
  11610     SOC_IF_ERROR_RETURN(
  11611                 WRITE_EGR_VLAN_TAG_ACTION_FOR_BYPASSr(unit, port, rval));
  11612 
  11613     return BCM_E_NONE;
  11614 }
  11615 
  11616 /*
  11617  * Function:
  11618  *      _bcm_fast_egr_vlan_port_egress_default_action_get
  11619  * Purpose:
  11620  *      Get the egress port's default vlan tag actions in Low latency mode
  11621  * Parameters:
  11622  *      unit       - (IN) BCM unit.
  11623  *      port       - (IN) Port number.
  11624  *      action     - (IN) Vlan tag actions
  11625  * Returns:
  11626  *      BCM_E_XXX
  11627  */
  11628 STATIC int
  11629 _bcm_fast_egr_vlan_port_egress_default_action_get(
  11630             int unit,
  11631             bcm_port_t port,
  11632             bcm_vlan_action_set_t *action)
  11633 {
  11634     uint32 rval;
  11635 
  11636     /* Verify output param */
  11637     if (NULL == action)
  11638         return BCM_E_PARAM;
  11639 
  11640     SOC_IF_ERROR_RETURN(
  11641         READ_EGR_VLAN_TAG_ACTION_FOR_BYPASSr(unit, port, &rval));
  11642 
  11643     action->ot_outer = _BCM_TRX_PRI_CFI_ACTION_ENCODE(soc_reg_field_get(unit,
  11644         EGR_VLAN_TAG_ACTION_FOR_BYPASSr, rval, SOT_OTAG_ACTIONf));
  11645     action->ot_outer_prio = _BCM_TRX_PRI_CFI_ACTION_ENCODE(soc_reg_field_get(unit,
  11646         EGR_VLAN_TAG_ACTION_FOR_BYPASSr, rval, SOT_POTAG_ACTIONf));
  11647     action->ut_outer = _BCM_TRX_PRI_CFI_ACTION_ENCODE(soc_reg_field_get(unit,
  11648         EGR_VLAN_TAG_ACTION_FOR_BYPASSr, rval, UT_OTAG_ACTIONf));
  11649 
  11650     return BCM_E_NONE;
  11651 }
  11652 #endif
  11653 
  11654 /*
  11655  * Function:
  11656  *		_bcm_tr_vlan_translate_entry_update
  11657  * Purpose:
  11658  *		Update VLAN XLATE Entry 
  11659  * Parameters:
  11660  *  IN :  Unit
  11661  *  IN :  vlan_xlate_entry
  11662  *  OUT :  vlan_xlate_entry
  11663 
  11664  */
  11665 
  11666 STATIC int
  11667 _bcm_tr_vlan_translate_entry_update(int unit, void *vent, void *return_ent)
  11668 {
  11669     uint32  vp, key_type, value;
  11670     soc_mem_t mem = VLAN_XLATEm;
  11671 
  11672     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
  11673         mem = VLAN_XLATE_1_DOUBLEm;
  11674     }
  11675 
  11676     /* Check if Key_Type identical */
  11677     key_type = soc_mem_field32_get(unit, mem, vent, KEY_TYPEf);
  11678     value = soc_mem_field32_get(unit, mem, return_ent, KEY_TYPEf);
  11679     if (key_type != value) {
  11680          return BCM_E_PARAM;
  11681     }
  11682 
  11683     soc_mem_field32_set(unit, mem, return_ent, MPLS_ACTIONf, 0x1);
  11684     soc_mem_field32_set(unit, mem, return_ent, DISABLE_VLAN_CHECKSf, 1);
  11685     if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_VPf)) {
  11686         vp = soc_mem_field32_get(unit, mem, vent, SOURCE_VPf);
  11687         soc_mem_field32_set(unit, mem, return_ent, SOURCE_VPf, vp);
  11688     }
  11689     return BCM_E_NONE;
  11690 }
  11691 
  11692 /*
  11693  * Function:
  11694  *              _bcm_tr3_vlan_translate_entry_update
  11695  * Purpose:
  11696  *              Update VLAN XLATE Entry
  11697  * Parameters:  
  11698  *  IN :  Unit
  11699  *  IN :  vlan_xlate_extd_entry
  11700  *  OUT : vlan_xlate_extd_entry
  11701  */
  11702 
  11703 #if defined(BCM_TRIUMPH3_SUPPORT)
  11704 STATIC int
  11705 _bcm_tr3_vxlate_extd_entry_vp_update(int unit, 
  11706                vlan_xlate_entry_t *vent_in,  /* update entry */
  11707                void *ctxt,
  11708                vlan_xlate_entry_t *vent_out, /* entry read from mem */
  11709                vlan_xlate_extd_entry_t *vxent_out, /* entry read from mem or
  11710                                       converted from vent_out if not null */
  11711                int *use_extd_tbl)
  11712 {
  11713     uint32  vp;
  11714   
  11715     vp = PTR_TO_INT(ctxt);
  11716  
  11717     if (vent_out) {
  11718         BCM_IF_ERROR_RETURN
  11719             (_bcm_tr3_vxlate2vxlate_extd(unit,vent_out,vxent_out));
  11720     }
  11721 
  11722     soc_VLAN_XLATE_EXTDm_field32_set(unit, vxent_out,XLATE__MPLS_ACTIONf, 0x1);
  11723     soc_VLAN_XLATE_EXTDm_field32_set(unit, vxent_out, DISABLE_VLAN_CHECKSf, 1);
  11724     soc_VLAN_XLATE_EXTDm_field32_set(unit, vxent_out, SOURCE_VPf, vp);
  11725     *use_extd_tbl = TRUE;
  11726     return BCM_E_NONE;
  11727 }
  11728 #endif
  11729 
  11730 
  11731 int
  11732 _bcm_tr_vlan_translate_vp_add(int unit,
  11733                                bcm_gport_t port,
  11734                                bcm_vlan_translate_key_t key_type,
  11735                                bcm_vlan_t outer_vlan,
  11736                                bcm_vlan_t inner_vlan,
  11737                                int vp, bcm_vlan_action_set_t *action,
  11738                                int *existing_updated)
  11739 {
  11740     int rv, gport_id;
  11741     vlan_xlate_entry_t vx_ent, vx_ent_old;
  11742     vlan_xlate_1_double_entry_t vx1d_ent, vx1d_ent_old;
  11743     bcm_module_t mod_out;
  11744     bcm_port_t port_out;
  11745     bcm_trunk_t trunk_id;
  11746     int idx;
  11747     int key_type_value;
  11748     uint32 vxlate_action_profile_idx;
  11749     uint32 vxlate_action_profile_idx_old;
  11750    
  11751     soc_mem_t mem = VLAN_XLATEm;
  11752     soc_field_t vf = VALIDf;
  11753     void *vent = &vx_ent;
  11754     void *vent_old = &vx_ent_old;
  11755     uint32 ent_sz = sizeof(vx_ent);
  11756 
  11757     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
  11758         mem = VLAN_XLATE_1_DOUBLEm;
  11759         vf = BASE_VALID_0f; /* TD3TBD */
  11760         vent = &vx1d_ent;
  11761         vent_old = &vx1d_ent_old;
  11762         ent_sz = sizeof(vx1d_ent);
  11763     }
  11764 
  11765     rv = BCM_E_NONE; 
  11766     sal_memset(vent, 0, ent_sz);
  11767     switch (key_type) {
  11768         case bcmVlanTranslateKeyPortOuter:
  11769             BCM_IF_ERROR_RETURN
  11770                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
  11771                        VLXLT_HASH_KEY_TYPE_OVID,
  11772                        &key_type_value));
  11773             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
  11774             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
  11775                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
  11776                                         key_type_value);
  11777             }
  11778             soc_mem_field32_set(unit, mem, vent, OVIDf, outer_vlan);
  11779             break;
  11780         case bcmVlanTranslateKeyPortInner:
  11781             BCM_IF_ERROR_RETURN
  11782                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
  11783                        VLXLT_HASH_KEY_TYPE_IVID,
  11784                        &key_type_value));
  11785             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
  11786             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
  11787                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
  11788                                         key_type_value);
  11789             }
  11790             soc_mem_field32_set(unit, mem, vent, IVIDf, inner_vlan);
  11791             break;
  11792         case bcmVlanTranslateKeyPortDouble:
  11793             BCM_IF_ERROR_RETURN
  11794                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
  11795                        VLXLT_HASH_KEY_TYPE_IVID_OVID,
  11796                        &key_type_value));
  11797             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
  11798             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
  11799                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
  11800                                         key_type_value);
  11801             }
  11802             soc_mem_field32_set(unit, mem, vent, OVIDf, outer_vlan);
  11803             soc_mem_field32_set(unit, mem, vent, IVIDf, inner_vlan);
  11804             break;
  11805         case bcmVlanTranslateKeyPortOuterPri:
  11806             BCM_IF_ERROR_RETURN
  11807                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
  11808                        VLXLT_HASH_KEY_TYPE_PRI_CFI,
  11809                        &key_type_value));
  11810             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
  11811             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
  11812                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
  11813                                         key_type_value);
  11814             }
  11815             /* outer_vlan: Bits 12-15 contains VLAN_PRI + CFI, vlan=BCM_E_NONE */
  11816             soc_mem_field32_set(unit, mem, vent, OTAGf, outer_vlan);
  11817             break;
  11818         case bcmVlanTranslateKeyPortOuterTag:
  11819             /* allow 16 bit VLAN id */
  11820             BCM_IF_ERROR_RETURN
  11821                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
  11822                        VLXLT_HASH_KEY_TYPE_OTAG,
  11823                        &key_type_value));
  11824             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
  11825             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
  11826                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
  11827                                         key_type_value);
  11828             }
  11829             soc_mem_field32_set(unit, mem, vent, OTAGf, outer_vlan);
  11830             break;
  11831         default:
  11832             return BCM_E_PARAM;
  11833     }
  11834     BCM_IF_ERROR_RETURN
  11835         (_bcm_esw_gport_resolve(unit, port, &mod_out, &port_out, &trunk_id,
  11836                                 &gport_id));
  11837 
  11838     if (BCM_GPORT_IS_TRUNK(port)) {
  11839         soc_mem_field32_set(unit, mem, vent, Tf, 1);
  11840         soc_mem_field32_set(unit, mem, vent, TGIDf, trunk_id);
  11841     } else {
  11842         soc_mem_field32_set(unit, mem, vent, MODULE_IDf, mod_out);
  11843         soc_mem_field32_set(unit, mem, vent, PORT_NUMf, port_out);
  11844     }
  11845         
  11846     if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_VPf)) {
  11847         soc_mem_field32_set(unit, mem, vent, SOURCE_VPf, vp);
  11848     }
  11849 
  11850     if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) {
  11851         /* set default vlan_xlate key source_type as SGLP */
  11852         soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1);
  11853     }
  11854 
  11855     if (mem == VLAN_XLATEm) {
  11856         soc_mem_field32_set(unit, mem, vent, vf, 1);
  11857     } else {
  11858         soc_mem_field32_set(unit, mem, vent, vf, 3);
  11859         soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7);
  11860     }
  11861 
  11862     if (action) {
  11863         vxlate_action_profile_idx = 0;
  11864         BCM_IF_ERROR_RETURN(
  11865             _bcm_trx_vlan_action_verify(unit, action));
  11866         vxlate_action_profile_idx_old = 
  11867          soc_mem_field32_get(unit, mem, vent, TAG_ACTION_PROFILE_PTRf);
  11868         /* Add new tag action profile table ptr */
  11869         BCM_IF_ERROR_RETURN
  11870           (_bcm_trx_vlan_action_profile_entry_add(unit, action, 
  11871                                   &vxlate_action_profile_idx));
  11872         soc_mem_field32_set(unit, mem, vent, TAG_ACTION_PROFILE_PTRf,
  11873                                               vxlate_action_profile_idx);
  11874         /* Delete old tag action profile table ptr expect entry zero
  11875          * It contains initialize cache hardware ING_VLAN_TAG_ACTION_PROFILE
  11876          * and EGR_VLAN_TAG_ACTION_PROFILE tables in RAM.
  11877          * ING_VLAN profile contains PORT_TAB and VLAN_PROTOCOL_DATA
  11878          * EGR_VLAN profile contains all ports, sub ports and vlan subnets */
  11879         if (vxlate_action_profile_idx_old != ING_ACTION_PROFILE_DEFAULT) {
  11880             BCM_IF_ERROR_RETURN
  11881                 (_bcm_trx_vlan_action_profile_entry_delete(unit,
  11882                             vxlate_action_profile_idx_old));
  11883         }
  11884         /* Set new OVID and IVID from the 'action' specified */
  11885         soc_mem_field32_set(unit, mem, vent, NEW_OVIDf, action->new_outer_vlan);
  11886         soc_mem_field32_set(unit, mem, vent, NEW_IVIDf, action->new_inner_vlan);
  11887 
  11888 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_APACHE_SUPPORT) || \
  11889     defined(BCM_GREYHOUND2_SUPPORT)
  11890         if (soc_feature(unit, soc_feature_global_meter) &&
  11891             (SOC_IS_KATANAX(unit) || SOC_IS_APACHE(unit) ||
  11892              SOC_IS_GREYHOUND2(unit))) {
  11893             rv = _bcm_esw_add_policer_to_table(unit, action->policer_id,
  11894                                                mem,0, vent);
  11895             BCM_IF_ERROR_RETURN(rv);
  11896         }
  11897 #endif /* BCM_KATANA_SUPPORT || BCM_APACHE_SUPPORT ||
  11898           BCM_GREYHOUND2_SUPPORT */
  11899     }
  11900 
  11901 #if defined(BCM_TRIUMPH3_SUPPORT)
  11902     if (SOC_IS_TRIUMPH3(unit)) {
  11903         BCM_IF_ERROR_RETURN
  11904             (_bcm_tr3_vxlate_entry_add(unit,vent,
  11905                           (void *)INT_TO_PTR(vp),
  11906                           _bcm_tr3_vxlate_extd_entry_vp_update,
  11907                           existing_updated));
  11908     } else
  11909 #endif
  11910     {
  11911     soc_mem_field32_set(unit, mem, vent, MPLS_ACTIONf, 0x1); /* SVP */
  11912     if (action) {
  11913         if (action->flags & BCM_VLAN_ACTION_SET_VLAN_CHECKS_DISABLE) {
  11914             soc_mem_field32_set(unit, mem, vent, DISABLE_VLAN_CHECKSf, 1);
  11915         }
  11916     }
  11917     if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_ACTION_VALIDf)) {
  11918         soc_mem_field32_set(unit, mem, vent, VLAN_ACTION_VALIDf, 1);
  11919     }
  11920 
  11921     /* look up existing entry */
  11922     soc_mem_lock(unit, mem);
  11923     rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, &idx, vent, vent_old, 0);
  11924     if(rv == SOC_E_NONE) {
  11925          BCM_IF_ERROR_RETURN(
  11926               _bcm_tr_vlan_translate_entry_update (unit, vent, vent_old));
  11927          rv = soc_mem_write(unit, mem,
  11928                                        MEM_BLOCK_ALL, idx, vent_old);
  11929         if (existing_updated != NULL) {
  11930             *existing_updated = 1;
  11931         }
  11932         soc_mem_unlock(unit, mem);
  11933         return BCM_E_EXISTS;
  11934     } else if (rv != SOC_E_NOT_FOUND) {
  11935         soc_mem_unlock(unit, mem);
  11936         return rv;
  11937     } 
  11938 
  11939     rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, vent);
  11940     soc_mem_unlock(unit, mem);
  11941     }
  11942     return rv;
  11943 }
  11944 
  11945 int
  11946 _bcm_tr_lltag_vlan_translate_vp_add(int unit,
  11947                                bcm_gport_t port,
  11948                                bcm_vlan_translate_key_t key_type,
  11949                                bcm_vlan_t lltag_vlan,
  11950                                bcm_vlan_t other_vlan,
  11951                                int vp, bcm_vlan_action_set_t *action)
  11952 {
  11953     int rv, gport_id;
  11954     vlan_xlate_entry_t vx_ent, vx_ent_old;
  11955     vlan_xlate_1_double_entry_t v1dent, v1dent_old;
  11956     bcm_module_t mod_out;
  11957     bcm_port_t port_out;
  11958     bcm_trunk_t trunk_id;
  11959     int idx;
  11960     int key_type_value;
  11961     uint32 vxlate_action_profile_idx;
  11962     uint32 vxlate_action_profile_idx_old;
  11963     soc_mem_t mem = VLAN_XLATEm;
  11964     soc_field_t vf = VALIDf;
  11965     void *vent = &vx_ent;
  11966     void *vent_old = &vx_ent_old;
  11967     uint32 ent_sz = sizeof(vx_ent);
  11968 
  11969     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
  11970         mem = VLAN_XLATE_1_DOUBLEm;
  11971         vf = BASE_VALID_0f; /* TD3TBD */
  11972         vent = &v1dent;
  11973         vent_old = &v1dent_old;
  11974         ent_sz = sizeof(v1dent);
  11975     }
  11976    
  11977     rv = BCM_E_NONE; 
  11978 
  11979     if (!soc_feature(unit, soc_feature_lltag)) {
  11980         return BCM_E_UNAVAIL;
  11981     }
  11982         
  11983     sal_memset(vent, 0, ent_sz);
  11984     switch (key_type) {
  11985         case bcmVlanTranslateKeyPortPonTunnel:
  11986             BCM_IF_ERROR_RETURN
  11987                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
  11988                        VLXLT_HASH_KEY_TYPE_LLVID,
  11989                        &key_type_value));
  11990             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
  11991             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
  11992                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
  11993                                         key_type_value);
  11994             }
  11995             soc_mem_field32_set(unit, mem, vent, LLTAG__LLVIDf, lltag_vlan);
  11996             break;
  11997         case bcmVlanTranslateKeyPortPonTunnelOuter:
  11998             BCM_IF_ERROR_RETURN
  11999                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
  12000                        VLXLT_HASH_KEY_TYPE_LLVID_OVID,
  12001                        &key_type_value));
  12002             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
  12003             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
  12004                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
  12005                                         key_type_value);
  12006             }
  12007             soc_mem_field32_set(unit, mem, vent, LLTAG__LLVIDf, lltag_vlan);
  12008             soc_mem_field32_set(unit, mem, vent, LLTAG__OVIDf, other_vlan);
  12009             break;
  12010         case bcmVlanTranslateKeyPortPonTunnelInner:
  12011             BCM_IF_ERROR_RETURN
  12012                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
  12013                        VLXLT_HASK_KEY_TYPE_LLVID_IVID,
  12014                        &key_type_value));
  12015             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
  12016             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
  12017                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
  12018                                         key_type_value);
  12019             }
  12020             soc_mem_field32_set(unit, mem, vent, LLTAG__LLVIDf, lltag_vlan);
  12021             soc_mem_field32_set(unit, mem, vent, LLTAG__IVIDf, other_vlan);
  12022             break;
  12023         default:
  12024             return BCM_E_PARAM;
  12025     }
  12026     BCM_IF_ERROR_RETURN
  12027         (_bcm_esw_gport_resolve(unit, port, &mod_out, &port_out, &trunk_id,
  12028                                 &gport_id));
  12029 
  12030     if (BCM_GPORT_IS_TRUNK(port)) {
  12031         soc_mem_field32_set(unit, mem, vent, Tf, 1);
  12032         soc_mem_field32_set(unit, mem, vent, TGIDf, trunk_id);
  12033     } else {
  12034         soc_mem_field32_set(unit, mem, vent, MODULE_IDf, mod_out);
  12035         soc_mem_field32_set(unit, mem, vent, PORT_NUMf, port_out);
  12036     }
  12037         
  12038     if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_VPf)) {
  12039         soc_mem_field32_set(unit, mem, vent, SOURCE_VPf, vp);
  12040     }
  12041 
  12042     if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) {
  12043         /* set default vlan_xlate key source_type as SGLP */
  12044         soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1);
  12045     }
  12046 
  12047     if (mem == VLAN_XLATEm) {
  12048         soc_mem_field32_set(unit, mem, vent, vf, 1);
  12049     } else {
  12050         soc_mem_field32_set(unit, mem, vent, vf, 3);
  12051         soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7);
  12052     }
  12053 
  12054     if (action) {
  12055         vxlate_action_profile_idx = 0;
  12056         BCM_IF_ERROR_RETURN(
  12057             _bcm_trx_vlan_action_verify(unit, action));
  12058         vxlate_action_profile_idx_old = 
  12059          soc_mem_field32_get(unit, mem, vent, TAG_ACTION_PROFILE_PTRf);
  12060         /* Add new tag action profile table ptr */
  12061         BCM_IF_ERROR_RETURN
  12062           (_bcm_trx_vlan_action_profile_entry_add(unit, action, 
  12063                                   &vxlate_action_profile_idx));
  12064         soc_mem_field32_set(unit, mem, vent, TAG_ACTION_PROFILE_PTRf,
  12065                                               vxlate_action_profile_idx);
  12066         /* Delete old tag action profile table ptr expect entry zero
  12067          * It contains initialize cache hardware ING_VLAN_TAG_ACTION_PROFILE
  12068          * and EGR_VLAN_TAG_ACTION_PROFILE tables in RAM.
  12069          * ING_VLAN profile contains PORT_TAB and VLAN_PROTOCOL_DATA
  12070          * EGR_VLAN profile contains all ports, sub ports and vlan subnets
  12071          */
  12072         if (vxlate_action_profile_idx_old != 0) {
  12073             BCM_IF_ERROR_RETURN
  12074               (_bcm_trx_vlan_action_profile_entry_delete(unit,
  12075                               vxlate_action_profile_idx_old));
  12076         }
  12077         /* Set new OVID and IVID from the 'action' specified */
  12078         soc_mem_field32_set(unit, mem, vent, NEW_OVIDf, action->new_outer_vlan);
  12079         soc_mem_field32_set(unit, mem, vent, NEW_IVIDf, action->new_inner_vlan);
  12080     }
  12081 
  12082     soc_mem_field32_set(unit, mem, vent, MPLS_ACTIONf, 0x1); /* SVP */
  12083     soc_mem_field32_set(unit, mem, vent, DISABLE_VLAN_CHECKSf, 1);
  12084     if (SOC_MEM_FIELD_VALID(unit, mem, VLAN_ACTION_VALIDf)) {
  12085         soc_mem_field32_set(unit, mem, vent, VLAN_ACTION_VALIDf, 1);
  12086     }
  12087 
  12088     /* look up existing entry */
  12089     soc_mem_lock(unit, mem);
  12090     rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, &idx, vent, vent_old, 0);
  12091     if(rv == SOC_E_NONE) {
  12092          BCM_IF_ERROR_RETURN(
  12093               _bcm_tr_vlan_translate_entry_update (unit, vent, vent_old));
  12094          rv = soc_mem_write(unit, mem,
  12095                                        MEM_BLOCK_ALL, idx, vent_old);
  12096         soc_mem_unlock(unit, mem);
  12097         return BCM_E_EXISTS;
  12098     } else if (rv != SOC_E_NOT_FOUND) {
  12099         soc_mem_unlock(unit, mem);
  12100         return rv;
  12101     } 
  12102 
  12103     rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, vent);
  12104     soc_mem_unlock(unit, mem);
  12105    
  12106     return rv;
  12107 }
  12108 
  12109 
  12110 int
  12111 _bcm_tr_vlan_translate_vp_delete(int unit,
  12112                                   bcm_gport_t port,
  12113                                   bcm_vlan_translate_key_t key_type,
  12114                                   bcm_vlan_t outer_vlan,
  12115                                   bcm_vlan_t inner_vlan,
  12116                                   int vp)
  12117 {
  12118     int rv, gport_id;
  12119     vlan_xlate_entry_t vx_ent;
  12120     vlan_xlate_1_double_entry_t vx1d_ent;
  12121     bcm_module_t mod_out;
  12122     bcm_port_t port_out;
  12123     bcm_trunk_t trunk_id;
  12124     int key_type_value;
  12125 
  12126     soc_mem_t mem = VLAN_XLATEm;
  12127     soc_field_t vf = VALIDf;
  12128     void *vent = &vx_ent;
  12129     uint32 ent_sz = sizeof(vx_ent);
  12130 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_APACHE_SUPPORT) || \
  12131     defined(BCM_GREYHOUND2_SUPPORT)
  12132     vlan_xlate_entry_t current_vent;
  12133     bcm_policer_t current_policer = 0;
  12134     int idx;
  12135 #endif /* BCM_KATANA_SUPPORT || BCM_APACHE_SUPPORT ||
  12136           BCM_GREYHOUND2_SUPPORT */
  12137  
  12138     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
  12139         mem = VLAN_XLATE_1_DOUBLEm;
  12140         vf = BASE_VALID_0f; /* TD3TBD */
  12141         vent = &vx1d_ent;
  12142         ent_sz = sizeof(vx1d_ent);
  12143     }
  12144 
  12145     sal_memset(vent, 0, ent_sz);
  12146     switch (key_type) {
  12147         case bcmVlanTranslateKeyPortOuter:
  12148             BCM_IF_ERROR_RETURN
  12149                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
  12150                        VLXLT_HASH_KEY_TYPE_OVID,
  12151                        &key_type_value));
  12152             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
  12153             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
  12154                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
  12155                                         key_type_value);
  12156             }
  12157             soc_mem_field32_set(unit, mem, vent, OVIDf, outer_vlan);
  12158             break;
  12159         case bcmVlanTranslateKeyPortInner:
  12160             BCM_IF_ERROR_RETURN
  12161                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
  12162                        VLXLT_HASH_KEY_TYPE_IVID,
  12163                        &key_type_value));
  12164             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
  12165             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
  12166                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
  12167                                         key_type_value);
  12168             }
  12169             soc_mem_field32_set(unit, mem, vent, IVIDf, inner_vlan);
  12170             break;
  12171         case bcmVlanTranslateKeyPortDouble:
  12172             BCM_IF_ERROR_RETURN
  12173                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
  12174                        VLXLT_HASH_KEY_TYPE_IVID_OVID,
  12175                        &key_type_value));
  12176             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
  12177             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
  12178                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
  12179                                         key_type_value);
  12180             }
  12181             soc_mem_field32_set(unit, mem, vent, OVIDf, outer_vlan);
  12182             soc_mem_field32_set(unit, mem, vent, IVIDf, inner_vlan);
  12183             break;
  12184        case bcmVlanTranslateKeyPortOuterPri:
  12185             BCM_IF_ERROR_RETURN
  12186                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
  12187                        VLXLT_HASH_KEY_TYPE_PRI_CFI,
  12188                        &key_type_value));
  12189             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
  12190             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
  12191                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
  12192                                         key_type_value);
  12193             }
  12194             soc_mem_field32_set(unit, mem, vent, OTAGf, outer_vlan);
  12195             break;
  12196         case bcmVlanTranslateKeyPortOuterTag:
  12197             /* allow 16 bit VLAN id */
  12198             BCM_IF_ERROR_RETURN
  12199                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
  12200                        VLXLT_HASH_KEY_TYPE_OTAG,
  12201                        &key_type_value));
  12202             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
  12203             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
  12204                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
  12205                                         key_type_value);
  12206             }
  12207             soc_mem_field32_set(unit, mem, vent, OTAGf, outer_vlan);
  12208             break;
  12209         default:
  12210             return BCM_E_PARAM;
  12211     }
  12212     BCM_IF_ERROR_RETURN
  12213         (_bcm_esw_gport_resolve(unit, port, &mod_out, &port_out, &trunk_id,
  12214                                 &gport_id));
  12215 
  12216     if (BCM_GPORT_IS_TRUNK(port)) {
  12217         soc_mem_field32_set(unit, mem, vent, Tf, 1);
  12218         soc_mem_field32_set(unit, mem, vent, TGIDf, trunk_id);
  12219     } else {
  12220         soc_mem_field32_set(unit, mem, vent, MODULE_IDf, mod_out);
  12221         soc_mem_field32_set(unit, mem, vent, PORT_NUMf, port_out);
  12222     }
  12223 
  12224     if (mem == VLAN_XLATEm) {
  12225         soc_mem_field32_set(unit, mem, vent, vf, 1);
  12226     } else {
  12227         soc_mem_field32_set(unit, mem, vent, vf, 3);
  12228         soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7);
  12229     }
  12230 
  12231     if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) {
  12232         /* set default vlan_xlate key source_type as SGLP */
  12233         soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1);
  12234     }
  12235 
  12236 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_APACHE_SUPPORT) || \
  12237     defined(BCM_GREYHOUND2_SUPPORT)
  12238     if (soc_feature(unit, soc_feature_global_meter) &&
  12239         (SOC_IS_KATANAX(unit) || SOC_IS_APACHE(unit) ||
  12240          SOC_IS_GREYHOUND2(unit))) {
  12241         rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &idx, vent, &current_vent, 0);
  12242         if (rv == BCM_E_NONE) {
  12243             rv = _bcm_esw_get_policer_from_table(unit, mem, 0, &current_vent,
  12244                                                         &current_policer, 1);
  12245             if (current_policer) {
  12246                 rv = _bcm_esw_policer_decrement_ref_count(unit,
  12247                                                         current_policer);
  12248                 BCM_IF_ERROR_RETURN(rv);
  12249             }
  12250         }
  12251     }
  12252 #endif /* BCM_KATANA_SUPPORT || BCM_APACHE_SUPPORT ||
  12253           BCM_GREYHOUND2_SUPPORT */
  12254 
  12255     soc_mem_lock(unit, mem);
  12256     rv = soc_mem_delete(unit, mem, MEM_BLOCK_ANY, vent);
  12257     soc_mem_unlock(unit, mem);
  12258 
  12259 #if defined(BCM_TRIUMPH3_SUPPORT)
  12260     if (SOC_IS_TRIUMPH3(unit)) {
  12261         vlan_xlate_extd_entry_t vxent;
  12262 
  12263         if (rv == BCM_E_NOT_FOUND) { /* serarch for extend table */
  12264             sal_memset(&vxent, 0, sizeof(vxent));
  12265             BCM_IF_ERROR_RETURN
  12266                 (_bcm_tr3_vxlate2vxlate_extd(unit,vent,&vxent));
  12267             soc_mem_lock(unit, VLAN_XLATE_EXTDm);
  12268             rv = soc_mem_delete(unit, VLAN_XLATE_EXTDm, MEM_BLOCK_ANY, &vxent);  
  12269             soc_mem_unlock(unit, VLAN_XLATE_EXTDm);
  12270             return rv;
  12271         } 
  12272     }
  12273 #endif
  12274     return rv;
  12275 }
  12276 
  12277 int
  12278 _bcm_tr_lltag_vlan_translate_vp_delete(int unit,
  12279                                   bcm_gport_t port,
  12280                                   bcm_vlan_translate_key_t key_type,
  12281                                   bcm_vlan_t lltag_vlan,
  12282                                   bcm_vlan_t other_vlan,
  12283                                   int vp)
  12284 {
  12285     int rv, gport_id;
  12286     vlan_xlate_entry_t vx_ent;
  12287     vlan_xlate_1_double_entry_t vx1d_ent;
  12288     bcm_module_t mod_out;
  12289     bcm_port_t port_out;
  12290     bcm_trunk_t trunk_id;
  12291     int key_type_value;
  12292 
  12293     soc_mem_t mem = VLAN_XLATEm;
  12294     soc_field_t vf = VALIDf;
  12295     void *vent = &vx_ent;
  12296     uint32 ent_sz = sizeof(vx_ent);
  12297 
  12298     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
  12299         mem = VLAN_XLATE_1_DOUBLEm;
  12300         vf = BASE_VALID_0f; /* TD3TBD */
  12301         vent = &vx1d_ent;
  12302         ent_sz = sizeof(vx1d_ent);
  12303     }
  12304 
  12305     if (!soc_feature(unit, soc_feature_lltag)) {
  12306         return BCM_E_UNAVAIL;
  12307     }
  12308     
  12309     sal_memset(vent, 0, ent_sz);
  12310     switch (key_type) {
  12311         case bcmVlanTranslateKeyPortPonTunnel:
  12312             BCM_IF_ERROR_RETURN
  12313                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
  12314                        VLXLT_HASH_KEY_TYPE_LLVID,
  12315                        &key_type_value));
  12316             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
  12317             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
  12318                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
  12319                                         key_type_value);
  12320             }
  12321             soc_mem_field32_set(unit, mem, vent, LLTAG__LLVIDf, lltag_vlan);
  12322             break;
  12323         case bcmVlanTranslateKeyPortPonTunnelOuter:
  12324             BCM_IF_ERROR_RETURN
  12325                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
  12326                        VLXLT_HASH_KEY_TYPE_LLVID_OVID,
  12327                        &key_type_value));
  12328             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
  12329             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
  12330                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
  12331                                         key_type_value);
  12332             }
  12333             soc_mem_field32_set(unit, mem, vent, LLTAG__LLVIDf, lltag_vlan);
  12334             soc_mem_field32_set(unit, mem, vent, LLTAG__OVIDf, other_vlan);
  12335             break;
  12336         case bcmVlanTranslateKeyPortPonTunnelInner:
  12337             BCM_IF_ERROR_RETURN
  12338                 (_bcm_esw_vlan_xlate_key_type_value_get(unit,
  12339                        VLXLT_HASK_KEY_TYPE_LLVID_IVID,
  12340                        &key_type_value));
  12341             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, key_type_value);
  12342             if (soc_mem_field_valid(unit, mem, DATA_TYPEf)) {
  12343                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
  12344                                         key_type_value);
  12345             }
  12346             soc_mem_field32_set(unit, mem, vent, LLTAG__LLVIDf, lltag_vlan);
  12347             soc_mem_field32_set(unit, mem, vent, LLTAG__OVIDf, other_vlan);
  12348             break;
  12349         default:
  12350             return BCM_E_PARAM;
  12351     }
  12352     BCM_IF_ERROR_RETURN
  12353         (_bcm_esw_gport_resolve(unit, port, &mod_out, &port_out, &trunk_id,
  12354                                 &gport_id));
  12355 
  12356     if (BCM_GPORT_IS_TRUNK(port)) {
  12357         soc_mem_field32_set(unit, mem, vent, Tf, 1);
  12358         soc_mem_field32_set(unit, mem, vent, TGIDf, trunk_id);
  12359     } else {
  12360         soc_mem_field32_set(unit, mem, vent, MODULE_IDf, mod_out);
  12361         soc_mem_field32_set(unit, mem, vent, PORT_NUMf, port_out);
  12362     }
  12363 
  12364     if (mem == VLAN_XLATEm) {
  12365         soc_mem_field32_set(unit, mem, vent, vf, 1);
  12366     } else {
  12367         soc_mem_field32_set(unit, mem, vent, vf, 3);
  12368         soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7);
  12369     }
  12370 
  12371     if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) {
  12372         /* set default vlan_xlate key source_type as SGLP */
  12373         soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1);
  12374     }
  12375 
  12376     soc_mem_lock(unit, mem);
  12377     rv = soc_mem_delete(unit, mem, MEM_BLOCK_ANY, vent);
  12378     soc_mem_unlock(unit, mem);
  12379 
  12380     return rv;
  12381 }
  12382 
  12383 
  12384 #ifdef BCM_TRIUMPH2_SUPPORT
  12385 #define _BCM_OUTER_VLAN_RANGE_TYPE 0
  12386 #define _BCM_INNER_VLAN_RANGE_TYPE 1
  12387 
  12388 int
  12389 _bcm_tr2_vlan_tranlate_range_data_insert(bcm_vlan_t vlan_low, bcm_vlan_t vlan_high, 
  12390                                          bcm_vlan_t *min_vlan, bcm_vlan_t *max_vlan)
  12391 {
  12392     int i = 0;
  12393     /* Find the first unused min/max range. Unused ranges are
  12394      * identified by { min == 1, max == 0 }
  12395      */
  12396     for (i = 0 ; i < 8 ; i++) {
  12397         if ((min_vlan[i] == 1) && (max_vlan[i] == 0)) {
  12398             break;
  12399         } else if (min_vlan[i] == vlan_low) {
  12400             /* Can't have multiple ranges with the same min */
  12401             return BCM_E_EXISTS;
  12402         }
  12403     }
  12404     if (i == 8) {
  12405         /* All ranges are taken */
  12406         return BCM_E_FULL;
  12407     }
  12408 
  12409     /* Insert the new range into the table entry sorted by min VID */
  12410     for ( ; i > 0 ; i--) {
  12411         if (min_vlan[i - 1] > vlan_low) {
  12412             /* Move existing min/max down */
  12413             min_vlan[i] = min_vlan[i - 1];
  12414             max_vlan[i] = max_vlan[i - 1];
  12415         } else {
  12416             break;
  12417         }
  12418     }
  12419     min_vlan[i] = vlan_low;
  12420     max_vlan[i] = vlan_high;
  12421     return BCM_E_NONE;
  12422 }
  12423 
  12424 int 
  12425 _bcm_tr2_vlan_tranlate_range_data_delete(bcm_vlan_t vlan_low, bcm_vlan_t vlan_high, 
  12426                                          bcm_vlan_t *min_vlan, bcm_vlan_t *max_vlan)
  12427 {
  12428     int i = 0;
  12429     /* Find the min/max range. */
  12430     for (i = 0; i < 8; i++) {
  12431         if ((min_vlan[i] == vlan_low) && (max_vlan[i] == vlan_high)) {
  12432             break;
  12433         }
  12434     }
  12435     if (i == 8) {
  12436         return BCM_E_NOT_FOUND;
  12437     }
  12438 
  12439     /* Remove the range from the table entry and fill in the gap */
  12440     for (; i < 7; i++) {
  12441         /* Move existing min/max UP */
  12442         min_vlan[i] = min_vlan[i + 1];
  12443         max_vlan[i] = max_vlan[i + 1];
  12444     }
  12445     /* Mark last min/max range as unused. Unused ranges are
  12446      * identified by { min == 1, max == 0 }
  12447      */
  12448     min_vlan[i] = 1;
  12449     max_vlan[i] = 0;
  12450     return BCM_E_NONE;
  12451 }
  12452 
  12453 
  12454 int 
  12455 _bcm_tr2_port_vlan_translate_range_profile_update(int unit, bcm_vlan_t *min_vlan, bcm_vlan_t *max_vlan, 
  12456                                                   bcm_module_t module, bcm_port_t port, int vt_range_type, 
  12457                                                   uint32 *new_idx)
  12458 {
  12459     int rv = BCM_E_NONE;
  12460     uint32 new_idx_local;
  12461     int stm_idx;
  12462         rv = _bcm_trx_vlan_range_profile_entry_add(unit, min_vlan, max_vlan,
  12463             &new_idx_local);
  12464         if (BCM_FAILURE(rv)) {
  12465         return rv;
  12466         }
  12467     rv = _bcm_esw_src_mod_port_table_index_get(unit, module, port, &stm_idx);
  12468         if (BCM_SUCCESS(rv)) {
  12469             soc_field_t field;
  12470             if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
  12471                     OUTER_VLAN_RANGE_IDXf) & (vt_range_type == _BCM_OUTER_VLAN_RANGE_TYPE)) {
  12472                 field = OUTER_VLAN_RANGE_IDXf;
  12473         } else if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
  12474                     INNER_VLAN_RANGE_IDXf) & (vt_range_type == _BCM_INNER_VLAN_RANGE_TYPE)) {
  12475             field = INNER_VLAN_RANGE_IDXf;
  12476             } else {
  12477                 field = VLAN_RANGE_IDXf;
  12478             }
  12479             rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, stm_idx,
  12480                 field, new_idx_local);
  12481         }
  12482         if (BCM_FAILURE(rv)) {
  12483         _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx_local);
  12484         return rv;
  12485     }
  12486     *new_idx = new_idx_local;
  12487     return rv;
  12488 }
  12489 
  12490 int
  12491 _bcm_tr2_vlan_translate_range_vp_add(int unit,
  12492                                      bcm_gport_t port,
  12493                                      bcm_vlan_t outer_vlan_low,
  12494                                      bcm_vlan_t outer_vlan_high,
  12495                                      bcm_vlan_t inner_vlan_low,
  12496                                      bcm_vlan_t inner_vlan_high,                                     
  12497                                      int vp,
  12498                                      bcm_vlan_action_set_t *action)
  12499 {
  12500     int i, key_type = 0, rv, gport_id, old_idx = -1, old_idx_inner = -1, stm_idx = 0;
  12501     uint32 new_idx = -1, new_idx_inner = -1;
  12502     source_trunk_map_table_entry_t stm_entry;
  12503     bcm_module_t mod_out;
  12504     bcm_port_t   port_out;
  12505     bcm_trunk_t  trunk_id, tid;
  12506     bcm_vlan_t min_vlan[8], max_vlan[8];
  12507     int port_count;
  12508     bcm_trunk_member_t *member_array = NULL;
  12509     bcm_module_t *mod_array = NULL;
  12510     bcm_port_t   *port_array = NULL;
  12511     int trunk128;
  12512     if (outer_vlan_low != BCM_VLAN_INVALID && 
  12513         inner_vlan_low != BCM_VLAN_INVALID) {
  12514         key_type = bcmVlanTranslateKeyPortDouble;
  12515     } else if (outer_vlan_low != BCM_VLAN_INVALID) {
  12516         key_type = bcmVlanTranslateKeyPortOuter;
  12517     } else if (inner_vlan_low != BCM_VLAN_INVALID) {
  12518         key_type = bcmVlanTranslateKeyPortInner;
  12519     } else {
  12520         return BCM_E_PARAM;
  12521     }
  12522 
  12523     BCM_IF_ERROR_RETURN
  12524         (_bcm_esw_gport_resolve(unit, port, &mod_out, &port_out, &trunk_id,
  12525                                 &gport_id));
  12526 
  12527     if (BCM_GPORT_IS_TRUNK(port)) {
  12528         if (BCM_TRUNK_INVALID == trunk_id) {
  12529             return BCM_E_PORT;
  12530         }
  12531 
  12532         BCM_IF_ERROR_RETURN
  12533             (bcm_esw_trunk_get(unit, trunk_id, NULL, 0, NULL, &port_count));
  12534 
  12535         member_array = sal_alloc(sizeof(bcm_trunk_member_t) * port_count,
  12536                 "trunk member array");
  12537         if (member_array == NULL) {
  12538             rv = BCM_E_MEMORY;
  12539             goto cleanup;
  12540         }
  12541         sal_memset(member_array, 0, sizeof(bcm_trunk_member_t) * port_count);
  12542 
  12543         rv = bcm_esw_trunk_get(unit, trunk_id, NULL, port_count,
  12544                 member_array, &port_count);
  12545         if (BCM_FAILURE(rv)) {
  12546             goto cleanup;
  12547         }
  12548 
  12549         mod_array = sal_alloc(sizeof(bcm_module_t) * port_count,
  12550                 "module ID array");
  12551         if (mod_array == NULL) {
  12552             rv = BCM_E_MEMORY;
  12553             goto cleanup;
  12554         }
  12555         sal_memset(mod_array, 0, sizeof(bcm_module_t) * port_count);
  12556 
  12557         port_array = sal_alloc(sizeof(bcm_port_t) * port_count,
  12558                 "port ID array");
  12559         if (port_array == NULL) {
  12560             rv = BCM_E_MEMORY;
  12561             goto cleanup;
  12562         }
  12563         sal_memset(port_array, 0, sizeof(bcm_port_t) * port_count);
  12564 
  12565         for (i = 0; i < port_count; i++) {
  12566             rv = _bcm_esw_gport_resolve(unit, member_array[i].gport,
  12567                     &mod_array[i], &port_array[i], &tid, &gport_id);
  12568             if (BCM_FAILURE(rv)) {
  12569                 goto cleanup;
  12570             }
  12571         }
  12572     } else {
  12573         if ((-1 == mod_out) || (-1 == port_out)) {
  12574             return BCM_E_PORT;
  12575         }
  12576 
  12577         port_count = 1;
  12578 
  12579         mod_array = sal_alloc(sizeof(bcm_module_t) * port_count,
  12580                 "module ID array");
  12581         if (mod_array == NULL) {
  12582             rv = BCM_E_MEMORY;
  12583             goto cleanup;
  12584         }
  12585         mod_array[0] = mod_out;
  12586 
  12587         port_array = sal_alloc(sizeof(bcm_port_t) * port_count,
  12588                 "port ID array");
  12589         if (port_array == NULL) {
  12590             rv = BCM_E_MEMORY;
  12591             goto cleanup;
  12592         }
  12593         port_array[0] = port_out;
  12594     }
  12595 
  12596     rv = _bcm_esw_src_mod_port_table_index_get(unit, mod_array[0],
  12597             port_array[0], &stm_idx);
  12598     if (BCM_FAILURE(rv)) {
  12599         goto cleanup;
  12600     }
  12601 
  12602     soc_mem_lock(unit, ING_VLAN_RANGEm);
  12603 
  12604     rv = READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, stm_idx, &stm_entry);
  12605     if (rv < 0) {
  12606         soc_mem_unlock(unit, ING_VLAN_RANGEm);
  12607         goto cleanup;
  12608     }
  12609     if (outer_vlan_low != BCM_VLAN_INVALID && outer_vlan_high != BCM_VLAN_INVALID) {
  12610         if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
  12611                     OUTER_VLAN_RANGE_IDXf)) {
  12612             old_idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm,
  12613                                       &stm_entry, OUTER_VLAN_RANGE_IDXf);
  12614         } else {
  12615             old_idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm,
  12616                                       &stm_entry, VLAN_RANGE_IDXf);
  12617         }
  12618 
  12619         /* Get the profile table entry for this port/trunk */
  12620         _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, max_vlan, old_idx);
  12621 
  12622         rv = _bcm_tr2_vlan_tranlate_range_data_insert(outer_vlan_low, outer_vlan_high, 
  12623                                                      min_vlan, max_vlan);
  12624         if (BCM_FAILURE(rv)) {
  12625             soc_mem_unlock(unit, ING_VLAN_RANGEm);
  12626             goto cleanup;
  12627         }
  12628         /* Adding the new profile table entry and update profile pointer */
  12629         for (i = 0; i < port_count; i++) {
  12630             rv = _bcm_tr2_port_vlan_translate_range_profile_update(unit, min_vlan, 
  12631                                                                    max_vlan, mod_array[i], 
  12632                                                                    port_array[i], 
  12633                                                                    _BCM_OUTER_VLAN_RANGE_TYPE, 
  12634                                                                    &new_idx);
  12635             if (BCM_FAILURE(rv)) {
  12636             soc_mem_unlock(unit, ING_VLAN_RANGEm);
  12637             goto cleanup;
  12638         }
  12639     }
  12640     }
  12641     if (inner_vlan_low != BCM_VLAN_INVALID && inner_vlan_high != BCM_VLAN_INVALID) {
  12642         if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
  12643                     INNER_VLAN_RANGE_IDXf)) {
  12644             old_idx_inner = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm,
  12645                                       &stm_entry, INNER_VLAN_RANGE_IDXf);
  12646         } else {
  12647             old_idx_inner = -1;
  12648         }
  12649         if (old_idx_inner >= 0 && inner_vlan_low != BCM_VLAN_INVALID && inner_vlan_high != BCM_VLAN_INVALID) {
  12650             /* Get the profile table entry for this port/trunk */
  12651             _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, max_vlan, old_idx_inner);
  12652 
  12653             rv =_bcm_tr2_vlan_tranlate_range_data_insert(inner_vlan_low, inner_vlan_high, 
  12654                                                          min_vlan, max_vlan);
  12655             if (BCM_FAILURE(rv)) {
  12656                 soc_mem_unlock(unit, ING_VLAN_RANGEm);
  12657                 goto cleanup;
  12658             }
  12659             /* Adding the new profile table entry and update profile pointer */
  12660             for (i = 0; i < port_count; i++) {
  12661                 rv = _bcm_tr2_port_vlan_translate_range_profile_update(unit, min_vlan, 
  12662                                                                        max_vlan, mod_array[i], 
  12663                                                                        port_array[i], 
  12664                                                                        _BCM_INNER_VLAN_RANGE_TYPE, 
  12665                                                                        &new_idx_inner);
  12666                 if (BCM_FAILURE(rv)) {
  12667                     soc_mem_unlock(unit, ING_VLAN_RANGEm);
  12668                     goto cleanup;
  12669                 }
  12670             }
  12671         }
  12672     }
  12673     if (BCM_GPORT_IS_TRUNK(port)) {
  12674         if (SOC_MEM_FIELD_VALID(unit, TRUNK32_PORT_TABLEm, VLAN_RANGE_IDXf)) {
  12675             trunk128 = soc_property_get(unit, spn_TRUNK_EXTEND, 1);
  12676             if (!trunk128) {
  12677                 rv = _bcm_trx_vlan_range_profile_entry_add(unit, min_vlan, max_vlan,
  12678                         &new_idx);
  12679                 if (BCM_FAILURE(rv)) {
  12680                     soc_mem_unlock(unit, ING_VLAN_RANGEm);
  12681                     goto cleanup;
  12682                 }
  12683                 rv = soc_mem_field32_modify(unit, TRUNK32_PORT_TABLEm, trunk_id, 
  12684                         VLAN_RANGE_IDXf, new_idx);
  12685                 if (BCM_FAILURE(rv)) {
  12686                     _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx);
  12687                     soc_mem_unlock(unit, ING_VLAN_RANGEm);
  12688                     goto cleanup;
  12689                 }
  12690                 _bcm_trx_vlan_range_profile_entry_delete(unit, old_idx);
  12691             }
  12692         }
  12693     }
  12694 
  12695     /* Add an entry in the vlan translate table for the low VID */
  12696     rv = _bcm_tr_vlan_translate_vp_add(unit, port, key_type, 
  12697                                         outer_vlan_low, inner_vlan_low,
  12698                                         vp, action, NULL);
  12699     if (rv != BCM_E_NONE) {
  12700         for (i = 0; i < port_count; i++) {
  12701             /* coverity[unsigned_compare] */
  12702             if (new_idx >= 0) {
  12703             _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx);
  12704         }
  12705             /* coverity[unsigned_compare] */
  12706             if (new_idx_inner >= 0) {
  12707                 _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx_inner);
  12708             }
  12709         }
  12710         soc_mem_unlock(unit, ING_VLAN_RANGEm);
  12711         goto cleanup;
  12712     }
  12713 
  12714     /* Delete the old profile entry */
  12715     for (i = 0; i < port_count; i++) {
  12716         if (new_idx >= 0) {
  12717         _bcm_trx_vlan_range_profile_entry_delete(unit, old_idx);
  12718     }
  12719         if (new_idx_inner >= 0) {
  12720             _bcm_trx_vlan_range_profile_entry_delete(unit, old_idx_inner);
  12721         }
  12722     }
  12723     soc_mem_unlock(unit, ING_VLAN_RANGEm);
  12724 
  12725 cleanup:
  12726     if (NULL != member_array) {
  12727         sal_free(member_array);
  12728     }
  12729     if (NULL != mod_array) {
  12730         sal_free(mod_array);
  12731     }
  12732     if (NULL != port_array) {
  12733         sal_free(port_array);
  12734     }
  12735 
  12736     return rv;
  12737 }
  12738 
  12739 int
  12740 _bcm_tr2_vlan_translate_range_vp_delete(int unit,
  12741                                         bcm_gport_t port,
  12742                                         bcm_vlan_t outer_vlan_low,
  12743                                         bcm_vlan_t outer_vlan_high,
  12744                                         bcm_vlan_t inner_vlan_low,
  12745                                         bcm_vlan_t inner_vlan_high,                                        
  12746                                         int vp)
  12747 {
  12748     int i, key_type = 0, rv, gport_id, old_idx = -1, old_idx_inner= -1, stm_idx = 0;
  12749     uint32 new_idx = 0, new_idx_inner = 0;
  12750     source_trunk_map_table_entry_t stm_entry;
  12751     bcm_module_t mod_out;
  12752     bcm_port_t   port_out;
  12753     bcm_trunk_t  trunk_id, tid;
  12754     bcm_vlan_t min_vlan[8], max_vlan[8];
  12755     int port_count;
  12756     bcm_trunk_member_t *member_array = NULL;
  12757     bcm_module_t *mod_array = NULL;
  12758     bcm_port_t   *port_array = NULL;
  12759     int trunk128;
  12760 
  12761     if (outer_vlan_low != BCM_VLAN_INVALID && 
  12762         inner_vlan_low != BCM_VLAN_INVALID) {
  12763         key_type = bcmVlanTranslateKeyPortDouble;
  12764     } else if (outer_vlan_low != BCM_VLAN_INVALID) {
  12765         key_type = bcmVlanTranslateKeyPortOuter;
  12766     } else if (inner_vlan_low != BCM_VLAN_INVALID) {
  12767         key_type = bcmVlanTranslateKeyPortInner;
  12768     } else {
  12769         return BCM_E_PARAM;
  12770     }
  12771 
  12772     BCM_IF_ERROR_RETURN
  12773         (_bcm_esw_gport_resolve(unit, port, &mod_out, &port_out, &trunk_id,
  12774                                 &gport_id));
  12775 
  12776     if (BCM_GPORT_IS_TRUNK(port)) {
  12777        if (BCM_TRUNK_INVALID == trunk_id) {
  12778             return BCM_E_PORT;
  12779         }
  12780 
  12781         BCM_IF_ERROR_RETURN
  12782             (bcm_esw_trunk_get(unit, trunk_id, NULL, 0, NULL, &port_count));
  12783 
  12784         member_array = sal_alloc(sizeof(bcm_trunk_member_t) * port_count,
  12785                 "trunk member array");
  12786         if (member_array == NULL) {
  12787             rv = BCM_E_MEMORY;
  12788             goto cleanup;
  12789         }
  12790         sal_memset(member_array, 0, sizeof(bcm_trunk_member_t) * port_count);
  12791 
  12792         rv = bcm_esw_trunk_get(unit, trunk_id, NULL, port_count,
  12793                 member_array, &port_count);
  12794         if (BCM_FAILURE(rv)) {
  12795             goto cleanup;
  12796         }
  12797 
  12798         mod_array = sal_alloc(sizeof(bcm_module_t) * port_count,
  12799                 "module ID array");
  12800         if (mod_array == NULL) {
  12801             rv = BCM_E_MEMORY;
  12802             goto cleanup;
  12803         }
  12804         sal_memset(mod_array, 0, sizeof(bcm_module_t) * port_count);
  12805 
  12806         port_array = sal_alloc(sizeof(bcm_port_t) * port_count,
  12807                 "port ID array");
  12808         if (port_array == NULL) {
  12809             rv = BCM_E_MEMORY;
  12810             goto cleanup;
  12811         }
  12812         sal_memset(port_array, 0, sizeof(bcm_port_t) * port_count);
  12813 
  12814         for (i = 0; i < port_count; i++) {
  12815             rv = _bcm_esw_gport_resolve(unit, member_array[i].gport,
  12816                     &mod_array[i], &port_array[i], &tid, &gport_id);
  12817             if (BCM_FAILURE(rv)) {
  12818                 goto cleanup;
  12819             }
  12820         }
  12821     } else {
  12822         if ((-1 == mod_out) || (-1 == port_out)) {
  12823             return BCM_E_PORT;
  12824         }
  12825 
  12826         port_count = 1;
  12827 
  12828         mod_array = sal_alloc(sizeof(bcm_module_t) * port_count,
  12829                 "module ID array");
  12830         if (mod_array == NULL) {
  12831             rv = BCM_E_MEMORY;
  12832             goto cleanup;
  12833         }
  12834         mod_array[0] = mod_out;
  12835 
  12836         port_array = sal_alloc(sizeof(bcm_port_t) * port_count,
  12837                 "port ID array");
  12838         if (port_array == NULL) {
  12839             rv = BCM_E_MEMORY;
  12840             goto cleanup;
  12841         }
  12842         port_array[0] = port_out;
  12843     }
  12844 
  12845     rv = _bcm_esw_src_mod_port_table_index_get(unit, mod_array[0],
  12846             port_array[0], &stm_idx);
  12847     if (BCM_FAILURE(rv)) {
  12848         goto cleanup;
  12849     }
  12850 
  12851     soc_mem_lock(unit, ING_VLAN_RANGEm);
  12852     rv = READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, stm_idx, &stm_entry);
  12853     if (rv < 0) {
  12854         soc_mem_unlock(unit, ING_VLAN_RANGEm);
  12855         goto cleanup;
  12856     }
  12857     if (outer_vlan_low != BCM_VLAN_INVALID && outer_vlan_high != BCM_VLAN_INVALID) {
  12858     if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
  12859                 OUTER_VLAN_RANGE_IDXf)) {
  12860             old_idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm,
  12861                                           &stm_entry, OUTER_VLAN_RANGE_IDXf);
  12862     } else {
  12863             old_idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm,
  12864                                           &stm_entry, VLAN_RANGE_IDXf);
  12865     }
  12866 
  12867     /* Get the profile table entry for this port/trunk */
  12868     _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, max_vlan, old_idx);
  12869 
  12870         rv = _bcm_tr2_vlan_tranlate_range_data_delete(outer_vlan_low, outer_vlan_high, 
  12871                                                      min_vlan, max_vlan);
  12872         if (BCM_FAILURE(rv)) {
  12873         soc_mem_unlock(unit, ING_VLAN_RANGEm);
  12874         goto cleanup;
  12875     }
  12876     /* Adding the new profile table entry and update profile pointer */
  12877     for (i = 0; i < port_count; i++) {
  12878             rv = _bcm_tr2_port_vlan_translate_range_profile_update(unit, min_vlan, 
  12879                                                                    max_vlan, mod_array[i], 
  12880                                                                    port_array[i], 
  12881                                                                    _BCM_OUTER_VLAN_RANGE_TYPE, 
  12882                 &new_idx);
  12883         if (BCM_FAILURE(rv)) {
  12884             soc_mem_unlock(unit, ING_VLAN_RANGEm);
  12885             goto cleanup;
  12886         }
  12887         }
  12888     }
  12889     if (inner_vlan_low != BCM_VLAN_INVALID && inner_vlan_high != BCM_VLAN_INVALID) {
  12890             if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
  12891                     INNER_VLAN_RANGE_IDXf)) {
  12892             old_idx_inner = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm,
  12893                                       &stm_entry, INNER_VLAN_RANGE_IDXf);
  12894             } else {
  12895             old_idx_inner = -1;
  12896             }
  12897         if (old_idx_inner >= 0 && inner_vlan_low != BCM_VLAN_INVALID && inner_vlan_high != BCM_VLAN_INVALID) {
  12898             /* Get the profile table entry for this port/trunk */
  12899             _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, max_vlan, old_idx_inner);
  12900 
  12901             rv =_bcm_tr2_vlan_tranlate_range_data_delete(inner_vlan_low, inner_vlan_high, 
  12902                                                          min_vlan, max_vlan);
  12903             if (BCM_FAILURE(rv)) {
  12904                 soc_mem_unlock(unit, ING_VLAN_RANGEm);
  12905                 goto cleanup;
  12906         }
  12907             /* Adding the new profile table entry and update profile pointer */
  12908             for (i = 0; i < port_count; i++) {
  12909                 rv = _bcm_tr2_port_vlan_translate_range_profile_update(unit, min_vlan, 
  12910                                                                        max_vlan, mod_array[i], 
  12911                                                                        port_array[i], 
  12912                                                                        _BCM_INNER_VLAN_RANGE_TYPE, 
  12913                                                                        &new_idx_inner);
  12914         if (BCM_FAILURE(rv)) {
  12915             soc_mem_unlock(unit, ING_VLAN_RANGEm);
  12916             goto cleanup;
  12917         }
  12918     }
  12919         }
  12920     }
  12921 
  12922     if (BCM_GPORT_IS_TRUNK(port)) {
  12923         if (SOC_MEM_FIELD_VALID(unit, TRUNK32_PORT_TABLEm, VLAN_RANGE_IDXf)) {
  12924             trunk128 = soc_property_get(unit, spn_TRUNK_EXTEND, 1);
  12925             if (!trunk128) {
  12926                 rv = _bcm_trx_vlan_range_profile_entry_add(unit, min_vlan, max_vlan,
  12927                         &new_idx);
  12928                 if (BCM_FAILURE(rv)) {
  12929                     soc_mem_unlock(unit, ING_VLAN_RANGEm);
  12930                     goto cleanup;
  12931                 }
  12932                 rv = soc_mem_field32_modify(unit, TRUNK32_PORT_TABLEm, trunk_id, 
  12933                         VLAN_RANGE_IDXf, new_idx);
  12934                 if (BCM_FAILURE(rv)) {
  12935                     _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx);
  12936                     soc_mem_unlock(unit, ING_VLAN_RANGEm);
  12937                     goto cleanup;
  12938                 }
  12939                 _bcm_trx_vlan_range_profile_entry_delete(unit, old_idx);
  12940             }
  12941         }
  12942     }
  12943 
  12944     /* Delete the entry from the vlan translate table for the low VID */
  12945     rv = _bcm_tr_vlan_translate_vp_delete(unit, port, key_type, 
  12946                                            outer_vlan_low, inner_vlan_low, vp);
  12947     if (rv != BCM_E_NONE) {
  12948         for (i = 0; i < port_count; i++) {
  12949             /* coverity[unsigned_compare] */
  12950             if (new_idx >= 0) {
  12951             _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx);
  12952         }
  12953             /* coverity[unsigned_compare] */
  12954             if (new_idx_inner >= 0) {
  12955                 _bcm_trx_vlan_range_profile_entry_delete(unit, new_idx_inner);
  12956             }
  12957         }
  12958         soc_mem_unlock(unit, ING_VLAN_RANGEm);
  12959         goto cleanup;
  12960     }
  12961 
  12962     /* Delete the old profile entry */
  12963     for (i = 0; i < port_count; i++) {
  12964         /* coverity[unsigned_compare] */
  12965         if (new_idx >= 0) {
  12966         _bcm_trx_vlan_range_profile_entry_delete(unit, old_idx);
  12967     }
  12968         /* coverity[unsigned_compare] */
  12969         if (new_idx_inner >= 0) {
  12970             _bcm_trx_vlan_range_profile_entry_delete(unit, old_idx_inner);
  12971         }
  12972     }
  12973     soc_mem_unlock(unit, ING_VLAN_RANGEm);
  12974 
  12975 cleanup:
  12976     if (NULL != member_array) {
  12977         sal_free(member_array);
  12978     }
  12979     if (NULL != mod_array) {
  12980         sal_free(mod_array);
  12981     }
  12982     if (NULL != port_array) {
  12983         sal_free(port_array);
  12984     }
  12985 
  12986     return rv;
  12987 }
  12988 #endif
  12989 
  12990 /*
  12991  * Function:
  12992  *     _bcm_trx_system_reserved_vlan_ing_set
  12993  * Purpose:
  12994  *     Set ingress system reserved VLAN
  12995  * Parameters:
  12996  *     unit  - Device unit number
  12997  *     flags - Operation flags
  12998  *     vlan  - VLAN
  12999  * Returns:
  13000  *     BCM_E_XXX
  13001  */
  13002 int
  13003 _bcm_trx_system_reserved_vlan_ing_set(int unit, int arg)
  13004 {
  13005     uint32 rval;
  13006     int rv;
  13007     int valid = (arg != BCM_VLAN_INVALID);
  13008     int vid = valid ? arg : 0;
  13009 
  13010     rval = 0;
  13011     soc_reg_field_set(unit, ING_SYS_RSVD_VIDr, &rval, VALIDf, valid);
  13012     soc_reg_field_set(unit, ING_SYS_RSVD_VIDr, &rval, VIDf, vid);
  13013     rv = WRITE_ING_SYS_RSVD_VIDr(unit, rval);
  13014 
  13015     return rv;
  13016 }
  13017 
  13018 /*
  13019  * Function:
  13020  *     _bcm_trx_system_reserved_vlan_egr_set
  13021  * Purpose:
  13022  *     Set egress system reserved VLAN
  13023  * Parameters:
  13024  *     unit  - Device unit number
  13025  *     flags - Operation flags
  13026  *     vlan  - VLAN
  13027  * Returns:
  13028  *     BCM_E_XXX
  13029  */
  13030 int
  13031 _bcm_trx_system_reserved_vlan_egr_set(int unit, int arg)
  13032 {
  13033     uint32 rval;
  13034     int rv;
  13035     int vid = (arg != BCM_VLAN_INVALID) ? arg : 0;
  13036 
  13037     rval = 0;
  13038     soc_reg_field_set(unit, EGR_SYS_RSVD_VIDr, &rval, VIDf, vid);
  13039     rv = WRITE_EGR_SYS_RSVD_VIDr(unit, rval);
  13040 
  13041     return rv;
  13042 }
  13043 
  13044 /*
  13045  * Function:
  13046  *     _bcm_trx_system_reserved_vlan_ing_get
  13047  * Purpose:
  13048  *     Get ingress system reserved VLAN
  13049  * Parameters:
  13050  *     unit  - Device unit number
  13051  *     vlan  - VLAN
  13052  * Returns:
  13053  *     BCM_E_XXX
  13054  */
  13055 int
  13056 _bcm_trx_system_reserved_vlan_ing_get(int unit, int *arg)
  13057 {
  13058     uint32 rval;
  13059     int rv = BCM_E_UNAVAIL;
  13060 
  13061     rv = READ_ING_SYS_RSVD_VIDr(unit, &rval);
  13062     if (SOC_SUCCESS(rv)) {
  13063         if (soc_reg_field_get(unit, ING_SYS_RSVD_VIDr, rval, VALIDf)) {
  13064             bcm_vlan_t vlan;
  13065 
  13066             vlan = soc_reg_field_get(unit, ING_SYS_RSVD_VIDr, rval, VIDf);
  13067             *arg = vlan;
  13068         } else {
  13069             *arg = BCM_VLAN_INVALID;
  13070         }
  13071     }
  13072     return rv;
  13073 }
  13074 
  13075 
  13076 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
  13077 #define _BCM_VLAN_PROTOCOL_DATA_CHUNK    16
  13078 #define _BCM_VLAN_ACTION_PROFILE_DEFAULT  0
  13079 #define _BCM_VLAN_PROTOCOL_DATA_PROFILE_DEFAULT 0
  13080 
  13081 STATIC
  13082 int
  13083 _bcm_trx_port_vlan_protocol_data_profile_index_set(int unit,
  13084     bcm_port_t port, int vlan_prot_offset, int action_profile_idx,
  13085     bcm_vlan_action_set_t *action)
  13086 {
  13087     int i, alloc_size = 0;
  13088     int vlan_prot_idx, rv = BCM_E_NONE;
  13089     vlan_protocol_data_entry_t *vlan_prot_data;
  13090     vlan_protocol_data_entry_t data[_BCM_VLAN_PROTOCOL_DATA_CHUNK];
  13091     void *entries[1];
  13092     _bcm_port_info_t            *pinfo;
  13093 
  13094 
  13095     if ((vlan_prot_offset < 0) ||
  13096         (vlan_prot_offset >= _BCM_VLAN_PROTOCOL_DATA_CHUNK)) {
  13097         return BCM_E_PARAM;
  13098     }
  13099 
  13100     BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
  13101     BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action));
  13102     vlan_prot_idx = pinfo->vlan_prot_ptr;
  13103 
  13104     if (SOC_IS_TOMAHAWKX(unit)) {
  13105         sal_memset(data, 0, sizeof(data));
  13106         for (i = 0; i < _BCM_VLAN_PROTOCOL_DATA_CHUNK; i++) {
  13107             BCM_IF_ERROR_RETURN(READ_VLAN_PROTOCOL_DATAm(
  13108                 unit, MEM_BLOCK_ANY, vlan_prot_idx + i, &data[i]));
  13109         }
  13110         vlan_prot_data = data;
  13111     } else {
  13112         /* Allocate memory for DMA */
  13113         alloc_size = _BCM_VLAN_PROTOCOL_DATA_CHUNK *
  13114                            sizeof(vlan_protocol_data_entry_t);
  13115         vlan_prot_data = soc_cm_salloc(unit, alloc_size,
  13116                                    "VLAN protocol data table");
  13117         if (NULL == vlan_prot_data) {
  13118             return (BCM_E_MEMORY);
  13119         }
  13120         sal_memset(vlan_prot_data, 0, alloc_size);
  13121 
  13122         /* Read the old profile chunk */
  13123 
  13124     rv = soc_mem_read_range(unit, VLAN_PROTOCOL_DATAm, 
  13125                             MEM_BLOCK_ANY, vlan_prot_idx, 
  13126                             vlan_prot_idx + (_BCM_VLAN_PROTOCOL_DATA_CHUNK - 1),
  13127                             vlan_prot_data);
  13128     if (BCM_FAILURE(rv)) {
  13129         soc_cm_sfree(unit, vlan_prot_data);
  13130         return (rv);
  13131     }
  13132     }
  13133 
  13134     /* Modify what's needed */
  13135     /* coverity[uninit_use_in_call: FALSE] */
  13136     _bcm_trx_vlan_protocol_data_entry_set(unit,
  13137         &vlan_prot_data[vlan_prot_offset], action, action_profile_idx);
  13138 
  13139     /* Delete the old profile chunk */
  13140     rv = _bcm_port_vlan_protocol_data_entry_delete(unit, vlan_prot_idx);
  13141     if (BCM_FAILURE(rv)) {
  13142         if (alloc_size > 0) {
  13143         soc_cm_sfree(unit, vlan_prot_data);
  13144         }
  13145         return (rv);
  13146     }
  13147 
  13148     /* Add new chunk and store new HW index */
  13149     entries[0] = vlan_prot_data;
  13150     rv = _bcm_port_vlan_protocol_data_entry_add(unit, entries,
  13151              _BCM_VLAN_PROTOCOL_DATA_CHUNK, (uint32 *)&vlan_prot_idx);
  13152     /* Free the DMA memory */
  13153     if (alloc_size > 0) {
  13154     soc_cm_sfree(unit, vlan_prot_data);
  13155     }
  13156     if (BCM_FAILURE(rv)) {
  13157         return (rv);
  13158     }
  13159 
  13160     rv = _bcm_esw_port_tab_set(unit, port,
  13161         _BCM_CPU_TABS_ETHER, VLAN_PROTOCOL_DATA_INDEXf, vlan_prot_idx / 16);
  13162     if (BCM_SUCCESS(rv)) {
  13163         pinfo->vlan_prot_ptr = vlan_prot_idx;
  13164     }
  13165 
  13166     return (rv);
  13167 }
  13168 
  13169 STATIC
  13170 int
  13171 _bcm_trx_port_vlan_protocol_data_profile_set(int unit,
  13172     bcm_port_t port, void **entries)
  13173 {
  13174     int               vlan_prot_idx, rv = BCM_E_NONE;
  13175     _bcm_port_info_t  *pinfo;
  13176 
  13177     PORT_LOCK(unit);
  13178 
  13179     /* Delete the old profile chunk */
  13180     rv = _bcm_port_info_get(unit, port, &pinfo);
  13181     if (BCM_FAILURE(rv)) {
  13182         goto cleanup;
  13183     }
  13184 
  13185     rv = _bcm_port_vlan_protocol_data_entry_delete(unit, pinfo->vlan_prot_ptr);
  13186     if (BCM_FAILURE(rv)) {
  13187         goto cleanup;
  13188     }
  13189 
  13190     /* Add new chunk and store new HW index */
  13191     rv = _bcm_port_vlan_protocol_data_entry_add(unit, entries,
  13192              _BCM_VLAN_PROTOCOL_DATA_CHUNK, (uint32 *)&vlan_prot_idx);
  13193     if (BCM_FAILURE(rv)) {
  13194         goto cleanup;
  13195     }
  13196 
  13197     /* Set VLAN_PROTOCOL_DATA_INDEXf  in PORT_TAB. */
  13198     rv = _bcm_esw_port_tab_set_without_portlock(unit, port,
  13199         _BCM_CPU_TABS_ETHER, VLAN_PROTOCOL_DATA_INDEXf, vlan_prot_idx / 16);
  13200     if (BCM_FAILURE(rv)) {
  13201         goto cleanup;
  13202     }
  13203     /* Update vlan_prot_ptr in SW port info */
  13204     pinfo->vlan_prot_ptr = vlan_prot_idx;
  13205 
  13206 cleanup:
  13207     PORT_UNLOCK(unit);
  13208     return (rv);
  13209 
  13210 }
  13211 
  13212 
  13213 /*
  13214  * Function   :
  13215  *      _bcm_trx_vlan_protocol_data_profile_update
  13216  * Description   :
  13217  *      Helper function for an API to update vlan port protocol data memory
  13218  *      for specific ports.
  13219  * Parameters   :
  13220  *      unit            (IN) BCM unit number
  13221  *      update_pbm      (IN) BCM port bitmap to update
  13222  *      prot_idx        (IN) Index to Port Protocol table
  13223  *      action          (IN) VLAN action to be used to update all ports in pbmp
  13224  */
  13225 int
  13226 _bcm_trx_vlan_protocol_data_profile_update(
  13227     int unit, bcm_pbmp_t update_pbm, int prot_idx,
  13228     bcm_vlan_action_set_t *action)
  13229 {
  13230     bcm_port_t                  p;
  13231     int                         data_idx;
  13232     uint32                      action_profile_idx, old_action_profile_idx;
  13233     int                         use_default = 0;
  13234     bcm_vlan_action_set_t       def_action, *action_p;
  13235     _bcm_port_info_t            *pinfo;
  13236     vlan_protocol_data_entry_t  vde;
  13237 
  13238     /* if action is NULL then default action should be used for each port */
  13239     if (NULL == action) {
  13240         use_default = 1;
  13241         action_p = &def_action;
  13242     } else {
  13243         BCM_IF_ERROR_RETURN(
  13244             _bcm_trx_vlan_action_verify(unit, action));
  13245         action_p = action;
  13246     }
  13247 
  13248     BCM_PBMP_ITER(update_pbm, p) {
  13249         BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, p, &pinfo));
  13250         data_idx = pinfo->vlan_prot_ptr + prot_idx;
  13251 
  13252         if (use_default) {
  13253             BCM_IF_ERROR_RETURN(
  13254                 bcm_esw_vlan_port_default_action_get(unit, p, action_p));
  13255             if(soc_feature(unit, soc_feature_decouple_protocol_vlan)){
  13256                 action_p->new_outer_vlan = BCM_VLAN_DEFAULT;
  13257             }
  13258         }
  13259 
  13260         BCM_IF_ERROR_RETURN(
  13261             READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY, data_idx, &vde));
  13262 
  13263         old_action_profile_idx =
  13264             soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde,
  13265                 TAG_ACTION_PROFILE_PTRf);
  13266 
  13267         BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_profile_entry_add(unit,
  13268             action_p, &action_profile_idx));
  13269 
  13270         /* Update  VLAN_PROTOCOL_DATA profile and
  13271         * PORT.VLAN_PROTOCOL_DATA_INDEX */
  13272         BCM_IF_ERROR_RETURN(
  13273             _bcm_trx_port_vlan_protocol_data_profile_index_set(unit,
  13274                 p, prot_idx, action_profile_idx, action_p));
  13275 
  13276         if (old_action_profile_idx >= ing_action_profile_def[unit]) {
  13277             BCM_IF_ERROR_RETURN(
  13278                 _bcm_trx_vlan_action_profile_entry_delete(unit,
  13279                     old_action_profile_idx));
  13280         }
  13281     }
  13282     return BCM_E_NONE;
  13283 }
  13284 
  13285 
  13286 /*
  13287  * Function:
  13288  *      _bcm_trx_vlan_port_default_action_profile_set
  13289  * Purpose:
  13290  *      Set the port's default vlan tag actions
  13291  * Parameters:
  13292  *      unit       - (IN) BCM unit.
  13293  *      port       - (IN) Port number.
  13294  *      action     - (IN) Vlan tag actions
  13295  * Returns:
  13296  *      BCM_E_XXX
  13297  */
  13298 int
  13299 _bcm_trx_vlan_port_default_action_profile_set(int unit, bcm_port_t port,
  13300                                      bcm_vlan_action_set_t *action)
  13301 {
  13302     uint32 action_profile_idx, old_action_profile_idx;
  13303     bcm_port_cfg_t pcfg;
  13304     vlan_protocol_data_entry_t vde;
  13305     int vlan_prot_entries, vlan_data_prot_start, i, rv;
  13306     int alloc_size = 0;
  13307     _bcm_port_info_t *pinfo;
  13308     vlan_protocol_data_entry_t *vlan_prot_data;
  13309     vlan_protocol_data_entry_t data[_BCM_VLAN_PROTOCOL_DATA_CHUNK];
  13310     void *entries[1];
  13311 
  13312     BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action));
  13313     BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_profile_entry_add(unit,
  13314         action, &action_profile_idx));
  13315 
  13316     BCM_IF_ERROR_RETURN
  13317         (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg));
  13318     
  13319     old_action_profile_idx = pcfg.pc_vlan_action;
  13320     pcfg.pc_vlan = action->new_outer_vlan;
  13321     pcfg.pc_ivlan = action->new_inner_vlan;
  13322     pcfg.pc_vlan_action = action_profile_idx;
  13323     if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
  13324         if (action->priority >= BCM_PRIO_MIN &&
  13325             action->priority <= BCM_PRIO_MAX) {
  13326             pcfg.pc_new_opri = action->priority;
  13327         }
  13328         pcfg.pc_new_ocfi = action->new_outer_cfi;
  13329         pcfg.pc_new_ipri = action->new_inner_pkt_prio;
  13330         pcfg.pc_new_icfi = action->new_inner_cfi;
  13331     } else {
  13332         if (action->priority >= BCM_PRIO_MIN &&
  13333             action->priority <= BCM_PRIO_MAX) {
  13334             pcfg.pc_new_opri = action->priority;
  13335         }
  13336     }
  13337 
  13338     BCM_IF_ERROR_RETURN
  13339         (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg));
  13340 
  13341     BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_profile_entry_delete(unit,
  13342         old_action_profile_idx));
  13343 
  13344     BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
  13345     vlan_data_prot_start = pinfo->vlan_prot_ptr;
  13346 
  13347     if (pinfo->p_vd_pbvl == 0) {
  13348         /* Avoid one crash in kt2 tr 18 test case in linux environment */
  13349         return (BCM_E_NONE);
  13350     }
  13351 
  13352     if (SOC_IS_TOMAHAWKX(unit)) {
  13353         sal_memset(data, 0, sizeof(data));
  13354         for (i = 0; i < _BCM_VLAN_PROTOCOL_DATA_CHUNK; i++) {
  13355             BCM_IF_ERROR_RETURN(READ_VLAN_PROTOCOL_DATAm(
  13356                 unit, MEM_BLOCK_ANY, vlan_data_prot_start + i, &data[i]));
  13357         }
  13358         vlan_prot_data = data;
  13359     } else {
  13360     /* Allocate memory for DMA */
  13361     alloc_size = _BCM_VLAN_PROTOCOL_DATA_CHUNK * 
  13362                        sizeof(vlan_protocol_data_entry_t);
  13363     vlan_prot_data = soc_cm_salloc(unit, alloc_size,
  13364                                "VLAN protocol data table");
  13365     if (NULL == vlan_prot_data) {
  13366         return (BCM_E_MEMORY);
  13367     }
  13368     sal_memset(vlan_prot_data, 0, alloc_size);
  13369 
  13370     /* Read the old profile chunk */
  13371     rv = soc_mem_read_range(unit, VLAN_PROTOCOL_DATAm, 
  13372              MEM_BLOCK_ANY, vlan_data_prot_start, 
  13373              vlan_data_prot_start + (_BCM_VLAN_PROTOCOL_DATA_CHUNK - 1),
  13374              vlan_prot_data);
  13375     if (BCM_FAILURE(rv)) {
  13376         soc_cm_sfree(unit, vlan_prot_data);
  13377         return (rv);
  13378     }
  13379     }
  13380 
  13381     /* Update TAG_ACTION_PROFILE_PTR in VLAN_PROTOCOL_DATA */
  13382     vlan_prot_entries = soc_mem_index_count(unit, VLAN_PROTOCOLm);
  13383     for (i = 0; i < vlan_prot_entries; i++) {
  13384         if (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, i)) { 
  13385             rv = READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY,
  13386                      vlan_data_prot_start + i, &vde);
  13387             if (BCM_FAILURE(rv)) {
  13388                 if (alloc_size > 0) {
  13389                 soc_cm_sfree(unit, vlan_prot_data);
  13390                 }
  13391                 return (rv);
  13392             }
  13393 
  13394             old_action_profile_idx = soc_VLAN_PROTOCOL_DATAm_field32_get(unit,
  13395                                          &vde, TAG_ACTION_PROFILE_PTRf);
  13396 
  13397             rv = _bcm_trx_vlan_action_profile_entry_add(unit,
  13398                     action, &action_profile_idx);
  13399             if (BCM_FAILURE(rv)) {
  13400                 if (alloc_size > 0) {
  13401                 soc_cm_sfree(unit, vlan_prot_data);
  13402                 }
  13403                 return (rv);
  13404             }
  13405 
  13406             /* Modify what's needed */
  13407             /* coverity[uninit_use_in_call: FALSE] */
  13408             _bcm_trx_vlan_protocol_data_entry_set(unit,
  13409                 &vlan_prot_data[i], action, action_profile_idx);
  13410 
  13411             rv = _bcm_trx_vlan_action_profile_entry_delete(unit,
  13412                      old_action_profile_idx);
  13413             if (BCM_FAILURE(rv)) {
  13414                 if (alloc_size > 0) {
  13415                 soc_cm_sfree(unit, vlan_prot_data);
  13416                 }
  13417                 return (rv);
  13418             }
  13419         }
  13420     }
  13421     entries[0] = vlan_prot_data;
  13422 
  13423     /* Update  VLAN_PROTOCOL_DATA profile and
  13424     * PORT.VLAN_PROTOCOL_DATA_INDEX */
  13425     rv  =_bcm_trx_port_vlan_protocol_data_profile_set(unit, port, entries);
  13426     if (alloc_size > 0) {
  13427     soc_cm_sfree(unit, vlan_prot_data);
  13428     }
  13429     return (rv);
  13430 }
  13431 
  13432 
  13433 /*
  13434  * Function:
  13435  *      _bcm_tr_vlan_port_default_action_delete
  13436  * Purpose:
  13437  *      Deletes the port's default vlan tag actions
  13438  * Parameters:
  13439  *      unit       - (IN) BCM unit.
  13440  *      port       - (IN) Port number.
  13441  * Returns:
  13442  *      BCM_E_XXX
  13443  */ 
  13444 int 
  13445 _bcm_trx_vlan_port_default_action_profile_delete(int unit, bcm_port_t port)
  13446 {
  13447     uint32                      old_action_profile_idx;
  13448     uint32                      action_profile_idx;
  13449     bcm_port_cfg_t              pcfg;
  13450     int                         num_ent, start, i;
  13451     _bcm_port_info_t            *pinfo;
  13452     vlan_protocol_data_entry_t  vde;
  13453     int                         rv = BCM_E_NONE;
  13454 
  13455     BCM_IF_ERROR_RETURN
  13456         (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg));
  13457     old_action_profile_idx = pcfg.pc_vlan_action;
  13458 
  13459     pcfg.pc_vlan = BCM_VLAN_DEFAULT;
  13460     pcfg.pc_ivlan = 0;
  13461     pcfg.pc_vlan_action = ing_action_profile_def[unit];
  13462     BCM_IF_ERROR_RETURN
  13463         (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg));
  13464 
  13465     _bcm_trx_vlan_action_profile_entry_increment(unit,
  13466          _BCM_VLAN_ACTION_PROFILE_DEFAULT);
  13467     BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_profile_entry_delete(unit,
  13468         old_action_profile_idx));
  13469 
  13470     num_ent = soc_mem_index_count(unit, VLAN_PROTOCOLm);
  13471     BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
  13472     start = pinfo->vlan_prot_ptr;
  13473 
  13474     if (start == 0) {
  13475         /* Decrease ref count of default profile and return */
  13476         rv = _bcm_port_vlan_protocol_data_entry_delete(unit, start);
  13477         return rv;
  13478     }
  13479 
  13480     for (i = 0; i < num_ent; i++) {
  13481         if (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, i)) { 
  13482             BCM_IF_ERROR_RETURN(READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY,
  13483                         start + i, &vde));
  13484             action_profile_idx = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde,
  13485                     TAG_ACTION_PROFILE_PTRf);
  13486 
  13487             _bcm_trx_vlan_action_profile_entry_increment(unit,
  13488                  _BCM_VLAN_ACTION_PROFILE_DEFAULT);
  13489             BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_profile_entry_delete(unit, 
  13490                         action_profile_idx));
  13491         }
  13492     }
  13493 
  13494     /* Delete the VLAN_PROTOCOL_DATA profile */
  13495     BCM_IF_ERROR_RETURN(_bcm_port_vlan_protocol_data_entry_delete(unit, start));
  13496 
  13497     /* Increase ref count of default profile and return */
  13498     BCM_IF_ERROR_RETURN(_bcm_port_vlan_protocol_data_entry_reference(unit,
  13499         _BCM_VLAN_PROTOCOL_DATA_PROFILE_DEFAULT,
  13500         _BCM_VLAN_PROTOCOL_DATA_CHUNK));
  13501     pinfo->vlan_prot_ptr = _BCM_VLAN_PROTOCOL_DATA_PROFILE_DEFAULT;
  13502 
  13503     return rv;
  13504 }
  13505 
  13506 #endif /*BCM_KATANA2_SUPPORT */
  13507 
  13508 /*
  13509  * Function:
  13510  *     _bcm_trx_vlan_action_profile_ref_count_get
  13511  * Purpose:
  13512  *     Get vlan action profile entry use count.
  13513  * Parameters:
  13514  *     unit      - (IN)  BCM device number.
  13515  *     index     - (IN)  Profile entry index.
  13516  *     ref_count - (OUT) Vlan Action profile use count.
  13517  * Returns:
  13518  *     BCM_E_XXX
  13519  */
  13520 int
  13521 _bcm_trx_vlan_action_profile_ref_count_get(int unit, int index, int *ref_count)
  13522 {
  13523     int rv = BCM_E_NONE;
  13524     if (NULL == ref_count) {
  13525         return (BCM_E_PARAM);
  13526     }
  13527 
  13528     ING_VLAN_TAG_ACTION_LOCK(unit);
  13529     rv = soc_profile_mem_ref_count_get(unit, ing_action_profile[unit],
  13530                                        index, ref_count);
  13531     ING_VLAN_TAG_ACTION_UNLOCK(unit);
  13532     return rv;
  13533 }
  13534 
  13535 
  13536 #ifndef BCM_SW_STATE_DUMP_DISABLE
  13537 /*
  13538  * Function:
  13539  *     _bcm_trx_vlan_sw_dump
  13540  * Purpose:
  13541  *     Displays VLAN information maintained by software.
  13542  * Parameters:
  13543  *     unit - Device unit number
  13544  * Returns:
  13545  *     None
  13546  */
  13547 void
  13548 _bcm_trx_vlan_sw_dump(int unit)
  13549 {
  13550     int     num_entries;
  13551     int     ref_count;
  13552     int     entries_per_set;
  13553     int     index;
  13554     ing_vlan_tag_action_profile_entry_t *ing_entry;
  13555     egr_vlan_tag_action_profile_entry_t *egr_entry;
  13556     ing_vlan_range_entry_t              *range_entry;
  13557 
  13558     /* Display entries with reference count > 0 */
  13559 
  13560     if (ing_action_profile[unit] != NULL) {
  13561         LOG_CLI((BSL_META_U(unit,
  13562                             "\nSW Information Ingress VLAN Action Profile - "
  13563                  "Unit %d\n"), unit));
  13564 
  13565         num_entries = soc_mem_index_count
  13566             (unit, ing_action_profile[unit]->tables[0].mem);
  13567         LOG_CLI((BSL_META_U(unit,
  13568                             " Number of entries: %d\n\n"), num_entries));
  13569 
  13570         for (index = 0; index < num_entries; index ++) {
  13571             ING_VLAN_TAG_ACTION_LOCK(unit);
  13572             if (SOC_FAILURE
  13573                 (soc_profile_mem_ref_count_get(unit,
  13574                                                ing_action_profile[unit],
  13575                                                index, &ref_count))) {
  13576                 ING_VLAN_TAG_ACTION_UNLOCK(unit);
  13577                 break;
  13578             }
  13579 
  13580             if (ref_count <= 0) {
  13581                 ING_VLAN_TAG_ACTION_UNLOCK(unit);
  13582                 continue;
  13583             }
  13584 
  13585             entries_per_set =
  13586                 ing_action_profile[unit]->tables[0].entries[index].entries_per_set;
  13587             ing_entry =
  13588                 SOC_PROFILE_MEM_ENTRY(unit,
  13589                                       ing_action_profile[unit],
  13590                                       ing_vlan_tag_action_profile_entry_t *,
  13591                                       index);
  13592             LOG_CLI((BSL_META_U(unit,
  13593                                 " Index           = 0x%x\n"), index));
  13594             LOG_CLI((BSL_META_U(unit,
  13595                                 " Reference count = %d\n"), ref_count));
  13596             LOG_CLI((BSL_META_U(unit,
  13597                                 " Entries per set = %d\n"), entries_per_set));
  13598             soc_mem_entry_dump(unit, ing_action_profile[unit]->tables[0].mem,
  13599                                ing_entry, BSL_LSS_CLI);
  13600             LOG_CLI((BSL_META_U(unit, "\n\n")));
  13601             ING_VLAN_TAG_ACTION_UNLOCK(unit);
  13602         }
  13603     }
  13604 
  13605     if (egr_action_profile[unit] != NULL) {
  13606         LOG_CLI((BSL_META_U(unit,
  13607                             "\nSW Information Egress VLAN Action Profile - "
  13608                  "Unit %d\n"), unit));
  13609 
  13610         num_entries = soc_mem_index_count
  13611             (unit, egr_action_profile[unit]->tables[0].mem);
  13612         LOG_CLI((BSL_META_U(unit,
  13613                             " Number of entries: %d\n\n"), num_entries));
  13614 
  13615         for (index = 0; index < num_entries; index ++) {
  13616             EGR_VLAN_TAG_ACTION_LOCK(unit);
  13617             if (SOC_FAILURE
  13618                 (soc_profile_mem_ref_count_get(unit,
  13619                                                egr_action_profile[unit],
  13620                                                index, &ref_count))) {
  13621                 EGR_VLAN_TAG_ACTION_UNLOCK(unit);
  13622                 break;
  13623             }
  13624 
  13625             if (ref_count <= 0) {
  13626                 EGR_VLAN_TAG_ACTION_UNLOCK(unit);
  13627                 continue;
  13628             }
  13629 
  13630             entries_per_set =
  13631                 egr_action_profile[unit]->tables[0].entries[index].entries_per_set;
  13632             egr_entry =
  13633                 SOC_PROFILE_MEM_ENTRY(unit,
  13634                                       egr_action_profile[unit],
  13635                                       egr_vlan_tag_action_profile_entry_t *,
  13636                                       index);
  13637             LOG_CLI((BSL_META_U(unit,
  13638                                 " Index           = 0x%x\n"), index));
  13639             LOG_CLI((BSL_META_U(unit,
  13640                                 " Reference count = %d\n"), ref_count));
  13641             LOG_CLI((BSL_META_U(unit,
  13642                                 " Entries per set = %d\n"), entries_per_set));
  13643             soc_mem_entry_dump(unit, egr_action_profile[unit]->tables[0].mem,
  13644                                egr_entry, BSL_LSS_CLI);
  13645             LOG_CLI((BSL_META_U(unit, "\n\n")));
  13646             EGR_VLAN_TAG_ACTION_UNLOCK(unit);
  13647         }
  13648     }
  13649 
  13650     if (vlan_range_profile[unit] != NULL) {
  13651         LOG_CLI((BSL_META_U(unit,
  13652                             "\nSW Information VLAN Range Profile - Unit %d\n"),
  13653                  unit));
  13654 
  13655         num_entries = soc_mem_index_count
  13656             (unit, vlan_range_profile[unit]->tables[0].mem);
  13657 
  13658         LOG_CLI((BSL_META_U(unit,
  13659                             " Number of entries: %d\n\n"), num_entries));
  13660 
  13661         for (index = 0; index < num_entries; index ++) {
  13662             VLAN_RANGE_LOCK(unit);
  13663             if (SOC_FAILURE
  13664                 (soc_profile_mem_ref_count_get(unit,
  13665                                                vlan_range_profile[unit],
  13666                                                index, &ref_count))) {
  13667                 VLAN_RANGE_UNLOCK(unit);
  13668                 break;
  13669             }
  13670 
  13671             if (ref_count <= 0) {
  13672                 VLAN_RANGE_UNLOCK(unit);
  13673                 continue;
  13674             }
  13675 
  13676             entries_per_set =
  13677                 vlan_range_profile[unit]->tables[0].entries[index].entries_per_set;
  13678             range_entry =
  13679                 SOC_PROFILE_MEM_ENTRY(unit,
  13680                                       vlan_range_profile[unit],
  13681                                       ing_vlan_range_entry_t *,
  13682                                       index);
  13683             LOG_CLI((BSL_META_U(unit,
  13684                                 " Index           = 0x%x\n"), index));
  13685             LOG_CLI((BSL_META_U(unit,
  13686                                 " Reference count = %d\n"), ref_count));
  13687             LOG_CLI((BSL_META_U(unit,
  13688                                 " Entries per set = %d\n"), entries_per_set));
  13689             soc_mem_entry_dump(unit, vlan_range_profile[unit]->tables[0].mem,
  13690                                range_entry, BSL_LSS_CLI);
  13691             LOG_CLI((BSL_META_U(unit, "\n\n")));
  13692             VLAN_RANGE_UNLOCK(unit);
  13693         }
  13694     }
  13695 
  13696     return;
  13697 }
  13698 #endif /* BCM_SW_STATE_DUMP_DISABLE */
  13699 
  13700 /*
  13701  * Function:
  13702  *      _bcm_trx_vlan_mac_port_key_fields_set
  13703  * Description   :
  13704  *      Set Key Fields in VLAM_MACm entry hw buffer for MAC+PORT View.
  13705  * Parameters   :
  13706  *      unit      (IN) BCM unit number
  13707  *      mac       (IN) MAC address
  13708  *      port      (IN) gport number
  13709  *      vment     (OUT) VLAN_MACm entry hw buffer
  13710  */
  13711 int _bcm_trx_vlan_mac_port_key_fields_set(
  13712     int unit,
  13713     bcm_vlan_match_info_t *match_info,
  13714     vlan_mac_entry_t *vment)
  13715 {
  13716     int rv = BCM_E_NONE;
  13717     int gport_id;
  13718     int source_type;
  13719     int max_bits;
  13720     bcm_trunk_t trunk_id;
  13721     bcm_module_t mod_out;
  13722     bcm_port_t port_out;
  13723 
  13724     /* Set Key Type */
  13725     soc_VLAN_MACm_field32_set(unit, vment, KEY_TYPEf,
  13726             TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT);
  13727 
  13728     /* Set entry MAC address */
  13729     soc_VLAN_MACm_mac_addr_set(unit, vment, MAC_PORT__MAC_ADDRf,
  13730             match_info->src_mac);
  13731 
  13732     switch(match_info->match) {
  13733         case BCM_VLAN_MATCH_MAC_PORT:
  13734             if (BCM_GPORT_IS_SET(match_info->port)) {
  13735                 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit,
  13736                             match_info->port, &mod_out, &port_out,
  13737                             &trunk_id, &gport_id));
  13738                 if (BCM_GPORT_IS_TRUNK(match_info->port)) {
  13739                     rv = _bcm_trunk_id_validate(unit, trunk_id);
  13740                     if (BCM_FAILURE(rv)) {
  13741                         return BCM_E_PORT;
  13742                     }
  13743                     source_type = 1;
  13744                     soc_VLAN_MACm_field32_set(unit, vment, MAC_PORT__Tf, 1);
  13745                     soc_VLAN_MACm_field32_set(unit, vment, MAC_PORT__TGIDf,
  13746                             trunk_id);
  13747                 } else if BCM_GPORT_IS_MODPORT(match_info->port) {
  13748                     if ((-1 == mod_out) || (-1 == port_out)) {
  13749                         return BCM_E_PORT;
  13750                     }
  13751                     source_type = 1;
  13752                     soc_VLAN_MACm_field32_set(unit, vment,
  13753                             MAC_PORT__PORT_NUMf, port_out);
  13754                     soc_VLAN_MACm_field32_set(unit, vment,
  13755                             MAC_PORT__MODULE_IDf, mod_out);
  13756                 } else {
  13757                     if (gport_id == -1) {
  13758                         return BCM_E_PORT;
  13759                     }
  13760                     source_type = 2;
  13761                     soc_VLAN_MACm_field32_set(unit, vment,
  13762                             MAC_PORT__SOURCE_FIELDf, gport_id);
  13763                 }
  13764             } else {
  13765                 return BCM_E_PORT;
  13766             }
  13767             break;
  13768         case BCM_VLAN_MATCH_MAC_PORT_CLASS:
  13769             max_bits =soc_mem_field_length(unit,
  13770                     VLAN_MACm, MAC_PORT__SOURCE_FIELDf);
  13771             if (match_info->port_class < (1 << max_bits)) {
  13772                 source_type = 3;
  13773                 soc_VLAN_MACm_field32_set(unit, vment, MAC_PORT__SOURCE_FIELDf,
  13774                         match_info->port_class);
  13775             } else {
  13776                 return BCM_E_PORT;
  13777             }
  13778             break;
  13779         default:
  13780             return BCM_E_PARAM;
  13781     }
  13782 
  13783     /* Set entry Source Field */
  13784     if (SOC_MEM_FIELD_VALID(unit, VLAN_MACm, SOURCE_TYPEf)) {
  13785         soc_VLAN_MACm_field32_set(unit, vment, SOURCE_TYPEf, source_type);
  13786     }
  13787 
  13788     return rv;
  13789 }
  13790 
  13791 /*
  13792  * Function:
  13793  *      _bcm_trx_vlan_mac_port_key_fields_get
  13794  * Description   :
  13795  *      Get Key Fields from VLAM_MACm entry hw buffer for MAC+PORT View.
  13796  * Parameters   :
  13797  *      unit      (IN) BCM unit number
  13798  *      vment     (IN) VLAN_MACm entry hw buffer
  13799  *      mac       (OUT) MAC address
  13800  *      port      (OUT) gport number
  13801  */
  13802 int _bcm_trx_vlan_mac_port_key_fields_get(int             unit,
  13803                                         vlan_mac_entry_t *vment,
  13804                                         bcm_vlan_match_info_t *match_info)
  13805 {
  13806     int rv = BCM_E_NONE;
  13807     uint32 port_in, mod_in;
  13808     uint32 trunk_id;
  13809 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
  13810     uint32 vp;
  13811     _bcm_gport_dest_t gport_dest;
  13812 #endif
  13813 
  13814     /* Get entry mac address. */
  13815     soc_VLAN_MACm_mac_addr_get(unit, vment, MAC_PORT__MAC_ADDRf, match_info->src_mac);
  13816 
  13817     /* Get Source Type */
  13818     switch(soc_VLAN_MACm_field32_get(unit, vment, SOURCE_TYPEf)) {
  13819         case 1: /* Port or Trunk */
  13820             match_info->match = BCM_VLAN_MATCH_MAC_PORT;
  13821             if (soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__Tf)) {
  13822                 trunk_id =
  13823                     soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__TGIDf);
  13824                 BCM_GPORT_TRUNK_SET(match_info->port, trunk_id);
  13825             } else {
  13826                 port_in =
  13827                     soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__PORT_NUMf);
  13828                 mod_in =
  13829                     soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__MODULE_IDf);
  13830                 BCM_GPORT_MODPORT_SET(match_info->port, mod_in, port_in);
  13831             }
  13832             break;
  13833 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
  13834         case 2: /* Virtual Port */
  13835             match_info->match = BCM_VLAN_MATCH_MAC_PORT;
  13836             vp = soc_VLAN_MACm_field32_get(unit,
  13837                     vment, MAC_PORT__SOURCE_FIELDf);
  13838             _bcm_gport_dest_t_init(&gport_dest);
  13839             rv = _bcm_vp_gport_dest_fill(unit, vp, &gport_dest);
  13840             BCM_IF_ERROR_RETURN(rv);
  13841 
  13842             rv = _bcm_esw_gport_construct(unit, &gport_dest, &match_info->port);
  13843             BCM_IF_ERROR_RETURN(rv);
  13844             break;
  13845 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */
  13846         case 3: /* Port Group */
  13847             match_info->match = BCM_VLAN_MATCH_MAC_PORT_CLASS;
  13848             match_info->port_class =
  13849                 soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__SOURCE_FIELDf);
  13850             break;
  13851         default:
  13852             match_info->match = BCM_VLAN_MATCH_INVALID;
  13853             break;
  13854     }
  13855 
  13856     return rv;
  13857 }
  13858 
  13859 /*
  13860  * Function:
  13861  *      _bcm_trx_vlan_match_action_add
  13862  * Description   :
  13863  *      Add action for match criteria for Vlan assignment.
  13864  * Parameters   :
  13865  *      unit      (IN) BCM unit number
  13866  *      options   (IN) Options for creating vlan match and assignment.
  13867  *      svp_port  (IN) Source VP gport.
  13868  *      match_info (IN) Vlan match criteria.
  13869  *      action_set (IN) Action Set.
  13870  */
  13871 int
  13872 _bcm_trx_vlan_match_action_add(
  13873     int unit,
  13874     uint32 options,
  13875     bcm_gport_t port,
  13876     bcm_vlan_match_info_t *match_info,
  13877     bcm_vlan_action_set_t *action_set)
  13878 {
  13879     int rv;
  13880     int idx = 0;
  13881     int gport_id;
  13882     int svp_valid;
  13883     bcm_trunk_t trunk_id;
  13884     bcm_module_t mod_out;
  13885     bcm_port_t port_out;
  13886     uint32 profile_idx;
  13887     vlan_mac_entry_t vment;
  13888     vlan_mac_entry_t res_vment;
  13889 
  13890     if (!SOC_MEM_IS_VALID(unit, VLAN_MACm)) {
  13891         return BCM_E_UNAVAIL;
  13892     }
  13893 
  13894     if (action_set != NULL) {
  13895         BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, action_set));
  13896         if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
  13897             if (action_set->priority == -1) {
  13898                 return BCM_E_PARAM;  /* no default priority action to take*/
  13899             }
  13900         }
  13901     }
  13902 
  13903     sal_memset(&vment, 0, sizeof(vlan_mac_entry_t));
  13904     sal_memset(&res_vment, 0, sizeof(vlan_mac_entry_t));
  13905 
  13906     /* Set Key Fields */
  13907     BCM_IF_ERROR_RETURN
  13908         (_bcm_trx_vlan_mac_port_key_fields_set(unit, match_info, &vment));
  13909 
  13910     soc_mem_lock(unit, VLAN_MACm);
  13911     rv = soc_mem_search(unit, VLAN_MACm, MEM_BLOCK_ALL, &idx,
  13912             &vment, &res_vment, 0);
  13913     soc_mem_unlock(unit, VLAN_MACm);
  13914 
  13915     /* If Entry exists, check svp configuration */
  13916     if (rv == BCM_E_NONE) {
  13917         svp_valid = FALSE;
  13918         if (soc_VLAN_MACm_field32_get(unit, &vment, MAC_PORT__SVP_VALIDf)) {
  13919             svp_valid = TRUE;
  13920         }
  13921         if (((port == BCM_GPORT_INVALID) && (svp_valid == TRUE)) ||
  13922                 ((port != BCM_GPORT_INVALID) && (svp_valid == FALSE))) {
  13923             return BCM_E_EXISTS;
  13924         }
  13925         if (!options & BCM_VLAN_MATCH_ACTION_REPLACE) {
  13926             return BCM_E_EXISTS;
  13927         }
  13928     }
  13929 
  13930     /* If Entry does not exists and want to replace */
  13931     if ((rv == BCM_E_NOT_FOUND) && (options & BCM_VLAN_MATCH_ACTION_REPLACE)) {
  13932         return rv;
  13933     }
  13934 
  13935     /* Set SVP Port */
  13936     if (BCM_GPORT_IS_SET(port)) {
  13937         BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit,
  13938                     port, &mod_out, &port_out, &trunk_id, &gport_id));
  13939         if (SOC_MEM_FIELD_VALID(unit, VLAN_MACm, MAC_PORT__SVPf)) {
  13940             soc_VLAN_MACm_field32_set(unit, &vment, MAC_PORT__SVP_VALIDf, 1);
  13941             soc_VLAN_MACm_field32_set(unit, &vment, MAC_PORT__SVPf, gport_id);
  13942         }
  13943     }
  13944 
  13945     if (action_set != NULL) {
  13946         BCM_IF_ERROR_RETURN
  13947             (_bcm_trx_vlan_action_profile_entry_add(unit, action_set, &profile_idx));
  13948 
  13949         /* Set Data Fields */
  13950         soc_VLAN_MACm_field32_set(unit, &vment,
  13951                 MAC_PORT__OVIDf, action_set->new_outer_vlan);
  13952         soc_VLAN_MACm_field32_set(unit, &vment,
  13953                 MAC_PORT__IVIDf, action_set->new_inner_vlan);
  13954         if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
  13955             soc_VLAN_MACm_field32_set(unit, &vment,
  13956                     MAC_PORT__OPRIf, action_set->priority);
  13957             soc_VLAN_MACm_field32_set(unit, &vment,
  13958                     MAC_PORT__OCFIf, action_set->new_outer_cfi);
  13959             soc_VLAN_MACm_field32_set(unit, &vment,
  13960                     MAC_PORT__IPRIf, action_set->new_inner_pkt_prio);
  13961             soc_VLAN_MACm_field32_set(unit, &vment,
  13962                     MAC_PORT__ICFIf, action_set->new_inner_cfi);
  13963         } else {
  13964             if (action_set->priority >= BCM_PRIO_MIN &&
  13965                     action_set->priority <= BCM_PRIO_MAX) {
  13966                 soc_VLAN_MACm_field32_set(unit, &vment,
  13967                         MAC_PORT__PRIf, action_set->priority);
  13968             }
  13969         }
  13970         soc_VLAN_MACm_field32_set(unit, &vment,
  13971                 MAC_PORT__TAG_ACTION_PROFILE_PTRf, profile_idx);
  13972         if (SOC_MEM_FIELD_VALID(unit, VLAN_MACm, MAC_PORT__VLAN_ACTION_VALIDf)) {
  13973             soc_VLAN_MACm_field32_set(unit, &vment,
  13974                     MAC_PORT__VLAN_ACTION_VALIDf, 1);
  13975         }
  13976     }
  13977     soc_VLAN_MACm_field32_set(unit, &vment, VALIDf, 1);
  13978 
  13979     /* Insert to VLAN_MACm */
  13980     rv = soc_mem_insert_return_old(unit, VLAN_MACm,
  13981             MEM_BLOCK_ALL, &vment, &vment);
  13982     if (rv == SOC_E_EXISTS) {
  13983         /* Delete the old vlan action profile entry */
  13984         if (soc_VLAN_MACm_field32_get(unit, &vment,
  13985                     MAC_PORT__VLAN_ACTION_VALIDf)) {
  13986             profile_idx = soc_VLAN_MACm_field32_get(unit, &vment,
  13987                     MAC_PORT__TAG_ACTION_PROFILE_PTRf);
  13988             rv = _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx);
  13989         }
  13990     }
  13991 
  13992     return rv;
  13993 }
  13994 
  13995 /*
  13996  * Function:
  13997  *      _bcm_trx_vlan_match_action_get
  13998  * Purpose:
  13999  *      Get action for given match criteria.
  14000  * Parameters:
  14001  *      unit         (IN)  Device Number
  14002  *      svp_port     (IN) source vp port
  14003  *      match_info - (IN) Match criteria info
  14004  *      action_set - (OUT) Action Set.
  14005  * Returns:
  14006  *      BCM_E_XXX
  14007  */
  14008 int
  14009 _bcm_trx_vlan_match_action_get(
  14010     int unit,
  14011     bcm_gport_t port,
  14012     bcm_vlan_match_info_t *match_info,
  14013     bcm_vlan_action_set_t *action_set)
  14014 {
  14015     int matched, svp_assigned, vp;
  14016     vlan_mac_entry_t vment;             /* Lookup key hw buffer.      */
  14017     vlan_mac_entry_t res_vment;         /* Lookup result buffer.      */
  14018     uint32 profile_idx;                 /* Vlan action profile index. */
  14019     int rv;                             /* Operation return status.   */
  14020     int idx = 0;                        /* Lookup result entry index. */
  14021 
  14022     if (!SOC_MEM_IS_VALID(unit, VLAN_MACm)) {
  14023         return BCM_E_UNAVAIL;
  14024     }
  14025 
  14026     /* Input parameters check. */
  14027     if (NULL == match_info) {
  14028         return (BCM_E_PARAM);
  14029     }
  14030 
  14031     sal_memset(&vment, 0, sizeof(vlan_mac_entry_t));
  14032     sal_memset(&res_vment, 0, sizeof(vlan_mac_entry_t));
  14033 
  14034     /* Set Key fields */
  14035     BCM_IF_ERROR_RETURN
  14036         (_bcm_trx_vlan_mac_port_key_fields_set(unit, match_info, &vment));
  14037 
  14038     /* Perform VLAN_MAC table search by mac address and port. */
  14039     soc_mem_lock(unit, VLAN_MACm);
  14040     rv = soc_mem_search(unit, VLAN_MACm, MEM_BLOCK_ALL, &idx,
  14041             &vment, &res_vment, 0);
  14042     soc_mem_unlock(unit, VLAN_MACm);
  14043     BCM_IF_ERROR_RETURN(rv);
  14044 
  14045     /* Evaluate svp */
  14046     matched = FALSE;
  14047     svp_assigned = soc_VLAN_MACm_field32_get(unit, &vment, MAC_PORT__SVP_VALIDf);
  14048 
  14049     if ((port != BCM_GPORT_INVALID) && (svp_assigned == TRUE)) {
  14050         vp = soc_VLAN_MACm_field32_get(unit, &vment, MAC_PORT__SVPf);
  14051         matched = _bcm_esw_port_vp_gport_check(port, vp);
  14052     } else if ((port == BCM_GPORT_INVALID) && (svp_assigned == FALSE)) {
  14053         matched = TRUE;
  14054     } else {
  14055         /* (((port != BCM_GPORT_INVALID) && (svp_assigned == FALSE)) ||
  14056            ((port == BCM_GPORT_INVALID) && (svp_assigned == TRUE))) */
  14057         matched = FALSE;
  14058     }
  14059     if (matched == FALSE) {
  14060         return BCM_E_NOT_FOUND;
  14061     }
  14062 
  14063 
  14064     /* Read Action Fields */
  14065     if (soc_VLAN_MACm_field32_get(unit, &res_vment,
  14066                 MAC_PORT__VLAN_ACTION_VALIDf)) {
  14067         if (NULL == action_set) {
  14068             return BCM_E_PARAM;
  14069         }
  14070 
  14071         action_set->new_outer_vlan =
  14072             soc_VLAN_MACm_field32_get(unit, &res_vment, MAC_PORT__OVIDf);
  14073         action_set->new_inner_vlan =
  14074             soc_VLAN_MACm_field32_get(unit, &res_vment, MAC_PORT__IVIDf);
  14075         if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
  14076             action_set->priority =
  14077                 soc_VLAN_MACm_field32_get(unit, &res_vment, MAC_PORT__OPRIf);
  14078             action_set->new_outer_cfi =
  14079                 soc_VLAN_MACm_field32_get(unit, &res_vment, MAC_PORT__OCFIf);
  14080             action_set->new_inner_pkt_prio =
  14081                 soc_VLAN_MACm_field32_get(unit, &res_vment, MAC_PORT__IPRIf);
  14082             action_set->new_inner_cfi =
  14083                 soc_VLAN_MACm_field32_get(unit, &res_vment, MAC_PORT__ICFIf);
  14084         } else {
  14085             action_set->priority =
  14086                 soc_VLAN_MACm_field32_get(unit, &res_vment, MAC_PORT__PRIf);
  14087         }
  14088 
  14089         /* Read action profile data. */
  14090         profile_idx = soc_VLAN_MACm_field32_get(unit,
  14091                 &res_vment, MAC_PORT__TAG_ACTION_PROFILE_PTRf);
  14092         _bcm_trx_vlan_action_profile_entry_get(unit, action_set, profile_idx);
  14093     }
  14094 
  14095     return (BCM_E_NONE);
  14096 }
  14097 
  14098 /*
  14099  * Function:
  14100  *      _bcm_trx_vlan_match_action_delete
  14101  * Purpose:
  14102  *      Remove action for a match criteria
  14103  * Parameters:
  14104  *      unit       (IN)  Device Number
  14105  *      match_info (IN)  Match criteria info.
  14106  * Returns:
  14107  *      BCM_E_XXX
  14108  */
  14109 int
  14110 _bcm_trx_vlan_match_action_delete(
  14111     int unit,
  14112     bcm_gport_t port,
  14113     bcm_vlan_match_info_t *vlan_match_info)
  14114 {
  14115     int rv, vp, svp_valid;
  14116     int matched;
  14117     vlan_mac_entry_t vment;             /* Lookup key hw buffer.      */
  14118     vlan_mac_entry_t res_vment;         /* Lookup result buffer.      */
  14119     uint32 profile_idx;                 /* Vlan action profile index. */
  14120     int idx = 0;                        /* Lookup result entry index. */
  14121 
  14122     sal_memset(&vment, 0, sizeof(vlan_mac_entry_t));
  14123     sal_memset(&res_vment, 0, sizeof(vlan_mac_entry_t));
  14124 
  14125     if (!SOC_MEM_IS_VALID(unit, VLAN_MACm)) {
  14126         return BCM_E_UNAVAIL;
  14127     }
  14128 
  14129     /* Set Key fields */
  14130     BCM_IF_ERROR_RETURN
  14131         (_bcm_trx_vlan_mac_port_key_fields_set(unit, vlan_match_info, &vment));
  14132 
  14133     /* Perform VLAN_MAC table search by mac address and port. */
  14134     soc_mem_lock(unit, VLAN_MACm);
  14135     rv = soc_mem_search(unit, VLAN_MACm, MEM_BLOCK_ALL, &idx,
  14136             &vment, &res_vment, 0);
  14137     soc_mem_unlock(unit, VLAN_MACm);
  14138     BCM_IF_ERROR_RETURN(rv);
  14139 
  14140     /* Evaluate SVP */
  14141     matched = FALSE;
  14142     svp_valid = soc_VLAN_MACm_field32_get(unit, &res_vment,
  14143             MAC_PORT__SVP_VALIDf);
  14144     if ((port != BCM_GPORT_INVALID) && (svp_valid == TRUE)) {
  14145         vp = soc_VLAN_MACm_field32_get(unit, &res_vment, MAC_PORT__SVPf);
  14146         matched = _bcm_esw_port_vp_gport_check(port, vp);
  14147     } else if ((port == BCM_GPORT_INVALID) && (svp_valid == FALSE)) {
  14148         matched = TRUE;
  14149     } else {
  14150         /* (((port != BCM_GPORT_INVALID) && (svp_valid == FALSE)) ||
  14151            ((port == BCM_GPORT_INVALID) && (svp_valid == TRUE))) */
  14152         matched = FALSE;
  14153     }
  14154 
  14155     if (matched == FALSE) {
  14156         return BCM_E_NOT_FOUND;
  14157     }
  14158 
  14159     /* Read action profile data. */
  14160     if (soc_VLAN_MACm_field32_get(unit, &res_vment,
  14161                 MAC_PORT__VLAN_ACTION_VALIDf)) {
  14162         profile_idx = soc_VLAN_MACm_field32_get(unit,
  14163                 &res_vment, MAC_PORT__TAG_ACTION_PROFILE_PTRf);
  14164         _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx);
  14165     }
  14166 
  14167     soc_mem_lock(unit, VLAN_MACm);
  14168     rv = soc_mem_delete_return_old(unit, VLAN_MACm, MEM_BLOCK_ALL,
  14169             &vment, &vment);
  14170     soc_mem_unlock(unit, VLAN_MACm);
  14171 
  14172     return (BCM_E_NONE);
  14173 }
  14174 
  14175 /*
  14176  * Function:
  14177  *      _bcm_trx_vlan_match_action_multi_get
  14178  * Purpose:
  14179  *      Get all actions and match criteria for given vlan match.
  14180  * Parameters:
  14181  *      unit       (IN)  Device Number
  14182  *      match      (IN)  vlan match
  14183  *      port       (IN)  gport number
  14184  *      size       (IN)  Number of elements in match_info_array
  14185  *      match_info_array (OUT) Vlan match info array
  14186  *      action_set (OUT) Action Set
  14187  *      count      (OUT) Actual number of elements in match_info_array
  14188  * Returns:
  14189  *      BCM_E_XXX
  14190  */
  14191 int
  14192 _bcm_trx_vlan_match_action_multi_get(int unit, bcm_vlan_match_t match,
  14193     bcm_gport_t port, int size, bcm_vlan_match_info_t *match_info_array,
  14194     bcm_vlan_action_set_t *action_set, int *count)
  14195 {
  14196     int vp, svp_valid;
  14197     int rv, i, matched, ctr;
  14198     int imin, imax, nent, vmbytes;
  14199     int key_type_value, key_type;
  14200     uint32 profile_idx;
  14201     bcm_vlan_match_info_t match_info;
  14202     vlan_mac_entry_t *vmtab = NULL;
  14203     vlan_mac_entry_t *vment = NULL;
  14204 
  14205     if (!SOC_MEM_IS_VALID(unit, VLAN_MACm)) {
  14206         return BCM_E_UNAVAIL;
  14207     }
  14208 
  14209     /* Parameter checks */
  14210     if ((size < 0) || (count == NULL)) {
  14211         return BCM_E_PARAM;
  14212     }
  14213     if ((size > 0) && ((match_info_array == NULL) ||
  14214                 (action_set == NULL))) {
  14215         return BCM_E_PARAM;
  14216     }
  14217 
  14218     imin = soc_mem_index_min(unit, VLAN_MACm);
  14219     imax = soc_mem_index_max(unit, VLAN_MACm);
  14220     nent = soc_mem_index_count(unit, VLAN_MACm);
  14221     vmbytes = soc_mem_entry_words(unit, VLAN_MACm);
  14222     vmbytes = WORDS2BYTES(vmbytes);
  14223 
  14224     vmtab = soc_cm_salloc(unit, nent * vmbytes, "vlan_mac");
  14225 
  14226     if (vmtab == NULL) {
  14227         return BCM_E_MEMORY;
  14228     }
  14229 
  14230     soc_mem_lock(unit, VLAN_MACm);
  14231     rv = soc_mem_read_range(unit, VLAN_MACm, MEM_BLOCK_ANY,
  14232             imin, imax, vmtab);
  14233     soc_mem_unlock(unit, VLAN_MACm);
  14234 
  14235     if (rv < 0) {
  14236         soc_cm_sfree(unit, vmtab);
  14237         return rv;
  14238     }
  14239 
  14240     soc_mem_lock(unit, VLAN_MACm);
  14241     for(i = 0, ctr = 0; i < nent; i++) {
  14242         if ((size != 0) && (size <= ctr)) {
  14243             break;
  14244         }
  14245 
  14246         vment = soc_mem_table_idx_to_pointer(unit, VLAN_MACm,
  14247                 vlan_mac_entry_t *, vmtab, i);
  14248 
  14249         if (!soc_VLAN_MACm_field32_get(unit, vment, VALIDf)) {
  14250             continue;
  14251         }
  14252 
  14253         /* Read KeyType */
  14254         key_type_value = soc_VLAN_MACm_field32_get(unit, vment, KEY_TYPEf);
  14255         (void) _bcm_esw_vlan_xlate_key_type_get(unit, key_type_value,
  14256                 &key_type);
  14257         switch(key_type) {
  14258             case VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT:
  14259                 /* Read Key Fields */
  14260                 bcm_vlan_match_info_t_init(&match_info);
  14261                 (void) _bcm_trx_vlan_mac_port_key_fields_get(unit,
  14262                         vment, &match_info);
  14263                 if (match_info.match == BCM_VLAN_MATCH_INVALID) {
  14264                     matched = FALSE;
  14265                     break;
  14266                 }
  14267 
  14268                 /* Evaluate SVP */
  14269                 matched = FALSE;
  14270                 svp_valid = soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__SVP_VALIDf);
  14271                 if ((port != BCM_GPORT_INVALID) && (svp_valid == TRUE)) {
  14272                     vp = soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__SVPf);
  14273                     matched = _bcm_esw_port_vp_gport_check(port, vp);
  14274                 } else if ((port == BCM_GPORT_INVALID) && (svp_valid == FALSE)) {
  14275                     matched = TRUE;
  14276                 } else {
  14277                     /* (((port != BCM_GPORT_INVALID) && (svp_valid == FALSE)) ||
  14278                        ((port == BCM_GPORT_INVALID) && (svp_valid == TRUE))) */
  14279                     matched = FALSE;
  14280                 }
  14281                 /* Evaluate match criteria */
  14282                 if ((match != BCM_VLAN_MATCH_INVALID) &&
  14283                         (match != match_info.match)) {
  14284                     matched = FALSE;
  14285                 }
  14286                 break;
  14287             default:
  14288                 matched = FALSE;
  14289                 break;
  14290         }
  14291 
  14292         if (matched == FALSE) {
  14293             continue;
  14294         }
  14295 
  14296         ctr++;
  14297         if (size >= ctr) {
  14298             /* Copy Key Fields */
  14299             sal_memcpy(match_info_array, &match_info,
  14300                     sizeof(bcm_vlan_match_info_t));
  14301 
  14302             /* Read Data Fields */
  14303             action_set->new_outer_vlan =
  14304                 soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__OVIDf);
  14305             action_set->new_inner_vlan =
  14306                 soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__IVIDf);
  14307             if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
  14308                 action_set->priority =
  14309                     soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__OPRIf);
  14310                 action_set->new_outer_cfi =
  14311                     soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__OCFIf);
  14312                 action_set->new_inner_pkt_prio =
  14313                     soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__IPRIf);
  14314                 action_set->new_inner_cfi =
  14315                     soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__ICFIf);
  14316             } else {
  14317                 action_set->priority =
  14318                     soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__PRIf);
  14319             }
  14320 
  14321             profile_idx = soc_VLAN_MACm_field32_get(unit, vment,
  14322                     MAC_PORT__TAG_ACTION_PROFILE_PTRf);
  14323 
  14324             _bcm_trx_vlan_action_profile_entry_get(unit, action_set, profile_idx);
  14325 
  14326             action_set++;
  14327             match_info_array++;
  14328         }
  14329     }
  14330     *count = ctr;
  14331 
  14332     soc_mem_unlock(unit, VLAN_MACm);
  14333     soc_cm_sfree(unit, vmtab);
  14334 
  14335     return rv;
  14336 }
  14337 
  14338 /*
  14339  * Function:
  14340  *      _bcm_trx_vlan_match_action_delete_all
  14341  * Purpose:
  14342  *      Remove all actions for vlan match
  14343  * Parameters:
  14344  *      unit       (IN)  Device Number
  14345  *      match      (IN)  vlan match
  14346  *      port       (IN)  port number
  14347  * Returns:
  14348  *      BCM_E_XXX
  14349  */
  14350 int
  14351 _bcm_trx_vlan_match_action_delete_all(int unit,
  14352                 bcm_vlan_match_t match, bcm_gport_t port)
  14353 {
  14354     int vp, svp_valid;
  14355     int rv, i, matched;
  14356     int imin, imax, nent, vmbytes;
  14357     uint32 profile_idx;
  14358     vlan_mac_entry_t *vmtab = NULL;
  14359     vlan_mac_entry_t *vment = NULL;
  14360     int key_type_value, key_type;
  14361     bcm_vlan_match_info_t match_info;
  14362 
  14363     if (!SOC_MEM_IS_VALID(unit, VLAN_MACm)) {
  14364         return BCM_E_UNAVAIL;
  14365     }
  14366 
  14367     imin = soc_mem_index_min(unit, VLAN_MACm);
  14368     imax = soc_mem_index_max(unit, VLAN_MACm);
  14369     nent = soc_mem_index_count(unit, VLAN_MACm);
  14370     vmbytes = soc_mem_entry_words(unit, VLAN_MACm);
  14371     vmbytes = WORDS2BYTES(vmbytes);
  14372 
  14373     vmtab = soc_cm_salloc(unit, nent * vmbytes, "vlan_mac");
  14374 
  14375     if (vmtab == NULL) {
  14376         return BCM_E_MEMORY;
  14377     }
  14378 
  14379     soc_mem_lock(unit, VLAN_MACm);
  14380     rv = soc_mem_read_range(unit, VLAN_MACm, MEM_BLOCK_ANY,
  14381             imin, imax, vmtab);
  14382     soc_mem_unlock(unit, VLAN_MACm);
  14383 
  14384     if (rv < 0) {
  14385         soc_cm_sfree(unit, vmtab);
  14386         return rv;
  14387     }
  14388 
  14389     soc_mem_lock(unit, VLAN_MACm);
  14390     for(i = 0; i < nent; i++) {
  14391 
  14392         vment = soc_mem_table_idx_to_pointer(unit, VLAN_MACm,
  14393                 vlan_mac_entry_t *, vmtab, i);
  14394 
  14395         if (!soc_VLAN_MACm_field32_get(unit, vment, VALIDf)) {
  14396             continue;
  14397         }
  14398 
  14399         /* Read KeyType */
  14400         key_type_value = soc_VLAN_MACm_field32_get(unit, vment, KEY_TYPEf);
  14401         (void) _bcm_esw_vlan_xlate_key_type_get(unit, key_type_value,
  14402                 &key_type);
  14403         switch(key_type) {
  14404             case VLXLT_HASH_KEY_TYPE_VLAN_MAC_PORT:
  14405                 matched = TRUE;
  14406                 /* Read Key Fields */
  14407                 bcm_vlan_match_info_t_init(&match_info);
  14408                 (void) _bcm_trx_vlan_mac_port_key_fields_get(unit,
  14409                         vment, &match_info);
  14410                 if (match_info.match == BCM_VLAN_MATCH_INVALID) {
  14411                     matched = FALSE;
  14412                     break;
  14413                 }
  14414 
  14415                 /* Evaluate SVP */
  14416                 matched = FALSE;
  14417                 svp_valid = soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__SVP_VALIDf);
  14418                 if ((port != BCM_GPORT_INVALID) && (svp_valid == TRUE)) {
  14419                     vp = soc_VLAN_MACm_field32_get(unit, vment, MAC_PORT__SVPf);
  14420                     matched = _bcm_esw_port_vp_gport_check(port, vp);
  14421                 } else if ((port == BCM_GPORT_INVALID) && (svp_valid == FALSE)) {
  14422                     matched = TRUE;
  14423                 } else {
  14424                     /* (((port != BCM_GPORT_INVALID) && (svp_valid == FALSE)) ||
  14425                        ((port == BCM_GPORT_INVALID) && (svp_valid == TRUE))) */
  14426                     matched = FALSE;
  14427                 }
  14428                 /* Evaluate match criteria */
  14429                 if ((match != BCM_VLAN_MATCH_INVALID) &&
  14430                         (match != match_info.match)) {
  14431                     matched = FALSE;
  14432                 }
  14433                 break;
  14434             default:
  14435                 matched = FALSE;
  14436                 break;
  14437         }
  14438 
  14439         if (matched == FALSE) {
  14440             continue;
  14441         }
  14442 
  14443         if (soc_VLAN_MACm_field32_get(unit, &vment,
  14444                     MAC_PORT__VLAN_ACTION_VALIDf)) {
  14445             /* Read action profile data. */
  14446             profile_idx = soc_VLAN_MACm_field32_get(unit,
  14447                     vment, MAC_PORT__TAG_ACTION_PROFILE_PTRf);
  14448             _bcm_trx_vlan_action_profile_entry_delete(unit, profile_idx);
  14449         }
  14450 
  14451         rv = soc_mem_delete_return_old(unit, VLAN_MACm, MEM_BLOCK_ALL,
  14452                 vment, vment);
  14453         if (rv != BCM_E_NONE) {
  14454             break;
  14455         }
  14456     }
  14457 
  14458     soc_mem_unlock(unit, VLAN_MACm);
  14459     soc_cm_sfree(unit, vmtab);
  14460 
  14461     return rv;
  14462 }
  14463 
  14464 #else /* BCM_TRX_SUPPORT */
  14465 int _triumph_vlan_not_empty;
  14466 #endif  /* BCM_TRX_SUPPORT */
  14467