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

l2gre.c (61787B)


      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:    l2gre.c
      8  * Purpose: TD2 L2GRE enhancements
      9  */
     10 #include <soc/defs.h>
     11 
     12 #include <assert.h>
     13 
     14 #include <sal/core/libc.h>
     15 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
     16 
     17 #include <soc/drv.h>
     18 #include <soc/mem.h>
     19 #include <soc/util.h>
     20 #include <soc/hash.h>
     21 #include <soc/debug.h>
     22 #include <bcm/types.h>
     23 #include <bcm/error.h>
     24 
     25 #include <bcm_int/esw/mbcm.h>
     26 #include <bcm_int/esw_dispatch.h>
     27 #include <bcm_int/esw/virtual.h>
     28 #include <bcm_int/esw/trx.h>
     29 #include <bcm_int/esw/triumph3.h>
     30 #include <bcm_int/esw/trident2.h>
     31 #include <bcm_int/esw/l2gre.h>
     32 #include <bcm_int/esw/stack.h>
     33 #include <bcm_int/common/multicast.h>
     34 
     35 #if defined(BCM_TRIDENT3_SUPPORT)
     36 #include <soc/esw/cancun.h>
     37 #endif
     38 
     39 #define L2GRE_INFO(_unit_)   (_bcm_tr3_l2gre_bk_info[_unit_])
     40 
     41 /*
     42  * Function:
     43  *        _bcm_td2_l2gre_match_vxlate_entry_set
     44  * Purpose:
     45  *       Set L2GRE Match Vxlate Entry
     46  * Parameters:
     47  *  IN :  Unit
     48  *  IN :  l2gre_port
     49  *  IN :  vlan_xlate_entry_t
     50  * Returns:
     51  *      BCM_E_XXX
     52  */
     53 
     54 STATIC int
     55 _bcm_td2_l2gre_match_vxlate_entry_set(int unit, bcm_l2gre_port_t *l2gre_port, uint32 *vent)
     56 {
     57     int rv = BCM_E_UNAVAIL;
     58     int index;
     59     bcm_module_t mod_out = -1;
     60     bcm_port_t port_out = -1;
     61     bcm_trunk_t trunk_id = -1;
     62     int    gport_id = -1;
     63     soc_mem_t mem;
     64     uint32 rvent[SOC_MAX_MEM_WORDS];
     65     int vp = _SHR_GPORT_L2GRE_PORT_ID_GET(l2gre_port->l2gre_port_id);
     66     _bcm_tr3_l2gre_bookkeeping_t *l2gre_info = L2GRE_INFO(unit);
     67 
     68 
     69 #if defined(BCM_TRIDENT3_SUPPORT)
     70     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
     71         mem = VLAN_XLATE_1_DOUBLEm;
     72 
     73         soc_mem_field32_set(unit, mem, vent, BASE_VALID_0f, 3);
     74         soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7);
     75     } else
     76 #endif
     77     {
     78         mem = VLAN_XLATEm;
     79         soc_mem_field32_set(unit, mem, vent, VALIDf, 0x1);
     80     }
     81 
     82     if (l2gre_info->match_key[vp].flags != _BCM_L2GRE_PORT_MATCH_TYPE_SHARED) {
     83        BCM_IF_ERROR_RETURN(_bcm_tr3_l2gre_port_resolve(unit, l2gre_port->l2gre_port_id, -1, &mod_out,
     84                     &port_out, &trunk_id, &gport_id));
     85     } else {
     86        BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, l2gre_port->match_port, &mod_out,
     87                     &port_out, &trunk_id, &gport_id));
     88     }
     89 
     90     if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) {
     91         soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1);
     92         soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, trunk_id);
     93     } else {
     94         soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf, mod_out);
     95         soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf, port_out);
     96     }
     97 
     98     soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1);
     99     soc_mem_field32_set(unit, mem, vent, XLATE__MPLS_ACTIONf, 0x1); /* SVP */
    100     soc_mem_field32_set(unit, mem, vent, XLATE__SOURCE_VPf, vp);
    101     soc_mem_field32_set(unit, mem, vent, XLATE__DISABLE_VLAN_CHECKSf, 1);
    102     if (l2gre_port->flags & BCM_L2GRE_PORT_ENABLE_VLAN_CHECKS) {
    103         soc_mem_field32_set(unit, mem, vent, XLATE__VLAN_ACTION_VALIDf, 1);
    104     }
    105 
    106 
    107     rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index, vent, &rvent, 0);
    108     if (rv == BCM_E_NONE) {
    109          BCM_IF_ERROR_RETURN(
    110             soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, vent));
    111     } else if (rv == BCM_E_NOT_FOUND) {
    112         if (l2gre_port->flags & BCM_VXLAN_PORT_REPLACE) {
    113             return BCM_E_NOT_FOUND;
    114         }
    115         BCM_IF_ERROR_RETURN(soc_mem_insert(unit, mem, MEM_BLOCK_ALL, vent));
    116     } else {
    117         return rv;
    118     }
    119 
    120 	if (l2gre_info->match_key[vp].flags != _BCM_L2GRE_PORT_MATCH_TYPE_SHARED) {
    121         /* Update software state */
    122         if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) {
    123             l2gre_info->match_key[vp].trunk_id = trunk_id;
    124             l2gre_info->match_key[vp].modid = -1;
    125         } else {
    126             l2gre_info->match_key[vp].port = port_out;
    127             l2gre_info->match_key[vp].modid = mod_out;
    128             l2gre_info->match_key[vp].trunk_id = -1;
    129         }
    130     }
    131 
    132     return BCM_E_NONE;
    133 }
    134 
    135 
    136 /*
    137  * Function:
    138  *      _bcm_td2_l2gre_match_add
    139  * Purpose:
    140  *      Assign match criteria of an L2GRE port
    141  * Parameters:
    142  *      unit    - (IN) Device Number
    143  *      l2gre_port - (IN) l2gre port information
    144  *      vp  - (IN) Source Virtual Port
    145  * Returns:
    146  *      BCM_E_XXX
    147  */
    148 
    149 int
    150 bcm_td2_l2gre_match_add(int unit, bcm_l2gre_port_t *l2gre_port, int vp, bcm_vpn_t vpn)
    151 {
    152     _bcm_tr3_l2gre_bookkeeping_t *l2gre_info = L2GRE_INFO(unit);
    153     int rv = BCM_E_NONE;
    154     bcm_module_t mod_out = -1;
    155     bcm_port_t port_out = -1;
    156     bcm_trunk_t trunk_id = -1;
    157     int    src_trk_idx=0;  /*Source Trunk table index.*/
    158     int    gport_id=-1;
    159 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    160     _bcm_vp_info_t vp_info;
    161 #endif
    162 	soc_mem_t mem;
    163     uint32 vent[SOC_MAX_MEM_WORDS] = {0};
    164 
    165 #if defined(BCM_TRIDENT3_SUPPORT)
    166     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
    167         mem = VLAN_XLATE_1_DOUBLEm;
    168     } else
    169 #endif
    170     {
    171         mem = VLAN_XLATEm;
    172     }
    173     if (l2gre_port->criteria == BCM_L2GRE_PORT_MATCH_SHARE) {
    174         /* there is no criteria to be configurated for shared vp,
    175            only updating software state to indicate this is a shared vp */
    176         l2gre_info->match_key[vp].flags = _BCM_L2GRE_PORT_MATCH_TYPE_SHARED;
    177         return BCM_E_NONE;
    178     }
    179     if (l2gre_info->match_key[vp].flags != _BCM_L2GRE_PORT_MATCH_TYPE_SHARED) {
    180        rv = _bcm_tr3_l2gre_port_resolve(unit, l2gre_port->l2gre_port_id, -1, &mod_out,
    181                     &port_out, &trunk_id, &gport_id);
    182     } else {
    183        rv = _bcm_esw_gport_resolve(unit, l2gre_port->match_port, &mod_out,
    184                     &port_out, &trunk_id, &gport_id);
    185     }
    186     BCM_IF_ERROR_RETURN(rv);
    187 
    188     if (l2gre_port->criteria == BCM_L2GRE_PORT_MATCH_PORT_VLAN ) {
    189         if (!BCM_VLAN_VALID(l2gre_port->match_vlan)) {
    190              return BCM_E_PARAM;
    191         }
    192 
    193         soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_OVID);
    194 #if defined(BCM_TRIDENT3_SUPPORT)
    195         if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
    196             soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_OVID);
    197         }
    198 #endif
    199         soc_mem_field32_set(unit, mem, vent, XLATE__OVIDf, l2gre_port->match_vlan);
    200         if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) {
    201             soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1);
    202             soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, trunk_id);
    203         } else {
    204             soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf, mod_out);
    205             soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf, port_out);
    206         }
    207 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    208         if (soc_feature(unit, soc_feature_vp_sharing)) {
    209             BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
    210             if (vp_info.flags & _BCM_VP_INFO_SHARED_PORT) {
    211                 int vfi = 0;
    212                 _BCM_L2GRE_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn);
    213                 soc_mem_field32_set(unit, mem, vent, XLATE__VFIf, vfi);
    214             }
    215         }
    216 #endif
    217 
    218         BCM_IF_ERROR_RETURN(
    219             _bcm_td2_l2gre_match_vxlate_entry_set(unit, l2gre_port, vent));
    220         if (l2gre_info->match_key[vp].flags != _BCM_L2GRE_PORT_MATCH_TYPE_SHARED) {
    221             /* Update software state */
    222             l2gre_info->match_key[vp].flags = _BCM_L2GRE_PORT_MATCH_TYPE_VLAN;
    223             l2gre_info->match_key[vp].match_vlan = l2gre_port->match_vlan;
    224             if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) {
    225                 l2gre_info->match_key[vp].trunk_id = trunk_id;
    226                 l2gre_info->match_key[vp].modid = -1;
    227             } else {
    228                 l2gre_info->match_key[vp].port = port_out;
    229                 l2gre_info->match_key[vp].modid = mod_out;
    230                 l2gre_info->match_key[vp].trunk_id = -1;
    231             }
    232         }
    233         if (!(l2gre_port->flags & BCM_L2GRE_PORT_REPLACE)) {
    234               bcm_tr3_l2gre_port_match_count_adjust(unit, vp, 1);
    235         }
    236     } else if (l2gre_port->criteria ==
    237                             BCM_L2GRE_PORT_MATCH_PORT_INNER_VLAN) {
    238         if (!BCM_VLAN_VALID(l2gre_port->match_inner_vlan)) {
    239             return BCM_E_PARAM;
    240         }
    241 
    242         soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID);
    243 #if defined(BCM_TRIDENT3_SUPPORT)
    244         if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
    245             soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID);
    246         }
    247 #endif
    248         soc_mem_field32_set(unit, mem, vent, XLATE__IVIDf, l2gre_port->match_inner_vlan);
    249         if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) {
    250             soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1);
    251             soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, trunk_id);
    252         } else {
    253             soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf, mod_out);
    254             soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf, port_out);
    255         }
    256 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    257         if (soc_feature(unit, soc_feature_vp_sharing)) {
    258             BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
    259             if (vp_info.flags & _BCM_VP_INFO_SHARED_PORT) {
    260                 int vfi = 0;
    261                 _BCM_L2GRE_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn);
    262                 soc_mem_field32_set(unit, mem, vent, XLATE__VFIf, vfi);
    263             }
    264         }
    265 #endif
    266         BCM_IF_ERROR_RETURN(
    267             _bcm_td2_l2gre_match_vxlate_entry_set(unit, l2gre_port, vent));
    268         if (l2gre_info->match_key[vp].flags != _BCM_L2GRE_PORT_MATCH_TYPE_SHARED) {
    269             l2gre_info->match_key[vp].flags = _BCM_L2GRE_PORT_MATCH_TYPE_INNER_VLAN;
    270             l2gre_info->match_key[vp].match_inner_vlan = l2gre_port->match_inner_vlan;
    271             if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) {
    272                 l2gre_info->match_key[vp].trunk_id = trunk_id;
    273                 l2gre_info->match_key[vp].modid = -1;
    274             } else {
    275                 l2gre_info->match_key[vp].port = port_out;
    276                 l2gre_info->match_key[vp].modid = mod_out;
    277                 l2gre_info->match_key[vp].trunk_id = -1;
    278             }
    279 		}
    280         if (!(l2gre_port->flags & BCM_L2GRE_PORT_REPLACE)) {
    281              bcm_tr3_l2gre_port_match_count_adjust(unit, vp, 1);
    282         }
    283     } else if (l2gre_port->criteria ==
    284                             BCM_L2GRE_PORT_MATCH_PORT_VLAN_STACKED) {
    285         if (!BCM_VLAN_VALID(l2gre_port->match_vlan) ||
    286                !BCM_VLAN_VALID(l2gre_port->match_inner_vlan)) {
    287              return BCM_E_PARAM;
    288         }
    289 
    290         soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID_OVID);
    291 #if defined(BCM_TRIDENT3_SUPPORT)
    292         if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
    293             soc_mem_field32_set(unit, mem, vent, DATA_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID_OVID);
    294 }
    295 #endif
    296         soc_mem_field32_set(unit, mem, vent, XLATE__OVIDf, l2gre_port->match_vlan);
    297         soc_mem_field32_set(unit, mem, vent, XLATE__IVIDf, l2gre_port->match_inner_vlan);
    298         if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) {
    299            soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1);
    300            soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, trunk_id);
    301         } else {
    302            soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf, mod_out);
    303            soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf, port_out);
    304         }
    305 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    306 	if (soc_feature(unit, soc_feature_vp_sharing)) {
    307             BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
    308             if (vp_info.flags & _BCM_VP_INFO_SHARED_PORT) {
    309                 int vfi = 0;
    310                 _BCM_L2GRE_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn);
    311                 soc_mem_field32_set(unit, mem, vent, XLATE__VFIf, vfi);
    312             }
    313         }
    314 #endif
    315         BCM_IF_ERROR_RETURN(
    316             _bcm_td2_l2gre_match_vxlate_entry_set(unit, l2gre_port, vent));
    317         if (l2gre_info->match_key[vp].flags != _BCM_L2GRE_PORT_MATCH_TYPE_SHARED) {
    318             l2gre_info->match_key[vp].flags = _BCM_L2GRE_PORT_MATCH_TYPE_VLAN_STACKED;
    319             l2gre_info->match_key[vp].match_vlan = l2gre_port->match_vlan;
    320             l2gre_info->match_key[vp].match_inner_vlan = l2gre_port->match_inner_vlan;
    321             if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) {
    322                 l2gre_info->match_key[vp].trunk_id = trunk_id;
    323                 l2gre_info->match_key[vp].modid = -1;
    324             } else {
    325                 l2gre_info->match_key[vp].port = port_out;
    326                 l2gre_info->match_key[vp].modid = mod_out;
    327                 l2gre_info->match_key[vp].trunk_id = -1;
    328             }
    329         }
    330         if (!(l2gre_port->flags & BCM_L2GRE_PORT_REPLACE)) {
    331             bcm_tr3_l2gre_port_match_count_adjust(unit, vp, 1);
    332         }
    333     } else if (l2gre_port->criteria ==
    334                                       BCM_L2GRE_PORT_MATCH_VLAN_PRI) {
    335         soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_PRI_CFI);
    336         /* match_vlan : Bits 12-15 contains VLAN_PRI + CFI, vlan=BCM_E_NONE */
    337         soc_mem_field32_set(unit, mem, vent, OTAGf, l2gre_port->match_vlan);
    338         if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) {
    339              soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1);
    340              soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, trunk_id);
    341         } else {
    342              soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf, mod_out);
    343              soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf, port_out);
    344         }
    345 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    346 		if (soc_feature(unit, soc_feature_vp_sharing)) {
    347             BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
    348             if (vp_info.flags & _BCM_VP_INFO_SHARED_PORT) {
    349                 int vfi = 0;
    350                 _BCM_L2GRE_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vpn);
    351                 soc_mem_field32_set(unit, mem, vent, XLATE__VFIf, vfi);
    352             }
    353         }
    354 #endif
    355         BCM_IF_ERROR_RETURN(
    356             _bcm_td2_l2gre_match_vxlate_entry_set(unit, l2gre_port, vent));
    357         if (l2gre_info->match_key[vp].flags != _BCM_L2GRE_PORT_MATCH_TYPE_SHARED) {
    358             l2gre_info->match_key[vp].flags = _BCM_L2GRE_PORT_MATCH_TYPE_VLAN_PRI;
    359             l2gre_info->match_key[vp].match_vlan = l2gre_port->match_vlan;
    360             if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) {
    361                 l2gre_info->match_key[vp].trunk_id = trunk_id;
    362                 l2gre_info->match_key[vp].modid = -1;
    363             } else {
    364                 l2gre_info->match_key[vp].port = port_out;
    365                 l2gre_info->match_key[vp].modid = mod_out;
    366                 l2gre_info->match_key[vp].trunk_id = -1;
    367             }
    368         }
    369         if (!(l2gre_port->flags & BCM_L2GRE_PORT_REPLACE)) {
    370              bcm_tr3_l2gre_port_match_count_adjust(unit, vp, 1);
    371         }
    372     }else if (l2gre_port->criteria == BCM_L2GRE_PORT_MATCH_PORT) {
    373         if (l2gre_info->match_key[vp].flags ==
    374                      _BCM_L2GRE_PORT_MATCH_TYPE_SHARED) {
    375             return BCM_E_PARAM;
    376         }
    377         if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) {
    378              rv = bcm_tr3_l2gre_match_trunk_add(unit, trunk_id, vp);
    379              if (rv >= 0) {
    380                    l2gre_info->match_key[vp].flags = _BCM_L2GRE_PORT_MATCH_TYPE_TRUNK;
    381                    l2gre_info->match_key[vp].trunk_id = trunk_id;
    382              }
    383              BCM_IF_ERROR_RETURN(rv);
    384         } else {
    385             int is_local;
    386 
    387             BCM_IF_ERROR_RETURN
    388                 ( _bcm_esw_modid_is_local(unit, mod_out, &is_local));
    389 
    390             /* Get index to source trunk map table */
    391             BCM_IF_ERROR_RETURN(
    392                    _bcm_esw_src_mod_port_table_index_get(unit, mod_out,
    393                      port_out, &src_trk_idx));
    394 
    395             rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm,
    396                                         src_trk_idx, SOURCE_VPf, vp);
    397             BCM_IF_ERROR_RETURN(rv);
    398             /* Enable SVP Mode */
    399             if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, SVP_VALIDf) ) {
    400                 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm,
    401                                         src_trk_idx, SVP_VALIDf, 0x1);
    402                 BCM_IF_ERROR_RETURN(rv);
    403             }
    404             if (is_local) {
    405                 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit,
    406                         l2gre_port->match_port, _BCM_CPU_TABS_NONE,
    407                         PORT_OPERATIONf, 0x1)); /* L2_SVP */
    408 
    409                 /* Set TAG_ACTION_PROFILE_PTR */
    410                 rv = bcm_tr3_l2gre_port_untagged_profile_set(unit, port_out);
    411                 BCM_IF_ERROR_RETURN(rv);
    412             }
    413 
    414             l2gre_info->match_key[vp].flags = _BCM_L2GRE_PORT_MATCH_TYPE_PORT;
    415             l2gre_info->match_key[vp].index = src_trk_idx;
    416         }
    417     }else if (l2gre_port->criteria == BCM_L2GRE_PORT_MATCH_VPNID) {
    418         BCM_IF_ERROR_RETURN(
    419             bcm_tr3_l2gre_match_tunnel_entry_set(unit, vp, l2gre_port));
    420     }
    421 
    422     return rv;
    423 }
    424 
    425 /*
    426  * Function:
    427  *      bcm_td2_l2gre_match_delete
    428  * Purpose:
    429  *      Delete match criteria of an L2GRE port
    430  * Parameters:
    431  *      unit    - (IN) Device Number
    432  *      l2gre_port - (IN) L2GRE port information
    433  *      vp  - (IN) Source Virtual Port
    434  * Returns:
    435  *      BCM_E_XXX
    436  */
    437 
    438 int
    439 bcm_td2_l2gre_match_delete(int unit,  int vp, bcm_l2gre_port_t *l2gre_port)
    440 {
    441     _bcm_tr3_l2gre_bookkeeping_t *l2gre_info = L2GRE_INFO(unit);
    442     int rv=BCM_E_NONE;
    443     bcm_trunk_t trunk_id;
    444     int    mod_id_idx=0;   /* Module_Id */
    445     soc_mem_t mem;
    446     uint32 vent[SOC_MAX_MEM_WORDS] = {0};
    447 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    448     bcm_module_t mod_out = -1;
    449     bcm_port_t port_out = -1;
    450     int    gport_id =-1;
    451 #endif
    452     int    src_trk_idx = 0;   /*Source Trunk table index.*/
    453     int    port = 0;
    454 
    455 #if defined(BCM_TRIDENT3_SUPPORT)
    456     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
    457         mem = VLAN_XLATE_1_DOUBLEm;
    458 
    459         soc_mem_field32_set(unit, mem, vent, BASE_VALID_0f, 3);
    460         soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7);
    461     } else
    462 #endif
    463     {
    464         mem = VLAN_XLATEm;
    465 
    466         soc_mem_field32_set(unit, mem, vent, VALIDf, 1);
    467     }
    468 
    469     /* Get module id for unit. */
    470     BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mod_id_idx));
    471 
    472     if  (l2gre_info->match_key[vp].flags == _BCM_L2GRE_PORT_MATCH_TYPE_VLAN) {
    473         soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1);
    474         soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_OVID);
    475 #if defined(BCM_TRIDENT3_SUPPORT)
    476         if (mem == VLAN_XLATE_1_DOUBLEm) {
    477             soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
    478                                 TR_VLXLT_HASH_KEY_TYPE_OVID);
    479         }
    480 #endif
    481         soc_mem_field32_set(unit, mem, vent, XLATE__OVIDf,
    482                         l2gre_info->match_key[vp].match_vlan);
    483         if (l2gre_info->match_key[vp].modid != -1) {
    484             soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf,
    485                                         l2gre_info->match_key[vp].modid);
    486             soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf,
    487                                         l2gre_info->match_key[vp].port);
    488         } else {
    489             soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1);
    490             soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf,
    491                                     l2gre_info->match_key[vp].trunk_id);
    492         }
    493         rv = soc_mem_delete(unit, mem, MEM_BLOCK_ANY, vent);
    494         BCM_IF_ERROR_RETURN(rv);
    495 
    496         (void) bcm_tr3_l2gre_match_clear (unit, vp);
    497          bcm_tr3_l2gre_port_match_count_adjust(unit, vp, -1);
    498     } else if  (l2gre_info->match_key[vp].flags ==
    499                      _BCM_L2GRE_PORT_MATCH_TYPE_INNER_VLAN) {
    500         soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1);
    501         soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, VLXLT_HASH_KEY_TYPE_IVID);
    502 #if defined(BCM_TRIDENT3_SUPPORT)
    503         if (mem == VLAN_XLATE_1_DOUBLEm) {
    504             soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
    505                                 VLXLT_HASH_KEY_TYPE_IVID);
    506         }
    507 #endif
    508         soc_mem_field32_set(unit, mem, vent, XLATE__IVIDf,
    509                     l2gre_info->match_key[vp].match_inner_vlan);
    510         if (l2gre_info->match_key[vp].modid != -1) {
    511             soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf,
    512                                         l2gre_info->match_key[vp].modid);
    513             soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf,
    514                                         l2gre_info->match_key[vp].port);
    515         } else {
    516             soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1);
    517             soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf,
    518                                 l2gre_info->match_key[vp].trunk_id);
    519         }
    520         rv = soc_mem_delete(unit, mem, MEM_BLOCK_ANY, &vent);
    521         BCM_IF_ERROR_RETURN(rv);
    522 
    523         (void) bcm_tr3_l2gre_match_clear (unit, vp);
    524         bcm_tr3_l2gre_port_match_count_adjust(unit, vp, -1);
    525     } else if (l2gre_info->match_key[vp].flags ==
    526                     _BCM_L2GRE_PORT_MATCH_TYPE_VLAN_STACKED) {
    527         soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1);
    528         soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID_OVID);
    529 #if defined(BCM_TRIDENT3_SUPPORT)
    530         if (mem == VLAN_XLATE_1_DOUBLEm) {
    531             soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
    532                                 TR_VLXLT_HASH_KEY_TYPE_IVID_OVID);
    533         }
    534 #endif
    535         soc_mem_field32_set(unit, mem, vent,
    536             XLATE__OVIDf, l2gre_info->match_key[vp].match_vlan);
    537         soc_mem_field32_set(unit, mem, vent,
    538             XLATE__IVIDf, l2gre_info->match_key[vp].match_inner_vlan);
    539         if (l2gre_info->match_key[vp].modid != -1) {
    540             soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf,
    541                                         l2gre_info->match_key[vp].modid);
    542             soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf,
    543                                         l2gre_info->match_key[vp].port);
    544         } else {
    545             soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1);
    546             soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf,
    547                                 l2gre_info->match_key[vp].trunk_id);
    548         }
    549         rv = soc_mem_delete(unit, mem, MEM_BLOCK_ANY, vent);
    550         BCM_IF_ERROR_RETURN(rv);
    551 
    552         (void) bcm_tr3_l2gre_match_clear (unit, vp);
    553         bcm_tr3_l2gre_port_match_count_adjust(unit, vp, -1);
    554     } else if	(l2gre_info->match_key[vp].flags ==
    555                                                _BCM_L2GRE_PORT_MATCH_TYPE_VLAN_PRI) {
    556         soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1);
    557         soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_PRI_CFI);
    558 #if defined(BCM_TRIDENT3_SUPPORT)
    559         if (mem == VLAN_XLATE_1_DOUBLEm) {
    560             soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
    561                                 TR_VLXLT_HASH_KEY_TYPE_PRI_CFI);
    562         }
    563 #endif
    564 
    565         soc_mem_field32_set(unit, mem, vent, XLATE__OTAGf,
    566                                l2gre_info->match_key[vp].match_vlan);
    567         if (l2gre_info->match_key[vp].modid != -1) {
    568             soc_mem_field32_set(unit, mem, vent,
    569                 XLATE__MODULE_IDf, l2gre_info->match_key[vp].modid);
    570             soc_mem_field32_set(unit, mem, vent,
    571                 XLATE__PORT_NUMf, l2gre_info->match_key[vp].port);
    572         } else {
    573             soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1);
    574             soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf,
    575                                   l2gre_info->match_key[vp].trunk_id);
    576         }
    577         rv = soc_mem_delete(unit, mem, MEM_BLOCK_ANY, vent);
    578         BCM_IF_ERROR_RETURN(rv);
    579 
    580         (void) bcm_tr3_l2gre_match_clear (unit, vp);
    581         bcm_tr3_l2gre_port_match_count_adjust(unit, vp, -1);
    582     }
    583 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    584     else if (l2gre_info->match_key[vp].flags ==
    585                     _BCM_L2GRE_PORT_MATCH_TYPE_SHARED) {
    586         bcm_trunk_t trunk_id = -1;
    587         if (NULL == l2gre_port) {
    588             return BCM_E_PARAM;
    589         }
    590 
    591         soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1);
    592 
    593         if (BCM_L2GRE_PORT_MATCH_PORT_VLAN == l2gre_port->criteria) {
    594             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf,
    595                                 TR_VLXLT_HASH_KEY_TYPE_OVID);
    596             soc_mem_field32_set(unit, mem, vent, XLATE__OVIDf,
    597                                 l2gre_port->match_vlan);
    598         } else if (BCM_L2GRE_PORT_MATCH_PORT_VLAN_STACKED == l2gre_port->criteria) {
    599             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf,
    600                                 TR_VLXLT_HASH_KEY_TYPE_IVID_OVID);
    601 #if defined(BCM_TRIDENT3_SUPPORT)
    602             if (mem == VLAN_XLATE_1_DOUBLEm) {
    603                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
    604                                     TR_VLXLT_HASH_KEY_TYPE_IVID_OVID);
    605             }
    606 #endif
    607             soc_mem_field32_set(unit, mem, vent, XLATE__OVIDf,
    608                                 l2gre_port->match_vlan);
    609             soc_mem_field32_set(unit, mem, vent, XLATE__IVIDf,
    610                                 l2gre_port->match_inner_vlan);
    611         } else if (BCM_L2GRE_PORT_MATCH_PORT_INNER_VLAN == l2gre_port->criteria) {
    612             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf,
    613                                 TR_VLXLT_HASH_KEY_TYPE_IVID);
    614 #if defined(BCM_TRIDENT3_SUPPORT)
    615             if (mem == VLAN_XLATE_1_DOUBLEm) {
    616                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
    617                                     TR_VLXLT_HASH_KEY_TYPE_IVID);
    618             }
    619 #endif
    620             soc_mem_field32_set(unit, mem, vent, XLATE__IVIDf,
    621                                 l2gre_port->match_inner_vlan);
    622         } else if (BCM_L2GRE_PORT_MATCH_VLAN_PRI == l2gre_port->criteria) {
    623             soc_mem_field32_set(unit, mem, vent, KEY_TYPEf,
    624                                 TR_VLXLT_HASH_KEY_TYPE_PRI_CFI);
    625 #if defined(BCM_TRIDENT3_SUPPORT)
    626             if (mem == VLAN_XLATE_1_DOUBLEm) {
    627                 soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
    628                                     TR_VLXLT_HASH_KEY_TYPE_PRI_CFI);
    629             }
    630 #endif
    631             soc_mem_field32_set(unit, mem, vent, XLATE__OTAGf,
    632                                 l2gre_port->match_vlan);
    633         } else {
    634             return BCM_E_UNAVAIL;
    635         }
    636 
    637         BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, l2gre_port->match_port, &mod_out,
    638                         &port_out, &trunk_id, &gport_id));
    639 
    640         if (BCM_GPORT_IS_TRUNK(l2gre_port->match_port)) {
    641             soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1);
    642             soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, trunk_id);
    643         } else {
    644             soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf, mod_out);
    645             soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf, port_out);
    646         }
    647 
    648         rv = soc_mem_delete(unit, mem, MEM_BLOCK_ANY, &vent);
    649         BCM_IF_ERROR_RETURN(rv);
    650 
    651         bcm_tr3_l2gre_port_match_count_adjust(unit, vp, -1);
    652     }
    653 #endif
    654     else if  (l2gre_info->match_key[vp].flags ==
    655                     _BCM_L2GRE_PORT_MATCH_TYPE_PORT) {
    656         int is_local;
    657 
    658         src_trk_idx = l2gre_info->match_key[vp].index;
    659         rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm,
    660                                   src_trk_idx, SOURCE_VPf, 0);
    661         BCM_IF_ERROR_RETURN(rv);
    662         /* Disable SVP Mode */
    663         if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, SVP_VALIDf) ) {
    664                rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm,
    665                                        src_trk_idx, SVP_VALIDf, 0x0);
    666                BCM_IF_ERROR_RETURN(rv);
    667         }
    668 
    669         BCM_IF_ERROR_RETURN(_bcm_esw_src_modid_port_get( unit, src_trk_idx,
    670                                                           &mod_id_idx, &port));
    671         BCM_IF_ERROR_RETURN
    672             ( _bcm_esw_modid_is_local(unit, mod_id_idx, &is_local));
    673 
    674         if (is_local) {
    675            BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit,
    676                 port, _BCM_CPU_TABS_NONE, PORT_OPERATIONf, 0x0));
    677 
    678            /* Reset TAG_ACTION_PROFILE_PTR */
    679            rv = bcm_tr3_l2gre_port_untagged_profile_reset(unit, port);
    680            BCM_IF_ERROR_RETURN(rv);
    681         }
    682         (void) bcm_tr3_l2gre_match_clear (unit, vp);
    683     } else if (l2gre_info->match_key[vp].flags ==
    684                   _BCM_L2GRE_PORT_MATCH_TYPE_TRUNK) {
    685          trunk_id = l2gre_info->match_key[vp].trunk_id;
    686          rv = bcm_tr3_l2gre_match_trunk_delete(unit, trunk_id, vp);
    687          BCM_IF_ERROR_RETURN(rv);
    688 
    689         (void) bcm_tr3_l2gre_match_clear (unit, vp);
    690     } else if (l2gre_info->match_key[vp].flags ==
    691                   _BCM_L2GRE_PORT_MATCH_TYPE_VPNID) {
    692         rv = bcm_tr3_l2gre_match_tunnel_entry_reset(unit, vp);
    693     }
    694     return rv;
    695 }
    696 
    697 /*
    698  * Function:
    699  *      _bcm_td2_l2gre_match_get
    700  * Purpose:
    701  *      Obtain match information of an l2gre port
    702  * Parameters:
    703  *      unit    - (IN) Device Number
    704  *      l2gre_port - (OUT) l2gre port information
    705  *      vp  - (IN) Source Virtual Port
    706  * Returns:
    707  *      BCM_E_XXX
    708  */
    709 
    710 int
    711 bcm_td2_l2gre_match_get(int unit, bcm_l2gre_port_t *l2gre_port, int vp)
    712 {
    713     _bcm_tr3_l2gre_bookkeeping_t *l2gre_info = L2GRE_INFO(unit);
    714     bcm_module_t mod_in=0, mod_out=0;
    715     bcm_port_t port_in=0, port_out=0;
    716     bcm_trunk_t trunk_id=0;
    717     int    src_trk_idx=0;    /*Source Trunk table index.*/
    718     int    tunnel_idx = -1;
    719     int    index;
    720     soc_mem_t mem;
    721     uint32 vent[SOC_MAX_MEM_WORDS] = {0};
    722 
    723 #if defined(BCM_TRIDENT3_SUPPORT)
    724     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
    725         mem = VLAN_XLATE_1_DOUBLEm;
    726 
    727         soc_mem_field32_set(unit, mem, vent, BASE_VALID_0f, 3);
    728         soc_mem_field32_set(unit, mem, vent, BASE_VALID_1f, 7);
    729     } else
    730 #endif
    731     {
    732         mem = VLAN_XLATEm;
    733 
    734         soc_mem_field32_set(unit, mem, vent, VALIDf, 1);
    735     }
    736     soc_mem_field32_set(unit, mem, vent, SOURCE_TYPEf, 1);
    737 
    738     if  (l2gre_info->match_key[vp].flags & _BCM_L2GRE_PORT_MATCH_TYPE_VLAN) {
    739         soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_OVID);
    740 #if defined(BCM_TRIDENT3_SUPPORT)
    741         if (mem == VLAN_XLATE_1_DOUBLEm) {
    742             soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
    743                                 TR_VLXLT_HASH_KEY_TYPE_OVID);
    744         }
    745 #endif
    746 
    747         l2gre_port->criteria = BCM_L2GRE_PORT_MATCH_PORT_VLAN;
    748         l2gre_port->match_vlan = l2gre_info->match_key[vp].match_vlan;
    749         soc_mem_field32_set(unit, mem, vent, XLATE__OVIDf, l2gre_port->match_vlan);
    750     } else if (l2gre_info->match_key[vp].flags &
    751                  _BCM_L2GRE_PORT_MATCH_TYPE_INNER_VLAN) {
    752         soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID);
    753 #if defined(BCM_TRIDENT3_SUPPORT)
    754         if (mem == VLAN_XLATE_1_DOUBLEm) {
    755             soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
    756                                 TR_VLXLT_HASH_KEY_TYPE_IVID);
    757         }
    758 #endif
    759 
    760         l2gre_port->criteria = BCM_L2GRE_PORT_MATCH_PORT_INNER_VLAN;
    761         l2gre_port->match_inner_vlan = l2gre_info->match_key[vp].match_inner_vlan;
    762         soc_mem_field32_set(unit, mem, vent, XLATE__IVIDf, l2gre_port->match_inner_vlan);
    763     }else if (l2gre_info->match_key[vp].flags &
    764                    _BCM_L2GRE_PORT_MATCH_TYPE_VLAN_STACKED) {
    765         soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_IVID_OVID);
    766 #if defined(BCM_TRIDENT3_SUPPORT)
    767         if (mem == VLAN_XLATE_1_DOUBLEm) {
    768             soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
    769                                 TR_VLXLT_HASH_KEY_TYPE_IVID_OVID);
    770         }
    771 #endif
    772 
    773         l2gre_port->criteria = BCM_L2GRE_PORT_MATCH_PORT_VLAN_STACKED;
    774         l2gre_port->match_vlan = l2gre_info->match_key[vp].match_vlan;
    775         l2gre_port->match_inner_vlan = l2gre_info->match_key[vp].match_inner_vlan;
    776         soc_mem_field32_set(unit, mem, vent, XLATE__OVIDf, l2gre_port->match_vlan);
    777         soc_mem_field32_set(unit, mem, vent, XLATE__IVIDf, l2gre_port->match_inner_vlan);
    778     } else if  (l2gre_info->match_key[vp].flags &  _BCM_L2GRE_PORT_MATCH_TYPE_VLAN_PRI) {
    779         soc_mem_field32_set(unit, mem, vent, KEY_TYPEf, TR_VLXLT_HASH_KEY_TYPE_PRI_CFI);
    780 #if defined(BCM_TRIDENT3_SUPPORT)
    781         if (mem == VLAN_XLATE_1_DOUBLEm) {
    782             soc_mem_field32_set(unit, mem, vent, DATA_TYPEf,
    783                                 TR_VLXLT_HASH_KEY_TYPE_PRI_CFI);
    784         }
    785 #endif
    786 
    787         l2gre_port->criteria = BCM_L2GRE_PORT_MATCH_VLAN_PRI;
    788         l2gre_port->match_vlan = l2gre_info->match_key[vp].match_vlan;
    789         soc_mem_field32_set(unit, mem, vent, OTAGf, l2gre_port->match_vlan);
    790     } else if (l2gre_info->match_key[vp].flags &
    791                   _BCM_L2GRE_PORT_MATCH_TYPE_PORT) {
    792 
    793         src_trk_idx = l2gre_info->match_key[vp].index;
    794         BCM_IF_ERROR_RETURN(_bcm_esw_src_modid_port_get( unit, src_trk_idx,
    795                                                          &mod_in, &port_in));
    796 
    797         l2gre_port->criteria = BCM_L2GRE_PORT_MATCH_PORT;
    798         BCM_IF_ERROR_RETURN(_bcm_esw_stk_modmap_map(unit,
    799             BCM_STK_MODMAP_GET, mod_in, port_in, &mod_out, &port_out));
    800         BCM_GPORT_MODPORT_SET(l2gre_port->match_port, mod_out, port_out);
    801     }else if (l2gre_info->match_key[vp].flags &
    802                  _BCM_L2GRE_PORT_MATCH_TYPE_TRUNK) {
    803 
    804         trunk_id = l2gre_info->match_key[vp].trunk_id;
    805         l2gre_port->criteria = BCM_L2GRE_PORT_MATCH_PORT;
    806         BCM_GPORT_TRUNK_SET(l2gre_port->match_port, trunk_id);
    807     } else if ((l2gre_info->match_key[vp].flags &
    808                           _BCM_L2GRE_PORT_MATCH_TYPE_VPNID)) {
    809         l2gre_port->criteria = BCM_L2GRE_PORT_MATCH_VPNID;
    810 
    811         tunnel_idx = l2gre_info->match_key[vp].match_tunnel_index;
    812         BCM_GPORT_TUNNEL_ID_SET(l2gre_port->match_tunnel_id, tunnel_idx);
    813     }else if (l2gre_info->match_key[vp].flags & _BCM_L2GRE_PORT_MATCH_TYPE_SHARED) {
    814         l2gre_port->criteria = BCM_L2GRE_PORT_MATCH_SHARE;
    815     } else {
    816         l2gre_port->criteria = BCM_L2GRE_PORT_MATCH_NONE;
    817     }
    818 
    819     if (l2gre_port->criteria == BCM_L2GRE_PORT_MATCH_PORT_VLAN ||
    820         l2gre_port->criteria == BCM_L2GRE_PORT_MATCH_PORT_INNER_VLAN ||
    821         l2gre_port->criteria == BCM_L2GRE_PORT_MATCH_PORT_VLAN_STACKED ||
    822         l2gre_port->criteria == BCM_L2GRE_PORT_MATCH_VLAN_PRI) {
    823 
    824         if (l2gre_info->match_key[vp].trunk_id != -1) {
    825             trunk_id = l2gre_info->match_key[vp].trunk_id;
    826             BCM_GPORT_TRUNK_SET(l2gre_port->match_port, trunk_id);
    827             soc_mem_field32_set(unit, mem, vent, XLATE__Tf, 1);
    828             soc_mem_field32_set(unit, mem, vent, XLATE__TGIDf, trunk_id);
    829         } else {
    830             port_in = l2gre_info->match_key[vp].port;
    831             mod_in = l2gre_info->match_key[vp].modid;
    832             BCM_IF_ERROR_RETURN(_bcm_esw_stk_modmap_map(unit,
    833                 BCM_STK_MODMAP_GET, mod_in, port_in, &mod_out, &port_out));
    834             BCM_GPORT_MODPORT_SET(l2gre_port->match_port, mod_out, port_out);
    835             soc_mem_field32_set(unit, mem, vent, XLATE__MODULE_IDf, mod_in);
    836             soc_mem_field32_set(unit, mem, vent, XLATE__PORT_NUMf, port_in);
    837         }
    838 
    839         BCM_IF_ERROR_RETURN(
    840             soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index, vent, vent, 0));
    841 
    842         if (soc_mem_field32_get(unit, mem, vent, XLATE__VLAN_ACTION_VALIDf)) {
    843             l2gre_port->flags |= BCM_L2GRE_PORT_ENABLE_VLAN_CHECKS;
    844         }
    845     }
    846 
    847     return BCM_E_NONE;
    848 }
    849 
    850 /*
    851  * Function:
    852  *      _bcm_td2_l2gre_eline_vp_configure
    853  * Purpose:
    854  *      Configure L2GRE ELINE virtual port
    855  * Parameters:
    856  *      unit    - (IN) Device Number
    857  *      vpn     - (IN) VPN instance ID
    858  * Returns:
    859  *      BCM_E_XXX
    860  */
    861 
    862 int
    863 _bcm_td2_l2gre_eline_vp_configure (int unit, int vfi_index, int active_vp,
    864                   source_vp_entry_t *svp, int tpid_enable, bcm_l2gre_port_t  *l2gre_port)
    865 {
    866     int rv = BCM_E_NONE;
    867     int network_group=0;
    868     source_vp_2_entry_t svp_2_entry;
    869 
    870     /* Set SOURCE_VP */
    871     soc_SOURCE_VPm_field32_set(unit, svp, CLASS_IDf,
    872                                 l2gre_port->if_class);
    873 
    874     network_group = l2gre_port->network_group_id;
    875     rv = _bcm_validate_splithorizon_network_group(unit,
    876             l2gre_port->flags & BCM_L2GRE_PORT_NETWORK, &network_group);
    877     BCM_IF_ERROR_RETURN(rv);
    878 
    879     /*Default Split Horizon Group Id
    880      *0 - For Access Port;1 - For Network Port*/
    881     if (l2gre_port->flags & BCM_L2GRE_PORT_NETWORK) {
    882         if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) {
    883             soc_SOURCE_VPm_field32_set(unit, svp, NETWORK_GROUPf,
    884                         network_group);
    885         } else {
    886             soc_SOURCE_VPm_field32_set(unit, svp, NETWORK_PORTf, 1);
    887         }
    888 #if defined(BCM_TRIDENT3_SUPPORT)
    889         if (SOC_IS_TRIDENT3X(unit)) {
    890         } else
    891 #endif
    892         {
    893             soc_SOURCE_VPm_field32_set(unit, svp, TPID_SOURCEf, _BCM_L2GRE_TPID_SVP_BASED);
    894         }
    895     } else {
    896         if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) {
    897             soc_SOURCE_VPm_field32_set(unit, svp, NETWORK_GROUPf,
    898                         network_group);
    899         } else {
    900             soc_SOURCE_VPm_field32_set(unit, svp, NETWORK_PORTf, 0);
    901         }
    902 #if defined(BCM_TRIDENT3_SUPPORT)
    903         if (SOC_IS_TRIDENT3X(unit)) {
    904         } else
    905 #endif
    906         {
    907             soc_SOURCE_VPm_field32_set(unit, svp, TPID_SOURCEf, _BCM_L2GRE_TPID_SGLP_BASED);
    908             /*  Configure IPARS Parser to signal to IMPLS Parser - Applicable only for HG2 PPD2 packets
    909                   to reconstruct TPID state based on HG header information - Only for VXLAN Access ports */
    910             sal_memset(&svp_2_entry, 0, sizeof(source_vp_2_entry_t));
    911             soc_SOURCE_VP_2m_field32_set(unit, &svp_2_entry, PARSE_USING_SGLP_TPIDf, 1);
    912             BCM_IF_ERROR_RETURN(WRITE_SOURCE_VP_2m(unit,
    913                     MEM_BLOCK_ALL, active_vp, &svp_2_entry));
    914         }
    915     }
    916 
    917     if (l2gre_port->flags & BCM_L2GRE_PORT_SERVICE_TAGGED) {
    918          soc_SOURCE_VPm_field32_set(unit, svp, SD_TAG_MODEf, 1);
    919 #if defined(BCM_TRIDENT3_SUPPORT)
    920          if (SOC_IS_TRIDENT3X(unit)) {
    921              uint32 svp1[SOC_MAX_MEM_WORDS];
    922 
    923              sal_memset(svp1, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS);
    924 
    925              soc_SVP_ATTRS_1m_field_set(unit, &svp1, TPID_ENABLEf, (uint32 *)&tpid_enable);
    926              BCM_IF_ERROR_RETURN(WRITE_SVP_ATTRS_1m(unit, MEM_BLOCK_ALL, active_vp, &svp1));
    927          } else
    928 #endif
    929          {
    930              soc_SOURCE_VPm_field32_set(unit, svp, TPID_ENABLEf, tpid_enable);
    931          }
    932     } else {
    933          soc_SOURCE_VPm_field32_set(unit, svp, SD_TAG_MODEf, 0);
    934     }
    935 
    936     soc_SOURCE_VPm_field32_set(unit, svp, DISABLE_VLAN_CHECKSf, 1);
    937     soc_SOURCE_VPm_field32_set(unit, svp,
    938                            ENTRY_TYPEf, _BCM_L2GRE_SOURCE_VP_TYPE_VFI); /* VFI Type */
    939     soc_SOURCE_VPm_field32_set(unit, svp, VFIf, vfi_index);
    940 
    941     rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, active_vp, svp);
    942 
    943 #if defined(BCM_TRIDENT3_SUPPORT)
    944     if (SOC_IS_TRIDENT3X(unit)) {
    945         if ((vfi_index != _BCM_L2GRE_VFI_INVALID) &&
    946             (l2gre_port->flags & BCM_L2GRE_PORT_NETWORK)) {
    947             if ( BCM_E_NONE != soc_cancun_app_dest_entry_set (unit, SOURCE_VPm,
    948                 active_vp, ENTRY_TYPEf, CANCUN_APP__SOURCE_VP__No_Control_Word,
    949                 _BCM_L2GRE_SOURCE_VP_TYPE_VFI)) {
    950                 LOG_ERROR(BSL_LS_BCM_L2GRE,
    951                    (BSL_META_U(unit,"SOURCE_VP cancun app cfg error\n")));
    952             }
    953         }
    954     }
    955 #endif
    956 
    957     return rv;
    958 }
    959 
    960 /*
    961  * Function:
    962  *      _bcm_td2_l2gre_elan_vp_configure
    963  * Purpose:
    964  *      Configure L2GRE ELAN virtual port
    965  * Parameters:
    966  *      unit    - (IN) Device Number
    967  *      vpn     - (IN) VPN instance ID
    968  * Returns:
    969  *      BCM_E_XXX
    970  */
    971 
    972 int
    973 _bcm_td2_l2gre_elan_vp_configure (int unit, int vfi_index, int vp,
    974                   source_vp_entry_t *svp, int tpid_enable, bcm_l2gre_port_t  *l2gre_port)
    975 {
    976     int rv = BCM_E_NONE;
    977     int network_group=0;
    978     int cml_default_enable=0, cml_default_new=0, cml_default_move=0;
    979     source_vp_2_entry_t svp_2_entry;
    980 
    981     /* Set SOURCE_VP */
    982     soc_SOURCE_VPm_field32_set(unit, svp, CLASS_IDf,
    983                          l2gre_port->if_class);
    984 
    985     if (vfi_index == _BCM_L2GRE_VFI_INVALID) {
    986         soc_SOURCE_VPm_field32_set(unit, svp,
    987                                    ENTRY_TYPEf, _BCM_L2GRE_SOURCE_VP_TYPE_INVALID); /* INVALID */
    988     } else {
    989         /* Initialize VP parameters */
    990         soc_SOURCE_VPm_field32_set(unit, svp,
    991                                    ENTRY_TYPEf, _BCM_L2GRE_SOURCE_VP_TYPE_VFI); /* VFI Type */
    992     }
    993 
    994 
    995     /*Default Split Horizon Group Id
    996      *0 - For Access Port;1 - For Network Port*/
    997     network_group = l2gre_port->network_group_id;
    998     rv = _bcm_validate_splithorizon_network_group(unit,
    999             l2gre_port->flags & BCM_L2GRE_PORT_NETWORK, &network_group);
   1000     BCM_IF_ERROR_RETURN(rv);
   1001 
   1002     if (l2gre_port->flags & BCM_L2GRE_PORT_NETWORK) {
   1003         if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) {
   1004             soc_SOURCE_VPm_field32_set(unit, svp, NETWORK_GROUPf,
   1005                         network_group);
   1006         } else {
   1007             soc_SOURCE_VPm_field32_set(unit, svp, NETWORK_PORTf, 1);
   1008         }
   1009 #if defined(BCM_TRIDENT3_SUPPORT)
   1010         if (SOC_IS_TRIDENT3X(unit)) {
   1011         } else
   1012 #endif
   1013         {
   1014             soc_SOURCE_VPm_field32_set(unit, svp, TPID_SOURCEf, _BCM_L2GRE_TPID_SVP_BASED);
   1015         }
   1016     } else {
   1017         if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) {
   1018             soc_SOURCE_VPm_field32_set(unit, svp, NETWORK_GROUPf,
   1019                          network_group);
   1020         } else {
   1021             soc_SOURCE_VPm_field32_set(unit, svp, NETWORK_PORTf, 0);
   1022         }
   1023 #if defined(BCM_TRIDENT3_SUPPORT)
   1024         if (SOC_IS_TRIDENT3X(unit)) {
   1025         } else
   1026 #endif
   1027         {
   1028             soc_SOURCE_VPm_field32_set(unit, svp, TPID_SOURCEf, _BCM_L2GRE_TPID_SGLP_BASED);
   1029             /*  Configure IPARS Parser to signal to IMPLS Parser - Applicable only for HG2 PPD2 packets
   1030                  to reconstruct TPID state based on HG header information - Only for VXLAN Access ports */
   1031             sal_memset(&svp_2_entry, 0, sizeof(source_vp_2_entry_t));
   1032             soc_SOURCE_VP_2m_field32_set(unit, &svp_2_entry, PARSE_USING_SGLP_TPIDf, 1);
   1033             BCM_IF_ERROR_RETURN(WRITE_SOURCE_VP_2m(unit, MEM_BLOCK_ALL, vp, &svp_2_entry));
   1034         }
   1035     }
   1036 
   1037     if (vfi_index == _BCM_L2GRE_VFI_INVALID) {
   1038         soc_SOURCE_VPm_field32_set(unit, svp, VFIf, 0);
   1039     } else {
   1040         soc_SOURCE_VPm_field32_set(unit, svp, VFIf, vfi_index);
   1041     }
   1042 
   1043     if (l2gre_port->flags & BCM_L2GRE_PORT_SERVICE_TAGGED) {
   1044          soc_SOURCE_VPm_field32_set(unit, svp, SD_TAG_MODEf, 1);
   1045 #if defined(BCM_TRIDENT3_SUPPORT)
   1046         if (SOC_IS_TRIDENT3X(unit)) {
   1047             uint32 svp1[SOC_MAX_MEM_WORDS];
   1048 
   1049             sal_memset(svp1, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS);
   1050 
   1051             soc_SVP_ATTRS_1m_field_set(unit, &svp1, TPID_ENABLEf, (uint32 *)&tpid_enable);
   1052             BCM_IF_ERROR_RETURN(WRITE_SVP_ATTRS_1m(unit, MEM_BLOCK_ALL, vp, &svp1));
   1053         } else
   1054 #endif
   1055         {
   1056             soc_SOURCE_VPm_field32_set(unit, svp, TPID_ENABLEf, tpid_enable);
   1057         }
   1058     } else {
   1059          soc_SOURCE_VPm_field32_set(unit, svp, SD_TAG_MODEf, 0);
   1060     }
   1061     rv = _bcm_vp_default_cml_mode_get (unit,
   1062                        &cml_default_enable, &cml_default_new,
   1063                        &cml_default_move);
   1064     if (rv < 0) {
   1065          return rv;
   1066     }
   1067     if (cml_default_enable) {
   1068         /* Set the CML to default values */
   1069         soc_SOURCE_VPm_field32_set(unit, svp, CML_FLAGS_NEWf, cml_default_new);
   1070         soc_SOURCE_VPm_field32_set(unit, svp, CML_FLAGS_MOVEf, cml_default_move);
   1071     } else {
   1072         /* Set the CML to PVP_CML_SWITCH by default (hw learn and forward) */
   1073         soc_SOURCE_VPm_field32_set(unit, svp, CML_FLAGS_NEWf, 0x8);
   1074         soc_SOURCE_VPm_field32_set(unit, svp, CML_FLAGS_MOVEf, 0x8);
   1075     }
   1076     if (soc_mem_field_valid(unit, SOURCE_VPm, DISABLE_VLAN_CHECKSf)) {
   1077         if (!soc_feature(unit, soc_feature_vlan_vfi_membership)) {
   1078             soc_SOURCE_VPm_field32_set(unit, svp, DISABLE_VLAN_CHECKSf, 1);
   1079         }
   1080     }
   1081 
   1082     BCM_IF_ERROR_RETURN
   1083            (WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, svp));
   1084 
   1085 #if defined(BCM_TRIDENT3_SUPPORT)
   1086     if (SOC_IS_TRIDENT3X(unit)) {
   1087         if ((vfi_index != _BCM_L2GRE_VFI_INVALID) &&
   1088             (l2gre_port->flags & BCM_L2GRE_PORT_NETWORK)) {
   1089             if ( BCM_E_NONE != soc_cancun_app_dest_entry_set (unit, SOURCE_VPm,
   1090                 vp, ENTRY_TYPEf, CANCUN_APP__SOURCE_VP__No_Control_Word,
   1091                 _BCM_L2GRE_SOURCE_VP_TYPE_VFI)) {
   1092                 LOG_ERROR(BSL_LS_BCM_L2GRE,
   1093                    (BSL_META_U(unit,"SOURCE_VP cancun app cfg error\n")));
   1094             }
   1095         }
   1096     }
   1097 #endif
   1098 
   1099     return rv;
   1100 }
   1101 /*
   1102  * Function:
   1103  *      _bcm_td2_l2gre_match_vp_replace
   1104  * Purpose:
   1105  *      Replace VP value in L2GRE VP's match entry.
   1106  * Parameters:
   1107  *      unit   - (IN) SOC unit number.
   1108  *      vp     - (IN) L2GRE VP whose match entry is being replaced.
   1109  *      new_vp - (IN) New VP value.
   1110  *      old_vp - (OUT) Old VP value.
   1111  * Returns:
   1112  *      BCM_X_XXX
   1113  */
   1114 STATIC int
   1115 _bcm_td2_l2gre_match_vp_replace(int unit, int vp, int new_vp,
   1116                                 int *old_vp)
   1117 {
   1118     int                rv = BCM_E_NONE;
   1119     soc_mem_t          mem;
   1120     int                key_type = bcmVlanTranslateKeyInvalid;
   1121     uint32             svp_valid, tunnel_index, tunnel_sip;
   1122     int                entry_index;
   1123     int                port, my_modid, stm_idx, i;
   1124     int                local_port[SOC_MAX_NUM_PORTS];
   1125     int                local_port_count = 0;
   1126     uint32 vent[SOC_MAX_MEM_WORDS], old_vent[SOC_MAX_MEM_WORDS];
   1127     source_trunk_map_table_entry_t stm_entry;
   1128     uint32 ment[SOC_MAX_MEM_WORDS];
   1129     _bcm_l2gre_match_port_info_t *mkey = NULL;
   1130 
   1131     mkey = &(L2GRE_INFO(unit)->match_key[vp]);
   1132 
   1133     switch (mkey->flags) {
   1134         case _BCM_L2GRE_PORT_MATCH_TYPE_VLAN:
   1135             if (key_type == bcmVlanTranslateKeyInvalid) {
   1136                 key_type = bcmVlanTranslateKeyPortOuter;
   1137             }
   1138             /* Fall through */
   1139         case _BCM_L2GRE_PORT_MATCH_TYPE_INNER_VLAN:
   1140             if (key_type == bcmVlanTranslateKeyInvalid) {
   1141                 key_type = bcmVlanTranslateKeyPortInner;
   1142             }
   1143             /* Fall through */
   1144         case _BCM_L2GRE_PORT_MATCH_TYPE_VLAN_STACKED:
   1145             if (key_type == bcmVlanTranslateKeyInvalid) {
   1146                 key_type = bcmVlanTranslateKeyPortDouble;
   1147             }
   1148             /* Fall through */
   1149         case _BCM_L2GRE_PORT_MATCH_TYPE_VLAN_PRI:
   1150             if (key_type == bcmVlanTranslateKeyInvalid) {
   1151                 key_type = bcmVlanTranslateKeyPortOuterPri;
   1152             }
   1153 
   1154             mem = VLAN_XLATEm;
   1155 
   1156             if (mkey->modid != -1) {
   1157                 BCM_GPORT_MODPORT_SET(port, mkey->modid, mkey->port);
   1158             } else {
   1159                 BCM_GPORT_TRUNK_SET(port, mkey->trunk_id);
   1160             }
   1161             /* Construct lookup key */
   1162             sal_memset(vent, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS);
   1163             rv = _bcm_trx_vlan_translate_entry_assemble(
   1164                      unit, &vent, port, key_type, mkey->match_inner_vlan,
   1165                      mkey->match_vlan);
   1166             if (BCM_FAILURE(rv)) {
   1167                 return rv;
   1168             }
   1169             soc_mem_lock(unit, mem);
   1170             /* Lookup existing entry */
   1171             rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL,
   1172                                 &entry_index, vent, old_vent, 0);
   1173             if (BCM_FAILURE(rv)) {
   1174                 soc_mem_unlock(unit, mem);
   1175                 return rv;
   1176             }
   1177             /* Replace entry's VP value */
   1178             *old_vp = soc_mem_field32_get(unit, mem, old_vent, SOURCE_VPf);
   1179             soc_mem_field32_set(unit, mem, old_vent, SOURCE_VPf, new_vp);
   1180 
   1181             /* Insert new entry */
   1182             rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, old_vent);
   1183             if (rv == SOC_E_EXISTS) {
   1184                 rv = BCM_E_NONE;
   1185             } else {
   1186                 soc_mem_unlock(unit, mem);
   1187                 return BCM_E_INTERNAL;
   1188             }
   1189             soc_mem_unlock(unit, mem);
   1190             break;
   1191         case _BCM_L2GRE_PORT_MATCH_TYPE_PORT:
   1192             mem = SOURCE_TRUNK_MAP_TABLEm;
   1193 
   1194             soc_mem_lock(unit, mem);
   1195 
   1196             rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, mkey->index,
   1197                               &stm_entry);
   1198             if (BCM_FAILURE(rv)) {
   1199                 soc_mem_unlock(unit, mem);
   1200                 return rv;
   1201             }
   1202             /* Resolve SVP Mode */
   1203             if (soc_mem_field_valid(unit, mem, SVP_VALIDf)) {
   1204                 svp_valid = soc_mem_field32_get(unit, mem, &stm_entry,
   1205                                                 SVP_VALIDf);
   1206                 if (svp_valid == 0) {
   1207                     soc_mem_unlock(unit, mem);
   1208                     return BCM_E_INTERNAL;
   1209                 }
   1210             }
   1211             *old_vp = soc_mem_field32_get(unit, mem, &stm_entry, SOURCE_VPf);
   1212             rv = soc_mem_field32_modify(unit, mem, mkey->index, SOURCE_VPf,
   1213                                         new_vp);
   1214             soc_mem_unlock(unit, mem);
   1215             break;
   1216         case _BCM_L2GRE_PORT_MATCH_TYPE_TRUNK:
   1217             mem = SOURCE_TRUNK_MAP_TABLEm;
   1218 
   1219             /* Get module id for unit. */
   1220             rv = bcm_esw_stk_my_modid_get(unit, &my_modid);
   1221             if (BCM_FAILURE(rv)) {
   1222                 return rv;
   1223             }
   1224 
   1225             rv = _bcm_esw_trunk_local_members_get(
   1226                      unit, mkey->trunk_id, SOC_MAX_NUM_PORTS,
   1227                      local_port, &local_port_count);
   1228             if (BCM_FAILURE(rv)) {
   1229                 return rv;
   1230             }
   1231 
   1232             soc_mem_lock(unit, mem);
   1233             for (i = 0; i < local_port_count; i++) {
   1234                 /* Get index to source trunk map table */
   1235                 rv = _bcm_esw_src_mod_port_table_index_get(unit, my_modid,
   1236                                                            local_port[i],
   1237                                                            &stm_idx);
   1238                 if (BCM_FAILURE(rv)) {
   1239                     soc_mem_unlock(unit, mem);
   1240                     return rv;
   1241                 }
   1242 
   1243                 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, stm_idx,
   1244                                   &stm_entry);
   1245                 if (BCM_FAILURE(rv)) {
   1246                     soc_mem_unlock(unit, mem);
   1247                     return rv;
   1248                 }
   1249 
   1250                 /* Resolve SVP Mode */
   1251                 if (soc_mem_field_valid(unit, mem, SVP_VALIDf)) {
   1252                     svp_valid = soc_mem_field32_get(unit, mem, &stm_entry,
   1253                                                     SVP_VALIDf);
   1254                     if (svp_valid == 0) {
   1255                         soc_mem_unlock(unit, mem);
   1256                         return BCM_E_INTERNAL;
   1257                     }
   1258                 }
   1259                 *old_vp = soc_mem_field32_get(unit, mem, &stm_entry,
   1260                                               SOURCE_VPf);
   1261                 rv = soc_mem_field32_modify(unit, mem, stm_idx, SOURCE_VPf,
   1262                                             new_vp);
   1263                 if (BCM_FAILURE(rv)) {
   1264                     soc_mem_unlock(unit, mem);
   1265                     return rv;
   1266                 }
   1267             }
   1268 
   1269             soc_mem_unlock(unit, mem);
   1270             break;
   1271         case _BCM_L2GRE_PORT_MATCH_TYPE_VPNID:
   1272             tunnel_index = mkey->match_tunnel_index;
   1273             tunnel_sip = L2GRE_INFO(unit)->l2gre_tunnel_term[tunnel_index].sip;
   1274 
   1275             sal_memset(ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS);
   1276             mem = MPLS_ENTRYm;
   1277             soc_mem_lock(unit, mem);
   1278             soc_mem_field32_set(unit, mem, &ment, VALIDf, 1);
   1279 
   1280             soc_mem_field32_set(unit, mem, &ment, L2GRE_SIP__SIPf, tunnel_sip);
   1281             soc_mem_field32_set(unit, mem, &ment, KEY_TYPEf,
   1282                                 _BCM_L2GRE_KEY_TYPE_TUNNEL);
   1283             rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &entry_index, &ment,
   1284                                 &ment, 0);
   1285 
   1286             if (rv == BCM_E_NOT_FOUND) {
   1287                 rv = BCM_E_PARAM;
   1288             }
   1289 
   1290             if (BCM_FAILURE(rv)) {
   1291                 soc_mem_unlock(unit, mem);
   1292                 return rv;
   1293             }
   1294 
   1295             /* Replace entry's VP value */
   1296             *old_vp = soc_mem_field32_get(unit, mem, &ment, L2GRE_SIP__SVPf);
   1297             soc_mem_field32_set(unit, mem, &ment, L2GRE_SIP__SVPf, new_vp);
   1298             /* Insert new entry */
   1299             rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, ment);
   1300 
   1301             soc_mem_unlock(unit, mem);
   1302 
   1303             if (rv == SOC_E_EXISTS) {
   1304                 rv = BCM_E_NONE;
   1305             } else {
   1306                 return BCM_E_INTERNAL;
   1307             }
   1308             break;
   1309         default:
   1310             return BCM_E_PARAM;
   1311     }
   1312 
   1313     return rv;
   1314 }
   1315 
   1316 /*
   1317  * Function:
   1318  *      bcm_td2_l2gre_port_source_vp_lag_set
   1319  * Purpose:
   1320  *      Set source VP LAG for a L2GRE virtual port.
   1321  * Parameters:
   1322  *      unit      - (IN) SOC unit number.
   1323  *      gport     - (IN) L2GRE virtual port GPORT ID.
   1324  *      vp_lag_vp - (IN) VP representing the VP LAG.
   1325  * Returns:
   1326  *      BCM_X_XXX
   1327  */
   1328 int
   1329 bcm_td2_l2gre_port_source_vp_lag_set(int unit, bcm_gport_t gport,
   1330                                      int vp_lag_vp)
   1331 {
   1332     int vp, old_vp;
   1333     int rv = BCM_E_NONE;
   1334 
   1335     if (!BCM_GPORT_IS_L2GRE_PORT(gport)) {
   1336         return BCM_E_PARAM;
   1337     }
   1338 
   1339     vp = BCM_GPORT_L2GRE_PORT_ID_GET(gport);
   1340     if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre)) {
   1341         return BCM_E_PARAM;
   1342     }
   1343 
   1344     /* Set source VP LAG by replacing the SVP field in L2GRE VP's
   1345      * match entry with the VP value representing the VP LAG.
   1346      */
   1347     rv = _bcm_td2_l2gre_match_vp_replace(unit, vp, vp_lag_vp, &old_vp);
   1348     if (BCM_FAILURE(rv)) {
   1349         return rv;
   1350     }
   1351 
   1352     return rv;
   1353 }
   1354 /*
   1355  * Function:
   1356  *      bcm_td2_l2gre_port_source_vp_lag_clear
   1357  * Purpose:
   1358  *      Clear source VP LAG for a L2GRE virtual port.
   1359  * Parameters:
   1360  *      unit      - (IN) SOC unit number.
   1361  *      gport     - (IN) L2GRE virtual port GPORT ID.
   1362  *      vp_lag_vp - (IN) VP representing the VP LAG.
   1363  * Returns:
   1364  *      BCM_X_XXX
   1365  */
   1366 int
   1367 bcm_td2_l2gre_port_source_vp_lag_clear(int unit, bcm_gport_t gport,
   1368                                        int vp_lag_vp)
   1369 {
   1370     int vp, old_vp;
   1371 
   1372     if (!BCM_GPORT_IS_L2GRE_PORT(gport)) {
   1373         return BCM_E_PARAM;
   1374     }
   1375     vp = BCM_GPORT_L2GRE_PORT_ID_GET(gport);
   1376     if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre)) {
   1377         return BCM_E_PARAM;
   1378     }
   1379 
   1380     /* Clear source VP LAG by replacing the SVP field in L2GRE VP's
   1381      * match entry with the VP value.
   1382      */
   1383     BCM_IF_ERROR_RETURN(
   1384         _bcm_td2_l2gre_match_vp_replace(unit, vp, vp, &old_vp));
   1385 
   1386     /* Check that the old VP value matches the VP value representing
   1387      * the VP LAG or has been restored.
   1388      */
   1389     if ((old_vp != vp_lag_vp) && (old_vp != vp)) {
   1390         return BCM_E_INTERNAL;
   1391     }
   1392 
   1393     return BCM_E_NONE;
   1394 }
   1395 
   1396 /*
   1397  * Function:
   1398  *      bcm_td2_l2gre_port_source_vp_lag_get
   1399  * Purpose:
   1400  *      Get source VP LAG for a L2GRE virtual port.
   1401  * Parameters:
   1402  *      unit      - (IN) SOC unit number.
   1403  *      gport     - (IN) L2GRE virtual port GPORT ID.
   1404  *      vp_lag_vp - (OUT) VP representing the VP LAG.
   1405  * Returns:
   1406  *      BCM_X_XXX
   1407  */
   1408 int
   1409 bcm_td2_l2gre_port_source_vp_lag_get(int unit, bcm_gport_t gport,
   1410                                      int *vp_lag_vp)
   1411 {
   1412     int                rv = BCM_E_NONE;
   1413     soc_mem_t          mem;
   1414     int                key_type = bcmVlanTranslateKeyInvalid;
   1415     bcm_gport_t        vp;
   1416     uint32             svp_valid, tunnel_index, tunnel_sip;
   1417     int                entry_index;
   1418     int                port, my_modid, stm_idx;
   1419     int                local_port[SOC_MAX_NUM_PORTS];
   1420     int                local_port_count = 0;
   1421     uint32 vent[SOC_MAX_MEM_WORDS], old_vent[SOC_MAX_MEM_WORDS];
   1422     uint32 ment[SOC_MAX_MEM_WORDS];
   1423     source_trunk_map_table_entry_t stm_entry;
   1424     _bcm_l2gre_match_port_info_t *mkey = NULL;
   1425 
   1426 
   1427     if (!BCM_GPORT_IS_L2GRE_PORT(gport)) {
   1428         return BCM_E_PARAM;
   1429     }
   1430 
   1431     vp = BCM_GPORT_L2GRE_PORT_ID_GET(gport);
   1432     if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre)) {
   1433         return BCM_E_PARAM;
   1434     }
   1435 
   1436     mkey = &(L2GRE_INFO(unit)->match_key[vp]);
   1437 
   1438     switch (mkey->flags) {
   1439         case _BCM_L2GRE_PORT_MATCH_TYPE_VLAN:
   1440             if (key_type == bcmVlanTranslateKeyInvalid) {
   1441                 key_type = bcmVlanTranslateKeyPortOuter;
   1442             }
   1443             /* Fall through */
   1444         case _BCM_L2GRE_PORT_MATCH_TYPE_INNER_VLAN:
   1445             if (key_type == bcmVlanTranslateKeyInvalid) {
   1446                 key_type = bcmVlanTranslateKeyPortInner;
   1447             }
   1448             /* Fall through */
   1449         case _BCM_L2GRE_PORT_MATCH_TYPE_VLAN_STACKED:
   1450             if (key_type == bcmVlanTranslateKeyInvalid) {
   1451                 key_type = bcmVlanTranslateKeyPortDouble;
   1452             }
   1453             /* Fall through */
   1454         case _BCM_L2GRE_PORT_MATCH_TYPE_VLAN_PRI:
   1455             if (key_type == bcmVlanTranslateKeyInvalid) {
   1456                 key_type = bcmVlanTranslateKeyPortOuterPri;
   1457             }
   1458 
   1459             mem = VLAN_XLATEm;
   1460 
   1461             if (mkey->modid != -1) {
   1462                 BCM_GPORT_MODPORT_SET(port, mkey->modid, mkey->port);
   1463             } else {
   1464                 BCM_GPORT_TRUNK_SET(port, mkey->trunk_id);
   1465             }
   1466             /* Construct lookup key */
   1467             sal_memset(vent, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS);
   1468             rv = _bcm_trx_vlan_translate_entry_assemble(
   1469                      unit, &vent, port, key_type, mkey->match_inner_vlan,
   1470                      mkey->match_vlan);
   1471             if (BCM_FAILURE(rv)) {
   1472                 return rv;
   1473             }
   1474             /* Lookup existing entry */
   1475             rv = soc_mem_search(unit, mem, MEM_BLOCK_ALL, &entry_index, vent,
   1476                                 old_vent, 0);
   1477             if (BCM_FAILURE(rv)) {
   1478                 return rv;
   1479             }
   1480             /* Get VP value representing VP LAG */
   1481             *vp_lag_vp = soc_mem_field32_get(unit, mem, old_vent, SOURCE_VPf);
   1482             break;
   1483         case _BCM_L2GRE_PORT_MATCH_TYPE_PORT:
   1484             mem = SOURCE_TRUNK_MAP_TABLEm;
   1485 
   1486             rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, mkey->index,
   1487                               &stm_entry);
   1488             if (BCM_FAILURE(rv)) {
   1489                 return rv;
   1490             }
   1491             /* Resolve SVP Mode */
   1492             if (soc_mem_field_valid(unit, mem, SVP_VALIDf)) {
   1493                 svp_valid = soc_mem_field32_get(unit, mem, &stm_entry,
   1494                                                 SVP_VALIDf);
   1495                 if (svp_valid == 0) {
   1496                     return BCM_E_INTERNAL;
   1497                 }
   1498             }
   1499             /* Get VP value representing VP LAG */
   1500             *vp_lag_vp = soc_mem_field32_get(unit, mem, &stm_entry, SOURCE_VPf);
   1501             break;
   1502         case _BCM_L2GRE_PORT_MATCH_TYPE_TRUNK:
   1503             mem = SOURCE_TRUNK_MAP_TABLEm;
   1504 
   1505             /* Get module id for unit. */
   1506             rv = bcm_esw_stk_my_modid_get(unit, &my_modid);
   1507             if (BCM_FAILURE(rv)) {
   1508                 return rv;
   1509             }
   1510 
   1511             rv = _bcm_esw_trunk_local_members_get(
   1512                      unit, mkey->trunk_id, SOC_MAX_NUM_PORTS, local_port,
   1513                      &local_port_count);
   1514             if (BCM_FAILURE(rv)) {
   1515                 return rv;
   1516             }
   1517 
   1518             /* Get index to source trunk map table,
   1519              * Only get it from the first member in LAG
   1520              */
   1521             rv = _bcm_esw_src_mod_port_table_index_get(
   1522                      unit, my_modid, local_port[0], &stm_idx);
   1523             if (BCM_FAILURE(rv)) {
   1524                 return rv;
   1525             }
   1526 
   1527             rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, stm_idx, &stm_entry);
   1528             if (BCM_FAILURE(rv)) {
   1529                 return rv;
   1530             }
   1531 
   1532             /* Resolve SVP Mode */
   1533             if (soc_mem_field_valid(unit, mem, SVP_VALIDf)) {
   1534                 svp_valid = soc_mem_field32_get(unit, mem, &stm_entry,
   1535                                                 SVP_VALIDf);
   1536                 if (svp_valid == 0) {
   1537                     return BCM_E_INTERNAL;
   1538                 }
   1539             }
   1540             /* Get VP value representing VP LAG */
   1541             *vp_lag_vp = soc_mem_field32_get(unit, mem, &stm_entry, SOURCE_VPf);
   1542             break;
   1543         case _BCM_L2GRE_PORT_MATCH_TYPE_VPNID:
   1544             tunnel_index = mkey->match_tunnel_index;
   1545             tunnel_sip = L2GRE_INFO(unit)->l2gre_tunnel_term[tunnel_index].sip;
   1546 
   1547             sal_memset(ment, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS);
   1548             mem = MPLS_ENTRYm;
   1549             soc_mem_lock(unit, mem);
   1550             soc_mem_field32_set(unit, mem, &ment, VALIDf, 1);
   1551 
   1552             soc_mem_field32_set(unit, mem, &ment, L2GRE_SIP__SIPf, tunnel_sip);
   1553             soc_mem_field32_set(unit, mem, &ment,
   1554                 KEY_TYPEf, _BCM_L2GRE_KEY_TYPE_TUNNEL);
   1555             soc_mem_lock(unit, mem);
   1556             rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &entry_index, &ment,
   1557                                 &ment, 0);
   1558             soc_mem_unlock(unit, mem);
   1559             if (rv == BCM_E_NOT_FOUND) {
   1560                 rv = BCM_E_PARAM;
   1561             }
   1562 
   1563             if (BCM_FAILURE(rv)) {
   1564                 return rv;
   1565             }
   1566 
   1567             /* Get VP value representing VP LAG */
   1568             *vp_lag_vp = soc_mem_field32_get(unit, mem, &ment, L2GRE_SIP__SVPf);
   1569             break;
   1570         default:
   1571             return BCM_E_PARAM;
   1572     }
   1573 
   1574     if (!_bcm_vp_used_get(unit, *vp_lag_vp, _bcmVpTypeVpLag)) {
   1575         return BCM_E_INTERNAL;
   1576     }
   1577 
   1578     return rv;
   1579 }
   1580 #else /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */
   1581 int bcm_esw_td2_l2gre_not_empty;
   1582 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */