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

mim.c (32606B)


      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:    mim.c
      8  * Purpose: Manages MiM functions for triumph3
      9  */
     10 
     11 #include <soc/defs.h>
     12 #include <sal/core/libc.h>
     13 
     14 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
     15 
     16 #include <soc/drv.h>
     17 #include <soc/hash.h>
     18 #include <soc/mem.h>
     19 #include <soc/util.h>
     20 #include <soc/debug.h>
     21 #include <soc/triumph.h>
     22 
     23 #include <bcm/error.h>
     24 #include <bcm/mim.h>
     25 
     26 #include <bcm_int/esw/mbcm.h>
     27 #include <bcm_int/esw/l3.h>
     28 #include <bcm_int/esw/firebolt.h>
     29 #include <bcm_int/esw/triumph.h>
     30 #include <bcm_int/esw/triumph2.h>
     31 #include <bcm_int/esw/xgs3.h>
     32 #include <bcm_int/esw/mim.h>
     33 #include <bcm_int/common/multicast.h>
     34 #include <bcm_int/esw/virtual.h>
     35 #include <bcm_int/esw/trx.h>
     36 #include <bcm_int/esw/stack.h>
     37 #include <bcm_int/esw/triumph3.h>
     38 
     39 #include <bcm_int/esw_dispatch.h>
     40 #include <bcm_int/api_xlate_port.h>
     41 
     42 
     43 #define L3_INFO(unit)    (&_bcm_l3_bk_info[unit])
     44 #define MIM_INFO(_unit_) (&_bcm_tr2_mim_bk_info[_unit_])
     45 #define VPN_ISID(_unit_, _vfi_)  \
     46         (_bcm_tr2_mim_bk_info[_unit_].vpn_info[_vfi_].isid)
     47 
     48 /*
     49  * Function:
     50  *      _bcm_tr3_mim_match_add
     51  * Purpose: 
     52  *      Add MiM match parameters
     53  *
     54  * Parameters: 
     55  *      unit       - (IN) bcm device
     56  *      mim_port   - (IN) mim port
     57  *      vp         - (IN) vp
     58  *
     59  * Returns:
     60  *      BCM_E_NONE - Success
     61  *      BCM_E_XXX
     62  * Notes:
     63  */
     64 int
     65 _bcm_tr3_mim_match_add(int unit, bcm_mim_port_t *mim_port, int vp)
     66 {
     67     int rv = BCM_E_NONE, i, gport_id;
     68     bcm_module_t mod_out;
     69     bcm_port_t port_out;
     70     bcm_trunk_t trunk_id;
     71     bcm_mac_t mac_mask;
     72 
     73 
     74     rv = _bcm_esw_gport_resolve(unit, mim_port->port, &mod_out,
     75                                 &port_out, &trunk_id, &gport_id);
     76     BCM_IF_ERROR_RETURN(rv);
     77 
     78     if ((mim_port->criteria == BCM_MIM_PORT_MATCH_PORT_VLAN) ||
     79         (mim_port->criteria == BCM_MIM_PORT_MATCH_PORT_VLAN_STACKED)) {
     80         vlan_xlate_extd_entry_t vent;
     81         soc_mem_t xlate_mem;
     82         int xlate_index = -1;
     83         vlan_xlate_extd_entry_t return_vent;
     84 
     85         sal_memset(&vent, 0, sizeof(vent));
     86         xlate_mem = VLAN_XLATE_EXTDm;
     87         soc_mem_field32_set(unit, xlate_mem, &vent, KEY_TYPE_0f,
     88                                     TR3_VLXLT_X_HASH_KEY_TYPE_OVID);
     89         soc_mem_field32_set(unit, xlate_mem, &vent, KEY_TYPE_1f,
     90                                     TR3_VLXLT_X_HASH_KEY_TYPE_OVID);
     91         soc_mem_field32_set(unit, xlate_mem, &vent, VALID_0f, 0x1);
     92         soc_mem_field32_set(unit, xlate_mem, &vent, VALID_1f, 0x1);
     93         /* vlan xlate data */
     94         soc_mem_field32_set(unit, xlate_mem, &vent, MPLS_ACTIONf, 0x1); /* SVP */
     95         soc_mem_field32_set(unit, xlate_mem, &vent, DISABLE_VLAN_CHECKSf, 1);
     96         soc_mem_field32_set(unit, xlate_mem, &vent, SOURCE_VPf, vp);
     97 
     98         
     99         /* vlan xlate key */
    100         if (mim_port->criteria == BCM_MIM_PORT_MATCH_PORT_VLAN) {
    101             if (!BCM_VLAN_VALID(mim_port->match_vlan)) {
    102                 return BCM_E_PARAM;
    103             }
    104             soc_mem_field32_set(unit, xlate_mem, &vent, OVIDf,
    105                                         mim_port->match_vlan);
    106             MIM_INFO(unit)->port_info[vp].flags |= 
    107                                      _BCM_MIM_PORT_TYPE_ACCESS_PORT_VLAN;
    108             MIM_INFO(unit)->port_info[vp].match_vlan = mim_port->match_vlan;
    109 
    110         } else {
    111             if (!BCM_VLAN_VALID(mim_port->match_vlan) || 
    112                 !BCM_VLAN_VALID(mim_port->match_inner_vlan)) {
    113                 return BCM_E_PARAM;
    114             }
    115             soc_mem_field32_set(unit, xlate_mem, &vent, KEY_TYPE_0f,
    116                                         TR3_VLXLT_X_HASH_KEY_TYPE_OVID);
    117             soc_mem_field32_set(unit, xlate_mem, &vent, KEY_TYPE_1f,
    118                                         TR3_VLXLT_X_HASH_KEY_TYPE_OVID);
    119             soc_mem_field32_set(unit, xlate_mem, &vent, VALID_0f, 0x1);
    120             soc_mem_field32_set(unit, xlate_mem, &vent, VALID_1f, 0x1);
    121             soc_mem_field32_set(unit, xlate_mem, &vent, OVIDf,
    122                                         mim_port->match_vlan);
    123             soc_mem_field32_set(unit, xlate_mem, &vent, IVIDf,
    124                                         mim_port->match_inner_vlan);
    125             MIM_INFO(unit)->port_info[vp].flags |= 
    126                              _BCM_MIM_PORT_TYPE_ACCESS_PORT_VLAN_STACKED;
    127             MIM_INFO(unit)->port_info[vp].match_vlan = mim_port->match_vlan;
    128             MIM_INFO(unit)->port_info[vp].match_inner_vlan = 
    129                              mim_port->match_inner_vlan;
    130         }
    131 
    132         if (BCM_GPORT_IS_TRUNK(mim_port->port)) {
    133             soc_mem_field32_set(unit, xlate_mem, &vent, Tf, 1);
    134             soc_mem_field32_set(unit, xlate_mem, &vent, TGIDf, trunk_id);
    135         } else {
    136             soc_mem_field32_set(unit, xlate_mem, &vent, MODULE_IDf, mod_out);
    137             soc_mem_field32_set(unit, xlate_mem, &vent, PORT_NUMf, port_out);
    138         }
    139         rv = soc_mem_search(unit, xlate_mem, MEM_BLOCK_ANY, &xlate_index,
    140                             &vent, &return_vent, 0);
    141         if (BCM_E_NONE == rv) {
    142             if (mim_port->flags & BCM_MIM_PORT_REPLACE) {
    143                 BCM_IF_ERROR_RETURN(
    144                     soc_mem_write(unit,
    145                                   xlate_mem, MEM_BLOCK_ALL, xlate_index, &vent));
    146             } else {
    147                 return BCM_E_EXISTS;
    148             }
    149         } else if (BCM_E_NOT_FOUND == rv) {
    150             if (mim_port->flags & BCM_MIM_PORT_REPLACE) {
    151                 return BCM_E_NOT_FOUND;
    152             }
    153             rv = soc_mem_insert(unit, xlate_mem, MEM_BLOCK_ALL, &vent);
    154             BCM_IF_ERROR_RETURN(rv);
    155             _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1);
    156         } else {
    157             return rv;
    158         }
    159     } else if (mim_port->criteria == BCM_MIM_PORT_MATCH_PORT) {
    160         if (BCM_GPORT_IS_TRUNK(mim_port->port)) {
    161             rv = _bcm_tr2_mim_match_trunk_add(unit, trunk_id, vp);
    162             if (rv >= 0) {
    163                 MIM_INFO(unit)->port_info[vp].flags |= 
    164                     _BCM_MIM_PORT_TYPE_ACCESS_PORT_TRUNK;
    165                 MIM_INFO(unit)->port_info[vp].index = trunk_id;
    166             }
    167             BCM_IF_ERROR_RETURN(rv);
    168         } else {
    169             source_trunk_map_modbase_entry_t modbase_entry;
    170             int mod_id_idx=0; /* Module Id */
    171             int isLocal;
    172 
    173             BCM_IF_ERROR_RETURN(_bcm_esw_modid_is_local(unit, mod_out, &isLocal));
    174             BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mod_id_idx));
    175 
    176             if ((!isLocal) && (mod_out != BCM_MODID_INVALID)) {
    177                 mod_id_idx = mod_out;
    178             }
    179 
    180             BCM_IF_ERROR_RETURN
    181             (soc_mem_read(unit, SOURCE_TRUNK_MAP_MODBASEm, MEM_BLOCK_ANY,
    182                 mod_id_idx, &modbase_entry));
    183 
    184             i = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_MODBASEm,
    185                     &modbase_entry, BASEf) + port_out;
    186             rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm,
    187                     i, SOURCE_VPf, vp);
    188             BCM_IF_ERROR_RETURN(rv);
    189 
    190             rv = soc_mem_field32_modify(unit, PORT_TABm, port_out,
    191                     PORT_OPERATIONf, 0x1); /* L2_SVP */
    192             BCM_IF_ERROR_RETURN(rv);
    193 
    194             MIM_INFO(unit)->port_info[vp].flags |= 
    195                              _BCM_MIM_PORT_TYPE_ACCESS_PORT;
    196             MIM_INFO(unit)->port_info[vp].index = i;
    197         }
    198     } else if ((mim_port->criteria == BCM_MIM_PORT_MATCH_LABEL)) {
    199         mpls_entry_entry_t ment;
    200         int index = -1;
    201         mpls_entry_entry_t return_ment;
    202 
    203         sal_memset(&ment, 0, sizeof(mpls_entry_entry_t));
    204         if (BCM_GPORT_IS_TRUNK(mim_port->port)) {
    205             soc_MPLS_ENTRYm_field32_set(unit, &ment, Tf, 1);
    206             soc_MPLS_ENTRYm_field32_set(unit, &ment, TGIDf, trunk_id);
    207         } else {
    208             soc_MPLS_ENTRYm_field32_set(unit, &ment, MODULE_IDf, mod_out);
    209             soc_MPLS_ENTRYm_field32_set(unit, &ment, PORT_NUMf, port_out);
    210         }
    211         soc_MPLS_ENTRYm_field32_set(unit, &ment, MPLS_LABELf,
    212                                     mim_port->match_label);
    213         soc_MPLS_ENTRYm_field32_set(unit, &ment, VALIDf, 1);
    214         soc_MPLS_ENTRYm_field32_set(unit, &ment, SOURCE_VPf, vp);
    215         soc_MPLS_ENTRYm_field32_set(unit, &ment, MPLS_ACTION_IF_BOSf,
    216                                     0x1); /* L2 SVP */
    217         soc_MPLS_ENTRYm_field32_set(unit, &ment, MPLS_ACTION_IF_NOT_BOSf,
    218                                     0x0); /* INVALID */
    219         rv = soc_mem_search(unit, MPLS_ENTRYm, MEM_BLOCK_ANY, &index,
    220                             &ment, &return_ment, 0);
    221         if (BCM_E_NONE == rv) {
    222             if (mim_port->flags & BCM_MIM_PORT_REPLACE) {
    223                 BCM_IF_ERROR_RETURN(
    224                     soc_mem_write(unit,
    225                                   MPLS_ENTRYm, MEM_BLOCK_ALL, index, &ment));
    226             } else {
    227                 return BCM_E_EXISTS;
    228             }
    229         } else if (BCM_E_NOT_FOUND == rv) {
    230             if (mim_port->flags & BCM_MIM_PORT_REPLACE) {
    231                 return BCM_E_NOT_FOUND;
    232             }
    233             rv = soc_mem_insert(unit, MPLS_ENTRYm, MEM_BLOCK_ALL, &ment);
    234             BCM_IF_ERROR_RETURN(rv);
    235         } else {
    236             return rv;
    237         }
    238         MIM_INFO(unit)->port_info[vp].flags |= 
    239                          _BCM_MIM_PORT_TYPE_ACCESS_LABEL;
    240         MIM_INFO(unit)->port_info[vp].match_label = mim_port->match_label;
    241 
    242     } else if ((mim_port->criteria == BCM_MIM_PORT_MATCH_TUNNEL_VLAN_SRCMAC)) {
    243         mpls_entry_extd_entry_t ment;
    244         soc_mem_t mpls_mem;
    245         uint64 temp_mac;
    246         int index = -1;
    247         mpls_entry_extd_entry_t return_ment;
    248 
    249         /* Configure peer  Network Virtual port ( NVP) */
    250         if (!BCM_VLAN_VALID(mim_port->match_tunnel_vlan)) {
    251             return BCM_E_PARAM;
    252         }
    253 
    254         sal_memset(&ment, 0, sizeof(ment));
    255         mpls_mem = MPLS_ENTRY_EXTDm;
    256         soc_mem_field32_set(unit, mpls_mem, &ment, KEY_TYPE_0f, 0x17); /* MIM NVP */
    257         soc_mem_field32_set(unit, mpls_mem, &ment, KEY_TYPE_1f, 0x17);
    258         soc_mem_field32_set(unit, mpls_mem, &ment, VALID_0f, 1);
    259         soc_mem_field32_set(unit, mpls_mem, &ment, VALID_1f, 1);
    260 
    261         /* MIM_NVP key */
    262         soc_mem_field32_set(unit, mpls_mem, &ment, MIM_NVP__BVIDf,
    263                                     mim_port->match_tunnel_vlan);
    264         soc_mem_mac_addr_set(unit, mpls_mem, &ment, MIM_NVP__BMACSAf, 
    265                              mim_port->match_tunnel_srcmac);
    266 
    267         /* MIM_NVP data */ 
    268         if (BCM_GPORT_IS_TRUNK(mim_port->port)) {
    269             soc_mem_field32_set(unit, mpls_mem, &ment, MIM_NVP__Tf, 1);
    270             soc_mem_field32_set(unit, mpls_mem, &ment, MIM_NVP__TGIDf, trunk_id);
    271         } else {
    272             soc_mem_field32_set(unit, mpls_mem, &ment, MIM_NVP__MODULE_IDf, mod_out);
    273             soc_mem_field32_set(unit, mpls_mem, &ment, MIM_NVP__PORT_NUMf, port_out);
    274         }
    275         if (mim_port->flags & BCM_MIM_PORT_TYPE_PEER) {
    276             soc_mem_t tunnel_mem;
    277             soc_tunnel_term_t tnl_entry;
    278             uint32 index;
    279 
    280             sal_memset(&tnl_entry, 0, sizeof(tnl_entry));
    281             tunnel_mem = L3_TUNNELm;
    282            
    283             /* MIM L3 TUNNEL Type */
    284             soc_mem_field32_set(unit, tunnel_mem, &tnl_entry, KEY_TYPEf, 0x3);
    285  
    286             /* MIM L3 TUNNEL KEY BMACSA+BVID */
    287             soc_mem_mac_addr_set(unit, tunnel_mem, &tnl_entry, MIM__BMACSAf, 
    288                                                 mim_port->match_tunnel_srcmac);
    289             soc_mem_field32_set(unit, tunnel_mem, &tnl_entry, MIM__BVIDf,
    290                                                  mim_port->match_tunnel_vlan);
    291 
    292             /* Enable ISID,BMACSA, BVID lookup in mpls entry table */
    293             soc_mem_field32_set(unit, tunnel_mem, &tnl_entry, 
    294                 MIM__ISID_LOOKUP_KEY_CONTROLf, 1);
    295 
    296             sal_memset(&mac_mask, 0xff, sizeof(mac_mask));
    297             soc_mem_field32_set(unit, tunnel_mem, 
    298                         &tnl_entry, MIM__SGLP_MASKf, 0xffff);
    299             soc_mem_field32_set(unit, tunnel_mem, 
    300                         &tnl_entry, MIM__BVID_MASKf, 0xfff);
    301             soc_mem_mac_addr_set(unit, tunnel_mem, 
    302                         &tnl_entry, MIM__BMACSA_MASKf, mac_mask);
    303             soc_mem_field32_set(unit, tunnel_mem, 
    304                         &tnl_entry, MIM__KEY_TYPE_MASKf, 0x3);
    305             soc_mem_field32_set(unit,  tunnel_mem, &tnl_entry, VALIDf, 1);
    306 
    307             rv = soc_tunnel_term_insert(unit, &tnl_entry, &index);
    308             BCM_IF_ERROR_RETURN(rv);
    309             MIM_INFO(unit)->port_info[vp].flags |= 
    310                              _BCM_MIM_PORT_TYPE_PEER;
    311         } else {
    312             MIM_INFO(unit)->port_info[vp].flags |= 
    313                              _BCM_MIM_PORT_TYPE_NETWORK;
    314         }
    315         soc_mem_field32_set(unit, mpls_mem, &ment, MIM_NVP__SVPf, vp);
    316        
    317         rv = soc_mem_search(unit, mpls_mem, MEM_BLOCK_ANY, &index,
    318                             &ment, &return_ment, 0);
    319         if (BCM_E_NONE == rv) {
    320             if (mim_port->flags & BCM_MIM_PORT_REPLACE) {
    321                 BCM_IF_ERROR_RETURN(
    322                     soc_mem_write(unit,
    323                                   mpls_mem, MEM_BLOCK_ALL, index, &ment));
    324             } else {
    325                 return BCM_E_EXISTS;
    326             }
    327         } else if (BCM_E_NOT_FOUND == rv) {
    328             if (mim_port->flags & BCM_MIM_PORT_REPLACE) {
    329                 return BCM_E_NOT_FOUND;
    330             }
    331             rv = soc_mem_insert(unit, mpls_mem, MEM_BLOCK_ALL, &ment);
    332             BCM_IF_ERROR_RETURN(rv);
    333         } else {
    334             return rv;
    335         }
    336         SAL_MAC_ADDR_TO_UINT64(mim_port->match_tunnel_srcmac, temp_mac);
    337         SAL_MAC_ADDR_FROM_UINT64
    338            (MIM_INFO(unit)->port_info[vp].match_tunnel_srcmac, temp_mac); 
    339         MIM_INFO(unit)->port_info[vp].match_tunnel_vlan = 
    340                          mim_port->match_tunnel_vlan;
    341     }
    342     return rv;
    343 }
    344 
    345 /*
    346  * Function:
    347  *      _bcm_tr3_mim_match_delete
    348  * Purpose: 
    349  *      Delete MIM match parameters
    350  *
    351  * Parameters: 
    352  *      unit       - (IN) bcm device
    353  *      vp         - (IN) virtual port
    354  *
    355  * Returns:
    356  *      BCM_E_NONE - Success
    357  *      BCM_E_XXX
    358  * Notes:
    359  */
    360 
    361 int
    362 _bcm_tr3_mim_match_delete(int unit, int vp)
    363 {
    364     int port, rv;
    365 
    366     if (MIM_INFO(unit)->port_info[vp].flags & 
    367         _BCM_MIM_PORT_TYPE_ACCESS_PORT_VLAN) {
    368         vlan_xlate_extd_entry_t vent;
    369         soc_mem_t   xlate_mem;
    370         sal_memset(&vent, 0, sizeof(vent));
    371 
    372         xlate_mem = VLAN_XLATE_EXTDm;
    373         soc_mem_field32_set(unit, xlate_mem, &vent, KEY_TYPE_0f,
    374                                     TR3_VLXLT_X_HASH_KEY_TYPE_OVID);
    375         soc_mem_field32_set(unit, xlate_mem, &vent, KEY_TYPE_1f,
    376                                     TR3_VLXLT_X_HASH_KEY_TYPE_OVID);
    377         soc_mem_field32_set(unit, xlate_mem, &vent, VALID_0f, 0x1);
    378         soc_mem_field32_set(unit, xlate_mem, &vent, VALID_1f, 0x1);
    379 
    380         /* vlan xlate key */
    381         soc_mem_field32_set(unit, xlate_mem, &vent, OVIDf,
    382                                     MIM_INFO(unit)->port_info[vp].match_vlan);
    383         if (MIM_INFO(unit)->port_info[vp].modid != -1) {
    384             soc_mem_field32_set(unit, xlate_mem, &vent, MODULE_IDf, 
    385                                         MIM_INFO(unit)->port_info[vp].modid);
    386             soc_mem_field32_set(unit, xlate_mem, &vent, PORT_NUMf, 
    387                                         MIM_INFO(unit)->port_info[vp].port);
    388         } else {
    389             soc_mem_field32_set(unit, xlate_mem, &vent, Tf, 1);
    390             soc_mem_field32_set(unit, xlate_mem, &vent, TGIDf, 
    391                                         MIM_INFO(unit)->port_info[vp].tgid);
    392         }
    393         rv = soc_mem_delete(unit, xlate_mem, MEM_BLOCK_ANY, &vent);
    394         if (rv != BCM_E_NOT_FOUND) {
    395             _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1);
    396             return rv; /* Match has been deleted by bcm_port_match_delete */
    397         }
    398 
    399     } else if (MIM_INFO(unit)->port_info[vp].flags & 
    400                _BCM_MIM_PORT_TYPE_ACCESS_PORT_VLAN_STACKED) {
    401         vlan_xlate_extd_entry_t vent;
    402         soc_mem_t   xlate_mem;
    403         sal_memset(&vent, 0, sizeof(vent));
    404 
    405         xlate_mem = VLAN_XLATE_EXTDm;
    406         soc_mem_field32_set(unit, xlate_mem, &vent, KEY_TYPE_0f,
    407                                     TR3_VLXLT_X_HASH_KEY_TYPE_IVID_OVID);
    408         soc_mem_field32_set(unit, xlate_mem, &vent, KEY_TYPE_1f,
    409                                     TR3_VLXLT_X_HASH_KEY_TYPE_OVID);
    410         soc_mem_field32_set(unit, xlate_mem, &vent, VALID_0f, 0x1);
    411         soc_mem_field32_set(unit, xlate_mem, &vent, VALID_1f, 0x1);
    412 
    413         /* vlan xlate key */
    414         soc_mem_field32_set(unit, xlate_mem, &vent, OVIDf,
    415                                     MIM_INFO(unit)->port_info[vp].match_vlan);
    416         soc_mem_field32_set(unit, xlate_mem, &vent, IVIDf,
    417                               MIM_INFO(unit)->port_info[vp].match_inner_vlan);
    418         if (MIM_INFO(unit)->port_info[vp].modid != -1) {
    419             soc_mem_field32_set(unit, xlate_mem, &vent, MODULE_IDf, 
    420                                         MIM_INFO(unit)->port_info[vp].modid);
    421             soc_mem_field32_set(unit, xlate_mem, &vent, PORT_NUMf, 
    422                                         MIM_INFO(unit)->port_info[vp].port);
    423         } else {
    424             soc_mem_field32_set(unit, xlate_mem, &vent, Tf, 1);
    425             soc_mem_field32_set(unit, xlate_mem, &vent, TGIDf, 
    426                                         MIM_INFO(unit)->port_info[vp].tgid);
    427         }
    428         rv = soc_mem_delete(unit, xlate_mem, MEM_BLOCK_ANY, &vent);
    429         BCM_IF_ERROR_RETURN(rv);   
    430 
    431     } else if (MIM_INFO(unit)->port_info[vp].flags & 
    432                _BCM_MIM_PORT_TYPE_ACCESS_PORT) {
    433         rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 
    434                                     MIM_INFO(unit)->port_info[vp].index, 
    435                                     SOURCE_VPf, 0);        
    436         BCM_IF_ERROR_RETURN(rv);
    437         port = MIM_INFO(unit)->port_info[vp].index & SOC_PORT_ADDR_MAX(unit);
    438         rv = soc_mem_field32_modify(unit, PORT_TABm, port,
    439                                     PORT_OPERATIONf, 0x0); /* NORMAL */
    440         BCM_IF_ERROR_RETURN(rv);
    441 
    442     } else if(MIM_INFO(unit)->port_info[vp].flags & 
    443               _BCM_MIM_PORT_TYPE_ACCESS_PORT_TRUNK) {
    444         int trunk_id;
    445         trunk_id = MIM_INFO(unit)->port_info[vp].index;
    446         rv = _bcm_tr_mim_match_trunk_delete(unit, trunk_id, vp);
    447         BCM_IF_ERROR_RETURN(rv);
    448     } else if (MIM_INFO(unit)->port_info[vp].flags & 
    449                _BCM_MIM_PORT_TYPE_ACCESS_LABEL) {
    450         mpls_entry_entry_t ment; 
    451         sal_memset(&ment, 0, sizeof(mpls_entry_entry_t));
    452         if (MIM_INFO(unit)->port_info[vp].modid != -1) {
    453             soc_MPLS_ENTRYm_field32_set(unit, &ment, MODULE_IDf, 
    454                                         MIM_INFO(unit)->port_info[vp].modid);
    455             soc_MPLS_ENTRYm_field32_set(unit, &ment, PORT_NUMf, 
    456                                         MIM_INFO(unit)->port_info[vp].port);
    457         } else {
    458             soc_MPLS_ENTRYm_field32_set(unit, &ment, Tf, 1);
    459             soc_MPLS_ENTRYm_field32_set(unit, &ment, TGIDf, 
    460                                         MIM_INFO(unit)->port_info[vp].tgid);
    461         }
    462         soc_MPLS_ENTRYm_field32_set(unit, &ment, MPLS_LABELf,
    463                                     MIM_INFO(unit)->port_info[vp].match_label);
    464         rv = soc_mem_delete(unit, MPLS_ENTRYm, MEM_BLOCK_ANY, &ment);
    465         BCM_IF_ERROR_RETURN(rv);
    466 
    467     } else if (MIM_INFO(unit)->port_info[vp].flags & 
    468                (_BCM_MIM_PORT_TYPE_NETWORK | _BCM_MIM_PORT_TYPE_PEER)) {
    469         mpls_entry_extd_entry_t ment;
    470         soc_mem_t mpls_mem;
    471 
    472         sal_memset(&ment, 0, sizeof(ment));
    473         mpls_mem = MPLS_ENTRY_EXTDm;
    474         soc_mem_field32_set(unit, mpls_mem, &ment, KEY_TYPE_0f, 0x17); /* MIM NVP */
    475         soc_mem_field32_set(unit, mpls_mem, &ment, KEY_TYPE_1f, 0x17);
    476         soc_mem_field32_set(unit, mpls_mem, &ment, VALID_0f, 1);
    477         soc_mem_field32_set(unit, mpls_mem, &ment, VALID_1f, 1);
    478         
    479         /* MIM_NVP key */
    480         soc_mem_field32_set(unit, mpls_mem, &ment, MIM_NVP__BVIDf,
    481                                MIM_INFO(unit)->port_info[vp].match_tunnel_vlan);
    482         soc_mem_mac_addr_set(unit, mpls_mem, &ment, MIM_NVP__BMACSAf, 
    483                              MIM_INFO(unit)->port_info[vp].match_tunnel_srcmac);
    484         rv = soc_mem_delete(unit, mpls_mem, MEM_BLOCK_ALL, &ment);
    485         BCM_IF_ERROR_RETURN(rv);
    486        
    487         /* Delete L3_Tunnel MIM entry for peer port */ 
    488         if (MIM_INFO(unit)->port_info[vp].flags & _BCM_MIM_PORT_TYPE_PEER) {
    489             soc_mem_t tunnel_mem;
    490             soc_tunnel_term_t tnl_entry;
    491 
    492             sal_memset(&tnl_entry, 0, sizeof(tnl_entry));
    493             tunnel_mem = L3_TUNNELm;
    494            
    495             /* MIM L3 TUNNEL Type */
    496             soc_mem_field32_set(unit, tunnel_mem, &tnl_entry, KEY_TYPEf, 0x3);
    497  
    498             /* MIM L3 TUNNEL KEY BMACSA+BVID */
    499             soc_mem_mac_addr_set(unit, tunnel_mem, &tnl_entry, MIM__BMACSAf, 
    500                                                 MIM_INFO(unit)->port_info[vp].match_tunnel_srcmac);
    501             soc_mem_field32_set(unit, tunnel_mem, &tnl_entry, MIM__BVIDf,
    502                                                  MIM_INFO(unit)->port_info[vp].match_tunnel_vlan);
    503             rv = soc_tunnel_term_delete(unit, &tnl_entry);
    504             BCM_IF_ERROR_RETURN(rv);
    505         }
    506     }
    507     return BCM_E_NONE;
    508 }
    509 
    510 
    511 /*
    512  * Function:
    513  *      _bcm_tr3_mim_peer_port_config_add
    514  * Purpose: 
    515  *      Add ISID and VP for peer ports.
    516  * Parameters: 
    517  *      unit       - (IN) bcm device
    518  *      mim_port   - (IN) mim port
    519  *      vp         - (IN) virtual port
    520  *      vpn        - (IN) VPN ID (VFI)
    521  * Returns:
    522  *      BCM_E_NONE - Success
    523  *      BCM_E_XXX
    524  * Notes:
    525  */
    526 int
    527 _bcm_tr3_mim_peer_port_config_add(int unit, bcm_mim_port_t *mim_port, 
    528                                   int vp, bcm_mim_vpn_t vpn) 
    529 {
    530     mpls_entry_extd_entry_t ment;
    531     uint32 egr_vlan_xlate_entry[SOC_MAX_MEM_WORDS];
    532     int index, vfi, rv = BCM_E_NONE;
    533 
    534     /* Need an ISID-SVP entry in MPLS_ENTRY */
    535     _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, vpn);
    536 
    537     sal_memset(&ment, 0, sizeof(ment));
    538     soc_MPLS_ENTRY_EXTDm_field32_set(unit, &ment, KEY_TYPE_0f, 0x19); /* MIM_ISID_SVP */
    539     soc_MPLS_ENTRY_EXTDm_field32_set(unit, &ment, KEY_TYPE_1f, 0x19); /* MIM_ISID_SVP */
    540     soc_MPLS_ENTRY_EXTDm_field32_set(unit, &ment, VALID_0f, 0x1);
    541     soc_MPLS_ENTRY_EXTDm_field32_set(unit, &ment, VALID_1f, 0x1);
    542     /* MIM_ISID_SVP key */ 
    543     soc_MPLS_ENTRY_EXTDm_field32_set(unit, &ment, MIM_ISID__ISIDf, 
    544                                 VPN_ISID(unit, vfi));
    545 
    546     /* MIM_ISID_SVP data */ 
    547     
    548     soc_MPLS_ENTRY_EXTDm_field32_set(unit, &ment, MIM_ISID__VFIf, vfi);
    549     rv = soc_mem_search(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ANY, &index,
    550                         &ment, &ment, 0);
    551     if (rv == SOC_E_NONE) {
    552         return BCM_E_EXISTS;
    553     } else if (rv != SOC_E_NOT_FOUND) {
    554         return rv;
    555     }
    556     BCM_IF_ERROR_RETURN(soc_mem_insert(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ALL, &ment));
    557 
    558     /* Also need the reverse entry in the egress */
    559     sal_memset(egr_vlan_xlate_entry, 0, sizeof(egr_vlan_xlate_entry[SOC_MAX_MEM_WORDS]));
    560     soc_EGR_VLAN_XLATEm_field32_set(unit, egr_vlan_xlate_entry, KEY_TYPEf, 
    561                                     0x3);
    562     soc_EGR_VLAN_XLATEm_field32_set(unit, egr_vlan_xlate_entry, VALIDf, 0x1);
    563     /* MIM_ISID_DVP key */
    564     soc_EGR_VLAN_XLATEm_field32_set(unit, egr_vlan_xlate_entry, MIM_ISID__VFIf, 
    565                                     vfi);
    566     soc_EGR_VLAN_XLATEm_field32_set(unit, egr_vlan_xlate_entry, 
    567                                     MIM_ISID__DVPf, vp);
    568     /* MIM_ISID_DVP data */
    569     soc_EGR_VLAN_XLATEm_field32_set(unit, egr_vlan_xlate_entry,  
    570                                     MIM_ISID__ISIDf, VPN_ISID(unit, vfi));
    571 
    572     /* Deal with egress SD tag actions */
    573     if (mim_port->flags & BCM_MIM_PORT_EGRESS_SERVICE_VLAN_TAGGED) {
    574         BCM_IF_ERROR_RETURN
    575             (_bcm_tr2_mim_egr_vxlt_sd_tag_actions(unit, mim_port, NULL,
    576                                                   egr_vlan_xlate_entry));
    577     }
    578 
    579     rv = soc_mem_search(unit, EGR_VLAN_XLATEm, MEM_BLOCK_ANY, &index,
    580                         egr_vlan_xlate_entry, egr_vlan_xlate_entry, 0);
    581     if (rv == SOC_E_NONE) {
    582         return BCM_E_EXISTS;
    583     } else if (rv != SOC_E_NOT_FOUND) {
    584         return rv;
    585     }
    586     rv = soc_mem_insert(unit, EGR_VLAN_XLATEm, MEM_BLOCK_ALL, egr_vlan_xlate_entry);
    587 
    588     return rv;
    589 }
    590 
    591 /*
    592  * Function:
    593  *      _bcm_tr3_mim_peer_port_config_delete
    594  * Purpose: 
    595  *      Delete MPLS_ENTRy and EGR_VLAN_XLATE ISID/VFI instances
    596  *
    597  * Parameters: 
    598  *      unit       - (IN) bcm device
    599  *      vp         - (IN) vp
    600  *      vpn        - (IN) VPN Id ( VFI)
    601  * Returns:
    602  *      BCM_E_NONE - Success
    603  *      BCM_E_XXX
    604  * Notes:
    605  */
    606 int
    607 _bcm_tr3_mim_peer_port_config_delete(int unit, int vp, bcm_mim_vpn_t vpn) 
    608 {
    609     mpls_entry_extd_entry_t ment;
    610     egr_vlan_xlate_entry_t egr_vlan_xlate_entry;
    611     int vfi, rv = BCM_E_NONE;
    612     int index = -1;
    613 
    614     _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, vpn);
    615 
    616     sal_memset(&egr_vlan_xlate_entry, 0, sizeof(egr_vlan_xlate_entry_t));
    617     soc_EGR_VLAN_XLATEm_field32_set(unit, &egr_vlan_xlate_entry, KEY_TYPEf,
    618                                     0x3);
    619     soc_EGR_VLAN_XLATEm_field32_set(unit, &egr_vlan_xlate_entry, VALIDf, 0x1);
    620     soc_EGR_VLAN_XLATEm_field32_set(unit, &egr_vlan_xlate_entry, MIM_ISID__VFIf,
    621                                     vfi);
    622     soc_EGR_VLAN_XLATEm_field32_set(unit, &egr_vlan_xlate_entry,
    623                                     MIM_ISID__DVPf, vp);
    624 
    625     rv = soc_mem_search(unit, EGR_VLAN_XLATEm, MEM_BLOCK_ANY, &index,
    626                         &egr_vlan_xlate_entry, &egr_vlan_xlate_entry, 0);
    627     BCM_IF_ERROR_RETURN(rv);
    628 
    629     /* Delete the ISID-SVP entry in MPLS_ENTRY */
    630     sal_memset(&ment, 0, sizeof(ment));
    631     soc_MPLS_ENTRY_EXTDm_field32_set(unit, &ment, KEY_TYPE_0f, 0x19); /* MIM_ISID_SVP */
    632     soc_MPLS_ENTRY_EXTDm_field32_set(unit, &ment, KEY_TYPE_1f, 0x19); /* MIM_ISID_SVP */
    633     soc_MPLS_ENTRY_EXTDm_field32_set(unit, &ment, VALID_0f, 0x1);
    634     soc_MPLS_ENTRY_EXTDm_field32_set(unit, &ment, VALID_1f, 0x1);
    635     /* MIM_ISID_SVP key */ 
    636     soc_MPLS_ENTRY_EXTDm_field32_set(unit, &ment, MIM_ISID__ISIDf, 
    637                                 VPN_ISID(unit, vfi));
    638     
    639     rv = soc_mem_delete(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ANY, &ment);
    640     BCM_IF_ERROR_RETURN(rv);
    641 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
    642     /*delete TP_ID from software*/
    643     BCM_IF_ERROR_RETURN(
    644         _bcm_tr2_mim_egr_vxlt_sd_tag_actions_delete(unit,
    645                                                     (void *)&egr_vlan_xlate_entry));
    646 #endif
    647     /* Delete the reverse entry in the egress */
    648     rv = soc_mem_delete(unit, EGR_VLAN_XLATEm, MEM_BLOCK_ANY, 
    649                         &egr_vlan_xlate_entry);
    650     return rv;
    651 }
    652 
    653 /*
    654  * Function:
    655  *      _bcm_tr3_mim_lookup_id_stat_get_table_info
    656  * Description:
    657  *      Provides relevant flex table information(table-name,index with
    658  *      direction)  for given MiM I-SID entry.
    659  *
    660  * Parameters:
    661  *      unit             - (IN) unit number
    662  *      lookup_id        - (IN) I-SID value
    663  *      num_of_tables    - (OUT) Number of flex counter tables
    664  *      table_info       - (OUT) Flex counter tables information
    665  *
    666  * Return Value:
    667  *      BCM_E_XXX
    668  * Notes:
    669  */
    670 bcm_error_t _bcm_tr3_mim_lookup_id_stat_get_table_info(
    671                    int                        unit,
    672                    int                        lookup_id,
    673                    uint32                     *num_of_tables,
    674                    bcm_stat_flex_table_info_t *table_info)
    675 {
    676     int index, rv = BCM_E_NONE;
    677     int vfi = -1;
    678     uint32 mpls_vent[SOC_MAX_MEM_WORDS] = {0};
    679     uint32 vxlate_mem_vent[SOC_MAX_MEM_WORDS] = {0};
    680     soc_mem_t mpls_mem = MPLS_ENTRYm;
    681     soc_mem_t vxlate_mem = EGR_VLAN_XLATEm;
    682 
    683     /* Get MPLS_ENTRYm MIM_ISID Entry */
    684 #if defined(BCM_TRIDENT2_SUPPORT)    
    685     if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit)) {
    686         /* MIM_ISID */
    687         soc_mem_field32_set(unit, mpls_mem, mpls_vent, KEY_TYPEf, 0x2);
    688         soc_mem_field32_set(unit, mpls_mem, mpls_vent, VALIDf, 0x1);
    689     } else
    690 #endif /* BCM_TRIDENT2_SUPPORT */
    691 #if defined(BCM_TRIDENT3_SUPPORT)
    692     if (SOC_IS_TRIDENT3X(unit)) {
    693         soc_mem_field32_set(unit, mpls_mem, mpls_vent, KEY_TYPEf, 0x2);
    694         soc_mem_field32_set(unit, mpls_mem, mpls_vent, BASE_VALID_0f, 0x3);
    695         soc_mem_field32_set(unit, mpls_mem, mpls_vent, BASE_VALID_1f, 0x7);
    696     } else
    697 #endif /* BCM_TRIDENT2_SUPPORT */
    698     {
    699         mpls_mem = MPLS_ENTRY_EXTDm;
    700         /* MIM_ISID */
    701         soc_mem_field32_set(unit, mpls_mem, mpls_vent, KEY_TYPE_0f, 0x18);
    702         soc_mem_field32_set(unit, mpls_mem, mpls_vent, KEY_TYPE_1f, 0x18);
    703         soc_mem_field32_set(unit, mpls_mem, mpls_vent, VALID_0f, 0x1);
    704         soc_mem_field32_set(unit, mpls_mem, mpls_vent, VALID_1f, 0x1);
    705     }
    706     /* MIM_ISID key */ 
    707     soc_mem_field32_set(unit, mpls_mem, &mpls_vent, MIM_ISID__ISIDf, lookup_id);
    708 
    709     rv = soc_mem_search(unit, mpls_mem, MEM_BLOCK_ANY, &index,
    710                         mpls_vent, mpls_vent, 0);
    711     if (rv == BCM_E_NONE) {
    712         table_info[*num_of_tables].table = mpls_mem;
    713         table_info[*num_of_tables].index = index;
    714         table_info[*num_of_tables].direction = bcmStatFlexDirectionIngress;
    715         (*num_of_tables)++;
    716     }
    717 
    718     vfi = soc_mem_field32_get(unit, mpls_mem, &mpls_vent, MIM_ISID__VFIf);
    719 
    720     /* Get EGR_VLAN_XLATEm MIM_ISID Entry */
    721 #if defined(BCM_TRIUMPH3_SUPPORT)
    722     if (SOC_IS_TRIUMPH3(unit)) {
    723         soc_mem_field32_set(unit, vxlate_mem, vxlate_mem_vent,
    724             KEY_TYPEf, 0x2);  /* MIM_ISID */
    725     } else
    726 #endif /* BCM_TRIUMPH3_SUPPORT */
    727 #if defined(BCM_TRIDENT3_SUPPORT)
    728     if (SOC_IS_TRIDENT3X(unit)) {
    729         vxlate_mem = EGR_VLAN_XLATE_1_DOUBLEm;
    730         soc_mem_field32_set(unit, vxlate_mem, vxlate_mem_vent, BASE_VALID_0f, 3);
    731         soc_mem_field32_set(unit, vxlate_mem, vxlate_mem_vent, BASE_VALID_1f, 7);
    732         soc_mem_field32_set(unit, vxlate_mem, vxlate_mem_vent, DATA_TYPEf, 0x3);
    733         soc_mem_field32_set(unit, vxlate_mem, vxlate_mem_vent, KEY_TYPEf, 0x3);
    734     } else
    735 #endif
    736     {
    737         soc_mem_field32_set(unit, vxlate_mem, vxlate_mem_vent, ENTRY_TYPEf, 0x3);
    738     }
    739 
    740     /* MIIM_ISID key */
    741     soc_mem_field32_set(unit, vxlate_mem, vxlate_mem_vent, MIM_ISID__VFIf, vfi);
    742     rv = soc_mem_search(unit, vxlate_mem, MEM_BLOCK_ANY, &index,
    743                         vxlate_mem_vent, vxlate_mem_vent, 0);
    744 
    745     if (rv == BCM_E_NONE) {
    746         table_info[*num_of_tables].table = vxlate_mem;
    747         table_info[*num_of_tables].index = index;
    748         table_info[*num_of_tables].direction = bcmStatFlexDirectionEgress;
    749         (*num_of_tables)++;
    750     }
    751 
    752     return rv;
    753 }
    754 
    755 /*
    756  * Function:
    757  *      _bcm_tr3_mim_vpn_stat_get_table_info
    758  * Description:
    759  *      Provides relevant flex table information(table-name,index with
    760  *      direction)  for given MiM VPN entry
    761  *
    762  * Parameters:
    763  *      unit             - (IN) unit number
    764  *      vpn              - (IN) MiM VPN
    765  *      num_of_tables    - (OUT) Number of flex counter tables
    766  *      table_info       - (OUT) Flex counter tables information
    767  *
    768  * Return Value:
    769  *      BCM_E_XXX
    770  * Notes:
    771  */
    772 bcm_error_t _bcm_tr3_mim_vpn_stat_get_table_info(
    773                    int                        unit,
    774                    bcm_mim_vpn_t              vpn,
    775                    uint32                     *num_of_tables,
    776                    bcm_stat_flex_table_info_t *table_info)
    777 {
    778     int vfi;
    779 
    780     *num_of_tables = 0;
    781 
    782     /* Get Ingress stats index */
    783     _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, vpn);
    784     if (!_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeMim)) {
    785         return BCM_E_NOT_FOUND;
    786     }
    787     table_info[*num_of_tables].table = VFIm;
    788     table_info[*num_of_tables].index = vfi;
    789     table_info[*num_of_tables].direction = bcmStatFlexDirectionIngress;
    790     (*num_of_tables)++;
    791 
    792     /* Get Egress stats index */
    793     table_info[*num_of_tables].table=EGR_VFIm;
    794     table_info[*num_of_tables].index=vfi;
    795     table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress;
    796     (*num_of_tables)++;
    797 
    798     return BCM_E_NONE;
    799 }
    800 
    801 /*
    802  * Function:
    803  *      bcm_tr3_mim_peer_port_config_delete
    804  * Purpose: 
    805  *
    806  *
    807  * Parameters: 
    808  *      unit       - (IN) bcm device
    809  *
    810  * Returns:
    811  *      BCM_E_NONE - Success
    812  *      BCM_E_XXX
    813  * Notes:
    814  */
    815 
    816 #endif /* defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) */