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

virtual.c (133074B)


      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:    virtual.c
      8  * Purpose: Manages VP / VFI resources
      9  */
     10 #if defined(INCLUDE_L3)
     11 #include <soc/drv.h>
     12 #include <soc/scache.h>
     13 #include <soc/l2x.h>
     14 #include <soc/mcm/allenum.h>
     15 #include <sal/compiler.h>
     16 
     17 #include <bcm/error.h>
     18 #include <bcm/types.h>
     19 #include <bcm/module.h>
     20 #include <bcm_int/esw/virtual.h>
     21 #include <bcm_int/esw/trx.h>
     22 #include <bcm_int/esw/mim.h>
     23 #include <bcm_int/esw/mpls.h>
     24 #include <bcm_int/esw/firebolt.h>
     25 #include <bcm_int/esw_dispatch.h>
     26 #ifdef BCM_WARM_BOOT_SUPPORT
     27 #include <bcm_int/esw/switch.h>
     28 #endif /* BCM_WARM_BOOT_SUPPORT */
     29 #if defined(BCM_TRIDENT_SUPPORT)
     30 #include <bcm_int/esw/trident.h>
     31 #endif /* BCM_TRIDENT_SUPPORT */
     32 #if defined(BCM_ENDURO_SUPPORT)
     33 #include <bcm_int/esw/enduro.h>
     34 #endif /* BCM_ENDURO_SUPPORT */
     35 #if defined(BCM_TRIUMPH2_SUPPORT)
     36 #include <bcm_int/esw/triumph2.h>
     37 #endif /* BCM_TRIUMPH2_SUPPORT */
     38 #if defined(BCM_TRIDENT2_SUPPORT)
     39 #include <bcm_int/esw/trident2.h>
     40 #endif /* BCM_TRIDENT2_SUPPORT */
     41 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
     42 #include <bcm_int/esw/stg.h>
     43 #include <bcm_int/esw/trident2plus.h>
     44 #endif /* BCM_TRIDENT2_SUPPORT */
     45 #if defined(BCM_SABER2_SUPPORT)
     46 #include <soc/saber2.h>
     47 #endif /* BCM_SABER2_SUPPORT */
     48 #if defined(BCM_TRIDENT3_SUPPORT)
     49 #include <bcm_int/esw/flow.h>
     50 #endif
     51 
     52 /*
     53  * Global virtual book keeping info
     54  */
     55 _bcm_virtual_bookkeeping_t  _bcm_virtual_bk_info[BCM_MAX_NUM_UNITS] = {{ 0 }};
     56 STATIC sal_mutex_t _virtual_mutex[BCM_MAX_NUM_UNITS] = {NULL};
     57 
     58 #define VIRTUAL_INFO(_unit_)   (&_bcm_virtual_bk_info[_unit_])
     59 
     60 /*
     61  * VFI table usage bitmap operations
     62  */
     63 #define _BCM_VIRTUAL_VFI_USED_GET(_u_, _vfi_) \
     64         ((VIRTUAL_INFO(_u_)->vfi_bitmap) ? \
     65         SHR_BITGET(VIRTUAL_INFO(_u_)->vfi_bitmap, (_vfi_)) : 0)
     66 #define _BCM_VIRTUAL_VFI_USED_SET(_u_, _vfi_) \
     67         SHR_BITSET(VIRTUAL_INFO((_u_))->vfi_bitmap, (_vfi_))
     68 #define _BCM_VIRTUAL_VFI_USED_CLR(_u_, _vfi_) \
     69         SHR_BITCLR(VIRTUAL_INFO((_u_))->vfi_bitmap, (_vfi_))
     70 
     71 /*
     72  * Virtual Port usage bitmap operations
     73  */
     74 #define _BCM_VIRTUAL_VP_USED_GET(_u_, _vp_) \
     75         ((VIRTUAL_INFO(_u_)->vp_bitmap) ? \
     76         SHR_BITGET(VIRTUAL_INFO(_u_)->vp_bitmap, (_vp_)) : 0)
     77 #define _BCM_VIRTUAL_VP_USED_SET(_u_, _vp_) \
     78         SHR_BITSET(VIRTUAL_INFO((_u_))->vp_bitmap, (_vp_))
     79 #define _BCM_VIRTUAL_VP_USED_CLR(_u_, _vp_) \
     80         SHR_BITCLR(VIRTUAL_INFO((_u_))->vp_bitmap, (_vp_))
     81 
     82 /*
     83  * MPLS VFI table usage bitmap operations
     84  */
     85 #define _BCM_MPLS_VFI_USED_GET(_u_, _vfi_) \
     86         ((VIRTUAL_INFO(_u_)->mpls_vfi_bitmap) ? \
     87         SHR_BITGET(VIRTUAL_INFO(_u_)->mpls_vfi_bitmap, (_vfi_)) : 0)
     88 #define _BCM_MPLS_VFI_USED_SET(_u_, _vfi_) \
     89         SHR_BITSET(VIRTUAL_INFO((_u_))->mpls_vfi_bitmap, (_vfi_))
     90 #define _BCM_MPLS_VFI_USED_CLR(_u_, _vfi_) \
     91         SHR_BITCLR(VIRTUAL_INFO((_u_))->mpls_vfi_bitmap, (_vfi_))
     92 
     93 /*
     94  * MPLS Virtual Port usage bitmap operations
     95  */
     96 #define _BCM_MPLS_VP_USED_GET(_u_, _vp_) \
     97         ((VIRTUAL_INFO(_u_)->mpls_vp_bitmap) ? \
     98         SHR_BITGET(VIRTUAL_INFO(_u_)->mpls_vp_bitmap, (_vp_)) : 0)
     99 #define _BCM_MPLS_VP_USED_SET(_u_, _vp_) \
    100         SHR_BITSET(VIRTUAL_INFO((_u_))->mpls_vp_bitmap, (_vp_))
    101 #define _BCM_MPLS_VP_USED_CLR(_u_, _vp_) \
    102         SHR_BITCLR(VIRTUAL_INFO((_u_))->mpls_vp_bitmap, (_vp_))
    103 
    104 /*
    105  * MIM VFI table usage bitmap operations
    106  */
    107 #define _BCM_MIM_VFI_USED_GET(_u_, _vfi_) \
    108         ((VIRTUAL_INFO(_u_)->mim_vfi_bitmap) ? \
    109         SHR_BITGET(VIRTUAL_INFO(_u_)->mim_vfi_bitmap, (_vfi_)) : 0)
    110 #define _BCM_MIM_VFI_USED_SET(_u_, _vfi_) \
    111         SHR_BITSET(VIRTUAL_INFO((_u_))->mim_vfi_bitmap, (_vfi_))
    112 #define _BCM_MIM_VFI_USED_CLR(_u_, _vfi_) \
    113         SHR_BITCLR(VIRTUAL_INFO((_u_))->mim_vfi_bitmap, (_vfi_))
    114 
    115 /*
    116  * MIM Virtual Port usage bitmap operations
    117  */
    118 #define _BCM_MIM_VP_USED_GET(_u_, _vp_) \
    119         ((VIRTUAL_INFO(_u_)->mim_vp_bitmap) ? \
    120         SHR_BITGET(VIRTUAL_INFO(_u_)->mim_vp_bitmap, (_vp_)) : 0)
    121 #define _BCM_MIM_VP_USED_SET(_u_, _vp_) \
    122         SHR_BITSET(VIRTUAL_INFO((_u_))->mim_vp_bitmap, (_vp_))
    123 #define _BCM_MIM_VP_USED_CLR(_u_, _vp_) \
    124         SHR_BITCLR(VIRTUAL_INFO((_u_))->mim_vp_bitmap, (_vp_))
    125 
    126 /*
    127  * L2GRE VFI usage bitmap operations
    128  */
    129 #define _BCM_L2GRE_VFI_USED_GET(_u_, _vfi_) \
    130         ((VIRTUAL_INFO(_u_)->l2gre_vfi_bitmap) ? \
    131         SHR_BITGET(VIRTUAL_INFO(_u_)->l2gre_vfi_bitmap, (_vfi_)) : 0)
    132 #define _BCM_L2GRE_VFI_USED_SET(_u_, _vfi_) \
    133         SHR_BITSET(VIRTUAL_INFO((_u_))->l2gre_vfi_bitmap, (_vfi_))
    134 #define _BCM_L2GRE_VFI_USED_CLR(_u_, _vfi_) \
    135         SHR_BITCLR(VIRTUAL_INFO((_u_))->l2gre_vfi_bitmap, (_vfi_))
    136 
    137 /*
    138  * L2GRE Virtual Port usage bitmap operations
    139  */
    140 #define _BCM_L2GRE_VP_USED_GET(_u_, _vp_) \
    141         ((VIRTUAL_INFO(_u_)->l2gre_vp_bitmap) ? \
    142         SHR_BITGET(VIRTUAL_INFO(_u_)->l2gre_vp_bitmap, (_vp_)) : 0)
    143 #define _BCM_L2GRE_VP_USED_SET(_u_, _vp_) \
    144         SHR_BITSET(VIRTUAL_INFO((_u_))->l2gre_vp_bitmap, (_vp_))
    145 #define _BCM_L2GRE_VP_USED_CLR(_u_, _vp_) \
    146         SHR_BITCLR(VIRTUAL_INFO((_u_))->l2gre_vp_bitmap, (_vp_))
    147 
    148 
    149 /*
    150  * VXLAN VFI usage bitmap operations
    151  */
    152 #define _BCM_VXLAN_VFI_USED_GET(_u_, _vfi_) \
    153         ((VIRTUAL_INFO(_u_)->vxlan_vfi_bitmap) ? \
    154         SHR_BITGET(VIRTUAL_INFO(_u_)->vxlan_vfi_bitmap, (_vfi_)) : 0)
    155 #define _BCM_VXLAN_VFI_USED_SET(_u_, _vfi_) \
    156         SHR_BITSET(VIRTUAL_INFO((_u_))->vxlan_vfi_bitmap, (_vfi_))
    157 #define _BCM_VXLAN_VFI_USED_CLR(_u_, _vfi_) \
    158         SHR_BITCLR(VIRTUAL_INFO((_u_))->vxlan_vfi_bitmap, (_vfi_))
    159 
    160 /*
    161  * VXLAN Virtual Port usage bitmap operations
    162  */
    163 #define _BCM_VXLAN_VP_USED_GET(_u_, _vp_) \
    164         ((VIRTUAL_INFO(_u_)->vxlan_vp_bitmap) ? \
    165         SHR_BITGET(VIRTUAL_INFO(_u_)->vxlan_vp_bitmap, (_vp_)) : 0)
    166 #define _BCM_VXLAN_VP_USED_SET(_u_, _vp_) \
    167         SHR_BITSET(VIRTUAL_INFO((_u_))->vxlan_vp_bitmap, (_vp_))
    168 #define _BCM_VXLAN_VP_USED_CLR(_u_, _vp_) \
    169         SHR_BITCLR(VIRTUAL_INFO((_u_))->vxlan_vp_bitmap, (_vp_))
    170 
    171 /*
    172  * FLOW  VFI usage bitmap operations
    173  */
    174 #define _BCM_FLOW_VFI_USED_GET(_u_, _vfi_) \
    175         ((VIRTUAL_INFO(_u_)->flow_vfi_bitmap) ? \
    176         SHR_BITGET(VIRTUAL_INFO(_u_)->flow_vfi_bitmap, (_vfi_)) : 0)
    177 #define _BCM_FLOW_VFI_USED_SET(_u_, _vfi_) \
    178         SHR_BITSET(VIRTUAL_INFO((_u_))->flow_vfi_bitmap, (_vfi_))
    179 #define _BCM_FLOW_VFI_USED_CLR(_u_, _vfi_) \
    180         SHR_BITCLR(VIRTUAL_INFO((_u_))->flow_vfi_bitmap, (_vfi_))
    181 
    182 /*
    183  * FLOW Virtual Port usage bitmap operations
    184  */
    185 #define _BCM_FLOW_VP_USED_GET(_u_, _vp_) \
    186         ((VIRTUAL_INFO(_u_)->flow_vp_bitmap) ? \
    187         SHR_BITGET(VIRTUAL_INFO(_u_)->flow_vp_bitmap, (_vp_)) : 0)
    188 #define _BCM_FLOW_VP_USED_SET(_u_, _vp_) \
    189         SHR_BITSET(VIRTUAL_INFO((_u_))->flow_vp_bitmap, (_vp_))
    190 #define _BCM_FLOW_VP_USED_CLR(_u_, _vp_) \
    191         SHR_BITCLR(VIRTUAL_INFO((_u_))->flow_vp_bitmap, (_vp_))
    192 
    193 /*
    194  * VXLAN shared Virtual Port usage bitmap operations
    195  */
    196 #define _BCM_SHARED_VP_USED_GET(_u_, _vp_) \
    197         ((VIRTUAL_INFO(_u_)->vp_shared_vp_bitmap) ? \
    198         SHR_BITGET(VIRTUAL_INFO(_u_)->vp_shared_vp_bitmap, (_vp_)) : 0)
    199 #define _BCM_SHARED_VP_USED_SET(_u_, _vp_) \
    200         SHR_BITSET(VIRTUAL_INFO((_u_))->vp_shared_vp_bitmap, (_vp_))
    201 #define _BCM_SHARED_VP_USED_CLR(_u_, _vp_) \
    202         SHR_BITCLR(VIRTUAL_INFO((_u_))->vp_shared_vp_bitmap, (_vp_))
    203 
    204 /*
    205  * Network Port bit-map for VxLAN/L2GRE/TRILL
    206  */
    207 #define _BCM_NETWORK_VP_USED_GET(_u_, _vp_) \
    208         ((VIRTUAL_INFO(_u_)->vp_network_vp_bitmap) ? \
    209         SHR_BITGET(VIRTUAL_INFO(_u_)->vp_network_vp_bitmap, (_vp_)) : 0)
    210 #define _BCM_NETWORK_VP_USED_SET(_u_, _vp_) \
    211         SHR_BITSET(VIRTUAL_INFO((_u_))->vp_network_vp_bitmap, (_vp_))
    212 #define _BCM_NETWORK_VP_USED_CLR(_u_, _vp_) \
    213         SHR_BITCLR(VIRTUAL_INFO((_u_))->vp_network_vp_bitmap, (_vp_))
    214 
    215 
    216 /* 
    217  * Virtual resource lock
    218  */
    219 #define VIRTUAL_LOCK(unit) \
    220         sal_mutex_take(_virtual_mutex[unit], sal_mutex_FOREVER); 
    221 
    222 #define VIRTUAL_UNLOCK(unit) \
    223         sal_mutex_give(_virtual_mutex[unit]); 
    224 
    225 /*
    226  * Subport Virtual Port usage bitmap operations
    227  */
    228 #define _BCM_SUBPORT_VP_USED_GET(_u_, _vp_) \
    229         ((VIRTUAL_INFO(_u_)->subport_vp_bitmap) ? \
    230         SHR_BITGET(VIRTUAL_INFO(_u_)->subport_vp_bitmap, (_vp_)) : 0)
    231 #define _BCM_SUBPORT_VP_USED_SET(_u_, _vp_) \
    232         SHR_BITSET(VIRTUAL_INFO((_u_))->subport_vp_bitmap, (_vp_))
    233 #define _BCM_SUBPORT_VP_USED_CLR(_u_, _vp_) \
    234         SHR_BITCLR(VIRTUAL_INFO((_u_))->subport_vp_bitmap, (_vp_))
    235 
    236 /*
    237  * WLAN Virtual Port usage bitmap operations
    238  */
    239 #define _BCM_WLAN_VP_USED_GET(_u_, _vp_) \
    240         ((VIRTUAL_INFO(_u_)->wlan_vp_bitmap) ? \
    241         SHR_BITGET(VIRTUAL_INFO(_u_)->wlan_vp_bitmap, (_vp_)) : 0)
    242 #define _BCM_WLAN_VP_USED_SET(_u_, _vp_) \
    243         SHR_BITSET(VIRTUAL_INFO((_u_))->wlan_vp_bitmap, (_vp_))
    244 #define _BCM_WLAN_VP_USED_CLR(_u_, _vp_) \
    245         SHR_BITCLR(VIRTUAL_INFO((_u_))->wlan_vp_bitmap, (_vp_))
    246 
    247    /*
    248      * TRILL Virtual Port usage bitmap operations
    249      */
    250 #define _BCM_TRILL_VP_USED_GET(_u_, _vp_) \
    251         ((VIRTUAL_INFO(_u_)->trill_vp_bitmap) ? \
    252         SHR_BITGET(VIRTUAL_INFO(_u_)->trill_vp_bitmap, (_vp_)) : 0)
    253 #define _BCM_TRILL_VP_USED_SET(_u_, _vp_) \
    254         SHR_BITSET(VIRTUAL_INFO((_u_))->trill_vp_bitmap, (_vp_))
    255 #define _BCM_TRILL_VP_USED_CLR(_u_, _vp_) \
    256         SHR_BITCLR(VIRTUAL_INFO((_u_))->trill_vp_bitmap, (_vp_))
    257 /*
    258  * VLAN Virtual Port usage bitmap operations
    259  */
    260 #define _BCM_VLAN_VP_USED_GET(_u_, _vp_) \
    261         ((VIRTUAL_INFO(_u_)->vlan_vp_bitmap) ? \
    262         SHR_BITGET(VIRTUAL_INFO(_u_)->vlan_vp_bitmap, (_vp_)) : 0)
    263 #define _BCM_VLAN_VP_USED_SET(_u_, _vp_) \
    264         SHR_BITSET(VIRTUAL_INFO((_u_))->vlan_vp_bitmap, (_vp_))
    265 #define _BCM_VLAN_VP_USED_CLR(_u_, _vp_) \
    266         SHR_BITCLR(VIRTUAL_INFO((_u_))->vlan_vp_bitmap, (_vp_))
    267 
    268 /*
    269  * NIV Virtual Port usage bitmap operations
    270  */
    271 #define _BCM_NIV_VP_USED_GET(_u_, _vp_) \
    272         ((VIRTUAL_INFO(_u_)->niv_vp_bitmap) ? \
    273         SHR_BITGET(VIRTUAL_INFO(_u_)->niv_vp_bitmap, (_vp_)) : 0)
    274 #define _BCM_NIV_VP_USED_SET(_u_, _vp_) \
    275         SHR_BITSET(VIRTUAL_INFO((_u_))->niv_vp_bitmap, (_vp_))
    276 #define _BCM_NIV_VP_USED_CLR(_u_, _vp_) \
    277         SHR_BITCLR(VIRTUAL_INFO((_u_))->niv_vp_bitmap, (_vp_))
    278 
    279 /*
    280  * Extender Virtual Port usage bitmap operations
    281  */
    282 #define _BCM_EXTENDER_VP_USED_GET(_u_, _vp_) \
    283         ((VIRTUAL_INFO(_u_)->extender_vp_bitmap) ? \
    284         SHR_BITGET(VIRTUAL_INFO(_u_)->extender_vp_bitmap, (_vp_)) : 0)
    285 #define _BCM_EXTENDER_VP_USED_SET(_u_, _vp_) \
    286         SHR_BITSET(VIRTUAL_INFO((_u_))->extender_vp_bitmap, (_vp_))
    287 #define _BCM_EXTENDER_VP_USED_CLR(_u_, _vp_) \
    288         SHR_BITCLR(VIRTUAL_INFO((_u_))->extender_vp_bitmap, (_vp_))
    289 
    290 /*
    291  * VP LAG Virtual Port usage bitmap operations
    292  */
    293 #define _BCM_VP_LAG_VP_USED_GET(_u_, _vp_) \
    294         ((VIRTUAL_INFO(_u_)->vp_lag_vp_bitmap) ? \
    295         SHR_BITGET(VIRTUAL_INFO(_u_)->vp_lag_vp_bitmap, (_vp_)) : 0)
    296 #define _BCM_VP_LAG_VP_USED_SET(_u_, _vp_) \
    297         SHR_BITSET(VIRTUAL_INFO((_u_))->vp_lag_vp_bitmap, (_vp_))
    298 #define _BCM_VP_LAG_VP_USED_CLR(_u_, _vp_) \
    299         SHR_BITCLR(VIRTUAL_INFO((_u_))->vp_lag_vp_bitmap, (_vp_))
    300 
    301 /*
    302  * VLAN VFI usage bitmap operations
    303  */
    304 #define _BCM_VLAN_VFI_USED_GET(_u_, _vfi_) \
    305         ((VIRTUAL_INFO(_u_)->vlan_vfi_bitmap) ? \
    306         SHR_BITGET(VIRTUAL_INFO(_u_)->vlan_vfi_bitmap, (_vfi_)) : 0)
    307 #define _BCM_VLAN_VFI_USED_SET(_u_, _vfi_) \
    308         SHR_BITSET(VIRTUAL_INFO((_u_))->vlan_vfi_bitmap, (_vfi_))
    309 #define _BCM_VLAN_VFI_USED_CLR(_u_, _vfi_) \
    310         SHR_BITCLR(VIRTUAL_INFO((_u_))->vlan_vfi_bitmap, (_vfi_))
    311 
    312 /*
    313  * Virtual Port to VPN operations
    314  */
    315 #define _BCM_VIRTUAL_VP_VFI_MAP(_u_, _vp_) \
    316         VIRTUAL_INFO((_u_))->vp_to_vpn[_vp_]
    317 
    318 #define VIRTUAL_INIT_CHECK(_u_) \
    319         if (NULL == _virtual_mutex[_u_]) { return BCM_E_INIT; }
    320 
    321 /*
    322  * Function:
    323  *      _bcm_virtual_free_resource
    324  * Purpose:
    325  *      Free all allocated resources
    326  * Parameters:
    327  *      unit - SOC unit number
    328  * Returns:
    329  *      Nothing
    330  */
    331 STATIC void
    332 _bcm_virtual_free_resource(int unit, _bcm_virtual_bookkeeping_t *virtual_info)
    333 {
    334     if (!virtual_info) {
    335         return;
    336     }
    337 
    338     if (_virtual_mutex[unit]) {
    339         sal_mutex_destroy(_virtual_mutex[unit]);
    340         _virtual_mutex[unit] = NULL;
    341     } 
    342 
    343     if (virtual_info->vfi_bitmap) {
    344         sal_free(virtual_info->vfi_bitmap);
    345         virtual_info->vfi_bitmap = NULL;
    346     }
    347 
    348     if (virtual_info->vp_bitmap) {
    349         /* Before we free the VP bitmap, unregister it from the
    350          * SOC layer L2X thread. */
    351         soc_l2x_cml_vp_bitmap_set(unit, NULL);
    352         sal_free(virtual_info->vp_bitmap);
    353         virtual_info->vp_bitmap = NULL;
    354     }
    355 
    356     if (virtual_info->mpls_vfi_bitmap) {
    357         sal_free(virtual_info->mpls_vfi_bitmap);
    358         virtual_info->mpls_vfi_bitmap = NULL;
    359     }
    360 
    361     if (virtual_info->mpls_vp_bitmap) {
    362         sal_free(virtual_info->mpls_vp_bitmap);
    363         virtual_info->mpls_vp_bitmap = NULL;
    364     }
    365 
    366     if (virtual_info->mim_vfi_bitmap) {
    367         sal_free(virtual_info->mim_vfi_bitmap);
    368         virtual_info->mim_vfi_bitmap = NULL;
    369     }
    370 
    371     if (virtual_info->mim_vp_bitmap) {
    372         sal_free(virtual_info->mim_vp_bitmap);
    373         virtual_info->mim_vp_bitmap = NULL;
    374     }
    375 
    376     if (virtual_info->subport_vp_bitmap) {
    377         sal_free(virtual_info->subport_vp_bitmap);
    378         virtual_info->subport_vp_bitmap = NULL;
    379     }
    380 
    381     if (virtual_info->wlan_vp_bitmap) {
    382         sal_free(virtual_info->wlan_vp_bitmap);
    383         virtual_info->wlan_vp_bitmap = NULL;
    384     }
    385 
    386     if (virtual_info->trill_vp_bitmap) {
    387         sal_free(virtual_info->trill_vp_bitmap);
    388         virtual_info->trill_vp_bitmap = NULL;
    389     }
    390 
    391     if (virtual_info->vlan_vp_bitmap) {
    392         sal_free(virtual_info->vlan_vp_bitmap);
    393         virtual_info->vlan_vp_bitmap = NULL;
    394     }
    395 
    396     if (virtual_info->niv_vp_bitmap) {
    397         sal_free(virtual_info->niv_vp_bitmap);
    398         virtual_info->niv_vp_bitmap = NULL;
    399     }
    400 
    401     if (virtual_info->l2gre_vfi_bitmap) {
    402         sal_free(virtual_info->l2gre_vfi_bitmap);
    403         virtual_info->l2gre_vfi_bitmap = NULL;
    404     }
    405 
    406     if (virtual_info->l2gre_vp_bitmap) {
    407         sal_free(virtual_info->l2gre_vp_bitmap);
    408         virtual_info->l2gre_vp_bitmap = NULL;
    409     }
    410 
    411     if (virtual_info->vxlan_vfi_bitmap) {
    412         sal_free(virtual_info->vxlan_vfi_bitmap);
    413         virtual_info->vxlan_vfi_bitmap = NULL;
    414     }
    415 
    416     if (virtual_info->vxlan_vp_bitmap) {
    417         sal_free(virtual_info->vxlan_vp_bitmap);
    418         virtual_info->vxlan_vp_bitmap = NULL;
    419     }
    420 
    421     if (virtual_info->extender_vp_bitmap) {
    422         sal_free(virtual_info->extender_vp_bitmap);
    423         virtual_info->extender_vp_bitmap = NULL;
    424     }
    425 
    426     if (virtual_info->vp_lag_vp_bitmap) {
    427         sal_free(virtual_info->vp_lag_vp_bitmap);
    428         virtual_info->vp_lag_vp_bitmap = NULL;
    429     }
    430     if (virtual_info->vp_shared_vp_bitmap) {
    431         sal_free(virtual_info->vp_shared_vp_bitmap);
    432         virtual_info->vp_shared_vp_bitmap = NULL;
    433     }
    434     if (virtual_info->vp_network_vp_bitmap) {
    435         sal_free(virtual_info->vp_network_vp_bitmap);
    436         virtual_info->vp_network_vp_bitmap = NULL;
    437     }
    438     if (virtual_info->vlan_vfi_bitmap) {
    439         sal_free(virtual_info->vlan_vfi_bitmap);
    440         virtual_info->vlan_vfi_bitmap = NULL;
    441     }
    442 
    443     if (virtual_info->flow_vfi_bitmap) {
    444         sal_free(virtual_info->flow_vfi_bitmap);
    445         virtual_info->flow_vfi_bitmap = NULL;
    446     }
    447 
    448     if (virtual_info->flow_vp_bitmap) {
    449         sal_free(virtual_info->flow_vp_bitmap);
    450         virtual_info->flow_vp_bitmap = NULL;
    451     }
    452 
    453     if (virtual_info->vp_to_vpn) {
    454         sal_free(virtual_info->vp_to_vpn);
    455         virtual_info->vp_to_vpn = NULL;
    456     }
    457 }
    458 
    459 #ifdef BCM_WARM_BOOT_SUPPORT
    460 
    461 #define BCM_WB_VERSION_1_0                SOC_SCACHE_VERSION(1,0)
    462 #define BCM_WB_VERSION_1_1                SOC_SCACHE_VERSION(1,1)
    463 #define BCM_WB_VERSION_1_2                SOC_SCACHE_VERSION(1,2)
    464 #define BCM_WB_VERSION_1_3                SOC_SCACHE_VERSION(1,3)
    465 #define BCM_WB_VERSION_1_4                SOC_SCACHE_VERSION(1,4)
    466 #define BCM_WB_VERSION_1_5                SOC_SCACHE_VERSION(1,5)
    467 #define BCM_WB_VERSION_1_6                SOC_SCACHE_VERSION(1,6)
    468 #define BCM_WB_VERSION_1_7                SOC_SCACHE_VERSION(1,7)
    469 #define BCM_WB_VERSION_1_8                SOC_SCACHE_VERSION(1,8)
    470 #define BCM_WB_VERSION_1_9                SOC_SCACHE_VERSION(1,9)
    471 #define BCM_WB_VERSION_1_10               SOC_SCACHE_VERSION(1,10)
    472 #define BCM_WB_VERSION_1_11               SOC_SCACHE_VERSION(1,11)
    473 #define BCM_WB_VERSION_1_12               SOC_SCACHE_VERSION(1,12)
    474 #define BCM_WB_VERSION_1_13               SOC_SCACHE_VERSION(1,13)
    475 #define BCM_WB_VERSION_1_14               SOC_SCACHE_VERSION(1,14)
    476 #define BCM_WB_DEFAULT_VERSION            BCM_WB_VERSION_1_14
    477 
    478 /*
    479  * Function:
    480  *      _bcm_esw_virtual_sync
    481  * Purpose:
    482  *      - Copy the s/w state of 'Virtual' module to external
    483  *        memory.
    484  *      - Not called during Warm Boot.
    485  * Parameters:
    486  *      unit    -  (IN) Device number.
    487  * Returns:
    488  *      BCM_X_XXX
    489  */
    490 int
    491 _bcm_esw_virtual_sync(int unit)
    492 {
    493     int                 stable_size, alloc_sz = 0;
    494     int                 num_vp, num_vfi;
    495     uint8               *virtual_bitmap;
    496     soc_scache_handle_t scache_handle;  /* SCache reference number        */
    497 #if defined(BCM_SABER2_SUPPORT)
    498     uint32     source_vp_sb2_5626x = 0xFED5ABC7;
    499 #endif /* BCM_SABER2_SUPPORT */
    500 
    501     SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
    502 
    503     if ((0 == stable_size) || (SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit))) {
    504         return BCM_E_NONE;
    505     }
    506     if ((!SOC_MEM_IS_VALID(unit, VFIm)) ||
    507         (!SOC_MEM_IS_VALID(unit, SOURCE_VPm))) {
    508         /* ===============================================       */
    509         /* Either VFI not present or SOURCE_VP not present.      */
    510         /* Possible with some chips(hurricane) so not continuing */
    511         /* ===============================================       */
    512 
    513         /* if (SOC_IS_HURRICANE(unit)) */
    514         return BCM_E_NONE;
    515     }
    516 
    517     num_vfi = soc_mem_index_count(unit, VFIm);
    518     num_vp = soc_mem_index_count(unit, SOURCE_VPm);
    519 
    520     alloc_sz += SHR_BITALLOCSIZE(num_vp);
    521     alloc_sz += SHR_BITALLOCSIZE(num_vfi);
    522     /* mpls vp */
    523     alloc_sz += SHR_BITALLOCSIZE(num_vp);
    524     /* mpls vfi */
    525     alloc_sz += SHR_BITALLOCSIZE(num_vfi);
    526     /* mim vp */
    527     alloc_sz += SHR_BITALLOCSIZE(num_vp);
    528     /* mim vfi */
    529     alloc_sz += SHR_BITALLOCSIZE(num_vfi);
    530     /* subport vp */
    531     alloc_sz += SHR_BITALLOCSIZE(num_vp);
    532     /* vlan vp */
    533     if (soc_feature(unit, soc_feature_vlan_vp)) {
    534         alloc_sz += SHR_BITALLOCSIZE(num_vp);
    535     }
    536     /* niv vp */
    537     if (soc_feature(unit, soc_feature_niv)) {
    538         alloc_sz += SHR_BITALLOCSIZE(num_vp);
    539     }
    540     /* trill vp */
    541     if (soc_feature(unit, soc_feature_trill)) {
    542         alloc_sz += SHR_BITALLOCSIZE(num_vp);
    543     }
    544     /* l2gre vp */
    545     if (soc_feature(unit, soc_feature_l2gre)) {
    546         alloc_sz += SHR_BITALLOCSIZE(num_vp);
    547         /* l2gre vfi */
    548         alloc_sz += SHR_BITALLOCSIZE(num_vfi);
    549     }
    550     /* extender vp */
    551     if (soc_feature(unit, soc_feature_port_extension)) {
    552         alloc_sz += SHR_BITALLOCSIZE(num_vp);
    553     }
    554     /* vp lag vp */
    555     if (soc_feature(unit, soc_feature_vp_lag)) {
    556         alloc_sz += SHR_BITALLOCSIZE(num_vp);
    557     }
    558 
    559     /* vxlan vfi & vp */
    560     if (soc_feature(unit, soc_feature_vxlan)) {
    561         alloc_sz += SHR_BITALLOCSIZE(num_vfi); 
    562         alloc_sz += SHR_BITALLOCSIZE(num_vp); 
    563     } 
    564 
    565     /* Shared vp */
    566     if (soc_feature(unit, soc_feature_vp_sharing)) {
    567         alloc_sz += SHR_BITALLOCSIZE(num_vp); 
    568     } 
    569 
    570     /* Network vp bitmap */
    571     alloc_sz += SHR_BITALLOCSIZE(num_vp); 
    572 
    573     /*vlan vfi*/
    574     if (soc_feature(unit, soc_feature_vlan_vfi)) {
    575         alloc_sz += SHR_BITALLOCSIZE(num_vfi);
    576     }
    577 
    578     /* flow vfi & vp */
    579     if (soc_feature(unit, soc_feature_flex_flow)) {
    580         alloc_sz += SHR_BITALLOCSIZE(num_vfi);
    581         alloc_sz += SHR_BITALLOCSIZE(num_vp);
    582     }
    583 
    584     /* Use the same bitmap as shared access VP, if it was allocated,
    585      * DO NOT allocate it again.
    586      */
    587     if ((!soc_feature(unit, soc_feature_vp_sharing)) &&
    588         soc_feature(unit, soc_feature_nexthop_share_dvp)) {
    589         alloc_sz += SHR_BITALLOCSIZE(num_vp); 
    590     }
    591 
    592     /* Maximum virtual port supported on saber2 5626x devices are 4K
    593      * This fix is related to scaling down of vpn from 8K to 4K
    594      */
    595 #if defined(BCM_SABER2_SUPPORT)
    596         if (soc_sb2_5626x_devtype(unit)) {
    597             alloc_sz += sizeof(source_vp_sb2_5626x);
    598         }
    599 #endif /* BCM_SABER2_SUPPORT */
    600 
    601 #ifdef BCM_TRIDENT2_SUPPORT
    602     if (soc_feature(unit, soc_feature_vlan_vp) &&
    603         soc_feature(unit, soc_feature_vp_lag)) {
    604         int vlan_vp_scache_size = 0;
    605         BCM_IF_ERROR_RETURN(
    606             _bcm_td2_vlan_vp_scache_size_get(unit, &vlan_vp_scache_size));
    607 
    608         /* VLAN VP Info */
    609         alloc_sz += vlan_vp_scache_size;
    610     }
    611 
    612     if (soc_feature(unit, soc_feature_vp_lag)) {
    613         int egr_dis_vp_scache_size = 0;
    614         BCM_IF_ERROR_RETURN(
    615             _bcm_td2_vp_lag_egr_dis_vp_scache_size_get(unit, &egr_dis_vp_scache_size));
    616         alloc_sz += egr_dis_vp_scache_size;
    617     }
    618 #endif
    619 
    620     SOC_SCACHE_HANDLE_SET(scache_handle,
    621                           unit, BCM_MODULE_VIRTUAL, 0);
    622 
    623     if (stable_size > alloc_sz) {
    624         SOC_IF_ERROR_RETURN (_bcm_esw_scache_ptr_get(unit, scache_handle, FALSE,
    625                              alloc_sz, &virtual_bitmap, 
    626                              BCM_WB_DEFAULT_VERSION, NULL));
    627         
    628         VIRTUAL_LOCK(unit);
    629         /* Maximum virtual port supported on saber2 5626x devices are 4K
    630          * This fix is related to scaling down of vpn from 8K to 4K
    631          */
    632 #if defined(BCM_SABER2_SUPPORT)
    633         if (soc_sb2_5626x_devtype(unit)) {
    634             sal_memcpy(virtual_bitmap, &source_vp_sb2_5626x,
    635                     sizeof(source_vp_sb2_5626x));
    636             virtual_bitmap += sizeof(source_vp_sb2_5626x);
    637         }
    638 #endif /* BCM_SABER2_SUPPORT */
    639         sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->vp_bitmap,
    640                    SHR_BITALLOCSIZE(num_vp));
    641         virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
    642         sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->vfi_bitmap,
    643                    SHR_BITALLOCSIZE(num_vfi));
    644         virtual_bitmap += SHR_BITALLOCSIZE(num_vfi);
    645         sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->mpls_vp_bitmap,
    646                    SHR_BITALLOCSIZE(num_vp));
    647         virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
    648         sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->mpls_vfi_bitmap,
    649                    SHR_BITALLOCSIZE(num_vfi));
    650         virtual_bitmap += SHR_BITALLOCSIZE(num_vfi);
    651         sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->mim_vp_bitmap,
    652                    SHR_BITALLOCSIZE(num_vp));
    653         virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
    654         sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->mim_vfi_bitmap,
    655                    SHR_BITALLOCSIZE(num_vfi));
    656         virtual_bitmap += SHR_BITALLOCSIZE(num_vfi);
    657         sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->subport_vp_bitmap,
    658                    SHR_BITALLOCSIZE(num_vp));
    659         virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
    660         
    661         if (soc_feature(unit, soc_feature_vlan_vp)) {
    662             sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->vlan_vp_bitmap, 
    663                        SHR_BITALLOCSIZE(num_vp));
    664             virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
    665         }
    666 
    667         if (soc_feature(unit, soc_feature_niv)) {
    668             sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->niv_vp_bitmap,
    669                            SHR_BITALLOCSIZE(num_vp));
    670             virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
    671         }
    672 
    673         if (soc_feature(unit, soc_feature_trill)) {
    674             sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->trill_vp_bitmap,
    675                           SHR_BITALLOCSIZE(num_vp));
    676             virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
    677         }
    678 
    679         if (soc_feature(unit, soc_feature_l2gre)) {
    680             sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->l2gre_vp_bitmap,
    681                           SHR_BITALLOCSIZE(num_vp));
    682             virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
    683         }
    684 
    685         if (soc_feature(unit, soc_feature_port_extension)) {
    686             sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->extender_vp_bitmap,
    687                            SHR_BITALLOCSIZE(num_vp));
    688             virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
    689         }
    690 
    691         if (soc_feature(unit, soc_feature_vp_lag)) {
    692             sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->vp_lag_vp_bitmap,
    693                            SHR_BITALLOCSIZE(num_vp));
    694             virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
    695         }
    696 
    697         /* 
    698          *  BCM_WB_VERSION_1_3
    699          */
    700 
    701         /* Store VXLAN vfi/vp BITMAP */
    702         /* 
    703          *  VXLAN vfi/vp BITMAP points to a struct array with a base type of uint32.
    704          *  sized to hold the maximum number of VFI / VP
    705          * 
    706          *  uint32[(size of (SOURCE_VPm) + 32) / 32]     *vxlan_ip_tnl_bitmap
    707          */
    708 
    709         if (soc_feature(unit, soc_feature_vxlan)) {
    710             sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->vxlan_vfi_bitmap,
    711                            SHR_BITALLOCSIZE(num_vfi));
    712             virtual_bitmap += SHR_BITALLOCSIZE(num_vfi);
    713 
    714             sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->vxlan_vp_bitmap,
    715                            SHR_BITALLOCSIZE(num_vp));
    716             virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
    717         }
    718 
    719         /* 
    720          *  BCM_WB_VERSION_1_4
    721          */
    722 
    723         /* Store shared VP */ 
    724         if (soc_feature(unit, soc_feature_vp_sharing)) {
    725             sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->vp_shared_vp_bitmap,
    726                            SHR_BITALLOCSIZE(num_vp));
    727             virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
    728         }
    729 
    730         /*
    731          * BCM_WB_VERSION_1_5
    732          * vp_network_vp_bitmap
    733          * Bit-map that specifies if the VP belongs to network-side port
    734          * Used for VxLAN/L2GRE/TRILL
    735          */
    736         sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->vp_network_vp_bitmap,
    737                        SHR_BITALLOCSIZE(num_vp));
    738         virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
    739 
    740         /*
    741          *  BCM_WB_VERSION_1_6
    742          */
    743 
    744         /* Store VLAN VFI */
    745         if (soc_feature(unit, soc_feature_vlan_vfi)) {
    746             sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->vlan_vfi_bitmap,
    747                            SHR_BITALLOCSIZE(num_vfi));
    748             virtual_bitmap += SHR_BITALLOCSIZE(num_vfi);
    749         }
    750 
    751         /*
    752          *  BCM_WB_VERSION_1_7
    753          */
    754         /* reuse the shared access vp bitmap to save the shared network dvp*/
    755         if ((!soc_feature(unit, soc_feature_vp_sharing)) &&
    756             soc_feature(unit, soc_feature_nexthop_share_dvp)) {
    757             sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->vp_shared_vp_bitmap,
    758                            SHR_BITALLOCSIZE(num_vp));
    759             virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
    760         }
    761 
    762         /* BCM_WB_VERSION_1_10 */
    763         /* Store Vlan Vp Info */
    764 #ifdef BCM_TRIDENT2_SUPPORT
    765         if (soc_feature(unit, soc_feature_vlan_vp) &&
    766             soc_feature(unit, soc_feature_vp_lag)) {
    767             int rv = BCM_E_NONE;
    768 
    769             rv = _bcm_td2_vlan_vp_sync(unit, &virtual_bitmap);
    770             if (BCM_FAILURE(rv)) {
    771                 VIRTUAL_UNLOCK(unit);
    772                 return rv;
    773             }
    774         }
    775 #endif
    776 
    777         if (soc_feature(unit, soc_feature_l2gre)) {
    778             sal_memcpy(virtual_bitmap,
    779                     VIRTUAL_INFO(unit)->l2gre_vfi_bitmap,
    780                     SHR_BITALLOCSIZE(num_vfi));
    781             virtual_bitmap += SHR_BITALLOCSIZE(num_vfi);
    782         }
    783 
    784         /* BCM_WB_VERSION_1_13 */
    785         if (soc_feature(unit, soc_feature_flex_flow)) {
    786             sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->flow_vfi_bitmap,
    787                            SHR_BITALLOCSIZE(num_vfi));
    788             virtual_bitmap += SHR_BITALLOCSIZE(num_vfi);
    789 
    790             sal_memcpy(virtual_bitmap, VIRTUAL_INFO(unit)->flow_vp_bitmap,
    791                            SHR_BITALLOCSIZE(num_vp));
    792             virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
    793         }
    794 
    795 #if defined(BCM_TRIDENT2_SUPPORT)
    796         /* BCM_EB_VERSION_1_14 */
    797         if (soc_feature(unit, soc_feature_vp_lag)) {
    798             int rv = BCM_E_NONE;
    799             rv = _bcm_td2_vp_lag_egr_dis_vp_sync(unit, &virtual_bitmap);
    800             if (BCM_FAILURE(rv)) {
    801                 VIRTUAL_UNLOCK(unit);
    802                 return rv;
    803             }
    804         }
    805 
    806 #endif /* BCM_TRIDENT2_SUPPORT  */
    807         VIRTUAL_UNLOCK(unit);
    808  
    809     }
    810 
    811     return BCM_E_NONE;
    812 }
    813 
    814 /* 
    815  * Function:
    816  *      _bcm_vp_info_hw_recover
    817  * Purpose: 
    818  *     Reconstruct the following VP info from h/w by
    819  *     traversing the source VP table:
    820  *     - Network VP bitmap
    821  *
    822  * Parameters:
    823  *      unit    : (IN) Device Unit Number
    824  * Returns:
    825  *      BCM_E_XXX
    826  */
    827 STATIC int
    828 _bcm_vp_info_hw_recover (int unit)
    829 {
    830     source_vp_entry_t *svp_entry; 
    831     int chnk_idx, ent_idx, chnk_idx_max, mem_idx_min, mem_idx_max;
    832     int buf_size, chunksize, chnk_end;
    833     uint32 *tbl_chnk;
    834     soc_mem_t mem = SOURCE_VPm;
    835     int rv = BCM_E_NONE;
    836     int is_network_port = FALSE;
    837 
    838     chunksize = 1024;
    839     buf_size = sizeof(source_vp_entry_t) * chunksize;
    840     tbl_chnk = soc_cm_salloc(unit, buf_size, "source_vp traverse");
    841     if (NULL == tbl_chnk) {
    842         return BCM_E_MEMORY;
    843     }
    844 
    845     mem_idx_min = soc_mem_index_min(unit, mem);
    846     mem_idx_max = soc_mem_index_max(unit, mem);
    847 
    848     for (chnk_idx = mem_idx_min;
    849          chnk_idx <= mem_idx_max;
    850          chnk_idx += chunksize) {
    851         sal_memset((void *)tbl_chnk, 0, buf_size);
    852 
    853         chnk_idx_max =
    854             ((chnk_idx + chunksize) <= mem_idx_max) ?
    855             chnk_idx + chunksize - 1: mem_idx_max;
    856 
    857         soc_mem_lock(unit, mem);
    858         rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY,
    859                                 chnk_idx, chnk_idx_max, tbl_chnk);
    860         if (SOC_FAILURE(rv)) {
    861             soc_mem_unlock(unit, mem);
    862             soc_cm_sfree(unit, tbl_chnk);
    863             return rv;
    864         }
    865         chnk_end = (chnk_idx_max - chnk_idx);
    866         for (ent_idx = 0 ; ent_idx <= chnk_end; ent_idx ++) {
    867             svp_entry = soc_mem_table_idx_to_pointer(unit, mem, 
    868                                              source_vp_entry_t *,
    869                                              tbl_chnk, ent_idx);
    870             if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) {
    871                 is_network_port =
    872                     soc_SOURCE_VPm_field32_get(unit, svp_entry, NETWORK_GROUPf);
    873             } else {
    874                 is_network_port =
    875                     soc_SOURCE_VPm_field32_get(unit, svp_entry, NETWORK_PORTf);
    876             }
    877             if (is_network_port) {
    878                 _BCM_NETWORK_VP_USED_SET(unit, ent_idx+chnk_idx);
    879             }
    880         }
    881         soc_mem_unlock(unit, mem);
    882     }
    883 
    884     soc_cm_sfree(unit, tbl_chnk);
    885     return BCM_E_NONE;
    886 }
    887 
    888 /*
    889  * Function:
    890  *      _bcm_vp_vpn_hw_recover
    891  * Purpose:
    892  *     Reconstruct the VP to VPN map from h/w by
    893  *     traversing the source VP table
    894  *
    895  * Parameters:
    896  *      unit    : (IN) Device Unit Number
    897  * Returns:
    898  *      BCM_E_XXX
    899  */
    900 STATIC int
    901 _bcm_vp_vpn_hw_recover(int unit)
    902 {
    903     source_vp_entry_t *svp_entry;
    904     int chnk_idx, ent_idx, chnk_idx_max, mem_idx_min, mem_idx_max;
    905     int buf_size, chunksize, chnk_end;
    906     uint32 *tbl_chnk;
    907     soc_mem_t mem = SOURCE_VPm;
    908     int rv = BCM_E_NONE;
    909     uint32 vfi = 0;
    910     bcm_vpn_t vpn = 0;
    911 
    912     chunksize = 1024;
    913     buf_size = sizeof(source_vp_entry_t) * chunksize;
    914     tbl_chnk = soc_cm_salloc(unit, buf_size, "source_vp traverse");
    915     if (NULL == tbl_chnk) {
    916         return BCM_E_MEMORY;
    917     }
    918 
    919     mem_idx_min = soc_mem_index_min(unit, mem);
    920     mem_idx_max = soc_mem_index_max(unit, mem);
    921 
    922     for (chnk_idx = mem_idx_min;
    923          chnk_idx <= mem_idx_max;
    924          chnk_idx += chunksize) {
    925         sal_memset((void *)tbl_chnk, 0, buf_size);
    926 
    927         chnk_idx_max =
    928             ((chnk_idx + chunksize) <= mem_idx_max) ?
    929             chnk_idx + chunksize - 1: mem_idx_max;
    930 
    931         soc_mem_lock(unit, mem);
    932         rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY,
    933                                 chnk_idx, chnk_idx_max, tbl_chnk);
    934         if (SOC_FAILURE(rv)) {
    935             soc_mem_unlock(unit, mem);
    936             soc_cm_sfree(unit, tbl_chnk);
    937             return rv;
    938         }
    939         chnk_end = (chnk_idx_max - chnk_idx);
    940         for (ent_idx = 0 ; ent_idx <= chnk_end; ent_idx ++) {
    941             svp_entry = soc_mem_table_idx_to_pointer(unit, mem,
    942                                                      source_vp_entry_t *,
    943                                                      tbl_chnk, ent_idx);
    944             /* Only record VPN for MPLS VPLS*/
    945             if (0x1 ==
    946                 soc_SOURCE_VPm_field32_get(unit, svp_entry, ENTRY_TYPEf)) {
    947                 vfi = soc_SOURCE_VPm_field32_get(unit, svp_entry, VFIf);
    948                 if (_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeMpls)) {
    949                     _BCM_MPLS_VPN_SET(vpn, _BCM_MPLS_VPN_TYPE_VPLS, vfi);
    950                     _bcm_vp_vfi_set(unit, ent_idx+chnk_idx, vpn);
    951                 }
    952             }
    953         }
    954         soc_mem_unlock(unit, mem);
    955     }
    956 
    957     soc_cm_sfree(unit, tbl_chnk);
    958     return BCM_E_NONE;
    959 }
    960 
    961 /*
    962  * Function:
    963  *      _bcm_virtual_reinit
    964  * Purpose:
    965  *      - Top level reinit func for Virtual module.
    966  *      - Do nothing for Unsynchronized (level 1) and Limited 
    967  *        scache (level 1.5) based recovery.
    968  *      - Extended scache (level 2) based recovery:
    969  *        a. Cold Boot: Allocate external memory required to store 
    970  *                 module specific s/w state.
    971  *        b. Warm Boot: Recover the s/w state from external memory.
    972  * Parameters:
    973  *      unit    -  (IN) Device number.
    974  * Returns:
    975  *      BCM_X_XXX
    976  */
    977 STATIC int
    978 _bcm_virtual_reinit(int unit) {
    979 
    980     int rv = BCM_E_NONE;
    981     int32  stable_size = 0;
    982     uint32 num_vp, num_vfi;
    983     uint32 alloc_sz = 0;
    984     uint8  *virtual_bitmap;
    985     uint16 recovered_ver;
    986     uint32  virtual_scache_size;
    987     soc_scache_handle_t scache_handle;  /* SCache reference number */
    988     int        old_num_vp = 0;
    989 #if defined(BCM_SABER2_SUPPORT)
    990     uint32     source_vp_sb2_5626x = 0;
    991 #endif /* BCM_SABER2_SUPPORT */
    992 
    993     SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
    994 
    995     if ((0 == stable_size) || (SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit))) {
    996     /* Unsynchronized or Limited scache support based recovery */
    997         return rv;
    998     } else { 
    999     /* Extended scache support available */
   1000 
   1001         num_vfi = soc_mem_index_count(unit, VFIm);
   1002         num_vp = soc_mem_index_count(unit, SOURCE_VPm);
   1003         SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_VIRTUAL, 0);
   1004     
   1005         alloc_sz += SHR_BITALLOCSIZE(num_vp);
   1006         alloc_sz += SHR_BITALLOCSIZE(num_vfi);
   1007         /* mpls vp */
   1008         alloc_sz += SHR_BITALLOCSIZE(num_vp);
   1009         /* mpls vfi */
   1010         alloc_sz += SHR_BITALLOCSIZE(num_vfi);
   1011         /* mim vp */
   1012         alloc_sz += SHR_BITALLOCSIZE(num_vp);
   1013         /* mim vfi */
   1014         alloc_sz += SHR_BITALLOCSIZE(num_vfi);
   1015         /* subport vp */
   1016         alloc_sz += SHR_BITALLOCSIZE(num_vp);
   1017         /* vlan vp */
   1018         if (soc_feature(unit, soc_feature_vlan_vp)) {
   1019             alloc_sz += SHR_BITALLOCSIZE(num_vp);
   1020         }
   1021         /* niv vp */
   1022         if (soc_feature(unit, soc_feature_niv)) {
   1023             alloc_sz += SHR_BITALLOCSIZE(num_vp);
   1024         }
   1025         /* trill vp */
   1026         if (soc_feature(unit, soc_feature_trill)) {
   1027             alloc_sz += SHR_BITALLOCSIZE(num_vp);
   1028         }
   1029         /* l2gre vp */
   1030         if (soc_feature(unit, soc_feature_l2gre)) {
   1031             alloc_sz += SHR_BITALLOCSIZE(num_vp);
   1032             alloc_sz += SHR_BITALLOCSIZE(num_vfi);
   1033         }
   1034         /* extender vp */
   1035         if (soc_feature(unit, soc_feature_port_extension)) {
   1036             alloc_sz += SHR_BITALLOCSIZE(num_vp);
   1037         }
   1038         /* vp lag vp */
   1039         if (soc_feature(unit, soc_feature_vp_lag)) {
   1040             alloc_sz += SHR_BITALLOCSIZE(num_vp);
   1041         }
   1042         /* vxlan vfi & vp */
   1043         if (soc_feature(unit, soc_feature_vxlan)) {
   1044             alloc_sz += SHR_BITALLOCSIZE(num_vfi); 
   1045             alloc_sz += SHR_BITALLOCSIZE(num_vp); 
   1046         }  
   1047 
   1048         /* flow vfi  & vp */
   1049         if (soc_feature(unit, soc_feature_flex_flow)) {
   1050             alloc_sz += SHR_BITALLOCSIZE(num_vfi);
   1051             alloc_sz += SHR_BITALLOCSIZE(num_vp);
   1052         }
   1053         
   1054         /* Shared vp */
   1055         if (soc_feature(unit, soc_feature_vp_sharing)) {
   1056             alloc_sz += SHR_BITALLOCSIZE(num_vp); 
   1057         } 
   1058         
   1059         /* Network vp */
   1060         alloc_sz += SHR_BITALLOCSIZE(num_vp); 
   1061 
   1062         /*vlan vfi*/
   1063         if (soc_feature(unit, soc_feature_vlan_vfi)) {
   1064             alloc_sz += SHR_BITALLOCSIZE(num_vfi);
   1065         }
   1066 
   1067         /* Use the same bitmap as shared access VP, if it was allocated,
   1068          * DO NOT allocate it again.
   1069          */
   1070         if ((!soc_feature(unit, soc_feature_vp_sharing)) &&
   1071             soc_feature(unit, soc_feature_nexthop_share_dvp)) {
   1072             alloc_sz += SHR_BITALLOCSIZE(num_vp); 
   1073         }
   1074 
   1075         /* Maximum virtual port supported on saber2 5626x devices are 4K
   1076          * This fix is related to scaling down of vpn from 8K to 4K
   1077          */
   1078 #if defined(BCM_SABER2_SUPPORT)
   1079         if (soc_sb2_5626x_devtype(unit)) {
   1080             alloc_sz += sizeof(source_vp_sb2_5626x);
   1081         }
   1082 #endif /* BCM_SABER2_SUPPORT */
   1083 
   1084 #ifdef BCM_TRIDENT2_SUPPORT
   1085         if (soc_feature(unit, soc_feature_vlan_vp) &&
   1086             soc_feature(unit, soc_feature_vp_lag)) {
   1087             int vlan_vp_scache_size = 0;
   1088             BCM_IF_ERROR_RETURN(
   1089                 _bcm_td2_vlan_vp_scache_size_get(unit, &vlan_vp_scache_size));
   1090 
   1091             /* VLAN VP Info */
   1092             alloc_sz += vlan_vp_scache_size;
   1093         }
   1094 
   1095         if (soc_feature(unit, soc_feature_vp_lag)) {
   1096             int vp_lag_scache_size = 0;;
   1097             BCM_IF_ERROR_RETURN(_bcm_td2_vp_lag_egr_dis_vp_scache_size_get(unit,
   1098                                     &vp_lag_scache_size));
   1099             alloc_sz += vp_lag_scache_size;
   1100         }
   1101 #endif
   1102 
   1103         if (SOC_WARM_BOOT(unit)) {
   1104         /* Warm Boot */
   1105             if (stable_size > alloc_sz) {
   1106                 SOC_IF_ERROR_RETURN(_bcm_esw_scache_ptr_get(unit, scache_handle,
   1107                                     FALSE, alloc_sz, &virtual_bitmap, 
   1108                                     BCM_WB_DEFAULT_VERSION, &recovered_ver));
   1109                 /* Maximum virtual port supported on saber2 5626x devices are 4K
   1110                  * This fix is related to scaling down of vpn from 8K to 4K
   1111                  */
   1112 #if defined(BCM_SABER2_SUPPORT)
   1113                 if (soc_sb2_5626x_devtype(unit)) {
   1114                     sal_memcpy(&source_vp_sb2_5626x, virtual_bitmap,
   1115                             sizeof(source_vp_sb2_5626x));
   1116                     if (source_vp_sb2_5626x == 0xFED5ABC7) {
   1117                         virtual_bitmap += sizeof(source_vp_sb2_5626x);
   1118                     } else {
   1119                         old_num_vp = 1;
   1120                     }
   1121                 }
   1122 #endif /* BCM_SABER2_SUPPORT */
   1123                 sal_memcpy(VIRTUAL_INFO(unit)->vp_bitmap, virtual_bitmap,
   1124                           SHR_BITALLOCSIZE(num_vp));
   1125                 /* coverity[dead_error_condition : FALSE] */
   1126                 if (old_num_vp) {
   1127                     virtual_bitmap += SHR_BITALLOCSIZE(num_vp * 2);
   1128                 } else {
   1129                     virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
   1130                 }
   1131                 sal_memcpy(VIRTUAL_INFO(unit)->vfi_bitmap, virtual_bitmap,
   1132                           SHR_BITALLOCSIZE(num_vfi));
   1133                 virtual_bitmap += SHR_BITALLOCSIZE(num_vfi);
   1134                 sal_memcpy(VIRTUAL_INFO(unit)->mpls_vp_bitmap, virtual_bitmap,
   1135                           SHR_BITALLOCSIZE(num_vp));
   1136                 /* coverity[dead_error_condition : FALSE] */
   1137                 if (old_num_vp) {
   1138                     virtual_bitmap += SHR_BITALLOCSIZE(num_vp * 2);
   1139                 } else {
   1140                     virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
   1141                 }
   1142                 sal_memcpy(VIRTUAL_INFO(unit)->mpls_vfi_bitmap, virtual_bitmap,
   1143                           SHR_BITALLOCSIZE(num_vfi));
   1144                 virtual_bitmap += SHR_BITALLOCSIZE(num_vfi);
   1145                 sal_memcpy(VIRTUAL_INFO(unit)->mim_vp_bitmap, virtual_bitmap,
   1146                           SHR_BITALLOCSIZE(num_vp));
   1147                 /* coverity[dead_error_condition : FALSE] */
   1148                 if (old_num_vp) {
   1149                     virtual_bitmap += SHR_BITALLOCSIZE(num_vp * 2);
   1150                 } else {
   1151                     virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
   1152                 }
   1153                 sal_memcpy(VIRTUAL_INFO(unit)->mim_vfi_bitmap, virtual_bitmap,
   1154                           SHR_BITALLOCSIZE(num_vfi));
   1155                 virtual_bitmap += SHR_BITALLOCSIZE(num_vfi);
   1156                 sal_memcpy(VIRTUAL_INFO(unit)->subport_vp_bitmap, virtual_bitmap,
   1157                           SHR_BITALLOCSIZE(num_vp));
   1158                 /* coverity[dead_error_condition : FALSE] */
   1159                 if (old_num_vp) {
   1160                     virtual_bitmap += SHR_BITALLOCSIZE(num_vp * 2);
   1161                 } else {
   1162                     virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
   1163                 }
   1164 
   1165                 virtual_scache_size = 0;
   1166                 if (recovered_ver >= BCM_WB_VERSION_1_1) {
   1167                     if (soc_feature(unit, soc_feature_vlan_vp)) {
   1168                             sal_memcpy(VIRTUAL_INFO(unit)->vlan_vp_bitmap, virtual_bitmap,
   1169                                       SHR_BITALLOCSIZE(num_vp));
   1170                             /* coverity[dead_error_condition : FALSE] */
   1171                             if (old_num_vp) {
   1172                                 virtual_bitmap += SHR_BITALLOCSIZE(num_vp * 2);
   1173                             } else {
   1174                                 virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
   1175                             }
   1176                     }
   1177 
   1178                     if (soc_feature(unit, soc_feature_niv)) {
   1179 #ifdef BCM_KATANA2_SUPPORT
   1180                         if (recovered_ver < BCM_WB_VERSION_1_9) {
   1181                             if (!SOC_IS_KATANA2(unit)) {
   1182                                 sal_memcpy(VIRTUAL_INFO(unit)->niv_vp_bitmap,
   1183                                            virtual_bitmap,
   1184                                            SHR_BITALLOCSIZE(num_vp));
   1185                                 /* coverity[dead_error_condition : FALSE] */
   1186                                 if (old_num_vp) {
   1187                                     virtual_bitmap += SHR_BITALLOCSIZE(num_vp * 2);
   1188                                 } else {
   1189                                     virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
   1190                                 }
   1191                             }
   1192                         } else
   1193 #endif /* BCM_KATANA2_SUPPORT */
   1194                         {
   1195                             sal_memcpy(VIRTUAL_INFO(unit)->niv_vp_bitmap,
   1196                                        virtual_bitmap,
   1197                                        SHR_BITALLOCSIZE(num_vp));
   1198                             /* coverity[dead_error_condition : FALSE] */
   1199                             if (old_num_vp) {
   1200                                 virtual_bitmap += SHR_BITALLOCSIZE(num_vp * 2);
   1201                             } else {
   1202                                 virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
   1203                             }
   1204                         }
   1205                     }
   1206 
   1207                     if (soc_feature(unit, soc_feature_trill)) {
   1208                             sal_memcpy(VIRTUAL_INFO(unit)->trill_vp_bitmap, virtual_bitmap,
   1209                                       SHR_BITALLOCSIZE(num_vp));
   1210                             /* coverity[dead_error_condition : FALSE] */
   1211                             if (old_num_vp) {
   1212                                 virtual_bitmap += SHR_BITALLOCSIZE(num_vp * 2);
   1213                             } else {
   1214                                 virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
   1215                             }
   1216                     }
   1217                 } else {
   1218                     if (soc_feature(unit, soc_feature_vlan_vp)) {
   1219                         /* coverity[dead_error_condition : FALSE] */
   1220                         if (old_num_vp) {
   1221                             virtual_scache_size += SHR_BITALLOCSIZE(num_vp * 2);
   1222                         } else {
   1223                             virtual_scache_size += SHR_BITALLOCSIZE(num_vp);
   1224                         }
   1225                     }
   1226                     if (soc_feature(unit, soc_feature_niv)) {
   1227                         if (!SOC_IS_KATANA2(unit)) {
   1228                             /* coverity[dead_error_condition : FALSE] */
   1229                             if (old_num_vp) {
   1230                                 virtual_scache_size += SHR_BITALLOCSIZE(num_vp * 2);
   1231                             } else {
   1232                                 virtual_scache_size += SHR_BITALLOCSIZE(num_vp); 
   1233                             }
   1234                         }
   1235                     }
   1236                     if (soc_feature(unit, soc_feature_trill)) {
   1237                         /* coverity[dead_error_condition : FALSE] */
   1238                         if (old_num_vp) {
   1239                             virtual_scache_size += SHR_BITALLOCSIZE(num_vp * 2);
   1240                         } else {
   1241                             virtual_scache_size += SHR_BITALLOCSIZE(num_vp);
   1242                         }
   1243                     }
   1244                 }
   1245 
   1246                 if (recovered_ver >= BCM_WB_VERSION_1_2) {
   1247                     if (soc_feature(unit, soc_feature_l2gre)) {
   1248                             sal_memcpy(VIRTUAL_INFO(unit)->l2gre_vp_bitmap, virtual_bitmap,
   1249                                        SHR_BITALLOCSIZE(num_vp));
   1250                             /* coverity[dead_error_condition : FALSE] */
   1251                             if (old_num_vp) {
   1252                                 virtual_bitmap += SHR_BITALLOCSIZE(num_vp * 2);
   1253                             } else {
   1254                                 virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
   1255                             }
   1256 
   1257                             if (recovered_ver == BCM_WB_VERSION_1_11) {
   1258                                 sal_memcpy(VIRTUAL_INFO(unit)->l2gre_vfi_bitmap, virtual_bitmap,
   1259                                         SHR_BITALLOCSIZE(num_vfi));
   1260                                 virtual_bitmap += SHR_BITALLOCSIZE(num_vfi);
   1261                             }
   1262                     }
   1263                     if (soc_feature(unit, soc_feature_port_extension)) {
   1264                             sal_memcpy(VIRTUAL_INFO(unit)->extender_vp_bitmap, virtual_bitmap,
   1265                                       SHR_BITALLOCSIZE(num_vp));
   1266                             /* coverity[dead_error_condition : FALSE] */
   1267                             if (old_num_vp) {
   1268                                 virtual_bitmap += SHR_BITALLOCSIZE(num_vp * 2);
   1269                             } else {
   1270                                 virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
   1271                             }
   1272                     }
   1273                     if (soc_feature(unit, soc_feature_vp_lag)) {
   1274                             sal_memcpy(VIRTUAL_INFO(unit)->vp_lag_vp_bitmap, virtual_bitmap,
   1275                                       SHR_BITALLOCSIZE(num_vp));
   1276                             /* coverity[dead_error_condition : FALSE] */
   1277                             if (old_num_vp) {
   1278                                 virtual_bitmap += SHR_BITALLOCSIZE(num_vp * 2);
   1279                             } else {
   1280                                 virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
   1281                             }
   1282                     }
   1283                 } else {
   1284                     if (soc_feature(unit, soc_feature_l2gre)) {
   1285                         /* coverity[dead_error_condition : FALSE] */
   1286                         if (old_num_vp) {
   1287                             virtual_scache_size += SHR_BITALLOCSIZE(num_vp * 2);
   1288                         } else {
   1289                             virtual_scache_size += SHR_BITALLOCSIZE(num_vp);
   1290                         }
   1291                     }
   1292                     if (soc_feature(unit, soc_feature_port_extension)) {
   1293                         /* coverity[dead_error_condition : FALSE] */
   1294                         if (old_num_vp) {
   1295                             virtual_scache_size += SHR_BITALLOCSIZE(num_vp * 2);
   1296                         } else {
   1297                             virtual_scache_size += SHR_BITALLOCSIZE(num_vp); 
   1298                         }
   1299                     }
   1300                     if (soc_feature(unit, soc_feature_vp_lag)) {
   1301                         /* coverity[dead_error_condition : FALSE] */
   1302                         if (old_num_vp) {
   1303                             virtual_scache_size += SHR_BITALLOCSIZE(num_vp * 2);
   1304                         } else {
   1305                             virtual_scache_size += SHR_BITALLOCSIZE(num_vp); 
   1306                         }
   1307                     }
   1308                 }
   1309 
   1310                 if (recovered_ver >= BCM_WB_VERSION_1_3) {
   1311                     if (soc_feature(unit, soc_feature_vxlan)) {
   1312                         if (recovered_ver >= BCM_WB_VERSION_1_8) {
   1313                             sal_memcpy(VIRTUAL_INFO(unit)->vxlan_vfi_bitmap, virtual_bitmap,
   1314                                        SHR_BITALLOCSIZE(num_vfi));
   1315                             virtual_bitmap += SHR_BITALLOCSIZE(num_vfi);
   1316                         } else {
   1317                             /* When the recovered version smaller than BCM_WB_VERSION_1_8,
   1318                              * the store was incorrect,  adjust the offset to recover the state */
   1319                             sal_memcpy(VIRTUAL_INFO(unit)->vxlan_vfi_bitmap,
   1320                             virtual_bitmap - (SHR_BITALLOCSIZE(num_vp) - SHR_BITALLOCSIZE(num_vfi)),
   1321                                        SHR_BITALLOCSIZE(num_vfi));
   1322                             virtual_bitmap += SHR_BITALLOCSIZE(num_vfi);
   1323                         }
   1324                         sal_memcpy(VIRTUAL_INFO(unit)->vxlan_vp_bitmap, virtual_bitmap,
   1325                                    SHR_BITALLOCSIZE(num_vp));
   1326                         /* coverity[dead_error_condition : FALSE] */
   1327                         if (old_num_vp) {
   1328                             virtual_bitmap += SHR_BITALLOCSIZE(num_vp * 2);
   1329                         } else {
   1330                             virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
   1331                         }
   1332 
   1333                     }
   1334                 } else {
   1335                     if (soc_feature(unit, soc_feature_vxlan)) {
   1336                         virtual_scache_size += SHR_BITALLOCSIZE(num_vfi);
   1337                         /* coverity[dead_error_condition : FALSE] */
   1338                         if (old_num_vp) {
   1339                             virtual_scache_size += SHR_BITALLOCSIZE(num_vp * 2);
   1340                         } else {
   1341                             virtual_scache_size += SHR_BITALLOCSIZE(num_vp); 
   1342                         }
   1343                     }
   1344                 } 
   1345                 
   1346                 if (recovered_ver >= BCM_WB_VERSION_1_4) {
   1347                     if (soc_feature(unit, soc_feature_vp_sharing)) {
   1348                         sal_memcpy(VIRTUAL_INFO(unit)->vp_shared_vp_bitmap, virtual_bitmap,
   1349                                    SHR_BITALLOCSIZE(num_vp));
   1350                         /* coverity[dead_error_condition : FALSE] */
   1351                         if (old_num_vp) {
   1352                             virtual_bitmap += SHR_BITALLOCSIZE(num_vp * 2);
   1353                         } else {
   1354                             virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
   1355                         }
   1356                     }
   1357                 } else {
   1358                     if (soc_feature(unit, soc_feature_vp_sharing)) {
   1359                         /* coverity[dead_error_condition : FALSE] */
   1360                         if (old_num_vp) {
   1361                             virtual_scache_size += SHR_BITALLOCSIZE(num_vp * 2);
   1362                         } else {
   1363                             virtual_scache_size += SHR_BITALLOCSIZE(num_vp); 
   1364                         }
   1365                     }
   1366                 } 
   1367 
   1368                 if (recovered_ver >= BCM_WB_VERSION_1_5) {
   1369                     sal_memcpy(VIRTUAL_INFO(unit)->vp_network_vp_bitmap, virtual_bitmap,
   1370                             SHR_BITALLOCSIZE(num_vp));
   1371                     /* coverity[dead_error_condition : FALSE] */
   1372                     if (old_num_vp) {
   1373                         virtual_bitmap += SHR_BITALLOCSIZE(num_vp * 2);
   1374                     } else {
   1375                         virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
   1376                     }
   1377                 } else {
   1378                     /* 
   1379                      * When the recovered version doesn't have vp_network_vp_bitmap 
   1380                      * in scache, recover the state from hw by reading 
   1381                      * source_vp table.
   1382                      */
   1383                     BCM_IF_ERROR_RETURN(_bcm_vp_info_hw_recover(unit));
   1384                     /* coverity[dead_error_condition : FALSE] */
   1385                     if (old_num_vp) {
   1386                         virtual_scache_size += SHR_BITALLOCSIZE(num_vp * 2);
   1387                     } else {
   1388                         virtual_scache_size += SHR_BITALLOCSIZE(num_vp); 
   1389                     }
   1390                 }
   1391 
   1392                 if (recovered_ver >= BCM_WB_VERSION_1_6) {
   1393                     if (soc_feature(unit, soc_feature_vlan_vfi)) {
   1394                         if (recovered_ver >= BCM_WB_VERSION_1_8) {
   1395                             sal_memcpy(VIRTUAL_INFO(unit)->vlan_vfi_bitmap, virtual_bitmap,
   1396                                        SHR_BITALLOCSIZE(num_vfi));
   1397                             virtual_bitmap += SHR_BITALLOCSIZE(num_vfi);
   1398                         } else {
   1399                             /* When the recovered version smaller than BCM_WB_VERSION_1_8,
   1400                              * the store was incorrect,  adjust the offset to recover the state */
   1401                             sal_memcpy(VIRTUAL_INFO(unit)->vlan_vfi_bitmap, 
   1402                             virtual_bitmap - (SHR_BITALLOCSIZE(num_vp) - SHR_BITALLOCSIZE(num_vfi)),
   1403                                        SHR_BITALLOCSIZE(num_vfi));
   1404                             virtual_bitmap += SHR_BITALLOCSIZE(num_vfi);
   1405                         }
   1406                     }
   1407                 } else {
   1408                     if (soc_feature(unit, soc_feature_vlan_vfi)) {
   1409                         virtual_scache_size += SHR_BITALLOCSIZE(num_vfi);
   1410                     }
   1411                 } 
   1412 
   1413                 if (recovered_ver >= BCM_WB_VERSION_1_7) {
   1414                     if ((!soc_feature(unit, soc_feature_vp_sharing)) &&
   1415                         soc_feature(unit, soc_feature_nexthop_share_dvp)) {
   1416                         sal_memcpy(VIRTUAL_INFO(unit)->vp_shared_vp_bitmap, virtual_bitmap,
   1417                                    SHR_BITALLOCSIZE(num_vp));
   1418                         /* coverity[dead_error_condition : FALSE] */
   1419                         if (old_num_vp) {
   1420                             virtual_bitmap += SHR_BITALLOCSIZE(num_vp * 2);
   1421                         } else {
   1422                             virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
   1423                         }
   1424                     }
   1425                 } else {
   1426                     if ((!soc_feature(unit, soc_feature_vp_sharing)) &&
   1427                         soc_feature(unit, soc_feature_nexthop_share_dvp)) {
   1428                         /* coverity[dead_error_condition : FALSE] */
   1429                         if (old_num_vp) {
   1430                             virtual_scache_size += SHR_BITALLOCSIZE(num_vp * 2);
   1431                         } else {
   1432                             virtual_scache_size += SHR_BITALLOCSIZE(num_vp); 
   1433                         }
   1434                     }
   1435                 }
   1436 
   1437 #ifdef BCM_TRIDENT2_SUPPORT
   1438                 if (soc_feature(unit, soc_feature_vlan_vp) &&
   1439                     soc_feature(unit, soc_feature_vp_lag)) {
   1440                     if (recovered_ver >= BCM_WB_VERSION_1_10) {
   1441                         BCM_IF_ERROR_RETURN(
   1442                             _bcm_td2_vlan_vp_recover(unit, &virtual_bitmap));
   1443                     } else {
   1444                         int vlan_vp_size = 0;
   1445                         BCM_IF_ERROR_RETURN(
   1446                             _bcm_td2_vlan_vp_scache_size_get(unit, &vlan_vp_size));
   1447 
   1448                         virtual_scache_size += vlan_vp_size;
   1449                     }
   1450                 }
   1451 #endif
   1452 
   1453                 /*Due to SDK-93047 changes downgrade is broken.Always add new changes
   1454                  * in the last in scache layout*/
   1455                 if (recovered_ver >= BCM_WB_VERSION_1_12) {
   1456                     if (soc_feature(unit, soc_feature_l2gre)) {
   1457                         sal_memcpy(VIRTUAL_INFO(unit)->l2gre_vfi_bitmap,
   1458                                 virtual_bitmap,
   1459                                 SHR_BITALLOCSIZE(num_vfi));
   1460                         virtual_bitmap += SHR_BITALLOCSIZE(num_vfi);
   1461                     }
   1462                 } else {
   1463                     virtual_scache_size += SHR_BITALLOCSIZE(num_vfi);
   1464                 }
   1465 
   1466                 if (recovered_ver >= BCM_WB_VERSION_1_13) {
   1467                     if (soc_feature(unit, soc_feature_flex_flow)) {
   1468                         sal_memcpy(VIRTUAL_INFO(unit)->flow_vfi_bitmap, virtual_bitmap,
   1469                                 SHR_BITALLOCSIZE(num_vfi));
   1470                         virtual_bitmap += SHR_BITALLOCSIZE(num_vfi);
   1471 
   1472                         sal_memcpy(VIRTUAL_INFO(unit)->flow_vp_bitmap, virtual_bitmap,
   1473                                    SHR_BITALLOCSIZE(num_vp));
   1474                         if (old_num_vp) {
   1475                             virtual_bitmap += SHR_BITALLOCSIZE(num_vp * 2);
   1476                         } else {
   1477                             virtual_bitmap += SHR_BITALLOCSIZE(num_vp);
   1478                         }
   1479                     }
   1480                 } else {
   1481                     if (soc_feature(unit, soc_feature_flex_flow)) {
   1482                         virtual_scache_size += SHR_BITALLOCSIZE(num_vfi);
   1483                         if (old_num_vp) {
   1484                             virtual_scache_size += SHR_BITALLOCSIZE(num_vp * 2);
   1485                         } else {
   1486                             virtual_scache_size += SHR_BITALLOCSIZE(num_vp); 
   1487                         }
   1488                     }
   1489                 }
   1490 
   1491 #if defined(BCM_TRIDENT2_SUPPORT)
   1492                 if (soc_feature(unit, soc_feature_vp_lag)) {
   1493                     if (recovered_ver >= BCM_WB_VERSION_1_14) {
   1494                         /* recover member VPs with BCM_TRUNK_MEMBER_EGRESS_DISABLE flag */
   1495                         BCM_IF_ERROR_RETURN(_bcm_td2_vp_lag_egr_dis_vp_scache_recover(unit,
   1496                                                 &virtual_bitmap));
   1497                     } else {
   1498                         int vp_lag_scache_size = 0;
   1499                         BCM_IF_ERROR_RETURN(_bcm_td2_vp_lag_egr_dis_vp_scache_size_get(unit,
   1500                                                 &vp_lag_scache_size));
   1501                         virtual_scache_size += vp_lag_scache_size;
   1502                     }
   1503                 }
   1504 #endif /* BCM_TRIDENT2_SUPPORT */
   1505 
   1506                 if (virtual_scache_size > 0) {
   1507                     SOC_IF_ERROR_RETURN
   1508                         (soc_scache_realloc(unit, scache_handle, virtual_scache_size));
   1509                 }
   1510 
   1511             } else {
   1512                 rv = BCM_E_INTERNAL; /* stable_size < alloc_size */
   1513             }
   1514 
   1515             /* VP to VPN */
   1516             BCM_IF_ERROR_RETURN(_bcm_vp_vpn_hw_recover(unit));
   1517         } else {
   1518         /* Cold Boot */
   1519             if (stable_size > alloc_sz) {
   1520                 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE,
   1521                                              alloc_sz, &virtual_bitmap, 
   1522                                              BCM_WB_DEFAULT_VERSION, NULL);
   1523                 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
   1524                     return rv;
   1525                 }
   1526             }
   1527         }
   1528     }
   1529     return rv;
   1530 }
   1531 
   1532 #endif /* BCM_WARM_BOOT_SUPPORT */
   1533 
   1534 /*
   1535  * Function:
   1536  *      _bcm_vp_info_init
   1537  * Purpose:
   1538  *      Internal function to initialize _bcm_vp_info_t structure
   1539  * Parameters:
   1540  *      _bcm_vp_info_t (IN/OUT) variable
   1541  * Returns:
   1542  *      void
   1543  */
   1544 void
   1545 _bcm_vp_info_init (_bcm_vp_info_t *vp_info)
   1546 {
   1547     if (vp_info != NULL) {
   1548         sal_memset(vp_info, 0, sizeof (*vp_info));
   1549     }
   1550     return;
   1551 }
   1552 
   1553 int _bcm_vlan_xlate_dummy_vp_init(int unit, int index)
   1554 {
   1555     source_vp_entry_t svp;
   1556     int min_vp, max_vp;
   1557 
   1558     min_vp = soc_mem_index_min(unit, SOURCE_VPm);
   1559     max_vp = soc_mem_index_max(unit, SOURCE_VPm);
   1560 
   1561     if ((index < min_vp) || (index > max_vp)) {
   1562         return BCM_E_PARAM;
   1563     }
   1564 
   1565     sal_memset(&svp, 0, sizeof(source_vp_entry_t));
   1566     soc_SOURCE_VPm_field32_set(unit, &svp, ENTRY_TYPEf, 7);
   1567     soc_SOURCE_VPm_field32_set(unit, &svp, IPV4L3_ENABLEf, 1);
   1568     soc_SOURCE_VPm_field32_set(unit, &svp, IPV6L3_ENABLEf, 1);
   1569     soc_SOURCE_VPm_field32_set(unit, &svp, ENABLE_IFILTERf, 0);
   1570     BCM_IF_ERROR_RETURN(WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, index, &svp));
   1571 
   1572     return BCM_E_NONE;
   1573 }
   1574 
   1575 /*
   1576  * Function:
   1577  *      _bcm_virtual_init
   1578  * Purpose:
   1579  *      Internal function for initializing virtual resource management
   1580  * Parameters:
   1581  *      unit    -  (IN) Device number.
   1582  * Returns:
   1583  *      BCM_X_XXX
   1584  */
   1585 int 
   1586 _bcm_virtual_init(int unit, soc_mem_t vp_mem, soc_mem_t vfi_mem)
   1587 {
   1588     int num_vfi, num_vp, num_wlan_vp=0, vp, rv = BCM_E_NONE;
   1589     _bcm_virtual_bookkeeping_t *virtual_info = VIRTUAL_INFO(unit);
   1590     _bcm_vp_info_t vp_info;
   1591     int num_bytes_vfi_table, idx, profile_idx;
   1592     uint8 *vfi_mem_buffer;
   1593     vfi_entry_t *vfi_entry;
   1594 
   1595 
   1596     num_vfi = soc_mem_index_count(unit, vfi_mem);
   1597     num_vp = soc_mem_index_count(unit, vp_mem);
   1598     if (soc_feature(unit, soc_feature_wlan)) {
   1599         if (SOC_MEM_IS_VALID(unit, WLAN_SVP_TABLEm)) {
   1600             num_wlan_vp = soc_mem_index_count(unit, WLAN_SVP_TABLEm);
   1601         } else {
   1602             num_wlan_vp = soc_mem_index_count(unit, SOURCE_VPm);
   1603         }
   1604     }
   1605     /* 
   1606      * Allocate resources 
   1607      */
   1608     if (NULL == _virtual_mutex[unit]) {
   1609         _virtual_mutex[unit] = sal_mutex_create("virtual mutex");
   1610         if (_virtual_mutex[unit] == NULL) {
   1611             _bcm_virtual_free_resource(unit, virtual_info);
   1612             return BCM_E_MEMORY;
   1613         }
   1614     }
   1615 
   1616     if (NULL == virtual_info->vfi_bitmap) {
   1617         virtual_info->vfi_bitmap =
   1618             sal_alloc(SHR_BITALLOCSIZE(num_vfi), "vfi_bitmap");
   1619         if (virtual_info->vfi_bitmap == NULL) {
   1620             _bcm_virtual_free_resource(unit, virtual_info);
   1621             return BCM_E_MEMORY;
   1622         }
   1623     }
   1624 
   1625     if (NULL == virtual_info->vp_bitmap) {
   1626         virtual_info->vp_bitmap =
   1627             sal_alloc(SHR_BITALLOCSIZE(num_vp), "vp_bitmap");
   1628         if (virtual_info->vp_bitmap == NULL) {
   1629             _bcm_virtual_free_resource(unit, virtual_info);
   1630             return BCM_E_MEMORY;
   1631         }
   1632     }
   1633 
   1634     if (NULL == virtual_info->mpls_vfi_bitmap) {
   1635         virtual_info->mpls_vfi_bitmap =
   1636             sal_alloc(SHR_BITALLOCSIZE(num_vfi), "mpls_vfi_bitmap");
   1637         if (virtual_info->mpls_vfi_bitmap == NULL) {
   1638             _bcm_virtual_free_resource(unit, virtual_info);
   1639             return BCM_E_MEMORY;
   1640         }
   1641     }
   1642 
   1643     if (NULL == virtual_info->mpls_vp_bitmap) {
   1644         virtual_info->mpls_vp_bitmap =
   1645             sal_alloc(SHR_BITALLOCSIZE(num_vp), "mpls_vp_bitmap");
   1646         if (virtual_info->mpls_vp_bitmap == NULL) {
   1647             _bcm_virtual_free_resource(unit, virtual_info);
   1648             return BCM_E_MEMORY;
   1649         }
   1650     }
   1651 
   1652     if (NULL == virtual_info->mim_vfi_bitmap) {
   1653         virtual_info->mim_vfi_bitmap =
   1654             sal_alloc(SHR_BITALLOCSIZE(num_vfi), "mim_vfi_bitmap");
   1655         if (virtual_info->mim_vfi_bitmap == NULL) {
   1656             _bcm_virtual_free_resource(unit, virtual_info);
   1657             return BCM_E_MEMORY;
   1658         }
   1659     }
   1660 
   1661     if (NULL == virtual_info->mim_vp_bitmap) {
   1662         virtual_info->mim_vp_bitmap =
   1663             sal_alloc(SHR_BITALLOCSIZE(num_vp), "mim_vp_bitmap");
   1664         if (virtual_info->mim_vp_bitmap == NULL) {
   1665             _bcm_virtual_free_resource(unit, virtual_info);
   1666             return BCM_E_MEMORY;
   1667         }
   1668     }
   1669 
   1670     if (NULL == virtual_info->subport_vp_bitmap) {
   1671         virtual_info->subport_vp_bitmap =
   1672             sal_alloc(SHR_BITALLOCSIZE(num_vp), "subport_vp_bitmap");
   1673         if (virtual_info->subport_vp_bitmap == NULL) {
   1674             _bcm_virtual_free_resource(unit, virtual_info);
   1675             return BCM_E_MEMORY;
   1676         }
   1677     }
   1678 
   1679     if (soc_feature(unit, soc_feature_wlan)) {
   1680         if (NULL == virtual_info->wlan_vp_bitmap) {
   1681             virtual_info->wlan_vp_bitmap =
   1682                 sal_alloc(SHR_BITALLOCSIZE(num_wlan_vp), "wlan_vp_bitmap");
   1683             if (virtual_info->wlan_vp_bitmap == NULL) {
   1684                 _bcm_virtual_free_resource(unit, virtual_info);
   1685                 return BCM_E_MEMORY;
   1686             }
   1687         }
   1688     }
   1689 
   1690     if (soc_feature(unit, soc_feature_trill)) {
   1691         if (NULL == virtual_info->trill_vp_bitmap) {
   1692             virtual_info->trill_vp_bitmap =
   1693                 sal_alloc(SHR_BITALLOCSIZE(num_vp), "trill_vp_bitmap");
   1694             if (virtual_info->trill_vp_bitmap == NULL) {
   1695                 _bcm_virtual_free_resource(unit, virtual_info);
   1696                 return BCM_E_MEMORY;
   1697             }
   1698         }
   1699     }
   1700 
   1701     if (soc_feature(unit, soc_feature_vlan_vp)) {
   1702         if (NULL == virtual_info->vlan_vp_bitmap) {
   1703             virtual_info->vlan_vp_bitmap =
   1704                 sal_alloc(SHR_BITALLOCSIZE(num_vp), "vlan_vp_bitmap");
   1705             if (virtual_info->vlan_vp_bitmap == NULL) {
   1706                 _bcm_virtual_free_resource(unit, virtual_info);
   1707                 return BCM_E_MEMORY;
   1708             }
   1709         }
   1710     }
   1711 
   1712     if (soc_feature(unit, soc_feature_niv)) {
   1713         if (NULL == virtual_info->niv_vp_bitmap) {
   1714             virtual_info->niv_vp_bitmap =
   1715                 sal_alloc(SHR_BITALLOCSIZE(num_vp), "niv_vp_bitmap");
   1716             if (virtual_info->niv_vp_bitmap == NULL) {
   1717                 _bcm_virtual_free_resource(unit, virtual_info);
   1718                 return BCM_E_MEMORY;
   1719             }
   1720         }
   1721     }
   1722 
   1723     if (soc_feature(unit, soc_feature_l2gre)) {
   1724         if (NULL == virtual_info->l2gre_vfi_bitmap) {
   1725             virtual_info->l2gre_vfi_bitmap =
   1726                    sal_alloc(SHR_BITALLOCSIZE(num_vfi), "l2gre_vfi_bitmap");
   1727             if (virtual_info->l2gre_vfi_bitmap == NULL) {
   1728                 _bcm_virtual_free_resource(unit, virtual_info);
   1729                 return BCM_E_MEMORY;
   1730             }
   1731         }
   1732     }
   1733     
   1734     if (soc_feature(unit, soc_feature_l2gre)) {
   1735         if (NULL == virtual_info->l2gre_vp_bitmap) {
   1736             virtual_info->l2gre_vp_bitmap =
   1737                 sal_alloc(SHR_BITALLOCSIZE(num_vp), "l2gre_vp_bitmap");
   1738             if (virtual_info->l2gre_vp_bitmap == NULL) {
   1739                 _bcm_virtual_free_resource(unit, virtual_info);
   1740                 return BCM_E_MEMORY;
   1741             }
   1742         }
   1743     }
   1744 
   1745     if (soc_feature(unit, soc_feature_vxlan)) {
   1746         if (NULL == virtual_info->vxlan_vfi_bitmap) {
   1747             virtual_info->vxlan_vfi_bitmap =
   1748                    sal_alloc(SHR_BITALLOCSIZE(num_vfi), "vxlan_vfi_bitmap");
   1749             if (virtual_info->vxlan_vfi_bitmap == NULL) {
   1750                 _bcm_virtual_free_resource(unit, virtual_info);
   1751                 return BCM_E_MEMORY;
   1752             }
   1753         }
   1754     }
   1755     
   1756     if (soc_feature(unit, soc_feature_vxlan)) {
   1757         if (NULL == virtual_info->vxlan_vp_bitmap) {
   1758             virtual_info->vxlan_vp_bitmap =
   1759                 sal_alloc(SHR_BITALLOCSIZE(num_vp), "vxlan_vp_bitmap");
   1760             if (virtual_info->vxlan_vp_bitmap == NULL) {
   1761                 _bcm_virtual_free_resource(unit, virtual_info);
   1762                 return BCM_E_MEMORY;
   1763             }
   1764         }
   1765     }
   1766 
   1767     if (soc_feature(unit, soc_feature_port_extension)) {
   1768         if (NULL == virtual_info->extender_vp_bitmap) {
   1769             virtual_info->extender_vp_bitmap =
   1770                 sal_alloc(SHR_BITALLOCSIZE(num_vp), "extender_vp_bitmap");
   1771             if (virtual_info->extender_vp_bitmap == NULL) {
   1772                 _bcm_virtual_free_resource(unit, virtual_info);
   1773                 return BCM_E_MEMORY;
   1774             }
   1775         }
   1776     }
   1777 
   1778     if (soc_feature(unit, soc_feature_vp_lag)) {
   1779         if (NULL == virtual_info->vp_lag_vp_bitmap) {
   1780             virtual_info->vp_lag_vp_bitmap =
   1781                 sal_alloc(SHR_BITALLOCSIZE(num_vp), "vp_lag_vp_bitmap");
   1782             if (virtual_info->vp_lag_vp_bitmap == NULL) {
   1783                 _bcm_virtual_free_resource(unit, virtual_info);
   1784                 return BCM_E_MEMORY;
   1785             }
   1786         }
   1787     }
   1788 
   1789     if (soc_feature(unit, soc_feature_vp_sharing) || 
   1790         soc_feature(unit, soc_feature_nexthop_share_dvp)) {
   1791         if (NULL == virtual_info->vp_shared_vp_bitmap) {
   1792             virtual_info->vp_shared_vp_bitmap =
   1793                 sal_alloc(SHR_BITALLOCSIZE(num_vp), "vp_shared_vp_bitmap");
   1794             if (virtual_info->vp_shared_vp_bitmap == NULL) {
   1795                 _bcm_virtual_free_resource(unit, virtual_info);
   1796                 return BCM_E_MEMORY;
   1797             }
   1798         }
   1799     }
   1800 
   1801     if (NULL == virtual_info->vp_network_vp_bitmap) {
   1802         virtual_info->vp_network_vp_bitmap =
   1803             sal_alloc(SHR_BITALLOCSIZE(num_vp), "vp_network_vp_bitmap");
   1804         if (virtual_info->vp_network_vp_bitmap == NULL) {
   1805             _bcm_virtual_free_resource(unit, virtual_info);
   1806             return BCM_E_MEMORY;
   1807         }
   1808     }
   1809 
   1810     if (soc_feature(unit, soc_feature_vlan_vp)) {
   1811         if (NULL == virtual_info->vlan_vfi_bitmap) {
   1812             virtual_info->vlan_vfi_bitmap =
   1813                 sal_alloc(SHR_BITALLOCSIZE(num_vfi), "vlan_vfi_bitmap");
   1814             if (virtual_info->vlan_vfi_bitmap == NULL) {
   1815                 _bcm_virtual_free_resource(unit, virtual_info);
   1816                 return BCM_E_MEMORY;
   1817             }
   1818         }
   1819     }
   1820 
   1821     if (soc_feature(unit, soc_feature_flex_flow)) {
   1822         if (NULL == virtual_info->flow_vfi_bitmap) {
   1823             virtual_info->flow_vfi_bitmap =
   1824                    sal_alloc(SHR_BITALLOCSIZE(num_vfi), "flow_vfi_bitmap");
   1825             if (virtual_info->flow_vfi_bitmap == NULL) {
   1826                 _bcm_virtual_free_resource(unit, virtual_info);
   1827                 return BCM_E_MEMORY;
   1828             }
   1829         }
   1830 
   1831         if (NULL == virtual_info->flow_vp_bitmap) {
   1832             virtual_info->flow_vp_bitmap =
   1833                 sal_alloc(SHR_BITALLOCSIZE(num_vp), "flow_vp_bitmap");
   1834             if (virtual_info->flow_vp_bitmap == NULL) {
   1835                 _bcm_virtual_free_resource(unit, virtual_info);
   1836                 return BCM_E_MEMORY;
   1837             }
   1838         }
   1839     }
   1840 
   1841     if (NULL == virtual_info->vp_to_vpn) {
   1842         virtual_info->vp_to_vpn =
   1843             sal_alloc(num_vp * sizeof(uint16), "vp_to_vpn_map");
   1844         if (virtual_info->vp_to_vpn == NULL) {
   1845             _bcm_virtual_free_resource(unit, virtual_info);
   1846             return BCM_E_MEMORY;
   1847         }
   1848     }
   1849 
   1850     /*
   1851      * Initialize 
   1852      */ 
   1853     sal_memset(virtual_info->vfi_bitmap, 0, SHR_BITALLOCSIZE(num_vfi));
   1854     sal_memset(virtual_info->vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp));
   1855     sal_memset(virtual_info->mpls_vfi_bitmap, 0, SHR_BITALLOCSIZE(num_vfi));
   1856     sal_memset(virtual_info->mpls_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp));
   1857     sal_memset(virtual_info->mim_vfi_bitmap, 0, SHR_BITALLOCSIZE(num_vfi));
   1858     sal_memset(virtual_info->mim_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp));
   1859     sal_memset(virtual_info->subport_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp));
   1860     if (soc_feature(unit, soc_feature_wlan)) {
   1861         sal_memset(virtual_info->wlan_vp_bitmap, 0, SHR_BITALLOCSIZE(num_wlan_vp));
   1862     }	
   1863     if (soc_feature(unit, soc_feature_trill)) {
   1864         sal_memset(virtual_info->trill_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp));
   1865     }
   1866     if (soc_feature(unit, soc_feature_vlan_vp)) {
   1867         sal_memset(virtual_info->vlan_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp));
   1868     }
   1869     if (soc_feature(unit, soc_feature_niv)) {
   1870         sal_memset(virtual_info->niv_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp));
   1871     }
   1872     if (soc_feature(unit, soc_feature_l2gre)) {
   1873         sal_memset(virtual_info->l2gre_vfi_bitmap, 0, SHR_BITALLOCSIZE(num_vfi));
   1874         sal_memset(virtual_info->l2gre_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp));
   1875     }
   1876     if (soc_feature(unit, soc_feature_vxlan)) {
   1877         sal_memset(virtual_info->vxlan_vfi_bitmap, 0, SHR_BITALLOCSIZE(num_vfi));
   1878         sal_memset(virtual_info->vxlan_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp));
   1879     }
   1880     if (soc_feature(unit, soc_feature_flex_flow)) {
   1881         sal_memset(virtual_info->flow_vfi_bitmap, 0, SHR_BITALLOCSIZE(num_vfi));
   1882         sal_memset(virtual_info->flow_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp));
   1883     }
   1884     if (soc_feature(unit, soc_feature_port_extension)) {
   1885         sal_memset(virtual_info->extender_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp));
   1886     }
   1887     if (soc_feature(unit, soc_feature_vp_lag)) {
   1888         sal_memset(virtual_info->vp_lag_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp));
   1889     }
   1890     if (soc_feature(unit, soc_feature_vp_sharing) || 
   1891         soc_feature(unit, soc_feature_nexthop_share_dvp)) {
   1892         sal_memset(virtual_info->vp_shared_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp));
   1893     }
   1894 
   1895     sal_memset(virtual_info->vp_network_vp_bitmap, 0, SHR_BITALLOCSIZE(num_vp));
   1896 
   1897     if (soc_feature(unit, soc_feature_vlan_vfi)) {
   1898         sal_memset(virtual_info->vlan_vfi_bitmap, 0, SHR_BITALLOCSIZE(num_vfi));
   1899     }
   1900 
   1901     sal_memset(virtual_info->vp_to_vpn, 0, num_vp * sizeof(uint16));
   1902 
   1903     /*enable pruning on split horizon group 1 by default*/
   1904     if (soc_feature(unit, soc_feature_reserve_shg_network_port) &&
   1905         !(soc_property_get(unit, spn_USE_ALL_SPLITHORIZON_GROUPS, 0))) {
   1906         bcm_switch_network_group_config_t network_shg_config;
   1907         sal_memset(&network_shg_config, 0,
   1908                 sizeof(bcm_switch_network_group_config_t));
   1909         network_shg_config.dest_network_group_id = 1;
   1910         network_shg_config.config_flags =
   1911             (BCM_SWITCH_NETWORK_GROUP_INGRESS_PRUNE_ENABLE |
   1912              BCM_SWITCH_NETWORK_GROUP_EGRESS_PRUNE_ENABLE);
   1913         _bcm_switch_network_group_pruning(unit, 1, &network_shg_config);
   1914     }
   1915 
   1916     /* HW retriction - mark VP index zero as used */
   1917     _bcm_vp_info_init(&vp_info);
   1918     vp_info.vp_type = _bcmVpTypeAny;
   1919     rv = _bcm_vp_alloc(unit, 0, (num_vp - 1), 1, SOURCE_VPm, vp_info, &vp);
   1920     if (vp != 0) {
   1921         rv = BCM_E_INTERNAL;
   1922     }
   1923     if (BCM_FAILURE(rv)) {
   1924         _bcm_virtual_free_resource(unit, virtual_info);
   1925         return rv;
   1926     }
   1927     /* HW restriction - mark wlan VP index zero as used */
   1928     /* wlan uses different table for vp management */
   1929     if (soc_feature(unit, soc_feature_wlan)) {
   1930         vp_info.vp_type = _bcmVpTypeWlan;
   1931         rv = _bcm_vp_alloc(unit, 0, (num_vp - 1), 1, SOURCE_VPm, vp_info, &vp);
   1932         if (vp != 0) {
   1933             rv = BCM_E_INTERNAL;
   1934         }
   1935         if (BCM_FAILURE(rv)) {
   1936             _bcm_virtual_free_resource(unit, virtual_info);
   1937             return rv;
   1938         }
   1939     }
   1940 
   1941     /* Hw restriction - mark SVP 1 used for unknown SVP support on TR2 B0 */
   1942     if (soc_feature(unit, soc_feature_mim_reserve_default_port) &&
   1943         soc_property_get(unit, spn_RESERVE_MIM_DEFAULT_SVP, 0)) {
   1944         /* reserve svp 1 for mim */
   1945         vp_info.vp_type = _bcmVpTypeMim;
   1946         rv = _bcm_vp_alloc(unit, 1, (num_vp - 1), 1, SOURCE_VPm,
   1947                             vp_info, &vp);
   1948         if (vp != _BCM_MIM_DEFAULT_PORT) {
   1949             rv = BCM_E_INTERNAL;
   1950         }
   1951         if(BCM_FAILURE(rv)) {
   1952             _bcm_virtual_free_resource(unit, virtual_info);
   1953             return rv;
   1954         }
   1955     }
   1956 
   1957 #ifdef BCM_TRIDENT2_SUPPORT
   1958     /* mark SVP 2 used as dummy VP for VLAN_XLATE*/
   1959     if (soc_feature(unit, soc_feature_vlan_xlate_iif_with_dummy_vp) &&
   1960         soc_property_get(unit, spn_VLAN_ACTION_DUMMY_VP_RESERVED, 0)) {
   1961         /* reserve svp 2 */
   1962         vp_info.vp_type = _bcmVpTypeAny;
   1963         rv = _bcm_vp_alloc(unit, _BCM_VLAN_XLATE_DUMMY_PORT, (num_vp - 1), 1, SOURCE_VPm,
   1964                            vp_info, &vp);
   1965         if (vp != _BCM_VLAN_XLATE_DUMMY_PORT) {
   1966             rv = BCM_E_INTERNAL;
   1967         }
   1968         if(BCM_FAILURE(rv)) {
   1969             _bcm_virtual_free_resource(unit, virtual_info);
   1970             return rv;
   1971         }
   1972 
   1973         if (!SOC_WARM_BOOT(unit)) {
   1974             rv = _bcm_vlan_xlate_dummy_vp_init(unit, _BCM_VLAN_XLATE_DUMMY_PORT);
   1975             if(BCM_FAILURE(rv)) {
   1976                 _bcm_virtual_free_resource(unit, virtual_info);
   1977                 return rv;
   1978             }
   1979         }
   1980     }
   1981 #endif /* BCM_TRIDENT2_SUPPORT */
   1982 
   1983     /* Now that the VP bitmap is initialized, register it with the
   1984      * SOC layer L2X thread to use during freeze/thaw. */
   1985     soc_l2x_cml_vp_bitmap_set(unit, virtual_info->vp_bitmap);
   1986 
   1987     /* Update reference count for protocol pkt control profile */
   1988     if (soc_mem_field_valid(unit, vfi_mem, PROTOCOL_PKT_INDEXf)) {
   1989         num_bytes_vfi_table = SOC_MEM_TABLE_BYTES(unit, vfi_mem);
   1990         vfi_mem_buffer = (uint8 *) soc_cm_salloc(unit, num_bytes_vfi_table,
   1991                                                  "VFI table buffer");
   1992         if (NULL == vfi_mem_buffer) {
   1993             _bcm_virtual_free_resource(unit, virtual_info);
   1994             return BCM_E_MEMORY;
   1995         }
   1996         sal_memset(vfi_mem_buffer, 0, num_bytes_vfi_table);
   1997         rv = soc_mem_read_range(unit, vfi_mem, MEM_BLOCK_ANY,
   1998                                 soc_mem_index_min(unit, vfi_mem),
   1999                                 soc_mem_index_max(unit, vfi_mem),
   2000                                 vfi_mem_buffer);
   2001         if (SOC_E_NONE != rv) {
   2002             soc_cm_sfree(unit, vfi_mem_buffer);
   2003             _bcm_virtual_free_resource(unit, virtual_info);
   2004             return rv;
   2005         }
   2006         for (idx = 0; idx < num_vfi; idx++) {
   2007             vfi_entry = soc_mem_table_idx_to_pointer(unit, vfi_mem,
   2008                                                      vfi_entry_t *,
   2009                                                      vfi_mem_buffer, idx);
   2010             profile_idx = soc_mem_field32_get(unit, vfi_mem, vfi_entry,
   2011                                               PROTOCOL_PKT_INDEXf);
   2012             rv = _bcm_prot_pkt_ctrl_reference(unit, profile_idx);
   2013             if (BCM_E_NONE != rv) {
   2014                 soc_cm_sfree(unit, vfi_mem_buffer);
   2015                 _bcm_virtual_free_resource(unit, virtual_info);
   2016                 return rv;
   2017             }
   2018         }
   2019         soc_cm_sfree(unit, vfi_mem_buffer);
   2020         vfi_mem_buffer = NULL;
   2021     }
   2022 #ifdef BCM_WARM_BOOT_SUPPORT
   2023     rv = _bcm_virtual_reinit(unit);
   2024     if (rv != BCM_E_NONE) {
   2025         _bcm_virtual_free_resource(unit, virtual_info);
   2026         return rv;
   2027     }
   2028 
   2029     if (SOC_WARM_BOOT(unit)) {
   2030 #ifdef BCM_TRIUMPH2_SUPPORT
   2031         if (soc_feature(unit, soc_feature_vlan_vp)) {
   2032             /* Warm boot recovery of VLAN module's VLAN_VP_INFO is postponed to
   2033              * here since it depends on the warm boot recovery of this module's
   2034              * virtual_info.
   2035              */
   2036 #ifdef BCM_ENDURO_SUPPORT
   2037             if (SOC_IS_ENDURO(unit)) {
   2038                 rv = bcm_enduro_vlan_virtual_reinit(unit);
   2039             } else
   2040 #endif /* BCM_ENDURO_SUPPORT */
   2041             {
   2042                 rv = bcm_tr2_vlan_virtual_reinit(unit);
   2043             } 
   2044             if (BCM_FAILURE(rv)) {
   2045                 _bcm_virtual_free_resource(unit, virtual_info);
   2046                 return rv;
   2047             }
   2048         }
   2049 #endif /* BCM_TRIUMPH2_SUPPORT */
   2050 
   2051 #ifdef BCM_TRIDENT2_SUPPORT
   2052         if (soc_feature(unit, soc_feature_vp_lag)) {
   2053             /* Warm boot recovery of trunk module's VP LAG info is postponed to
   2054              * here since it depends on the warm boot recovery of this module's
   2055              * VP LAG VP bitmap.
   2056              */
   2057             rv = bcm_td2_vp_lag_reinit(unit);
   2058             if (BCM_FAILURE(rv)) {
   2059                 _bcm_virtual_free_resource(unit, virtual_info);
   2060                 return rv;
   2061             }
   2062         }
   2063 #endif /* BCM_TRIDENT2_SUPPORT */
   2064 
   2065     }
   2066 
   2067 #endif /* BCM_WARM_BOOT_SUPPORT */
   2068 
   2069     return rv;
   2070 }
   2071 
   2072 /*
   2073  * Function:
   2074  *      _bcm_virtual_deinit
   2075  * Purpose:
   2076  *      Necessary deinit process such as resource release.
   2077  * Parameters:
   2078  *      unit    -  (IN) Device number.
   2079  * Returns:
   2080  *      BCM_X_XXX
   2081  */
   2082 int 
   2083 _bcm_virtual_deinit(int unit)
   2084 {
   2085     _bcm_virtual_free_resource(unit, VIRTUAL_INFO(unit));
   2086     return BCM_E_NONE;
   2087 }
   2088 
   2089 /*
   2090  * Function:
   2091  *      _bcm_vp_alloc
   2092  * Purpose:
   2093  *      Internal function for allocating a group of VPs
   2094  * Parameters:
   2095  *      unit    -  (IN) Device number.
   2096  *      start   -  (IN) First VP index to allocate from 
   2097  *      end     -  (IN) Last VP index to allocate from 
   2098  *      count   -  (IN) How many consecutive VPs to allocate
   2099  *      vp_mem  -  (IN) HW specific VP memory
   2100  *      info    -  (IN) VP type information
   2101  *      base_vp -  (OUT) Base VP index
   2102  * Returns:
   2103  *      BCM_X_XXX
   2104  */
   2105 int
   2106 _bcm_vp_alloc(int unit, int start, int end, int count, soc_mem_t vp_mem, 
   2107               _bcm_vp_info_t vp_info, int *base_vp)
   2108 {
   2109     _bcm_vp_type_e type = vp_info.vp_type;
   2110     int num_vp = soc_mem_index_count(unit, vp_mem);
   2111     int i, j, vp;
   2112     int found = 0;
   2113     int reverse = 0;
   2114 
   2115     VIRTUAL_INIT_CHECK(unit);
   2116 
   2117     if ((end >= num_vp) || (start >= num_vp)) {
   2118         return BCM_E_PARAM;
   2119     }
   2120     if (start > end) {
   2121         reverse = 1;
   2122     }
   2123 
   2124     /* vp_bitmap referenced by _BCM_VIRTUAL_VP_XXX macros, tracks
   2125      * the usage of SOURCE_VP table because all vp types except wlan use the
   2126      * same hardware table SOURCE_VP for vp assignment.  
   2127      * Since Wlan vp uses a different table exclusively for vp assignment, 
   2128      * the wlan_vp_bitmap alone should be sufficient to track wlan vp usage. 
   2129      */
   2130     VIRTUAL_LOCK(unit);
   2131     if (type == _bcmVpTypeWlan) {
   2132         if (!soc_feature(unit, soc_feature_wlan)) {
   2133             VIRTUAL_UNLOCK(unit);
   2134             return BCM_E_PORT;
   2135         }
   2136 
   2137         if (reverse) {
   2138             for (i = start; i >= end; i -= count) {
   2139                 for (j = 0; j < count; j++) {
   2140                     if (_BCM_WLAN_VP_USED_GET(unit, i - j)) {
   2141                         break;
   2142                     }
   2143                 }
   2144                 if (j == count) {
   2145                     break;
   2146                 }
   2147             }
   2148             if (i >= end) {
   2149                 *base_vp = i;
   2150                 for (j = 0; j < count; j++) {
   2151                     _BCM_WLAN_VP_USED_SET(unit, i - j);
   2152                 }
   2153                 VIRTUAL_UNLOCK(unit);
   2154                 return BCM_E_NONE;
   2155             }
   2156         } else {
   2157             for (i = start; i <= end; i += count) {
   2158                 for (j = 0; j < count; j++) {
   2159                     if (_BCM_WLAN_VP_USED_GET(unit, i + j)) {
   2160                         break;
   2161                     }
   2162                 }
   2163                 if (j == count) {
   2164                     break;
   2165                 }
   2166             }
   2167             if (i <= end) {
   2168                 *base_vp = i;
   2169                 for (j = 0; j < count; j++) {
   2170                     _BCM_WLAN_VP_USED_SET(unit, i + j);
   2171                 }
   2172                 VIRTUAL_UNLOCK(unit);
   2173                 return BCM_E_NONE;
   2174             }
   2175         }
   2176         VIRTUAL_UNLOCK(unit);
   2177         return BCM_E_RESOURCE;
   2178     }
   2179 
   2180     /* handle all other vp types except wlan */
   2181     if (reverse) {
   2182         for (i = start; i >= end; i -= count) {
   2183             for (j = 0; j < count; j++) {
   2184                 if (_BCM_VIRTUAL_VP_USED_GET(unit, i - j)) {
   2185                     break;
   2186                 }
   2187             }
   2188             if (j == count) {
   2189                 break;
   2190             }
   2191         }
   2192         if (i >= end) {
   2193             found = 1;
   2194         }
   2195     } else {
   2196         for (i = start; i <= end; i += count) {
   2197             for (j = 0; j < count; j++) {
   2198                 if (_BCM_VIRTUAL_VP_USED_GET(unit, i + j)) {
   2199                     break;
   2200                 }
   2201             }
   2202             if (j == count) {
   2203                 break;
   2204             }
   2205         }
   2206         if (i <= end) {
   2207             found = 1;
   2208         }
   2209     }
   2210     if (found) {
   2211         *base_vp = i;
   2212         for (j = 0; j < count; j++) {
   2213             if (reverse) {
   2214                 vp = i - j;
   2215             } else {
   2216                 vp = i + j;
   2217             }
   2218             _BCM_VIRTUAL_VP_USED_SET(unit, vp);
   2219             switch (type) {
   2220             case _bcmVpTypeMpls:
   2221                 _BCM_MPLS_VP_USED_SET(unit, vp);
   2222                 break;
   2223             case _bcmVpTypeMim:
   2224                 _BCM_MIM_VP_USED_SET(unit, vp);
   2225                 break;
   2226             case _bcmVpTypeSubport:
   2227                 _BCM_SUBPORT_VP_USED_SET(unit, vp);
   2228                 break;
   2229             case _bcmVpTypeTrill:
   2230                 if (!soc_feature(unit, soc_feature_trill)) {
   2231                     VIRTUAL_UNLOCK(unit);
   2232                     return BCM_E_PORT;
   2233                 }
   2234                 _BCM_TRILL_VP_USED_SET(unit, vp);
   2235                 break;
   2236             case _bcmVpTypeVlan:
   2237                 if (!soc_feature(unit, soc_feature_vlan_vp)) {
   2238                     VIRTUAL_UNLOCK(unit);
   2239                     return BCM_E_PORT;
   2240                 }
   2241                 _BCM_VLAN_VP_USED_SET(unit, vp);
   2242                 break;
   2243             case _bcmVpTypeNiv:
   2244                 if (!soc_feature(unit, soc_feature_niv)) {
   2245                     VIRTUAL_UNLOCK(unit);
   2246                     return BCM_E_PORT;
   2247                 }
   2248                 _BCM_NIV_VP_USED_SET(unit, vp);
   2249                 break;
   2250             case _bcmVpTypeL2Gre:
   2251                 if (!soc_feature(unit, soc_feature_l2gre)) {
   2252                     VIRTUAL_UNLOCK(unit);
   2253                     return BCM_E_PORT;
   2254                 }
   2255                 _BCM_L2GRE_VP_USED_SET(unit, vp);
   2256                 break;
   2257             case _bcmVpTypeVxlan:
   2258                 if (!soc_feature(unit, soc_feature_vxlan)) {
   2259                     VIRTUAL_UNLOCK(unit);
   2260                     return BCM_E_PORT;
   2261                 }
   2262                 _BCM_VXLAN_VP_USED_SET(unit, vp);
   2263                 break;
   2264             case _bcmVpTypeFlow:
   2265                 if (!soc_feature(unit, soc_feature_flex_flow)) {
   2266                     VIRTUAL_UNLOCK(unit);
   2267                     return BCM_E_PORT;
   2268                 }
   2269                 _BCM_FLOW_VP_USED_SET(unit, vp);
   2270                 break;
   2271             case _bcmVpTypeExtender:
   2272                 if (!soc_feature(unit, soc_feature_port_extension)) {
   2273                     VIRTUAL_UNLOCK(unit);
   2274                     return BCM_E_PORT;
   2275                 }
   2276                 _BCM_EXTENDER_VP_USED_SET(unit, vp);
   2277                 break;
   2278             case _bcmVpTypeVpLag:
   2279                 if (!soc_feature(unit, soc_feature_vp_lag)) {
   2280                     VIRTUAL_UNLOCK(unit);
   2281                     return BCM_E_PORT;
   2282                 }
   2283                 _BCM_VP_LAG_VP_USED_SET(unit, vp);
   2284                 break;
   2285             default:
   2286                 break;
   2287             }
   2288             if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) {
   2289                 _BCM_NETWORK_VP_USED_SET(unit, vp);
   2290             }
   2291             if (vp_info.flags & _BCM_VP_INFO_SHARED_PORT) {
   2292                 if (!(soc_feature(unit, soc_feature_vp_sharing) ||
   2293                           soc_feature(unit, soc_feature_nexthop_share_dvp))) {
   2294                     VIRTUAL_UNLOCK(unit);
   2295                     return BCM_E_UNAVAIL;
   2296                 }
   2297                 _BCM_SHARED_VP_USED_SET(unit, vp);
   2298             }
   2299         }
   2300         VIRTUAL_UNLOCK(unit);
   2301         return BCM_E_NONE;
   2302     }
   2303     VIRTUAL_UNLOCK(unit);
   2304     return BCM_E_RESOURCE;
   2305 }
   2306 
   2307 /*
   2308  * Function:
   2309  *      _bcm_vp_free
   2310  * Purpose:
   2311  *      Internal function for freeing a group of VPs
   2312  * Parameters:
   2313  *      unit    -  (IN) Device number
   2314  *      type    -  (IN) VP type
   2315  *      count   -  (IN) How many consecutive VPs to free
   2316  *      base_vp -  (IN) Base VP index
   2317  * Returns:
   2318  *      BCM_X_XXX
   2319  */
   2320 int
   2321 _bcm_vp_free(int unit, _bcm_vp_type_e type, int count, int base_vp)
   2322 {
   2323     int i;
   2324     VIRTUAL_INIT_CHECK(unit);
   2325     VIRTUAL_LOCK(unit);
   2326     for (i = 0; i < count; i++) {
   2327         if (type != _bcmVpTypeWlan) {
   2328             _BCM_VIRTUAL_VP_USED_CLR(unit, base_vp + i);
   2329         }
   2330         switch (type) {
   2331         case _bcmVpTypeMpls:
   2332             _BCM_MPLS_VP_USED_CLR(unit, base_vp + i);
   2333             break;
   2334         case _bcmVpTypeMim:
   2335             _BCM_MIM_VP_USED_CLR(unit, base_vp + i);
   2336             break;
   2337         case _bcmVpTypeSubport:
   2338             _BCM_SUBPORT_VP_USED_CLR(unit, base_vp + i);
   2339             break;
   2340         case _bcmVpTypeWlan:
   2341             if (!soc_feature(unit, soc_feature_wlan)) {
   2342                 VIRTUAL_UNLOCK(unit);
   2343                 return BCM_E_PORT;
   2344             }
   2345             _BCM_WLAN_VP_USED_CLR(unit, base_vp + i);
   2346             break;
   2347         case _bcmVpTypeTrill:
   2348             if (!soc_feature(unit, soc_feature_trill)) {
   2349                 VIRTUAL_UNLOCK(unit);
   2350                 return BCM_E_PORT;
   2351             }
   2352             _BCM_TRILL_VP_USED_CLR(unit, base_vp + i);
   2353             break;
   2354         case _bcmVpTypeVlan:
   2355             if (!soc_feature(unit, soc_feature_vlan_vp)) {
   2356                 VIRTUAL_UNLOCK(unit);
   2357                 return BCM_E_PORT;
   2358             }
   2359             _BCM_VLAN_VP_USED_CLR(unit, base_vp + i);
   2360             break;
   2361         case _bcmVpTypeNiv:
   2362             if (!soc_feature(unit, soc_feature_niv)) {
   2363                 VIRTUAL_UNLOCK(unit);
   2364                 return BCM_E_PORT;
   2365             }
   2366             _BCM_NIV_VP_USED_CLR(unit, base_vp + i);
   2367             break;
   2368         case _bcmVpTypeL2Gre:
   2369             if (!soc_feature(unit, soc_feature_l2gre)) {
   2370                 VIRTUAL_UNLOCK(unit);
   2371                 return BCM_E_PORT;
   2372             }
   2373             _BCM_L2GRE_VP_USED_CLR(unit, base_vp + i);
   2374             break;
   2375         case _bcmVpTypeVxlan:
   2376             if (!soc_feature(unit, soc_feature_vxlan)) {
   2377                 VIRTUAL_UNLOCK(unit);
   2378                 return BCM_E_PORT;
   2379             }
   2380             _BCM_VXLAN_VP_USED_CLR(unit, base_vp + i);
   2381             break;
   2382         case _bcmVpTypeFlow:
   2383             if (!soc_feature(unit, soc_feature_flex_flow)) {
   2384                 VIRTUAL_UNLOCK(unit);
   2385                 return BCM_E_PORT;
   2386             }
   2387             _BCM_FLOW_VP_USED_CLR(unit, base_vp + i);
   2388             break;
   2389         case _bcmVpTypeExtender:
   2390             if (!soc_feature(unit, soc_feature_port_extension)) {
   2391                 VIRTUAL_UNLOCK(unit);
   2392                 return BCM_E_PORT;
   2393             }
   2394             _BCM_EXTENDER_VP_USED_CLR(unit, base_vp + i);
   2395             break;
   2396         case _bcmVpTypeVpLag:
   2397             if (!soc_feature(unit, soc_feature_vp_lag)) {
   2398                 VIRTUAL_UNLOCK(unit);
   2399                 return BCM_E_PORT;
   2400             }
   2401             _BCM_VP_LAG_VP_USED_CLR(unit, base_vp + i);
   2402             break;
   2403         default:
   2404             break;
   2405         }
   2406         _BCM_NETWORK_VP_USED_CLR(unit, base_vp+i);
   2407 
   2408         if (soc_feature(unit, soc_feature_vp_sharing) ||
   2409                 soc_feature(unit, soc_feature_nexthop_share_dvp)) {
   2410             _BCM_SHARED_VP_USED_CLR(unit, base_vp+i);
   2411         }
   2412     }
   2413     VIRTUAL_UNLOCK(unit);
   2414     return BCM_E_NONE;
   2415 }
   2416 
   2417 /*
   2418  * Function:
   2419  *      _bcm_vp_used_set
   2420  * Purpose:
   2421  *      Mark the VP as used
   2422  * Parameters:
   2423  *      unit    -  (IN) Device number.
   2424  *      vp      -  (IN) VP
   2425  *      type   -  (IN) VP type
   2426  * Returns:
   2427  *      Boolean
   2428  */
   2429 int
   2430 _bcm_vp_used_set(int unit, int vp, _bcm_vp_info_t vp_info)
   2431 {
   2432     int rv=BCM_E_NONE;
   2433     _bcm_vp_type_e type = vp_info.vp_type;
   2434 
   2435     VIRTUAL_INIT_CHECK(unit);
   2436     VIRTUAL_LOCK(unit);
   2437 
   2438     if (type != _bcmVpTypeWlan) {
   2439         _BCM_VIRTUAL_VP_USED_SET(unit, vp);
   2440     }
   2441     switch (type) {
   2442          case _bcmVpTypeMpls:
   2443               _BCM_MPLS_VP_USED_SET(unit, vp);
   2444              break;
   2445          case _bcmVpTypeMim:
   2446               _BCM_MIM_VP_USED_SET(unit, vp);
   2447              break;
   2448          case _bcmVpTypeSubport:
   2449               _BCM_SUBPORT_VP_USED_SET(unit, vp);
   2450               break;
   2451          case _bcmVpTypeWlan:
   2452               if (!soc_feature(unit, soc_feature_wlan)) {
   2453                   VIRTUAL_UNLOCK(unit);
   2454                   return BCM_E_PORT;
   2455               }
   2456               _BCM_WLAN_VP_USED_SET(unit, vp);
   2457               break;
   2458          case _bcmVpTypeTrill:
   2459               if (!soc_feature(unit, soc_feature_trill)) {
   2460                   _BCM_VIRTUAL_VP_USED_CLR(unit, vp);
   2461                   VIRTUAL_UNLOCK(unit);
   2462                   return BCM_E_PORT;
   2463               }
   2464               _BCM_TRILL_VP_USED_SET(unit, vp);
   2465               break;
   2466          case _bcmVpTypeVlan:
   2467               if (!soc_feature(unit, soc_feature_vlan_vp)) {
   2468                   _BCM_VIRTUAL_VP_USED_CLR(unit, vp);
   2469                   VIRTUAL_UNLOCK(unit);
   2470                   return BCM_E_PORT;
   2471               }
   2472               _BCM_VLAN_VP_USED_SET(unit, vp);
   2473               break;
   2474          case _bcmVpTypeNiv:
   2475               if (!soc_feature(unit, soc_feature_niv)) {
   2476                   _BCM_VIRTUAL_VP_USED_CLR(unit, vp);
   2477                   VIRTUAL_UNLOCK(unit);
   2478                   return BCM_E_PORT;
   2479               }
   2480               _BCM_NIV_VP_USED_SET(unit, vp);
   2481               break;
   2482          case _bcmVpTypeL2Gre:
   2483               if (!soc_feature(unit, soc_feature_l2gre)) {
   2484                   _BCM_VIRTUAL_VP_USED_CLR(unit, vp);
   2485                   VIRTUAL_UNLOCK(unit);
   2486                   return BCM_E_PORT;
   2487               }
   2488               _BCM_L2GRE_VP_USED_SET(unit, vp);
   2489               break;
   2490          case _bcmVpTypeVxlan:
   2491               if (!soc_feature(unit, soc_feature_vxlan)) {
   2492                   _BCM_VIRTUAL_VP_USED_CLR(unit, vp);
   2493                   VIRTUAL_UNLOCK(unit);
   2494                   return BCM_E_PORT;
   2495               }
   2496               _BCM_VXLAN_VP_USED_SET(unit, vp);
   2497               break;
   2498          case _bcmVpTypeExtender:
   2499               if (!soc_feature(unit, soc_feature_port_extension)) {
   2500                   _BCM_VIRTUAL_VP_USED_CLR(unit, vp);
   2501                   VIRTUAL_UNLOCK(unit);
   2502                   return BCM_E_PORT;
   2503               }
   2504               _BCM_EXTENDER_VP_USED_SET(unit, vp);
   2505               break;
   2506          case _bcmVpTypeVpLag:
   2507               if (!soc_feature(unit, soc_feature_vp_lag)) {
   2508                   _BCM_VIRTUAL_VP_USED_CLR(unit, vp);
   2509                   VIRTUAL_UNLOCK(unit);
   2510                   return BCM_E_PORT;
   2511               }
   2512               _BCM_VP_LAG_VP_USED_SET(unit, vp);
   2513               break;
   2514          case _bcmVpTypeFlow:
   2515               if (!soc_feature(unit, soc_feature_flex_flow)) {
   2516                   _BCM_VIRTUAL_VP_USED_CLR(unit, vp);
   2517                   VIRTUAL_UNLOCK(unit);
   2518                   return BCM_E_PORT;
   2519               }
   2520               _BCM_FLOW_VP_USED_SET(unit, vp);
   2521               break;
   2522          default:
   2523               break;
   2524     }
   2525 
   2526     if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) {
   2527         _BCM_NETWORK_VP_USED_SET(unit, vp);
   2528     } else {
   2529         _BCM_NETWORK_VP_USED_CLR(unit, vp);
   2530     }
   2531 
   2532     if (vp_info.flags & _BCM_VP_INFO_SHARED_PORT) {
   2533         if (!(soc_feature(unit, soc_feature_vp_sharing) ||
   2534                   soc_feature(unit, soc_feature_nexthop_share_dvp))) {
   2535             VIRTUAL_UNLOCK(unit);
   2536             return BCM_E_UNAVAIL;
   2537         }
   2538         _BCM_SHARED_VP_USED_SET(unit, vp);
   2539     }
   2540 
   2541     VIRTUAL_UNLOCK(unit);
   2542     return rv;
   2543 }
   2544 
   2545 /*
   2546  * Function:
   2547  *      _bcm_vp_info_get
   2548  * Purpose:
   2549  *      Get the VP Type of a VP, given its Id
   2550  * Parameters:
   2551  *      unit     -  (IN) Device number.
   2552  *      vp       -  (IN) VP
   2553  *      vp_type  -  (OUT) VP type
   2554  * Returns:
   2555  *      BCM_E_XXX
   2556  */
   2557 int
   2558 _bcm_vp_info_get(int unit, int vp, _bcm_vp_info_t *vp_info)
   2559 {
   2560     _bcm_vp_type_e vpt;
   2561     _bcm_vp_info_init(vp_info);
   2562 
   2563     for (vpt = _bcmVpTypeMpls; vpt < _bcmVpTypeAny; vpt++) {
   2564         if (_bcm_vp_used_get(unit, vp, vpt)) {
   2565             vp_info->vp_type = vpt;
   2566             if (_BCM_NETWORK_VP_USED_GET(unit, vp)) {
   2567                 vp_info->flags |= _BCM_VP_INFO_NETWORK_PORT;
   2568             }
   2569             if (soc_feature(unit, soc_feature_vp_sharing) ||
   2570                     soc_feature(unit, soc_feature_nexthop_share_dvp)) {
   2571                 if (_BCM_SHARED_VP_USED_GET(unit, vp)) {
   2572                     vp_info->flags |= _BCM_VP_INFO_SHARED_PORT;
   2573                 }
   2574             }
   2575             return BCM_E_NONE;
   2576         }
   2577     }
   2578 
   2579     return BCM_E_NOT_FOUND;
   2580 }
   2581 
   2582 /*
   2583  * Function:
   2584  *      _bcm_vp_encode_gport
   2585  * Purpose:
   2586  *      Given a VP, encode its gport type
   2587  * Parameters:
   2588  *      unit    -  (IN) Device number.
   2589  *      vp      -  (IN) VP
   2590  *      type   -  (IN) VP type
   2591  * Returns:
   2592  *      Boolean
   2593  */
   2594 int 
   2595 _bcm_vp_encode_gport(int unit, int vp, int *gport)
   2596 {
   2597     _bcm_vp_info_t vp_info;
   2598 
   2599     if(_bcm_vp_info_get(unit, vp, &vp_info) == BCM_E_NONE) {
   2600         if(vp_info.vp_type == _bcmVpTypeMpls)
   2601             BCM_GPORT_MPLS_PORT_ID_SET(*gport, vp);
   2602         else if(vp_info.vp_type == _bcmVpTypeMim)
   2603             BCM_GPORT_MIM_PORT_ID_SET(*gport, vp);
   2604         else if(vp_info.vp_type == _bcmVpTypeSubport)
   2605             BCM_GPORT_SUBPORT_GROUP_SET(*gport, vp);  
   2606         else if(vp_info.vp_type == _bcmVpTypeWlan)
   2607             BCM_GPORT_WLAN_PORT_ID_SET(*gport, vp);
   2608         else if(vp_info.vp_type == _bcmVpTypeTrill)
   2609             BCM_GPORT_TRILL_PORT_ID_SET(*gport, vp);
   2610         else if(vp_info.vp_type == _bcmVpTypeVlan)
   2611             BCM_GPORT_VLAN_PORT_ID_SET(*gport, vp);
   2612         else if(vp_info.vp_type == _bcmVpTypeNiv)
   2613             BCM_GPORT_NIV_PORT_ID_SET(*gport, vp);
   2614         else if(vp_info.vp_type == _bcmVpTypeL2Gre)
   2615             BCM_GPORT_L2GRE_PORT_ID_SET(*gport, vp);
   2616         else if(vp_info.vp_type == _bcmVpTypeVxlan)
   2617             BCM_GPORT_VXLAN_PORT_ID_SET(*gport, vp);
   2618         else if(vp_info.vp_type == _bcmVpTypeExtender)
   2619             BCM_GPORT_EXTENDER_PORT_ID_SET(*gport, vp);
   2620         else if(vp_info.vp_type == _bcmVpTypeFlow)
   2621             BCM_GPORT_FLOW_PORT_ID_SET(*gport, vp);
   2622         else
   2623             return BCM_E_PARAM;
   2624     }
   2625 
   2626     return BCM_E_NONE;
   2627 }
   2628 
   2629 /*
   2630  * Function:
   2631  *      _bcm_vp_used_get
   2632  * Purpose:
   2633  *      Check whether a VP is used or not
   2634  * Parameters:
   2635  *      unit    -  (IN) Device number.
   2636  *      vp      -  (IN) VP
   2637  * Returns:
   2638  *      Boolean
   2639  */
   2640 int
   2641 _bcm_vp_used_get(int unit, int vp, _bcm_vp_type_e type)
   2642 {
   2643     int rv = BCM_E_NONE;
   2644     int vp_chg = 0;
   2645 
   2646     
   2647     switch (type) {
   2648     case _bcmVpTypeMpls:
   2649         if (vp < 0) {
   2650             return rv;
   2651         }
   2652         if (SOC_MEM_IS_VALID(unit, SOURCE_VPm)) {
   2653             if (_BCM_MPLS_GPORT_FAILOVER_VPLESS_GET(vp)) {
   2654                 vp_chg = _BCM_MPLS_GPORT_FAILOVER_VPLESS_CLEAR(vp);
   2655             } else {
   2656                 vp_chg = vp;
   2657             }
   2658             if (vp_chg > soc_mem_index_count(unit, SOURCE_VPm)) {
   2659                 return rv;
   2660             }
   2661             rv = _BCM_MPLS_VP_USED_GET(unit, vp_chg);
   2662         }
   2663         break;
   2664     case _bcmVpTypeMim:
   2665         if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
   2666             return rv;
   2667         }
   2668         rv = _BCM_MIM_VP_USED_GET(unit, vp);
   2669         break;
   2670     case _bcmVpTypeSubport:
   2671         if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
   2672             return rv;
   2673         }
   2674         rv = _BCM_SUBPORT_VP_USED_GET(unit, vp);
   2675         break;
   2676     case _bcmVpTypeWlan:
   2677         if (soc_feature(unit, soc_feature_wlan)) {
   2678             if (SOC_MEM_IS_VALID(unit, WLAN_SVP_TABLEm)) {
   2679                 if (vp > soc_mem_index_count(unit, WLAN_SVP_TABLEm)) {
   2680                     return rv;
   2681                 }
   2682             } else if (SOC_MEM_IS_VALID(unit,SOURCE_VP_ATTRIBUTES_2m)) {
   2683                 if (vp > soc_mem_index_count(unit, SOURCE_VP_ATTRIBUTES_2m)) {
   2684                     return rv;
   2685                 }
   2686             } else {
   2687                 return rv;
   2688             }
   2689             rv = _BCM_WLAN_VP_USED_GET(unit, vp);
   2690         }
   2691         break;
   2692     case _bcmVpTypeTrill:
   2693         if (soc_feature(unit, soc_feature_trill)) {
   2694             if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
   2695                 return rv;
   2696             }
   2697             rv = _BCM_TRILL_VP_USED_GET(unit, vp);
   2698         }
   2699         break;
   2700     case _bcmVpTypeVlan:
   2701         if (soc_feature(unit, soc_feature_vlan_vp)) {
   2702             if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
   2703                 return rv;
   2704             }
   2705             rv = _BCM_VLAN_VP_USED_GET(unit, vp);
   2706         }
   2707         break;
   2708     case _bcmVpTypeNiv:
   2709         if (soc_feature(unit, soc_feature_niv)) {
   2710             if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
   2711                 return rv;
   2712             }
   2713             rv = _BCM_NIV_VP_USED_GET(unit, vp);
   2714         }
   2715         break;
   2716     case _bcmVpTypeL2Gre:
   2717         if (soc_feature(unit, soc_feature_l2gre)) {
   2718             if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
   2719                 return rv;
   2720             }
   2721             rv = _BCM_L2GRE_VP_USED_GET(unit, vp);
   2722         }
   2723         break;
   2724     case _bcmVpTypeVxlan:
   2725         if (soc_feature(unit, soc_feature_vxlan)) {
   2726             if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
   2727                 return rv;
   2728             }
   2729             rv = _BCM_VXLAN_VP_USED_GET(unit, vp);
   2730         }
   2731         break;
   2732     case _bcmVpTypeExtender:
   2733         if (soc_feature(unit, soc_feature_port_extension)) {
   2734             if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
   2735                 return rv;
   2736             }
   2737             rv = _BCM_EXTENDER_VP_USED_GET(unit, vp);
   2738         }
   2739         break;
   2740     case _bcmVpTypeVpLag:
   2741         if (soc_feature(unit, soc_feature_vp_lag)) {
   2742             if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
   2743                 return rv;
   2744             }
   2745             rv = _BCM_VP_LAG_VP_USED_GET(unit, vp);
   2746         }
   2747         break;
   2748     case _bcmVpTypeFlow:
   2749         if (soc_feature(unit, soc_feature_flex_flow)) {
   2750             if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
   2751                 return rv;
   2752             }
   2753             rv = _BCM_FLOW_VP_USED_GET(unit, vp);
   2754         }
   2755         break;
   2756     default:
   2757         rv = _BCM_VIRTUAL_VP_USED_GET(unit, vp);
   2758         break;
   2759     }
   2760     return rv;
   2761 }
   2762 
   2763 
   2764 int
   2765 _bcm_vp_gport_dest_fill(int unit, int vp, _bcm_gport_dest_t *gport_dest)
   2766 {
   2767     _bcm_vp_info_t vp_info;
   2768 
   2769     BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
   2770 
   2771     switch (vp_info.vp_type) {
   2772     case _bcmVpTypeMpls:
   2773         gport_dest->gport_type = _SHR_GPORT_TYPE_MPLS_PORT;
   2774         gport_dest->mpls_id = vp;
   2775         break;
   2776     case _bcmVpTypeMim:
   2777         gport_dest->gport_type = _SHR_GPORT_TYPE_MIM_PORT;
   2778         gport_dest->mim_id = vp;
   2779         break;
   2780     case _bcmVpTypeSubport:
   2781         gport_dest->gport_type = _SHR_GPORT_TYPE_SUBPORT_PORT;
   2782         gport_dest->subport_id = vp;
   2783         break;
   2784     case _bcmVpTypeWlan:
   2785         gport_dest->gport_type = _SHR_GPORT_TYPE_WLAN_PORT;
   2786         gport_dest->wlan_id = vp;
   2787         break;
   2788     case _bcmVpTypeTrill:
   2789         gport_dest->gport_type = _SHR_GPORT_TYPE_TRILL_PORT;
   2790         gport_dest->trill_id = vp;
   2791         break;
   2792     case _bcmVpTypeVlan:
   2793         gport_dest->gport_type = _SHR_GPORT_TYPE_VLAN_PORT;
   2794         gport_dest->vlan_vp_id = vp;
   2795         break;
   2796     case _bcmVpTypeNiv:
   2797         gport_dest->gport_type = _SHR_GPORT_TYPE_NIV_PORT;
   2798         gport_dest->niv_id = vp;
   2799         break;
   2800     case _bcmVpTypeL2Gre:
   2801         gport_dest->gport_type = _SHR_GPORT_TYPE_L2GRE_PORT;
   2802         gport_dest->l2gre_id = vp;
   2803         break;
   2804     case _bcmVpTypeVxlan:
   2805         gport_dest->gport_type = _SHR_GPORT_TYPE_VXLAN_PORT;
   2806         gport_dest->vxlan_id = vp;
   2807         break;
   2808     case _bcmVpTypeExtender:
   2809         gport_dest->gport_type = _SHR_GPORT_TYPE_EXTENDER_PORT;
   2810         gport_dest->extender_id = vp;
   2811         break;
   2812     case _bcmVpTypeVpLag:
   2813         gport_dest->gport_type = _SHR_GPORT_TYPE_VP_GROUP;
   2814         break;
   2815     default:
   2816         gport_dest->gport_type = _SHR_GPORT_INVALID;
   2817         break;
   2818     }
   2819 
   2820     return BCM_E_NONE;
   2821 }
   2822 
   2823 
   2824 /*
   2825  * Function:
   2826  *      _bcm_vp_default_cml_mode_get
   2827  * Purpose:
   2828  *      Get Gport default cml_enable
   2829  * Parameters:
   2830  *      unit    -  (IN) Device number.
   2831  *      cml_default_enable  -  (OUT) default_cml_mode_enable
   2832  *      cml_new  - (OUT) default cml_new
   2833  *      cml_move - (OUT) default cml_move
   2834  * Returns:
   2835  *      Boolean
   2836  */
   2837 int
   2838 _bcm_vp_default_cml_mode_get (int unit, int *cml_default_enable, int *cml_new, int *cml_move)
   2839 {
   2840    int vp = 0;
   2841    int rv = BCM_E_NONE;
   2842    source_vp_entry_t svp;
   2843 
   2844     /* HW retriction - VP index zero is reserved */
   2845     if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeAny)) {
   2846         return BCM_E_UNAVAIL;
   2847     }
   2848     BCM_IF_ERROR_RETURN
   2849           (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp));
   2850 
   2851     if (soc_SOURCE_VPm_field32_get(unit, &svp, CLASS_IDf)) {
   2852          *cml_new = soc_SOURCE_VPm_field32_get(unit, &svp, CML_FLAGS_NEWf);
   2853          *cml_default_enable = 0x1;
   2854     } else {
   2855          *cml_new = 0x8; /* Default Value of cml */
   2856     }
   2857 
   2858     if (soc_feature(unit, soc_feature_generic_dest)) {
   2859         uint32 dv, dest_type = SOC_MEM_FIF_DEST_INVALID;
   2860         dv = soc_mem_field32_dest_get(unit, SOURCE_VPm, &svp, DESTINATIONf, &dest_type);
   2861         if (dest_type != SOC_MEM_FIF_DEST_DVP) {
   2862             dv = 0;
   2863         }
   2864         if (dv) {
   2865             *cml_move = soc_SOURCE_VPm_field32_get(unit, &svp, CML_FLAGS_MOVEf);
   2866             *cml_default_enable = 0x1;
   2867         } else {
   2868             *cml_move = 0x8;
   2869         }
   2870     } else {
   2871         if (soc_SOURCE_VPm_field32_get(unit, &svp, DVPf)) {
   2872             *cml_move = soc_SOURCE_VPm_field32_get(unit, &svp, CML_FLAGS_MOVEf);
   2873             *cml_default_enable = 0x1;
   2874         } else {
   2875             *cml_move = 0x8; /* Default Value of cml */
   2876         }
   2877     }
   2878     return rv;
   2879 }
   2880 
   2881 /*
   2882  * Function:
   2883  *      _bcm_vfi_init
   2884  * Purpose:
   2885  *      initialize VFI hardware tables
   2886  * Parameters:
   2887  *      unit    -  (IN) Device number.
   2888  *      vfi     -  (IN) VFI HW table index
   2889  * Returns:
   2890  *      BCM_X_XXX
   2891  */
   2892 int
   2893 _bcm_vfi_init(int unit, int vfi)
   2894 {
   2895     vfi_entry_t vfi_entry;
   2896     egr_vfi_entry_t egr_vfi_entry;
   2897 
   2898     sal_memset(&vfi_entry, 0, sizeof(vfi_entry_t));
   2899     sal_memset(&egr_vfi_entry, 0, sizeof(egr_vfi_entry_t));
   2900 
   2901 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   2902     if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
   2903         /* Initialize VFI with default stg group and membership profile */
   2904         soc_EGR_VFIm_field32_set(unit, &egr_vfi_entry, MEMBERSHIP_PROFILE_PTRf, 1);
   2905         soc_EGR_VFIm_field32_set(unit, &egr_vfi_entry, EN_EFILTERf, 1);
   2906     }
   2907 #endif
   2908 
   2909     BCM_IF_ERROR_RETURN(WRITE_VFIm(unit, MEM_BLOCK_ALL, vfi, &vfi_entry));
   2910     if (soc_mem_is_valid(unit, EGR_VFIm)) {
   2911         BCM_IF_ERROR_RETURN(WRITE_EGR_VFIm(unit, MEM_BLOCK_ALL, vfi, &egr_vfi_entry));
   2912     }
   2913 
   2914 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   2915     if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
   2916         bcm_vpn_t vpn;
   2917         bcm_stg_t stg;
   2918 
   2919         _BCM_VPN_SET(vpn, _BCM_VPN_TYPE_VFI, vfi);
   2920         BCM_IF_ERROR_RETURN(bcm_esw_stg_default_get(unit, &stg));
   2921         BCM_IF_ERROR_RETURN(bcm_esw_stg_vlan_add(unit, stg, vpn));
   2922     }
   2923 #endif
   2924 
   2925     return BCM_E_NONE;
   2926 }
   2927 
   2928 
   2929 /*
   2930  * Function:
   2931  *      _bcm_vfi_alloc
   2932  * Purpose:
   2933  *      Internal function for allocating a VFI
   2934  * Parameters:
   2935  *      unit    -  (IN) Device number.
   2936  *      vfi_mem -  (IN) HW specific VFI memory
   2937  *      type    -  (IN) VFI type
   2938  *      vfi     -  (OUT) Base VP index
   2939  * Returns:
   2940  *      BCM_X_XXX
   2941  */
   2942 int
   2943 _bcm_vfi_alloc(int unit, soc_mem_t vfi_mem, _bcm_vfi_type_e type, int *vfi)
   2944 {
   2945     int rv, i, num_vfi;
   2946     num_vfi = soc_mem_index_count(unit, vfi_mem);
   2947     VIRTUAL_LOCK(unit);
   2948     if (soc_feature(unit, soc_feature_vfi_zero_invalid)) {
   2949         i = 1;  /* entry 0 is not usable */
   2950     } else {
   2951         i = 0;
   2952     }
   2953     for (; i < num_vfi; i++) {
   2954         if (!_BCM_VIRTUAL_VFI_USED_GET(unit, i)) {
   2955             break;
   2956         }
   2957     }
   2958     if (i == num_vfi) {
   2959         VIRTUAL_UNLOCK(unit);
   2960         return BCM_E_RESOURCE;
   2961     }
   2962     *vfi = i;
   2963     _BCM_VIRTUAL_VFI_USED_SET(unit, i);
   2964     switch (type) {
   2965     case _bcmVfiTypeMpls:
   2966         _BCM_MPLS_VFI_USED_SET(unit, i);
   2967         break;
   2968     case _bcmVfiTypeMim:
   2969         _BCM_MIM_VFI_USED_SET(unit, i);
   2970         break;
   2971     case _bcmVfiTypeL2Gre:
   2972 #if defined(BCM_TRIUMPH3_SUPPORT)
   2973         if (soc_feature(unit, soc_feature_l2gre)) {
   2974             _BCM_L2GRE_VFI_USED_SET(unit, i);
   2975         }
   2976 #endif
   2977         break;
   2978     case _bcmVfiTypeVxlan:
   2979 #if defined(BCM_TRIDENT2_SUPPORT)
   2980         if (soc_feature(unit, soc_feature_vxlan)) {
   2981            _BCM_VXLAN_VFI_USED_SET(unit, i);
   2982         }
   2983 #endif
   2984         break;
   2985     case _bcmVfiTypeVlan:
   2986 #if defined(BCM_TRIUMPH3_SUPPORT)
   2987         if (soc_feature(unit, soc_feature_vlan_vfi)) {
   2988             _BCM_VLAN_VFI_USED_SET(unit, i);
   2989         }
   2990 #endif
   2991         break;
   2992     case _bcmVfiTypeFlow:
   2993 #if defined(BCM_TRIDENT3_SUPPORT)
   2994         if (soc_feature(unit, soc_feature_flex_flow)) {
   2995            _BCM_FLOW_VFI_USED_SET(unit, i);
   2996         }
   2997 #endif
   2998         break;
   2999     default:
   3000         break;
   3001     }
   3002 
   3003     rv = _bcm_vfi_init(unit, i);
   3004     VIRTUAL_UNLOCK(unit);
   3005 
   3006     return rv;
   3007 }
   3008 
   3009 /*
   3010  * Function:
   3011  *      _bcm_vfi_alloc_with_id
   3012  * Purpose:
   3013  *      Internal function for allocating a VFI with a given ID
   3014  * Parameters:
   3015  *      unit    -  (IN) Device number.
   3016  *      vfi_mem -  (IN) HW specific VFI memory
   3017  *      type    -  (IN) VFI type
   3018  *      vfi     -  (IN) VFI index
   3019  * Returns:
   3020  *      BCM_X_XXX
   3021  */
   3022  
   3023 int
   3024 _bcm_vfi_alloc_with_id(int unit, soc_mem_t vfi_mem, _bcm_vfi_type_e type, int vfi)
   3025 {
   3026     int rv, num_vfi;
   3027     num_vfi = soc_mem_index_count(unit, vfi_mem);
   3028 
   3029     /* Check Valid range of VFI */
   3030     if ( vfi < 0 || vfi >= num_vfi ) {
   3031          return BCM_E_RESOURCE;
   3032     }
   3033     if (soc_feature(unit, soc_feature_vfi_zero_invalid)) {
   3034         if (vfi == 0) { /* entry 0 is not usable */
   3035             return BCM_E_PARAM;
   3036         }
   3037     }
   3038    
   3039     VIRTUAL_LOCK(unit);
   3040     if (_BCM_VIRTUAL_VFI_USED_GET(unit, vfi)) {
   3041         VIRTUAL_UNLOCK(unit);
   3042         return BCM_E_EXISTS;
   3043     }
   3044 
   3045     _BCM_VIRTUAL_VFI_USED_SET(unit, vfi);
   3046 
   3047     switch (type) {
   3048     case _bcmVfiTypeMpls:
   3049         _BCM_MPLS_VFI_USED_SET(unit, vfi);
   3050         break;
   3051     case _bcmVfiTypeMim:
   3052         _BCM_MIM_VFI_USED_SET(unit, vfi);
   3053         break;
   3054     case _bcmVfiTypeL2Gre:
   3055 #if defined(BCM_TRIUMPH3_SUPPORT)
   3056         if (soc_feature(unit, soc_feature_l2gre)) {
   3057             _BCM_L2GRE_VFI_USED_SET(unit, vfi);
   3058         }
   3059 #endif
   3060         break;
   3061     case _bcmVfiTypeVxlan:
   3062 #if defined(BCM_TRIDENT2_SUPPORT)
   3063         if (soc_feature(unit, soc_feature_vxlan)) {
   3064             _BCM_VXLAN_VFI_USED_SET(unit, vfi);
   3065         }
   3066 #endif
   3067         break;
   3068     case _bcmVfiTypeVlan:
   3069 #if defined(BCM_TRIUMPH3_SUPPORT)
   3070         if (soc_feature(unit, soc_feature_vlan_vfi)) {
   3071             _BCM_VLAN_VFI_USED_SET(unit, vfi);
   3072         }
   3073 #endif
   3074         break;
   3075     case _bcmVfiTypeFlow:
   3076 #if defined(BCM_TRIDENT3_SUPPORT)
   3077         if (soc_feature(unit, soc_feature_flex_flow)) {
   3078             _BCM_FLOW_VFI_USED_SET(unit, vfi);
   3079         }
   3080 #endif
   3081         break;
   3082     default:
   3083         break;
   3084     }
   3085 
   3086     rv = _bcm_vfi_init(unit, vfi);
   3087     VIRTUAL_UNLOCK(unit);
   3088 
   3089     return rv;
   3090 }
   3091 
   3092 
   3093 /*
   3094  * Function:
   3095  *      _bcm_vfi_free
   3096  * Purpose:
   3097  *      Internal function for freeing a VFI
   3098  * Parameters:
   3099  *      unit    -  (IN) Device number.
   3100  *      type    -  (IN) VFI type
   3101  *      base_vfi - (IN) VFI index
   3102  * Returns:
   3103  *      BCM_X_XXX
   3104  */
   3105 int
   3106 _bcm_vfi_free(int unit, _bcm_vfi_type_e type, int vfi)
   3107 {
   3108     vfi_entry_t vfi_entry;
   3109     egr_vfi_entry_t egr_vfi_entry;
   3110     int rv = BCM_E_NONE;
   3111 
   3112 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   3113     if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
   3114         bcm_vpn_t vpn;
   3115         bcm_stg_t stg;
   3116 
   3117         /* Remove VPN from its spanning tree group */
   3118         _BCM_VPN_SET(vpn, _BCM_VPN_TYPE_VFI, vfi);
   3119         BCM_IF_ERROR_RETURN(bcm_esw_vlan_stg_get(unit, vpn, &stg));
   3120         BCM_IF_ERROR_RETURN(_bcm_stg_vlan_destroy(unit, stg, vpn));
   3121     }
   3122 
   3123     /* Delete VFI PROFILE */
   3124     if (soc_feature(unit, soc_feature_vfi_profile)) {
   3125         uint32 index = 0;
   3126 
   3127         BCM_IF_ERROR_RETURN(READ_VFIm(unit, MEM_BLOCK_ALL, vfi, &vfi_entry));
   3128         index = soc_VFIm_field32_get(unit, &vfi_entry, VFI_PROFILE_PTRf);
   3129         if (0 != index) {
   3130             BCM_IF_ERROR_RETURN(_bcm_vfi_profile_entry_delete(unit, index));
   3131         }
   3132     }
   3133 #endif
   3134 
   3135     VIRTUAL_LOCK(unit);
   3136     _BCM_VIRTUAL_VFI_USED_CLR(unit, vfi);
   3137     switch (type) {
   3138     case _bcmVfiTypeMpls:
   3139         _BCM_MPLS_VFI_USED_CLR(unit, vfi);
   3140         break;
   3141     case _bcmVfiTypeMim:
   3142         _BCM_MIM_VFI_USED_CLR(unit, vfi);
   3143         break;
   3144     case _bcmVfiTypeL2Gre:
   3145 #if defined(BCM_TRIUMPH3_SUPPORT)
   3146         if (soc_feature(unit, soc_feature_l2gre)) {
   3147             _BCM_L2GRE_VFI_USED_CLR(unit, vfi);
   3148         }
   3149 #endif
   3150         break;
   3151     case _bcmVfiTypeVxlan:
   3152 #if defined(BCM_TRIDENT2_SUPPORT)
   3153         if (soc_feature(unit, soc_feature_vxlan)) {
   3154             _BCM_VXLAN_VFI_USED_CLR(unit, vfi);
   3155         }
   3156 #endif
   3157         break;
   3158     case _bcmVfiTypeVlan:
   3159 #if defined(BCM_TRIUMPH3_SUPPORT)
   3160         if (soc_feature(unit, soc_feature_vlan_vfi)) {
   3161             _BCM_VLAN_VFI_USED_CLR(unit, vfi);
   3162         }
   3163 #endif
   3164         break;
   3165     case _bcmVfiTypeFlow:
   3166 #if defined(BCM_TRIDENT3_SUPPORT)
   3167         if (soc_feature(unit, soc_feature_flex_flow)) {
   3168             _BCM_FLOW_VFI_USED_CLR(unit, vfi);
   3169         }
   3170 #endif
   3171         break;
   3172     default:
   3173         break;
   3174     }
   3175 
   3176     sal_memset(&vfi_entry, 0, sizeof(vfi_entry_t));
   3177     rv = WRITE_VFIm(unit, MEM_BLOCK_ALL, vfi, &vfi_entry);
   3178     if (SOC_FAILURE(rv)) {
   3179         VIRTUAL_UNLOCK(unit);
   3180         return rv;
   3181     }
   3182     sal_memset(&egr_vfi_entry, 0, sizeof(egr_vfi_entry_t));
   3183     rv = WRITE_EGR_VFIm(unit, MEM_BLOCK_ALL, vfi, &egr_vfi_entry);
   3184     VIRTUAL_UNLOCK(unit);
   3185     return rv;
   3186 }
   3187 
   3188 /*
   3189  * Function:
   3190  *      _bcm_vfi_used_get
   3191  * Purpose:
   3192  *      Check whether a VFI is used or not 
   3193  * Parameters:
   3194  *      unit    -  (IN) Device number.
   3195  *      vfi     -  (IN) VFI
   3196  *      type    -  (IN) VFI type
   3197  * Returns:
   3198  *      Boolean
   3199  */
   3200 int
   3201 _bcm_vfi_used_get(int unit, int vfi, _bcm_vfi_type_e type)
   3202 {
   3203     int rv=0;
   3204 /* Removed Lock-Unlock - fn used in Interrupt context */
   3205     switch (type) {
   3206     case _bcmVfiTypeMpls:
   3207         rv = _BCM_MPLS_VFI_USED_GET(unit, vfi);
   3208         break;
   3209     case _bcmVfiTypeMim:
   3210         rv = _BCM_MIM_VFI_USED_GET(unit, vfi);
   3211         break;
   3212     case _bcmVfiTypeL2Gre:
   3213 #if defined(BCM_TRIUMPH3_SUPPORT)
   3214         if (soc_feature(unit, soc_feature_l2gre)) {
   3215             rv = _BCM_L2GRE_VFI_USED_GET(unit, vfi);
   3216         }
   3217 #endif
   3218         break;
   3219     case _bcmVfiTypeVxlan:
   3220 #if defined(BCM_TRIDENT2_SUPPORT)
   3221         if (soc_feature(unit, soc_feature_vxlan)) {
   3222             rv = _BCM_VXLAN_VFI_USED_GET(unit, vfi);
   3223         }
   3224 #endif
   3225         break;
   3226     case _bcmVfiTypeVlan:
   3227 #if defined(BCM_TRIUMPH3_SUPPORT)
   3228         if (soc_feature(unit, soc_feature_vlan_vfi)) {
   3229             rv = _BCM_VLAN_VFI_USED_GET(unit, vfi);
   3230         }
   3231 #endif
   3232         break;
   3233     case _bcmVfiTypeFlow:
   3234 #if defined(BCM_TRIDENT3_SUPPORT)
   3235         if (soc_feature(unit, soc_feature_flex_flow)) {
   3236             rv = _BCM_FLOW_VFI_USED_GET(unit, vfi);
   3237         }
   3238 #endif
   3239         break;
   3240     default:
   3241         rv = _BCM_VIRTUAL_VFI_USED_GET(unit, vfi);
   3242         break;
   3243     }
   3244     return rv;
   3245 }
   3246 
   3247 #ifdef BCM_TRIUMPH2_SUPPORT 
   3248 /*
   3249  * Function:
   3250  *      _bcm_vfi_flex_stat_index_set
   3251  * Purpose:
   3252  *      Associate a flexible stat with a VFI
   3253  * Parameters:
   3254  *      unit    -  (IN) Device number.
   3255  *      vfi     -  (IN) VFI
   3256  *      fs_idx  -  (IN) Flexible stat index
   3257  * Returns:
   3258  *      Boolean
   3259  */
   3260 int
   3261 _bcm_vfi_flex_stat_index_set(int unit, int vfi, _bcm_vfi_type_e type,
   3262                              int fs_idx,uint32 flags)
   3263 {
   3264     int rv,rv1;
   3265     vfi_entry_t vfi_entry;
   3266     egr_vfi_entry_t egr_vfi_entry;
   3267 
   3268     rv = BCM_E_NONE;
   3269     rv1 = BCM_E_NONE;
   3270     VIRTUAL_LOCK(unit);
   3271     if (_bcm_vfi_used_get(unit, vfi, type)) {
   3272         if (flags & _BCM_FLEX_STAT_HW_INGRESS) {
   3273             rv = soc_mem_read(unit, VFIm, MEM_BLOCK_ANY, vfi, &vfi_entry);
   3274             if (BCM_SUCCESS(rv)) {
   3275                 if (soc_mem_field_valid(unit, VFIm, USE_SERVICE_CTR_IDXf)) {
   3276                     soc_mem_field32_set(unit, VFIm, &vfi_entry,
   3277                                     USE_SERVICE_CTR_IDXf, fs_idx > 0 ? 1 : 0);
   3278                 }
   3279                 soc_mem_field32_set(unit, VFIm, &vfi_entry, SERVICE_CTR_IDXf,
   3280                                     fs_idx);
   3281                 rv = soc_mem_write(unit, VFIm, MEM_BLOCK_ANY, vfi, &vfi_entry);
   3282             }
   3283         }
   3284         if (flags & _BCM_FLEX_STAT_HW_EGRESS) {
   3285             rv1 = soc_mem_read(unit, EGR_VFIm, MEM_BLOCK_ANY, vfi,
   3286                               &egr_vfi_entry);
   3287             if (BCM_SUCCESS(rv1)) {
   3288                 if (soc_mem_field_valid(unit, EGR_VFIm,
   3289                                         USE_SERVICE_CTR_IDXf)) {
   3290                     soc_mem_field32_set(unit, EGR_VFIm, &egr_vfi_entry,
   3291                                         USE_SERVICE_CTR_IDXf,
   3292                                         fs_idx > 0 ? 1 : 0);
   3293                 }
   3294                 soc_mem_field32_set(unit, EGR_VFIm, &egr_vfi_entry,
   3295                                     SERVICE_CTR_IDXf, fs_idx);
   3296                 rv1 = soc_mem_write(unit, EGR_VFIm, MEM_BLOCK_ANY, vfi,
   3297                                    &egr_vfi_entry);
   3298             }
   3299         }
   3300     } else {
   3301         rv = BCM_E_NOT_FOUND;
   3302     }
   3303     VIRTUAL_UNLOCK(unit);
   3304     if (BCM_SUCCESS(rv1)) {
   3305         return rv;
   3306     } else {
   3307         return rv1;
   3308     }
   3309 }
   3310 #endif  /* BCM_TRIUMPH2_SUPPORT */
   3311 
   3312 /*
   3313  * Function:
   3314  *      _bcm_vp_ing_dvp_config
   3315  * Purpose:
   3316  *      Configures ING_DVP and ING_DVP_2 tables
   3317  * Parameters:
   3318  *   unit -  (IN) Device number.
   3319  *   op   -  (IN) Operation to perform on the ING_DVP_* tables
   3320  *     _bcmVpIngDvpConfigClear:  Clear the tables.
   3321  *     _bcmVpIngDvpConfigSet  :  Set the tables with inputs, rest to zeros.
   3322  *     _bcmVpIngDvpConfigUpdate: Update the tables with inputs, rest unmodified
   3323  *   vp   -          (IN) Virtual Port ID.
   3324  *   vp_type   -  (IN) Virtual Port type.
   3325  *   intf     -       (IN)  EGR L3 nexthops, DVP EGR L3 nexthops or
   3326  *                      ECMP group objects
   3327  *   network_port -  (IN) indicate network port or not.
   3328  * Returns:
   3329  *      BCM_E_XXX
   3330  * Note:
   3331  *     ING_DVP_2_TABLE also should be updated for IFP redirect to work.
   3332  *     For Td2p/Td2/TH, this table should be programed the same as ING_DVP_TABLE.
   3333  *     This function can be called by passing only the changed fields with 
   3334  *     _bcmVpIngDvpConfigUpdate. Any params set as invalid value should not be touched.
   3335  */
   3336 int
   3337 _bcm_vp_ing_dvp_config(int unit, _bcm_vp_ing_dvp_config_op_t op, int vp,
   3338                                 int vp_type, bcm_if_t intf, int network_port)
   3339 {
   3340     int rv = BCM_E_NONE;
   3341     int ecmp = -1;
   3342     int nh_ecmp_index = -1;
   3343     soc_field_t nw_field = NETWORK_PORTf;
   3344     ing_dvp_table_entry_t dvp_entry;
   3345 #if defined (BCM_TRIDENT_SUPPORT)
   3346     ing_dvp_2_table_entry_t dvp_2_entry;
   3347 #endif /* BCM_TRIDENT_SUPPORT */
   3348 
   3349     if ((soc_feature(unit, soc_feature_multiple_split_horizon_group))) {
   3350         nw_field = NETWORK_GROUPf;
   3351     }
   3352 
   3353     if (op == _bcmVpIngDvpConfigUpdate) {
   3354         /* read the entry from hardware */
   3355         rv = READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp_entry);
   3356         BCM_IF_ERROR_RETURN(rv);
   3357 
   3358 #if defined (BCM_TRIDENT_SUPPORT)
   3359         if (SOC_MEM_IS_VALID(unit, ING_DVP_2_TABLEm)) {
   3360             rv = READ_ING_DVP_2_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp_2_entry);
   3361             BCM_IF_ERROR_RETURN(rv);
   3362         }
   3363 #endif /* BCM_TRIDENT_SUPPORT */
   3364     } else {
   3365 
   3366         sal_memset(&dvp_entry, 0, sizeof(ing_dvp_table_entry_t));
   3367 #if defined (BCM_TRIDENT_SUPPORT)
   3368         sal_memset(&dvp_2_entry, 0, sizeof(ing_dvp_2_table_entry_t));
   3369 #endif /* BCM_TRIDENT_SUPPORT */
   3370 
   3371     }
   3372     if (BCM_XGS3_L3_EGRESS_IDX_VALID(unit, intf) || 
   3373         BCM_XGS3_DVP_EGRESS_IDX_VALID(unit, intf)) {
   3374 
   3375         /* Extract next hop index from unipath egress object. */
   3376         if (BCM_XGS3_L3_EGRESS_IDX_VALID(unit, intf)) {
   3377             nh_ecmp_index = intf - BCM_XGS3_EGRESS_IDX_MIN(unit);
   3378         } else {
   3379             nh_ecmp_index = intf - BCM_XGS3_DVP_EGRESS_IDX_MIN(unit);
   3380         }
   3381         ecmp = 0;
   3382     } else if (BCM_XGS3_L3_MPATH_EGRESS_IDX_VALID(unit, intf)) {
   3383         nh_ecmp_index = intf - BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit);
   3384         ecmp = 1;        
   3385 #ifdef BCM_MULTI_LEVEL_ECMP_SUPPORT
   3386         /*
   3387          * When Multi-level ECMP is enabled, ECMP group pointed
   3388          * to by DVP must be an underlay group.
   3389          */
   3390         if (BCMI_L3_ECMP_IS_MULTI_LEVEL(unit)) {
   3391             if (nh_ecmp_index < BCMI_L3_ECMP_OVERLAY_ENTRIES(unit)) {
   3392                 return BCM_E_PARAM;
   3393             }
   3394         }
   3395 #endif
   3396     }
   3397     /* Configure DVP table */
   3398     if (op != _bcmVpIngDvpConfigClear) {
   3399         if ((ecmp == 0) && (nh_ecmp_index > 0)) {
   3400             soc_ING_DVP_TABLEm_field32_set(unit, &dvp_entry,
   3401                                            ECMP_PTRf, 0);
   3402             soc_ING_DVP_TABLEm_field32_set(unit, &dvp_entry,
   3403                                            NEXT_HOP_INDEXf, nh_ecmp_index);
   3404             soc_ING_DVP_TABLEm_field32_set(unit, &dvp_entry,
   3405                                            ECMPf, 0);
   3406 #if defined (BCM_TRIDENT_SUPPORT)
   3407             if (SOC_MEM_IS_VALID(unit, ING_DVP_2_TABLEm)) {
   3408                 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp_2_entry,
   3409                                                  ECMP_PTRf, 0);
   3410                 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp_2_entry,
   3411                                                  NEXT_HOP_INDEXf, nh_ecmp_index);
   3412                 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp_2_entry,
   3413                                                  ECMPf, 0);
   3414             }
   3415 #endif /* BCM_TRIDENT_SUPPORT */
   3416         } 
   3417         if ((ecmp == 1) && (nh_ecmp_index >= 0)) {
   3418             soc_ING_DVP_TABLEm_field32_set(unit, &dvp_entry,
   3419                                            NEXT_HOP_INDEXf, 0);
   3420             soc_ING_DVP_TABLEm_field32_set(unit, &dvp_entry,
   3421                                            ECMPf, 1);
   3422             soc_ING_DVP_TABLEm_field32_set(unit, &dvp_entry,
   3423                                            ECMP_PTRf, nh_ecmp_index);
   3424 #if defined (BCM_TRIDENT_SUPPORT)
   3425             if (SOC_MEM_IS_VALID(unit, ING_DVP_2_TABLEm)) {
   3426                 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp_2_entry,
   3427                                                  NEXT_HOP_INDEXf, 0);
   3428                 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp_2_entry,
   3429                                                  ECMPf, 1);
   3430                 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp_2_entry,
   3431                                                  ECMP_PTRf, nh_ecmp_index);
   3432             }
   3433 #endif /* BCM_TRIDENT_SUPPORT */
   3434         }
   3435 
   3436         if ((vp_type >= _bcmVpIngDvpVpTypeMPLS_MIM_NIV) && 
   3437             (vp_type < _bcmVpIngDvpVpTypeCount)) {
   3438             soc_ING_DVP_TABLEm_field32_set(unit, &dvp_entry,
   3439                                            VP_TYPEf, vp_type);
   3440 #if defined (BCM_TRIDENT_SUPPORT)
   3441             if (SOC_MEM_IS_VALID(unit, ING_DVP_2_TABLEm)) {
   3442                 soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp_2_entry,
   3443                                                  VP_TYPEf, vp_type);
   3444             }
   3445 #endif /* BCM_TRIDENT_SUPPORT */
   3446         }
   3447         /*Do not allow (-1) as network group id*/
   3448         if (network_port != ING_DVP_CONFIG_INVALID_PORT_TYPE) {
   3449             if (soc_mem_field_valid(unit, ING_DVP_TABLEm, nw_field)) {
   3450                 soc_ING_DVP_TABLEm_field32_set(unit,
   3451                     &dvp_entry, nw_field, network_port);
   3452             }
   3453 #if defined (BCM_TRIDENT_SUPPORT)
   3454             if (SOC_MEM_IS_VALID(unit, ING_DVP_2_TABLEm)) {
   3455                 soc_ING_DVP_2_TABLEm_field32_set(unit,
   3456                     &dvp_2_entry, nw_field, network_port);
   3457             }
   3458 #endif /* BCM_TRIDENT_SUPPORT */
   3459         }
   3460     }
   3461 
   3462     rv = WRITE_ING_DVP_TABLEm(unit, MEM_BLOCK_ALL, vp, &dvp_entry);
   3463     BCM_IF_ERROR_RETURN(rv);
   3464 
   3465 #if defined (BCM_TRIDENT_SUPPORT)
   3466     if (SOC_MEM_IS_VALID(unit, ING_DVP_2_TABLEm)) {
   3467         rv = WRITE_ING_DVP_2_TABLEm(unit, MEM_BLOCK_ALL, vp, &dvp_2_entry);
   3468         BCM_IF_ERROR_RETURN(rv);
   3469     }
   3470 #endif /* BCM_TRIDENT_SUPPORT */
   3471 
   3472 
   3473     return rv;
   3474 }
   3475 
   3476 int
   3477 _bcm_vp_ing_dvp_to_ing_dvp2_2(int unit,
   3478     ing_dvp_table_entry_t *dvp, int vp, int network_group_id)
   3479 {
   3480     ing_dvp_2_table_entry_t dvp2;
   3481     uint8 vp_type;
   3482     uint8 ecmp;
   3483     uint8 nw_port, nw_group;
   3484     uint8 en_vplag_res;
   3485     uint32 nh_index;
   3486 
   3487     if (!soc_feature(unit, soc_feature_ifp_redirect_to_dvp)) {
   3488         return BCM_E_NONE;
   3489     }
   3490 
   3491     BCM_IF_ERROR_RETURN(READ_ING_DVP_2_TABLEm(unit, MEM_BLOCK_ANY,
   3492                 vp, &dvp2));
   3493 
   3494     vp_type = soc_ING_DVP_TABLEm_field32_get(unit, dvp, 
   3495             VP_TYPEf);
   3496     soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp2, VP_TYPEf, vp_type);
   3497 
   3498     if (soc_feature(unit, soc_feature_multiple_split_horizon_group)) {
   3499 #if defined(BCM_TRIDENT3_SUPPORT)
   3500         if (SOC_IS_TRIDENT3X(unit)) {
   3501             nw_group = network_group_id;
   3502         } else
   3503 #endif
   3504         {
   3505             nw_group = soc_ING_DVP_TABLEm_field32_get(unit, dvp,
   3506                 NETWORK_GROUPf);
   3507         }
   3508         soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp2, NETWORK_GROUPf, nw_group);
   3509     } else {
   3510         nw_port = soc_ING_DVP_TABLEm_field32_get(unit, dvp, NETWORK_PORTf);
   3511         soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp2, NETWORK_PORTf, nw_port);
   3512     }
   3513 
   3514     ecmp = soc_ING_DVP_TABLEm_field32_get(unit, dvp, 
   3515             ECMPf);
   3516     soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp2, ECMPf, ecmp);
   3517 
   3518     if (soc_feature(unit, soc_feature_vp_lag)) {
   3519         en_vplag_res = soc_ING_DVP_TABLEm_field32_get(unit, dvp, 
   3520                 ENABLE_VPLAG_RESOLUTIONf);
   3521         soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp2, ENABLE_VPLAG_RESOLUTIONf,
   3522                 en_vplag_res);
   3523     }
   3524 
   3525     nh_index = soc_ING_DVP_TABLEm_field32_get(unit, dvp, 
   3526             NEXT_HOP_INDEXf);
   3527     soc_ING_DVP_2_TABLEm_field32_set(unit, &dvp2, NEXT_HOP_INDEXf, nh_index);
   3528 
   3529     BCM_IF_ERROR_RETURN(WRITE_ING_DVP_2_TABLEm(unit, MEM_BLOCK_ANY,
   3530                 vp, &dvp2));
   3531 
   3532     return BCM_E_NONE;
   3533 }
   3534 
   3535 int
   3536 _bcm_vp_ing_dvp_to_ing_dvp2(int unit, ing_dvp_table_entry_t *dvp,
   3537     int vp)
   3538 {
   3539     return _bcm_vp_ing_dvp_to_ing_dvp2_2(unit, dvp, vp , 0);
   3540 }
   3541 
   3542 int
   3543 _bcm_validate_splithorizon_network_group(int unit,int is_nw_port,
   3544     int *network_group)
   3545 {
   3546     int group=0;
   3547     group=*network_group;
   3548 
   3549     /*If spn_USE_ALL_SPLITHORIZON_GROUPS config property is enabled customer
   3550       can use split horizon groups from zero to max supported otherwise
   3551       0 and 1 are reserved.And based on soc_feature_reserve_shg_network_port
   3552       BCM5656x family of devices the split horizon group index 1 is
   3553        reserved by default for network ports*/
   3554 
   3555     /*Do not allow out of range group ids*/
   3556     if (!_BCM_SWITCH_NETWORK_GROUP_ID_VALID (unit, group)) {
   3557         return BCM_E_PARAM;
   3558     }
   3559 
   3560     if(soc_feature(unit,
   3561                 soc_feature_multiple_split_horizon_group)) {
   3562 
   3563         if(!soc_property_get(unit, spn_USE_ALL_SPLITHORIZON_GROUPS, 0)) {
   3564             if (soc_feature(unit,
   3565                         soc_feature_reserve_shg_network_port)) {
   3566                 /*Default value:
   3567                  *0 - for access ports
   3568                  *1 - for network ports*/
   3569                 if (_BCM_SWITCH_RESERVED_NETWORK_GROUP_IDS(unit, group)) {
   3570                     if (is_nw_port) {
   3571                         *network_group = 1;
   3572                     } else {
   3573                         *network_group = 0;
   3574                     }
   3575                 }
   3576             }
   3577         }
   3578     }
   3579 
   3580     return BCM_E_NONE;
   3581 }
   3582 
   3583 /*
   3584  * Function:
   3585  *    _bcm_switch_network_group_pruning
   3586  * Parameters:
   3587  *    unit                   (IN)device number
   3588  *    source_network_group_id (IN) source split horizon group ID
   3589  *    config                 (IN) network group config information
   3590  * Purpose:
   3591  *    This API is used to get the enable/disable status of ingress pruning, egress pruning and
   3592  *    ingress IPMC group remap for a given pair of
   3593  *    source split horizon group and destination split horizon group.
   3594  *    Katana2 (BCM5645x) family of devices support 8 split horizon group.
   3595  * Returns:
   3596  *    BCM_E_XXX
   3597  */
   3598 int
   3599 _bcm_switch_network_group_pruning(int unit,
   3600         bcm_switch_network_group_t source_network_group_id,
   3601         bcm_switch_network_group_config_t *config)
   3602 {
   3603     int rv = BCM_E_NONE;
   3604     soc_mem_t mem;
   3605     soc_field_t field;
   3606     bcm_pbmp_t prune_pbmp;
   3607     ing_network_prune_control_entry_t ing_entry;
   3608     egr_network_prune_control_entry_t egr_entry;
   3609 
   3610     if (config == NULL) {
   3611         return BCM_E_PARAM;
   3612     }
   3613 
   3614     BCM_PBMP_CLEAR(prune_pbmp);
   3615     mem = ING_NETWORK_PRUNE_CONTROLm;
   3616     if (SOC_MEM_IS_VALID(unit, mem)) {
   3617         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, COPYNO_ALL,
   3618                     source_network_group_id, &ing_entry));
   3619 
   3620         field = REMAP_IPMC_GROUPf;
   3621         if (SOC_MEM_FIELD_VALID(unit, mem, field)) {
   3622             soc_mem_field32_set(unit, mem, &ing_entry, field,
   3623                     (config->config_flags &
   3624                      BCM_SWITCH_NETWORK_GROUP_MCAST_REMAP_ENABLE) ? 1 : 0);
   3625         }
   3626 
   3627         field = PRUNE_ENABLE_BITMAPf;
   3628         if (SOC_MEM_FIELD_VALID(unit, mem, field)) {
   3629             soc_mem_pbmp_field_get(unit, mem, &ing_entry, field, &prune_pbmp);
   3630             if (config->config_flags &
   3631                     BCM_SWITCH_NETWORK_GROUP_INGRESS_PRUNE_ENABLE) {
   3632                 BCM_PBMP_PORT_ADD(prune_pbmp, config->dest_network_group_id);
   3633             } else {
   3634                 BCM_PBMP_PORT_REMOVE(prune_pbmp, config->dest_network_group_id);
   3635             }
   3636             soc_mem_pbmp_field_set(unit, mem, &ing_entry, field, &prune_pbmp);
   3637         }
   3638 
   3639         BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, COPYNO_ALL,
   3640                     source_network_group_id, &ing_entry));
   3641     }
   3642 
   3643     BCM_PBMP_CLEAR(prune_pbmp);
   3644     mem = EGR_NETWORK_PRUNE_CONTROLm;
   3645     if (SOC_MEM_IS_VALID(unit, mem)) {
   3646         BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, COPYNO_ALL,
   3647                     source_network_group_id, &egr_entry));
   3648 
   3649         field = PRUNE_ENABLE_BITMAPf;
   3650         if (SOC_MEM_FIELD_VALID(unit, mem, field)) {
   3651             soc_mem_pbmp_field_get(unit, mem, &egr_entry, field, &prune_pbmp);
   3652             if (config->config_flags &
   3653                     BCM_SWITCH_NETWORK_GROUP_EGRESS_PRUNE_ENABLE) {
   3654                 BCM_PBMP_PORT_ADD(prune_pbmp, config->dest_network_group_id);
   3655             } else {
   3656                 BCM_PBMP_PORT_REMOVE(prune_pbmp, config->dest_network_group_id);
   3657             }
   3658             soc_mem_pbmp_field_set(unit, mem, &egr_entry, field, &prune_pbmp);
   3659         }
   3660 
   3661         BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, COPYNO_ALL,
   3662                     source_network_group_id, &egr_entry));
   3663 
   3664 #if defined(BCM_TRIDENT3_SUPPORT) && defined(INCLUDE_L3)
   3665         if (soc_feature(unit,soc_feature_flex_flow) &&
   3666             soc_property_get(unit, spn_IP6_VXLAN_MSHG_ENABLE, 0)) {
   3667             rv = bcmi_esw_flow_mshg_prune_egress_set(unit,
   3668                 source_network_group_id, config->dest_network_group_id,
   3669                 config->config_flags &
   3670                 BCM_SWITCH_NETWORK_GROUP_EGRESS_PRUNE_ENABLE);
   3671         }
   3672 #endif
   3673     }
   3674 
   3675     return rv;
   3676 }
   3677 
   3678 #ifdef BCM_RIOT_SUPPORT
   3679 
   3680 /*
   3681  * Function:
   3682  *      _bcm_vp_is_vfi_type
   3683  * Purpose: 
   3684  *      Finds out if GPORT is VFI type virtual port.
   3685  * Parameters:
   3686  *      unit  - SOC device unit number
   3687  *      gport - gport provided 
   3688  * Returns: 
   3689  *      TRUE/FALSE              
   3690  */
   3691 
   3692 int
   3693 _bcm_vp_is_vfi_type(int unit, bcm_gport_t gport)
   3694 {
   3695     int gport_type = 0;
   3696 
   3697     gport_type = BCMI_GPORT_TYPE_GET(gport);
   3698 
   3699     switch(gport_type) {
   3700         case BCM_GPORT_VXLAN_PORT:
   3701         case BCM_GPORT_L2GRE_PORT:
   3702         case BCM_GPORT_MPLS_PORT:
   3703         case BCM_GPORT_MIM_PORT:
   3704         case BCM_GPORT_FLOW_PORT:
   3705             return 1;
   3706         default:
   3707              return 0;
   3708     }
   3709 }
   3710 
   3711 /*
   3712  * Function:
   3713  *      _bcm_vp_vfi_type_vp_get
   3714  * Purpose:
   3715  *      Checks and gets a valid vp.
   3716  * Parameters:
   3717  *      unit - SOC device unit number
   3718  *      gport - (IN)gport provided 
   3719  *      vp    - (Out) Physical port decoded from gport
   3720  * Returns:
   3721  *      TRUE/FALSE              
   3722  */
   3723 int
   3724 _bcm_vp_vfi_type_vp_get(int unit, bcm_gport_t gport, int *vp)
   3725 {
   3726     int gport_type = 0;
   3727 
   3728     gport_type = BCMI_GPORT_TYPE_GET(gport);
   3729 
   3730     switch(gport_type) {
   3731         case BCM_GPORT_VXLAN_PORT:
   3732             *vp = BCM_GPORT_VXLAN_PORT_ID_GET(gport);
   3733             break;
   3734         case BCM_GPORT_L2GRE_PORT:
   3735             *vp = BCM_GPORT_L2GRE_PORT_ID_GET(gport);
   3736             break;
   3737         case BCM_GPORT_MPLS_PORT:
   3738             *vp = BCM_GPORT_MPLS_PORT_ID_GET(gport);
   3739             break;
   3740         case BCM_GPORT_MIM_PORT:
   3741             *vp = BCM_GPORT_MIM_PORT_ID_GET(gport);
   3742             break;
   3743         case BCM_GPORT_FLOW_PORT:
   3744             *vp = BCM_GPORT_FLOW_PORT_ID_GET(gport);
   3745             break;
   3746         default:
   3747              return 0;
   3748     }
   3749     return 1;
   3750 }
   3751 
   3752 /*
   3753  * Function:
   3754  *      _bcm_vp_lag_member_is_vfi_type
   3755  * Purpose:
   3756  *      Finds out if member of VP-LAG is VFI type virtual port.
   3757  * Parameters:
   3758  *      unit  - SOC device unit number
   3759  *      gport - gport provided
   3760  * Returns:
   3761  *      TRUE/FALSE
   3762  */
   3763 int
   3764 _bcm_vp_lag_member_is_vfi_type(int unit, bcm_gport_t gport)
   3765 {
   3766     int is_vfi_type = 0;
   3767 
   3768 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
   3769     if (soc_feature(unit, soc_feature_vp_lag)) {
   3770         if (BCM_GPORT_IS_TRUNK(gport)) {
   3771             bcm_trunk_t tid = BCM_TRUNK_INVALID;
   3772             int tid_is_vp_lag = 0;
   3773             int rv = BCM_E_NONE;
   3774 
   3775             tid = BCM_GPORT_TRUNK_GET(gport);
   3776             if (BCM_TRUNK_INVALID != tid) {
   3777                 rv = _bcm_esw_trunk_id_is_vp_lag(unit, tid, &tid_is_vp_lag);
   3778                 if (BCM_SUCCESS (rv) &&  tid_is_vp_lag) {
   3779                        (void)_bcm_td2_vp_lag_member_is_vfi_type(unit, tid, &is_vfi_type);
   3780                 }
   3781             }
   3782         }
   3783     }
   3784 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */
   3785 
   3786     return is_vfi_type;
   3787 }
   3788 
   3789 #endif /* BCM_RIOT_SUPPORT */
   3790 
   3791 void
   3792 _bcm_vp_vfi_set(int unit, int vp, int vfi)
   3793 {
   3794     _BCM_VIRTUAL_VP_VFI_MAP(unit, vp) = vfi;
   3795 }
   3796 
   3797 int
   3798 _bcm_vp_vfi_get(int unit, int vp)
   3799 {
   3800     int vpn = _BCM_VIRTUAL_VP_VFI_MAP(unit, vp);
   3801     int vfi = 0;
   3802 
   3803     if(_BCM_MPLS_VPN_IS_VPLS(vpn)) {
   3804         vfi = vpn;
   3805     }
   3806     return vfi;
   3807 }
   3808 
   3809 #else /* INCLUDE_L3 */
   3810 int _bcm_esw_trx_virtual_not_empty;
   3811 #endif  /* INCLUDE_L3 */