openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

vlan.c (271662B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:        vlan.c
      8  * Purpose:     Provide low-level access to XGS3 VLAN resources
      9  */
     10 
     11 #include <sal/core/boot.h>
     12 #include <shared/bsl.h>
     13 #include <soc/drv.h>
     14 #include <soc/mem.h>
     15 
     16 #include <bcm/error.h>
     17 #include <bcm/vlan.h>
     18 
     19 #include <bcm_int/esw/mbcm.h>
     20 #include <bcm_int/esw/field.h>
     21 #include <bcm_int/esw/firebolt.h>
     22 #include <bcm_int/esw/trx.h>
     23 /* #include <bcm_int/esw/firebolt.h> */
     24 #if defined(BCM_TRIUMPH_SUPPORT)
     25 #include <bcm_int/esw/triumph.h>
     26 #endif /* BCM_TRIUMPH_SUPPORT */
     27 #if defined(BCM_TRIUMPH2_SUPPORT)
     28 #include <bcm_int/esw/triumph2.h>
     29 #include <bcm_int/common/multicast.h>
     30 #endif /* BCM_TRIUMPH2_SUPPORT */
     31 #if defined(BCM_TRIDENT_SUPPORT)
     32 #include <bcm_int/esw/trident.h>
     33 #include <bcm_int/common/multicast.h>
     34 #endif /* BCM_TRIUMPH2_SUPPORT */
     35 #include <bcm_int/esw/port.h>
     36 #include <bcm_int/esw/vlan.h>
     37 #include <bcm_int/esw/multicast.h>
     38 #include <bcm_int/esw/xgs3.h>
     39 #include <bcm_int/esw/vpn.h>
     40 #include <bcm_int/esw/trill.h>
     41 
     42 #include <bcm_int/esw_dispatch.h>
     43 #if defined(BCM_TRIDENT2_SUPPORT)
     44 #include <bcm_int/esw/trident2.h>
     45 #endif
     46 #if defined(BCM_KATANA2_SUPPORT)
     47 #include <bcm_int/esw/katana2.h>
     48 #endif
     49 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
     50 #include <bcm_int/esw/trident2plus.h>
     51 #include <bcm_int/esw/virtual.h>
     52 #endif
     53 
     54 #if defined(BCM_TRIDENT3_SUPPORT)
     55 #include <bcm_int/esw/trident3.h>
     56 #endif
     57 #if defined(BCM_GREYHOUND2_SUPPORT)
     58 #include <bcm_int/esw/greyhound2.h>
     59 #endif
     60 
     61 #if defined(BCM_TOMAHAWK3_SUPPORT)
     62 #include <bcm_int/esw/tomahawk3.h>
     63 #endif
     64 
     65 #define TABLE_HAS_UT_BITMAP(unit, table)                        \
     66      ((SOC_IS_FBX(unit) && \
     67       (!soc_feature(unit, soc_feature_vlan_vfi_untag_profile)) && \
     68       (table) == EGR_VLANm) || \
     69      (SOC_IS_KATANA2 (unit) && (table) == VLAN_TABm))
     70 
     71 #define TABLE_HAS_T_BITMAP(unit, table)         \
     72     (((table) == VLAN_TABLE(unit)) ||           \
     73      (soc_feature(unit, soc_feature_egr_vlan_check) && (table) == EGR_VLANm))
     74 
     75 #define TABLE_HAS_PFM(unit, table)                              \
     76     (((table) == VLAN_TABm) ||                                  \
     77      (soc_feature(unit, soc_feature_egr_vlan_pfm) && (table) == EGR_VLANm))
     78 
     79 #ifdef BCM_KATANA_SUPPORT
     80 #define _BCM_QOS_MAP_TYPE_MASK                     0x3ff
     81 #define _BCM_QOS_MAP_SHIFT                            10
     82 #define _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE   5
     83 #define _BCM_QOS_MAP_ING_QUEUE_OFFSET_MAX              7
     84 #endif
     85 
     86 #define BCM_PROTO_PKT_CONTROL_MAX    64
     87 /*
     88  * Function :
     89  *    _bcm_vlan_mcast_flood_mode_to_pfm
     90  * 
     91  * Purpose  :
     92  *    Encode vlan flood mode to pfm value. 
     93  *
     94  * Parameters :
     95  *     unit  - (IN) BCM device number.
     96  *     mode  - (IN) Vlan flood mode. 
     97  *     pfm   - (OUT) PFM value.
     98  *
     99  * Return :
    100  *    BCM_E_XXX
    101  */
    102 int
    103 _bcm_vlan_mcast_flood_mode_to_pfm(int unit, int mode, int *pfm)
    104 {
    105     COMPILER_REFERENCE(unit);
    106 
    107     if (NULL == pfm) {
    108         return (BCM_E_PARAM);
    109     }
    110 
    111     switch (mode) {
    112       case BCM_VLAN_MCAST_FLOOD_ALL:
    113           *pfm = 0;
    114           break;
    115       case BCM_VLAN_MCAST_FLOOD_NONE: 
    116           *pfm = 2;
    117           break;
    118       default: 
    119           *pfm = 1;
    120     }
    121     return (BCM_E_NONE);
    122 }
    123 
    124 /*
    125  * Function :
    126  *    _bcm_vlan_mcast_pfm_to_flood_mode
    127  * 
    128  * Purpose  :
    129  *    Decode pfm value to vlan flood mode enumerator.
    130  *
    131  * Parameters :
    132  *     unit  - (IN) BCM device number.
    133  *     pfm   - (IN) PFM value.
    134  *     mode  - (OUT) Vlan flood mode. 
    135  *
    136  * Return :
    137  *    BCM_E_XXX
    138  */
    139 int
    140 _bcm_vlan_mcast_pfm_to_flood_mode(int unit, int pfm, 
    141                                   bcm_vlan_mcast_flood_t *mode)
    142 {
    143     COMPILER_REFERENCE(unit);
    144 
    145     if (NULL == mode) {
    146         return (BCM_E_PARAM);
    147     }
    148 
    149     switch (pfm) {
    150       case 0: 
    151           *mode = BCM_VLAN_MCAST_FLOOD_ALL;
    152           break;
    153       case 1: 
    154           *mode = BCM_VLAN_MCAST_FLOOD_UNKNOWN;
    155           break;
    156       case 2: 
    157           *mode = BCM_VLAN_MCAST_FLOOD_NONE;
    158           break;
    159       default: 
    160           return (BCM_E_PARAM);
    161     }
    162     return (BCM_E_NONE);
    163 }
    164 
    165 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
    166  || defined(BCM_RAVEN_SUPPORT)
    167 typedef struct _vlan_outer_tpid_s {
    168     uint16                     tpid;
    169     int                        ref_count;
    170 } _vlan_outer_tpid_t;
    171 
    172 #define BCM_MAX_TPID_ENTRIES 4
    173 
    174 STATIC _vlan_outer_tpid_t
    175            (*_vlan_outer_tpid_tab[BCM_MAX_NUM_UNITS])[BCM_MAX_TPID_ENTRIES];
    176 STATIC sal_mutex_t _fb2_outer_tpid_lock[BCM_MAX_NUM_UNITS];
    177 
    178 #define OUTER_TPID_TAB(unit) _vlan_outer_tpid_tab[unit]
    179 
    180 #define OUTER_TPID_ENTRY(unit, index) \
    181     ((*_vlan_outer_tpid_tab[unit])[index].tpid)
    182 
    183 #define OUTER_TPID_REF_COUNT(unit, index) \
    184     ((*_vlan_outer_tpid_tab[unit])[index].ref_count)
    185 
    186 #define OUTER_TPID_TAB_INIT_CHECK(unit) \
    187     if (OUTER_TPID_TAB(unit) == NULL) { return BCM_E_INIT; }
    188 
    189 #define BCM_FB2_TPID_MUTEX(_u_) _fb2_outer_tpid_lock[_u_]
    190 
    191 #define BCM_FB2_TPID_LOCK(_u_)   \
    192          ((_fb2_outer_tpid_lock[_u_]) ? \
    193          sal_mutex_take(_fb2_outer_tpid_lock[_u_], sal_mutex_FOREVER) :  \
    194          (BCM_E_INTERNAL))
    195 
    196 #define BCM_FB2_TPID_UNLOCK(_u_)  \
    197          ((_fb2_outer_tpid_lock[_u_]) ? \
    198          sal_mutex_give(_fb2_outer_tpid_lock[_u_]) : \
    199          (BCM_E_INTERNAL))
    200 
    201 
    202 /*
    203  * Function:
    204  *      _bcm_fb2_outer_tpid_detach
    205  * Purpose:
    206  *      De-allocate and initialize memory to cache tpid entries.
    207  *      Initialize lock for cached tpid entries.
    208  * Parameters:
    209  *      unit       - (IN)SOC unit number.
    210  * Returns:
    211  *      BCM_E_XXX
    212  * Notes:
    213  */
    214 int
    215 _bcm_fb2_outer_tpid_detach(int unit) 
    216 {
    217     sal_free (OUTER_TPID_TAB(unit));
    218     OUTER_TPID_TAB(unit) = NULL;
    219 
    220     if (NULL != BCM_FB2_TPID_MUTEX(unit)) {
    221         sal_mutex_destroy(BCM_FB2_TPID_MUTEX(unit));
    222         BCM_FB2_TPID_MUTEX(unit) = NULL;
    223     }
    224     return (BCM_E_NONE); 
    225 }
    226 
    227 /*
    228  * Function:
    229  *      _bcm_fb2_outer_tpid_init 
    230  * Purpose:
    231  *      Allocate and initialize memory to cache tpid entries.
    232  *      Initialize lock for cached tpid entries.
    233  * Parameters:
    234  *      unit       - (IN)SOC unit number.
    235  * Returns:
    236  *      BCM_E_XXX
    237  * Notes:
    238  */
    239 int
    240 _bcm_fb2_outer_tpid_init(int unit) {
    241     int               index;
    242     int               alloc_size;
    243     bcm_port_t        port;
    244     uint32            reg32;
    245     int               enabled;
    246     uint32            value; 
    247     bcm_pbmp_t        all_pbmp;
    248 
    249     /* Allocate memory to cache ING_OUTER_TPID entries.
    250      * ING_OUTER_TPID entries are always the same as
    251      * EGR_OUTER_TPID entries.
    252      */
    253     alloc_size = sizeof(_vlan_outer_tpid_t) * BCM_MAX_TPID_ENTRIES;
    254     if (OUTER_TPID_TAB(unit) == NULL) {
    255         OUTER_TPID_TAB(unit) = sal_alloc(alloc_size,
    256                                          "Cached ingress outer TPIDs");
    257         if (OUTER_TPID_TAB(unit) == NULL) {
    258             return BCM_E_MEMORY;
    259         }
    260     }
    261     sal_memset(OUTER_TPID_TAB(unit), 0, alloc_size);
    262     
    263     /* Cache ingress outer TPID table */
    264     for (index = 0; index < BCM_MAX_TPID_ENTRIES; index++) {
    265         uint32 outer_tpid = 0;
    266 
    267         if (SOC_IS_TRIDENT3X(unit)) {
    268             soc_reg_t ing_outer_tpid_reg[] = {
    269                 ING_OUTER_TPID_0r,
    270                 ING_OUTER_TPID_1r,
    271                 ING_OUTER_TPID_2r,
    272                 ING_OUTER_TPID_3r
    273             };
    274             if (SOC_WARM_BOOT(unit)) {
    275                 BCM_IF_ERROR_RETURN
    276                     (soc_reg32_get(unit, ing_outer_tpid_reg[index], REG_PORT_ANY,
    277                                    0, &outer_tpid));
    278                 OUTER_TPID_ENTRY(unit, index) =
    279                     soc_reg_field_get(unit, ing_outer_tpid_reg[index], outer_tpid, TPIDf);
    280             } else {
    281                 uint32 ing_outer_tpid_init_val[] = {
    282                     0x8100,
    283                     0x9100,
    284                     0x88a8,
    285                     0xaa8a
    286                 };
    287                 soc_reg_field_set(unit, ing_outer_tpid_reg[index],
    288                                   &outer_tpid, TPIDf,
    289                                   ing_outer_tpid_init_val[index]);
    290                 BCM_IF_ERROR_RETURN
    291                     (soc_reg32_set(unit, ing_outer_tpid_reg[index], REG_PORT_ANY,
    292                                    0, outer_tpid));
    293 
    294                 OUTER_TPID_ENTRY(unit, index) = ing_outer_tpid_init_val[index];
    295             }
    296         } else {
    297         BCM_IF_ERROR_RETURN
    298             (READ_ING_OUTER_TPIDr(unit, index, &outer_tpid));
    299             OUTER_TPID_ENTRY(unit, index) =
    300                 soc_reg_field_get(unit, ING_OUTER_TPIDr, outer_tpid, TPIDf);
    301         }
    302     }
    303 
    304     /* All port has a reference to TPID */
    305     BCM_PBMP_CLEAR(all_pbmp);
    306     BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
    307 
    308 #ifdef BCM_KATANA2_SUPPORT
    309     if (soc_feature(unit, soc_feature_linkphy_coe) ||
    310         soc_feature(unit, soc_feature_subtag_coe)) {
    311         _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
    312     }
    313     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
    314         BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
    315     }
    316 #endif
    317 
    318     PBMP_ITER(all_pbmp, port) {
    319         if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
    320             if (soc_feature(unit, soc_feature_egr_all_profile)) {
    321                 BCM_IF_ERROR_RETURN(
    322                     bcm_esw_port_egr_lport_field_get(unit, port,
    323                     EGR_VLAN_CONTROL_1m, OUTER_TPID_INDEXf, (void *)&index));
    324             } else {
    325             BCM_IF_ERROR_RETURN(
    326                 READ_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, &value));
    327                 index = soc_mem_field32_get(unit, EGR_VLAN_CONTROL_1m, &value,
    328                                             OUTER_TPID_INDEXf);
    329             }
    330         } else {
    331             BCM_IF_ERROR_RETURN
    332                 (READ_EGR_VLAN_CONTROL_1r(unit, port, &reg32));
    333             index = soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r, 
    334                                   reg32, OUTER_TPID_INDEXf);
    335         }
    336        
    337         if (index < BCM_MAX_TPID_ENTRIES) {
    338         OUTER_TPID_REF_COUNT(unit, index)++;
    339         }
    340 
    341         enabled = 0;
    342         BCM_IF_ERROR_RETURN
    343             (_bcm_esw_port_config_get(unit, port,
    344                                       _bcmPortOuterTpidEnables, &enabled));
    345         index = 0;
    346         while(enabled) {
    347             if (enabled & 1) {
    348                 OUTER_TPID_REF_COUNT(unit, index)++;
    349             }
    350             enabled = enabled >> 1;
    351             index++;
    352         } 
    353     } 
    354 
    355     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLEm) &&
    356                                     !SOC_WARM_BOOT(unit)) {
    357         int i, rv;
    358         int i_min;
    359         int i_max;
    360         void *buf = NULL;
    361         soc_mem_t mem = SYSTEM_CONFIG_TABLEm;
    362         system_config_table_entry_t *entry;
    363 
    364         buf = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, mem), "syscfg_tbl");
    365         if (buf == NULL) {
    366             return BCM_E_MEMORY;
    367         }
    368 
    369         i_min = soc_mem_index_min(unit, mem);
    370         i_max = soc_mem_index_max(unit, mem);
    371         rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, i_min, i_max, buf);
    372         if (BCM_FAILURE(rv)) {
    373             soc_cm_sfree(unit, buf);
    374             return rv;
    375         }
    376 
    377         for (i = i_min; i <= i_max; i++) {
    378             entry = soc_mem_table_idx_to_pointer(unit, mem,
    379                         system_config_table_entry_t *, buf, i);
    380             enabled = soc_mem_field32_get(unit, mem, entry,
    381                                           OUTER_TPID_ENABLEf);
    382             index = 0;
    383             while (enabled) {
    384                 if (enabled & 1) {
    385                     OUTER_TPID_REF_COUNT(unit, index)++;
    386                 }
    387                 enabled = enabled >> 1;
    388                 index++;
    389             }
    390         }
    391         soc_cm_sfree(unit, buf);
    392     }
    393 
    394     if (NULL == BCM_FB2_TPID_MUTEX(unit)) {
    395         /* Create protection mutex. */
    396         BCM_FB2_TPID_MUTEX(unit) = sal_mutex_create("outer_tpid_lock");
    397 
    398         if (NULL == BCM_FB2_TPID_MUTEX(unit)) {
    399             return (BCM_E_MEMORY);
    400         }
    401     }
    402     return (BCM_E_NONE); 
    403 }
    404 
    405 /*
    406  * Function:
    407  *      _bcm_fb2_priority_map_init 
    408  * Purpose:
    409  *      Initialize the priority map table so that the incomming
    410  *      and outgoing priority are the same if the switch logic doesn't
    411  *      change it.    
    412  * Parameters:
    413  *      unit       - (IN)SOC unit number.
    414  * Returns:
    415  *      BCM_E_XXX
    416  * Notes:
    417  */
    418 int
    419 _bcm_fb2_priority_map_init(int unit)
    420 {
    421     int          priority;
    422     int          cfi;
    423     bcm_color_t  color;
    424     bcm_port_t   port;
    425     bcm_color_t  color_array[] = {bcmColorGreen, bcmColorYellow, bcmColorRed};
    426     int          index;
    427     bcm_pbmp_t   all_pbmp;
    428 
    429 #ifdef BCM_WARM_BOOT_SUPPORT
    430     if (SOC_WARM_BOOT(unit)) {
    431         return (BCM_E_NONE);
    432     }
    433 #endif /* BCM_WARM_BOOT_SUPPORT */
    434 
    435     BCM_PBMP_CLEAR(all_pbmp);
    436     BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
    437 
    438 #ifdef BCM_KATANA2_SUPPORT
    439     if (soc_feature(unit, soc_feature_linkphy_coe) ||
    440         soc_feature(unit, soc_feature_subtag_coe)) {
    441         _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
    442     }
    443     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
    444         BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
    445     }
    446 #endif
    447 
    448     if (SOC_IS_TRIUMPH(unit) || SOC_IS_VALKYRIE(unit)
    449         || !soc_feature(unit, soc_feature_qos_profile)) {
    450         PBMP_ITER(all_pbmp, port) {
    451             for (cfi = 0; cfi <= 1; cfi++) {
    452                 for (priority = 0; priority <= 7; priority++){
    453                     color = _BCM_COLOR_DECODING(unit, cfi);
    454                     BCM_IF_ERROR_RETURN
    455                         (bcm_esw_port_vlan_priority_map_set
    456                             (unit, port, priority, cfi, priority, color));
    457                 }
    458             }
    459         }
    460     }
    461 
    462     PBMP_ITER(all_pbmp, port) {
    463 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    464         if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) {
    465             BCM_IF_ERROR_RETURN(_bcm_esw_egr_port_tab_set(unit, port,
    466                               EGR_QOS_PROFILE_INDEXf,0));
    467         } else if (SOC_IS_TRIDENT3X(unit)) {
    468             BCM_IF_ERROR_RETURN(_bcm_esw_egr_port_tab_set(unit, port,
    469                               EGR_QOS_PROFILE_INDEXf,0));
    470         } else
    471 #endif
    472         {
    473             for (index = 0; index < 3; index++) {
    474                 color = color_array[index];
    475                 for (priority = 0; priority <= 7; priority++) {
    476                     cfi = (color == bcmColorRed) ? 1 : 0;
    477                     BCM_IF_ERROR_RETURN
    478                         (bcm_esw_port_vlan_priority_unmap_set(unit, port, priority, 
    479                                                               color, priority, cfi));
    480                 }
    481             }    
    482         }
    483     }
    484     return (BCM_E_NONE);
    485 }
    486 
    487 /*
    488  * Function :
    489  *    _bcm_fb2_outer_tpid_entry_get
    490  * 
    491  * Purpose  :
    492  *    Get tpid value for tpid entry index . 
    493  *
    494  * Parameters :
    495  *     unit  - (IN) BCM device number.
    496  *     tpid  - (OUT) TPID value.
    497  *     index - (IN) Entry index.
    498  *
    499  * Return :
    500  *    BCM_E_XXX
    501  */
    502 int
    503 _bcm_fb2_outer_tpid_entry_get(int unit, uint16 *tpid, int index) 
    504 {
    505     if ((index < 0) || (index >= BCM_MAX_TPID_ENTRIES) ||
    506         (OUTER_TPID_REF_COUNT(unit, index) <= 0)) {
    507         return (BCM_E_PARAM);
    508     }
    509 
    510     *tpid = OUTER_TPID_ENTRY(unit, index);
    511     return (BCM_E_NONE);
    512 }
    513 
    514 /*
    515  * Function :
    516  *    _bcm_fb2_outer_tpid_entry_delete
    517  * 
    518  * Purpose  :
    519  *    Delete tpid entry by index.
    520  *
    521  * Parameters :
    522  *     unit  - (IN) BCM device number.
    523  *     index - (IN) Entry index.
    524  *
    525  * Return :
    526  *    BCM_E_XXX
    527  */
    528 int
    529 _bcm_fb2_outer_tpid_entry_delete(int unit, int index) 
    530 {
    531     int rv = BCM_E_NONE; 
    532 
    533     _bcm_fb2_outer_tpid_tab_lock(unit);
    534 
    535     if ((index < 0) || (index >= BCM_MAX_TPID_ENTRIES) ||
    536         (OUTER_TPID_REF_COUNT(unit, index) <= 0)) {
    537         rv = BCM_E_PARAM;
    538         goto _cleanup_bcm_fb2_outer_tpid_entry_delete;
    539     }
    540 
    541     OUTER_TPID_REF_COUNT(unit, index)--;
    542 
    543 #if defined(BCM_TRX_SUPPORT)
    544     if ((0 == OUTER_TPID_REF_COUNT(unit, index)) && (SOC_IS_SC_CQ(unit)) &&
    545         (0 == SOC_IS_SHADOW(unit))) {
    546         rv = _bcm_trx_egr_src_port_outer_tpid_set(unit, index, FALSE);
    547         if (BCM_FAILURE(rv)) {
    548             goto _cleanup_bcm_fb2_outer_tpid_entry_delete;
    549         }
    550     }
    551 #endif /* BCM_TRX_SUPPORT */
    552 
    553 _cleanup_bcm_fb2_outer_tpid_entry_delete:
    554     _bcm_fb2_outer_tpid_tab_unlock(unit);
    555     return (rv);
    556 }
    557 
    558 /*
    559  * Function :
    560  *    _bcm_fb2_outer_tpid_default_get
    561  * 
    562  * Purpose  :
    563  *    Get system default tpid value. 
    564  *
    565  * Parameters :
    566  *     unit  - (IN) BCM device number.
    567  *
    568  * Return :
    569  *    BCM_E_XXX
    570  */
    571 uint16
    572 _bcm_fb2_outer_tpid_default_get(int unit)
    573 {
    574     COMPILER_REFERENCE(unit);
    575     return 0x8100;
    576 }
    577 
    578 /*
    579  * Function :
    580  *    _bcm_fb2_outer_tpid_lkup
    581  * 
    582  * Purpose  :
    583  *    Get tpid entry index for specific tpid value.
    584  *
    585  * Parameters :
    586  *     unit  - (IN) BCM device number.
    587  *     tpid  - (IN) TPID value.
    588  *     index - (OUT) Entry index.
    589  *
    590  * Return :
    591  *    BCM_E_XXX
    592  */
    593 int
    594 _bcm_fb2_outer_tpid_lkup(int unit, uint16 tpid, int *index)
    595 {
    596     int i;
    597 
    598     for (i = 0; i < BCM_MAX_TPID_ENTRIES; i++) {
    599         if (OUTER_TPID_ENTRY(unit, i) == tpid) {
    600             *index = i;
    601             return BCM_E_NONE;
    602         }
    603     }
    604 
    605     return BCM_E_NOT_FOUND;
    606 }
    607 
    608 /*
    609  * Function:
    610  *      _bcm_fb2_outer_tpid_entry_add 
    611  * Purpose:
    612  *      Add a new TPID entry.
    613  *      Allocate and initialize memory to cache tpid entries.
    614  *      Initialize lock for cached tpid entries.
    615  * Parameters:
    616  *      unit       - (IN) SOC unit number.
    617  *      tpid       - (IN) TPID to be added.
    618  *      index      - (OUT) Index where the the new TPID is added.
    619  * Returns:
    620  *      BCM_E_XXX
    621  * Notes:
    622  *      If the same TPID already exists, simple increase the
    623  * reference count of the cached entry. Otherwise, add the entry
    624  * to the cached table and write the new entry to hardware.
    625  * Only four distinct TPID values are currently supported.
    626  */
    627 int
    628 _bcm_fb2_outer_tpid_entry_add(int unit, uint16 tpid, int *index)
    629 {
    630     int i, free_index;
    631     uint32 tpid_reg = 0;
    632     int rv = BCM_E_NONE;
    633     soc_reg_t ing_outer_tpid_reg[] = {
    634         ING_OUTER_TPID_0r,
    635         ING_OUTER_TPID_1r,
    636         ING_OUTER_TPID_2r,
    637         ING_OUTER_TPID_3r
    638     };
    639 
    640     _bcm_fb2_outer_tpid_tab_lock(unit);
    641     /*
    642      * Search for an existing entry.
    643      */
    644     free_index = -1;
    645     for (i = 0; i < BCM_MAX_TPID_ENTRIES; i++) {
    646         if (OUTER_TPID_ENTRY(unit, i) == tpid) {
    647             OUTER_TPID_REF_COUNT(unit, i)++;
    648             *index = i;
    649             goto _cleanup_bcm_fb2_outer_tpid_entry_add;
    650         }
    651         if (OUTER_TPID_REF_COUNT(unit, i) == 0) {
    652             free_index = i;
    653         }
    654     } 
    655 
    656     if (free_index < 0) {
    657         rv = BCM_E_RESOURCE;
    658         goto _cleanup_bcm_fb2_outer_tpid_entry_add;
    659     }
    660 
    661     /* 
    662      * Insert the new configuration into tpid table if a free
    663      * entry is available.
    664      */
    665     if (SOC_IS_TRIDENT3X(unit)) {
    666         soc_reg_field_set(unit, ing_outer_tpid_reg[free_index], &tpid_reg, TPIDf, tpid);
    667         rv = soc_reg32_set(unit, ing_outer_tpid_reg[free_index], REG_PORT_ANY, 0, tpid_reg);
    668     } else {
    669     soc_reg_field_set(unit, ING_OUTER_TPIDr, &tpid_reg, TPIDf, tpid);
    670     rv = WRITE_ING_OUTER_TPIDr(unit, free_index, tpid_reg);
    671     }
    672     if (BCM_FAILURE(rv)) {
    673         goto _cleanup_bcm_fb2_outer_tpid_entry_add;
    674     }
    675 #if defined(BCM_TOMAHAWK_SUPPORT)
    676     /* Skip EGR_OUTER_TPID for low latency mode, will be set via EGR_VLAN_TAG_ACTION_FOR_BYPASSr */
    677     if (!(soc_feature(unit, soc_feature_fast_egr_vlan_action))) {
    678         rv = WRITE_EGR_OUTER_TPIDr(unit, free_index, tpid_reg);
    679     }
    680 #else
    681     rv = WRITE_EGR_OUTER_TPIDr(unit, free_index, tpid_reg);
    682 #endif
    683     if (BCM_FAILURE(rv)) {
    684         goto _cleanup_bcm_fb2_outer_tpid_entry_add;
    685     }
    686 #if defined(BCM_TRIDENT3_SUPPORT)
    687     if (SOC_REG_IS_VALID(unit, EGR_PARSER_OUTER_TPIDr)) {
    688         rv = WRITE_EGR_PARSER_OUTER_TPIDr(unit, free_index, tpid_reg);
    689     }
    690     if (BCM_FAILURE(rv)) {
    691         goto _cleanup_bcm_fb2_outer_tpid_entry_add;
    692     }
    693 #endif
    694 #ifdef BCM_TRIUMPH_SUPPORT
    695     if (SOC_REG_IS_VALID(unit, ING_MPLS_TPID_0r)) {
    696         rv = WRITE_ING_MPLS_TPIDr(unit, free_index, tpid_reg);
    697         if (BCM_FAILURE(rv)) {
    698             goto _cleanup_bcm_fb2_outer_tpid_entry_add;
    699         }
    700     }
    701 #endif /* BCM_TRIUMPH_SUPPORT */
    702 #if defined(BCM_TRX_SUPPORT)
    703     if (SOC_IS_SC_CQ(unit)) {
    704         rv = _bcm_trx_egr_src_port_outer_tpid_set(unit, free_index, TRUE);
    705         if (BCM_FAILURE(rv)) {
    706             goto _cleanup_bcm_fb2_outer_tpid_entry_add;
    707         }
    708     }
    709 #endif /* BCM_TRX_SUPPORT */
    710     OUTER_TPID_ENTRY(unit, free_index) = tpid;
    711     OUTER_TPID_REF_COUNT(unit, free_index)++;
    712     *index = free_index;
    713 
    714 _cleanup_bcm_fb2_outer_tpid_entry_add:
    715     _bcm_fb2_outer_tpid_tab_unlock(unit);
    716     return rv;
    717 }
    718 
    719 /*
    720  * Function :
    721  *    _bcm_fb2_outer_tpid_tab_lock
    722  * 
    723  * Purpose  :
    724  *    Lock TPID values table.   
    725  *
    726  * Parameters :
    727  *     unit  - (IN) BCM device number.
    728  *
    729  * Return :
    730  *    BCM_E_XXX
    731  */
    732 int
    733 _bcm_fb2_outer_tpid_tab_lock(int unit) 
    734 {
    735     return BCM_FB2_TPID_LOCK(unit);
    736 }
    737 
    738 /*
    739  * Function :
    740  *    _bcm_fb2_outer_tpid_tab_unlock
    741  * 
    742  * Purpose  :
    743  *    Unlock TPID values table.   
    744  *
    745  * Parameters :
    746  *     unit  - (IN) BCM device number.
    747  *
    748  * Return :
    749  *    BCM_E_XXX
    750  */
    751 int
    752 _bcm_fb2_outer_tpid_tab_unlock(int unit) 
    753 {
    754     return BCM_FB2_TPID_UNLOCK(unit); 
    755 }
    756 
    757 /*
    758  * Function :
    759  *    _bcm_fb2_outer_tpid_tab_ref_count_add
    760  *
    761  * Purpose  :
    762  *    update tpid value reference count.
    763  *
    764  * Parameters :
    765  *     unit  - (IN) BCM device number.
    766  *     index - (IN) Table entry index. 
    767  *     count - (IN) Reference counter update diff.
    768  * 
    769  * Return :
    770  *    BCM_E_XXX
    771  */
    772 int
    773 _bcm_fb2_outer_tpid_tab_ref_count_add(int unit, int index, int count)
    774 {
    775     if (index >= BCM_MAX_TPID_ENTRIES) {
    776         return BCM_E_PARAM;
    777     }
    778     if ((OUTER_TPID_REF_COUNT(unit, index) + count) < 0) {
    779         return BCM_E_PARAM;
    780     }  
    781     _bcm_fb2_outer_tpid_tab_lock(unit);
    782 
    783     OUTER_TPID_REF_COUNT(unit, index) += count; 
    784 
    785     _bcm_fb2_outer_tpid_tab_unlock(unit);
    786 
    787     return BCM_E_NONE;
    788 }
    789 
    790 /* Flags for _vlan_profile_t.profile_flags. */
    791 #define _BCM_VLAN_PROFILE_PHB2_ENABLE         0x00000001
    792 #define _BCM_VLAN_PROFILE_PHB2_USE_INNER_TAG  0x00000002
    793 #define _BCM_VLAN_PROFILE_TRUST_DOT1P         0x00000004
    794 
    795 /*
    796  * Vlan profile structure.  
    797  *
    798  * Purpose  : Track per vlan configuration. 
    799  */
    800 typedef struct _vlan_profile_s {
    801     uint16                 outer_tpid; 
    802     uint32                 flags; 
    803     bcm_vlan_mcast_flood_t ip6_mcast_flood_mode; 
    804     bcm_vlan_mcast_flood_t ip4_mcast_flood_mode; 
    805     bcm_vlan_mcast_flood_t l2_mcast_flood_mode; 
    806 #if defined (BCM_TRX_SUPPORT)
    807     _trx_vlan_block_t      block;
    808 #endif /* BCM_TRX_SUPPORT */
    809     int                    qm_ptr;
    810     int                    trust_dot1p_ptr;
    811     uint32                 profile_flags; /* _BCM_VLAN_PROFILE_XXX */
    812     int                    ref_count;
    813 #if defined (BCM_TRX_SUPPORT)
    814     bcm_vlan_protocol_packet_ctrl_t   protocol_pkt;
    815 #endif /* BCM_TRX_SUPPORT */
    816 #if defined (BCM_HURRICANE3_SUPPORT)
    817     uint32                 learn_flags;   /* VLAN-based Learn control flags */
    818 #endif /* BCM_HURRICANE3_SUPPORT */
    819 } _vlan_profile_t;
    820 
    821 static _vlan_profile_t (*_vlan_profile[BCM_MAX_NUM_UNITS])[];
    822 
    823 #define VLAN_PROFILE(_unit_) _vlan_profile[_unit_]
    824 
    825 #define VLAN_PROFILE_ENTRY(_unit_, _idx_) (*VLAN_PROFILE(_unit_))[(_idx_)]
    826        
    827 #define VLAN_PROFILE_REF_COUNT(_unit_, _idx_) \
    828             VLAN_PROFILE_ENTRY(_unit_, _idx_).ref_count 
    829 
    830 #if defined(BCM_EASY_RELOAD_SUPPORT)
    831 typedef struct _vlan_profile_er_s {
    832     uint8      profile_num;
    833 } _vlan_profile_er_t;
    834 
    835 static _vlan_profile_er_t (*_vlan_profile_er[BCM_MAX_NUM_UNITS])[];
    836 
    837 #define VLAN_PROFILE_ER(_unit_) (_vlan_profile_er[_unit_])
    838 #define VLAN_PROFILE_PTR_ER(unit, vlan) \
    839                          ((*_vlan_profile_er[unit])[vlan].profile_num)
    840 #endif
    841 
    842 /*
    843  * Function :
    844  *    _vlan_profile_idx_get
    845  *
    846  * Purpose  :
    847  *    Get programmed vlan profile index.
    848  *
    849  * Parameters :
    850  *     unit        - (IN) BCM device number.
    851  *     mem         - (IN) Memory name.  
    852  *     field       - (IN) VLAN profile index field.
    853  *     buf         - (IN) HW entry buffer. 
    854  *     vlan        - (IN) Vlan id profile attached.
    855  *     profile_idx - (OUT) Profile index.
    856  * 
    857  * Return :
    858  *    BCM_E_XXX
    859  */
    860 STATIC int 
    861 _vlan_profile_idx_get(int unit, soc_mem_t mem, soc_field_t field,
    862                       uint32 *buf, bcm_vlan_t vlan, int *profile_index)
    863 {
    864     uint32 hw_buf[SOC_MAX_MEM_FIELD_WORDS];
    865     uint32 *hw_buf_ptr;
    866     int    rv;
    867 
    868     /* Input parameters check. */
    869     if (NULL == profile_index) {
    870         return (BCM_E_PARAM);
    871     }
    872 
    873 #if defined(BCM_EASY_RELOAD_SUPPORT)
    874     if (SOC_IS_RELOADING(unit)) {
    875         /*
    876          * Use VLAN_PROFILE_ER() as a write-through cache 
    877          * for VLAN profile pointers during easy reload
    878          */
    879         *profile_index = VLAN_PROFILE_PTR_ER(unit, vlan);
    880     } else 
    881 #endif
    882     {
    883         if (NULL == buf) {
    884             rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, vlan, hw_buf);
    885             BCM_IF_ERROR_RETURN(rv);
    886             hw_buf_ptr = hw_buf;
    887         } else {
    888             hw_buf_ptr = buf;
    889         }
    890         if (0 == soc_mem_field32_get(unit, mem, hw_buf_ptr, VALIDf)) {
    891             return BCM_E_NOT_FOUND;
    892         }
    893         *profile_index = soc_mem_field32_get(unit, mem, hw_buf_ptr, field);
    894     }
    895     return (BCM_E_NONE);
    896 }
    897 
    898 /*
    899  * Function :
    900  *    _vlan_profile_idx_set
    901  *
    902  * Purpose  :
    903  *    Set vlan profile index in vlan table.
    904  *
    905  * Parameters :
    906  *     unit        - (IN) BCM device number.
    907  *     mem         - (IN) Memory name.  
    908  *     field       - (IN) VLAN profile index field.
    909  *     buf         - (IN) HW entry buffer. 
    910  *     vlan        - (IN) Vlan id profile attached.
    911  *     profile_idx - (IN) Profile index.
    912  * 
    913  * Return :
    914  *    BCM_E_XXX
    915  */
    916 STATIC int 
    917 _vlan_profile_idx_set(int unit, soc_mem_t mem, soc_field_t field,
    918                       uint32 *buf, bcm_vlan_t vlan, int profile_index)
    919 {
    920     /* Input parameters check. */
    921     if (NULL == buf) {
    922         return (BCM_E_PARAM);
    923     }
    924 
    925 #if defined(BCM_EASY_RELOAD_SUPPORT)
    926     if (SOC_IS_RELOADING(unit)) {
    927         /*
    928          * Use VLAN_PROFILE_ER() as a write-through cache 
    929          * for VLAN profile pointers during easy reload
    930          */
    931         VLAN_PROFILE_PTR_ER(unit, vlan) = (uint8) profile_index;
    932     } else 
    933 #endif
    934     {
    935         soc_mem_field32_set(unit, mem, buf, field, profile_index);
    936     }
    937     return (BCM_E_NONE);
    938 }
    939 
    940   /*
    941   * Function:
    942   *      _bcm_xgs3_protocol_pkt_ctrl_get
    943   * Purpose:
    944   *      function to get protocol packet action for given protocol
    945   *      control register table index.
    946   * Parameters:
    947   *      unit - (IN) StrataSwitch PCI device unit number (driver internal).
    948   *      proto_index - (IN) index in PROTOCOL_PKT_CONTROLr and 
    949   *                                         IGMP_MLD_PKT_CONTROLr
    950   *      protocol_pkt- (OUT) protocol packet actions configured
    951   * Returns:
    952   *      BCM_E_NONE - protocol packet action get is successful.
    953   *      BCM_E_XXX  - Other error
    954   * Notes:
    955   *      None.
    956   */
    957 int
    958 _bcm_xgs3_protocol_pkt_ctrl_get(int unit, int proto_index,
    959                                 bcm_vlan_protocol_packet_ctrl_t *protocol_pkt)
    960 {
    961 #if defined (BCM_TRX_SUPPORT)
    962     if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl)) {
    963         soc_reg_t  reg;
    964         uint64     regval;
    965         uint32     value = 0;
    966         int        pkt_action = 0;
    967     
    968         COMPILER_64_ZERO(regval);
    969     
    970         reg = PROTOCOL_PKT_CONTROLr;
    971         BCM_IF_ERROR_RETURN
    972             (soc_reg_get(unit, reg, REG_PORT_ANY, proto_index, &regval));
    973     
    974         pkt_action = 0; 
    975         if (SOC_REG_FIELD_VALID(unit, reg, ARP_REPLY_TO_CPUf)) {
    976             value = soc_reg64_field32_get(unit, reg, regval, ARP_REPLY_TO_CPUf);
    977             pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0;
    978         }
    979         if (SOC_REG_FIELD_VALID(unit, reg, ARP_REPLY_DROPf)) {
    980             value = soc_reg64_field32_get(unit, reg, regval, ARP_REPLY_DROPf);
    981             pkt_action |= value ? BCM_VLAN_PROTO_PKT_DROP_ENABLE : 0;
    982         }
    983         protocol_pkt->arp_reply_action = pkt_action;
    984     
    985         pkt_action = 0; 
    986         if (SOC_REG_FIELD_VALID(unit, reg, ARP_REQUEST_TO_CPUf)) {
    987             value = soc_reg64_field32_get(unit, reg, regval,
    988                                           ARP_REQUEST_TO_CPUf);
    989             pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0;
    990         }
    991         if (SOC_REG_FIELD_VALID(unit, reg, ARP_REQUEST_DROPf)) {
    992             value = soc_reg64_field32_get(unit, reg, regval, ARP_REQUEST_DROPf);
    993             pkt_action |= value ? BCM_VLAN_PROTO_PKT_DROP_ENABLE : 0;
    994         }
    995         protocol_pkt->arp_request_action = pkt_action;
    996         
    997         pkt_action = 0; 
    998         if (SOC_REG_FIELD_VALID(unit, reg, ND_PKT_TO_CPUf)) {
    999             value = soc_reg64_field32_get(unit, reg, regval, ND_PKT_TO_CPUf);
   1000             pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0;
   1001         }
   1002         if (SOC_REG_FIELD_VALID(unit, reg, ND_PKT_DROPf)) {
   1003             value = soc_reg64_field32_get(unit, reg, regval, ND_PKT_DROPf);
   1004             pkt_action |= value ? BCM_VLAN_PROTO_PKT_DROP_ENABLE : 0;
   1005         }
   1006         protocol_pkt->nd_action = pkt_action;
   1007     
   1008         pkt_action = 0; 
   1009         if (SOC_REG_FIELD_VALID(unit, reg, DHCP_PKT_TO_CPUf)) {
   1010             value = soc_reg64_field32_get(unit, reg, regval, DHCP_PKT_TO_CPUf);
   1011             pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0;
   1012         }
   1013         if (SOC_REG_FIELD_VALID(unit, reg, DHCP_PKT_DROPf)) {
   1014             value = soc_reg64_field32_get(unit, reg, regval, DHCP_PKT_DROPf);
   1015             pkt_action |= value ? BCM_VLAN_PROTO_PKT_DROP_ENABLE : 0;
   1016         }
   1017         protocol_pkt->dhcp_action = pkt_action;
   1018     
   1019         pkt_action = 0;
   1020         if (SOC_REG_FIELD_VALID(unit, reg, MMRP_PKT_TO_CPUf)) {
   1021             value = soc_reg64_field32_get(unit, reg, regval, MMRP_PKT_TO_CPUf);
   1022             pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0;
   1023         }
   1024         if (SOC_REG_FIELD_VALID(unit, reg, MMRP_FWD_ACTIONf)) {
   1025             value = soc_reg64_field32_get(unit, reg, regval, MMRP_FWD_ACTIONf);
   1026             pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE :
   1027                           (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE :
   1028                                          BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   1029         }
   1030         protocol_pkt->mmrp_action = pkt_action;
   1031         
   1032         pkt_action = 0;
   1033         if (SOC_REG_FIELD_VALID(unit, reg, SRP_PKT_TO_CPUf)) {
   1034             value = soc_reg64_field32_get(unit, reg, regval, SRP_PKT_TO_CPUf);
   1035             pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0;
   1036         }
   1037         if (SOC_REG_FIELD_VALID(unit, reg, SRP_FWD_ACTIONf)) {
   1038             value = soc_reg64_field32_get(unit, reg, regval, SRP_FWD_ACTIONf);
   1039             pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE :
   1040                           (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE :
   1041                                          BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   1042         }
   1043         protocol_pkt->srp_action = pkt_action;
   1044     
   1045         reg = IGMP_MLD_PKT_CONTROLr;
   1046         BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, proto_index, 
   1047                                         &regval));
   1048 
   1049         pkt_action = 0; 
   1050         if (SOC_REG_FIELD_VALID(unit, reg, IGMP_REP_LEAVE_TO_CPUf)) {
   1051             value = soc_reg64_field32_get(unit, reg, regval,
   1052                                           IGMP_REP_LEAVE_TO_CPUf);
   1053             pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0;
   1054         }
   1055         if (SOC_REG_FIELD_VALID(unit, reg, IGMP_REP_LEAVE_FWD_ACTIONf)) {
   1056             value = soc_reg64_field32_get(unit, reg, regval,
   1057                                           IGMP_REP_LEAVE_FWD_ACTIONf);
   1058             pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE :
   1059                           (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE :
   1060                                          BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   1061         }
   1062         protocol_pkt->igmp_report_leave_action = pkt_action;
   1063         
   1064         pkt_action = 0; 
   1065         if (SOC_REG_FIELD_VALID(unit, reg, IGMP_QUERY_TO_CPUf)) {
   1066             value = soc_reg64_field32_get(unit, reg, regval,
   1067                                           IGMP_QUERY_TO_CPUf);
   1068             pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0;
   1069         }
   1070         if (SOC_REG_FIELD_VALID(unit, reg, IGMP_QUERY_FWD_ACTIONf)) {
   1071             value = soc_reg64_field32_get(unit, reg, regval,
   1072                                           IGMP_QUERY_FWD_ACTIONf);
   1073             pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE :
   1074                           (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE :
   1075                                          BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   1076         }
   1077         protocol_pkt->igmp_query_action = pkt_action;
   1078         pkt_action = 0; 
   1079         if (SOC_REG_FIELD_VALID(unit, reg, IGMP_UNKNOWN_MSG_TO_CPUf)) {
   1080             value = soc_reg64_field32_get(unit, reg, regval,
   1081                                           IGMP_UNKNOWN_MSG_TO_CPUf);
   1082             pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0;
   1083         }
   1084         if (SOC_REG_FIELD_VALID(unit, reg, IGMP_UNKNOWN_MSG_FWD_ACTIONf)) {
   1085             value = soc_reg64_field32_get(unit, reg, regval,
   1086                                           IGMP_UNKNOWN_MSG_FWD_ACTIONf);
   1087             pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE :
   1088                           (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE :
   1089                                          BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   1090         }
   1091         protocol_pkt->igmp_unknown_msg_action = pkt_action;
   1092         pkt_action = 0; 
   1093         if (SOC_REG_FIELD_VALID(unit, reg, MLD_REP_DONE_TO_CPUf)) {
   1094             value = soc_reg64_field32_get(unit, reg, regval,
   1095                                           MLD_REP_DONE_TO_CPUf);
   1096             pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0;
   1097         }
   1098         if (SOC_REG_FIELD_VALID(unit, reg, MLD_REP_DONE_FWD_ACTIONf)) {
   1099             value = soc_reg64_field32_get(unit, reg, regval,
   1100                                           MLD_REP_DONE_FWD_ACTIONf);
   1101             pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE :
   1102                           (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE :
   1103                                          BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   1104         }
   1105         protocol_pkt->mld_report_done_action = pkt_action;
   1106         pkt_action = 0; 
   1107         if (SOC_REG_FIELD_VALID(unit, reg, MLD_QUERY_TO_CPUf)) {
   1108             value = soc_reg64_field32_get(unit, reg, regval, MLD_QUERY_TO_CPUf);
   1109             pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0;
   1110         }
   1111         if (SOC_REG_FIELD_VALID(unit, reg, MLD_QUERY_FWD_ACTIONf)) {
   1112             value = soc_reg64_field32_get(unit, reg, regval,
   1113                                           MLD_QUERY_FWD_ACTIONf);
   1114             pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE :
   1115                           (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE :
   1116                                          BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   1117         }
   1118         protocol_pkt->mld_query_action = pkt_action;
   1119         pkt_action = 0; 
   1120         if (SOC_REG_FIELD_VALID(unit, reg, IPV4_RESVD_MC_PKT_TO_CPUf)) {
   1121             value = soc_reg64_field32_get(unit, reg, regval,
   1122                                           IPV4_RESVD_MC_PKT_TO_CPUf);
   1123             pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0;
   1124         }
   1125         if (SOC_REG_FIELD_VALID(unit, reg, IPV4_RESVD_MC_PKT_FWD_ACTIONf)) {
   1126             value = soc_reg64_field32_get(unit, reg, regval,
   1127                                           IPV4_RESVD_MC_PKT_FWD_ACTIONf);
   1128             pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE :
   1129                           (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE :
   1130                                          BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   1131         }
   1132         protocol_pkt->ip4_rsvd_mc_action = pkt_action;
   1133         pkt_action = 0; 
   1134         if (SOC_REG_FIELD_VALID(unit, reg, IPV6_RESVD_MC_PKT_TO_CPUf)) {
   1135             value = soc_reg64_field32_get(unit, reg, regval,
   1136                                           IPV6_RESVD_MC_PKT_TO_CPUf);
   1137             pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0;
   1138         }
   1139         if (SOC_REG_FIELD_VALID(unit, reg, IPV6_RESVD_MC_PKT_FWD_ACTIONf)) {
   1140             value = soc_reg64_field32_get(unit, reg, regval,
   1141                                           IPV6_RESVD_MC_PKT_FWD_ACTIONf);
   1142             pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE :
   1143                           (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE :
   1144                                          BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   1145         }
   1146         protocol_pkt->ip6_rsvd_mc_action = pkt_action;
   1147         pkt_action = 0; 
   1148         if (SOC_REG_FIELD_VALID(unit, reg, IPV4_MC_ROUTER_ADV_PKT_TO_CPUf)) {
   1149             value = soc_reg64_field32_get(unit, reg, regval,
   1150                                           IPV4_MC_ROUTER_ADV_PKT_TO_CPUf);
   1151             pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0;
   1152         }
   1153         if (SOC_REG_FIELD_VALID(unit, reg,IPV4_MC_ROUTER_ADV_PKT_FWD_ACTIONf)) {
   1154             value = soc_reg64_field32_get(unit, reg, regval,
   1155                                           IPV4_MC_ROUTER_ADV_PKT_FWD_ACTIONf);
   1156             pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE :
   1157                           (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE :
   1158                                          BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   1159         }
   1160         protocol_pkt->ip4_mc_router_adv_action = pkt_action;
   1161         pkt_action = 0; 
   1162         if (SOC_REG_FIELD_VALID(unit, reg, IPV6_MC_ROUTER_ADV_PKT_TO_CPUf)) {
   1163             value = soc_reg64_field32_get(unit, reg, regval,
   1164                                           IPV6_MC_ROUTER_ADV_PKT_TO_CPUf);
   1165             pkt_action |= value ? BCM_VLAN_PROTO_PKT_TOCPU_ENABLE : 0;
   1166         }
   1167         if (SOC_REG_FIELD_VALID(unit, reg,IPV6_MC_ROUTER_ADV_PKT_FWD_ACTIONf)) {
   1168             value = soc_reg64_field32_get(unit, reg, regval,
   1169                                           IPV6_MC_ROUTER_ADV_PKT_FWD_ACTIONf);
   1170             pkt_action |= (value == 2) ? BCM_VLAN_PROTO_PKT_FLOOD_ENABLE :
   1171                           (value == 1) ? BCM_VLAN_PROTO_PKT_DROP_ENABLE :
   1172                                          BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   1173         }
   1174         protocol_pkt->ip6_mc_router_adv_action = pkt_action;
   1175         
   1176         value = 0;
   1177         if (SOC_REG_FIELD_VALID(unit, reg, PFM_RULE_APPLYf)) {
   1178             value = soc_reg64_field32_get(unit, reg, regval,
   1179                                             PFM_RULE_APPLYf);
   1180         }
   1181         protocol_pkt->flood_action_according_to_pfm = value ? TRUE : FALSE;
   1182 
   1183         return BCM_E_NONE;
   1184     }
   1185 #endif /* BCM_TRX_SUPPORT */
   1186     return BCM_E_UNAVAIL;
   1187 }
   1188 
   1189  /*
   1190  * Function:
   1191  *      _bcm_xgs3_protocol_pkt_ctrl_set
   1192  * Purpose:
   1193  *      function to set protocol packet action for given protocol
   1194  *      control register table index.
   1195  *      
   1196  * Parameters:
   1197  *      unit - (IN) StrataSwitch PCI device unit number (driver internal).
   1198  *      vlan_profile_index - (IN) index in vlan_profile table
   1199  *      protocol_pkt- protocol packet actions to be configured
   1200  *      protocol_pkt_index (OUT) - the index in PROTOCOL_PKT_CONTROLr
   1201  *                    and IGPM_PLD_PKT_CONTROLr
   1202  * Returns:
   1203  *      BCM_E_NONE - protocol packet action configuration is successful.
   1204  *      BCM_E_XXX  - Other error
   1205  * Notes:
   1206  *      None.
   1207  */
   1208 int
   1209 _bcm_xgs3_protocol_pkt_ctrl_set(int unit, int old_protocol_pkt_index,
   1210                                 bcm_vlan_protocol_packet_ctrl_t *protocol_pkt,
   1211                                 int *protocol_pkt_index)
   1212 {
   1213 #if defined (BCM_TRX_SUPPORT)
   1214     if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl)) {
   1215         uint32      value;
   1216         uint32 prot_pkt_ctrl = 0, igmp_mld_pkt_ctrl = 0;
   1217         int pkt_action;
   1218     
   1219         uint32 index;
   1220         soc_reg_t reg;
   1221         int ref_count = 0;
   1222     
   1223         if (NULL == protocol_pkt) {
   1224             return BCM_E_PARAM;
   1225         }
   1226    
   1227         reg = PROTOCOL_PKT_CONTROLr;
   1228         pkt_action = protocol_pkt->arp_reply_action;
   1229         if (SOC_REG_FIELD_VALID(unit, reg, ARP_REPLY_TO_CPUf)) {
   1230             value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0;
   1231             soc_reg_field_set(unit, reg, &prot_pkt_ctrl, ARP_REPLY_TO_CPUf, 
   1232                               value);
   1233         }
   1234         if (SOC_REG_FIELD_VALID(unit, reg, ARP_REPLY_DROPf)) {
   1235             value = pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0;
   1236             soc_reg_field_set(unit, reg, &prot_pkt_ctrl, ARP_REPLY_DROPf,
   1237                               value);
   1238         }
   1239         pkt_action = protocol_pkt->arp_request_action;
   1240         if (SOC_REG_FIELD_VALID(unit, reg, ARP_REQUEST_TO_CPUf)) {
   1241             value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0;
   1242             soc_reg_field_set(unit, reg, &prot_pkt_ctrl,
   1243                     ARP_REQUEST_TO_CPUf, value);
   1244         }
   1245         if (SOC_REG_FIELD_VALID(unit, reg, ARP_REQUEST_DROPf)) {
   1246             value = pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0;
   1247             soc_reg_field_set(unit, reg, &prot_pkt_ctrl, ARP_REQUEST_DROPf, 
   1248                               value);
   1249         }
   1250         pkt_action = protocol_pkt->nd_action;
   1251         if (SOC_REG_FIELD_VALID(unit, reg, ND_PKT_TO_CPUf)) {
   1252             value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0;
   1253             soc_reg_field_set(unit, reg, &prot_pkt_ctrl, ND_PKT_TO_CPUf, value);
   1254         }
   1255         if (SOC_REG_FIELD_VALID(unit, reg, ND_PKT_DROPf)) {
   1256             value = pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0;
   1257             soc_reg_field_set(unit, reg, &prot_pkt_ctrl, ND_PKT_DROPf, value);
   1258         }
   1259         pkt_action = protocol_pkt->dhcp_action;
   1260         if (SOC_REG_FIELD_VALID(unit, reg, DHCP_PKT_TO_CPUf)) {
   1261             value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0;
   1262             soc_reg_field_set(unit, reg, &prot_pkt_ctrl, DHCP_PKT_TO_CPUf, 
   1263                               value);
   1264         }
   1265         if (SOC_REG_FIELD_VALID(unit, reg, DHCP_PKT_DROPf)) {
   1266             value = pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0;
   1267             soc_reg_field_set(unit, reg, &prot_pkt_ctrl, DHCP_PKT_DROPf, value);
   1268         }
   1269         pkt_action = protocol_pkt->mmrp_action;
   1270         if (SOC_REG_FIELD_VALID(unit, reg, MMRP_PKT_TO_CPUf)) {
   1271             value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0;
   1272             soc_reg_field_set(unit, reg, &prot_pkt_ctrl, MMRP_PKT_TO_CPUf, 
   1273                               value);
   1274         }
   1275         if (SOC_REG_FIELD_VALID(unit, reg, MMRP_FWD_ACTIONf)) {
   1276             value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 :
   1277                    (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0);
   1278             soc_reg_field_set(unit, reg, &prot_pkt_ctrl, MMRP_FWD_ACTIONf, 
   1279                               value);
   1280         }
   1281         pkt_action = protocol_pkt->srp_action;
   1282         if (SOC_REG_FIELD_VALID(unit, reg, SRP_PKT_TO_CPUf)) {
   1283             value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0;
   1284             soc_reg_field_set(unit, reg, &prot_pkt_ctrl, SRP_PKT_TO_CPUf, 
   1285                               value);
   1286         }
   1287         if (SOC_REG_FIELD_VALID(unit, reg, SRP_FWD_ACTIONf)) {
   1288             value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 :
   1289                    (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0);
   1290             soc_reg_field_set(unit, reg, &prot_pkt_ctrl, SRP_FWD_ACTIONf, 
   1291                               value);
   1292         }
   1293     
   1294         reg = IGMP_MLD_PKT_CONTROLr;
   1295         pkt_action = protocol_pkt->igmp_report_leave_action;
   1296         if (SOC_REG_FIELD_VALID(unit, reg, IGMP_REP_LEAVE_TO_CPUf)) {
   1297             value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0;
   1298             soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl,
   1299                     IGMP_REP_LEAVE_TO_CPUf, value);
   1300         }
   1301         if (SOC_REG_FIELD_VALID(unit, reg, IGMP_REP_LEAVE_FWD_ACTIONf)) {
   1302             value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 :
   1303                    (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0);
   1304             soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl,
   1305                     IGMP_REP_LEAVE_FWD_ACTIONf, value);
   1306         }
   1307         
   1308         pkt_action = protocol_pkt->igmp_query_action;
   1309         if (SOC_REG_FIELD_VALID(unit, reg, IGMP_QUERY_TO_CPUf)) {
   1310             value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0;
   1311             soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl, 
   1312                     IGMP_QUERY_TO_CPUf, value);
   1313         }
   1314         if (SOC_REG_FIELD_VALID(unit, reg, IGMP_QUERY_FWD_ACTIONf)) {
   1315             value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 :
   1316                    (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0);
   1317             soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl,
   1318                     IGMP_QUERY_FWD_ACTIONf, value);
   1319         }
   1320         
   1321         pkt_action = protocol_pkt->igmp_unknown_msg_action;
   1322         if (SOC_REG_FIELD_VALID(unit, reg, IGMP_UNKNOWN_MSG_TO_CPUf)) {
   1323             value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0;
   1324             soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl,
   1325                     IGMP_UNKNOWN_MSG_TO_CPUf, value);
   1326         }
   1327         if (SOC_REG_FIELD_VALID(unit, reg, IGMP_UNKNOWN_MSG_FWD_ACTIONf)) {
   1328             value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 :
   1329                    (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0);
   1330             soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl,
   1331                     IGMP_UNKNOWN_MSG_FWD_ACTIONf, value);
   1332         }
   1333     
   1334         pkt_action = protocol_pkt->mld_report_done_action;
   1335         if (SOC_REG_FIELD_VALID(unit, reg, MLD_REP_DONE_TO_CPUf)) {
   1336             value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0;
   1337             soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl,
   1338                     MLD_REP_DONE_TO_CPUf, value);
   1339         }
   1340         if (SOC_REG_FIELD_VALID(unit, reg, MLD_REP_DONE_FWD_ACTIONf)) {
   1341             value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 :
   1342                    (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0);
   1343             soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl,
   1344                     MLD_REP_DONE_FWD_ACTIONf, value);
   1345         }
   1346         
   1347         pkt_action = protocol_pkt->mld_query_action;
   1348         if (SOC_REG_FIELD_VALID(unit, reg, MLD_QUERY_TO_CPUf)) {
   1349             value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0;
   1350             soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl,
   1351                     MLD_QUERY_TO_CPUf, value);
   1352         }
   1353         if (SOC_REG_FIELD_VALID(unit, reg, MLD_QUERY_FWD_ACTIONf)) {
   1354             value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 :
   1355                    (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0);
   1356             soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl,
   1357                     MLD_QUERY_FWD_ACTIONf, value);
   1358         }
   1359     
   1360         pkt_action = protocol_pkt->ip4_rsvd_mc_action;
   1361         if (SOC_REG_FIELD_VALID(unit, reg, IPV4_RESVD_MC_PKT_TO_CPUf)) {
   1362             value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0;
   1363             soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl,
   1364                     IPV4_RESVD_MC_PKT_TO_CPUf, value);
   1365         }
   1366         if (SOC_REG_FIELD_VALID(unit, reg, IPV4_RESVD_MC_PKT_FWD_ACTIONf)) {
   1367             value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 :
   1368                    (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0);
   1369             soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl,
   1370                     IPV4_RESVD_MC_PKT_FWD_ACTIONf, value);
   1371         }
   1372     
   1373         pkt_action = protocol_pkt->ip6_rsvd_mc_action;
   1374         if (SOC_REG_FIELD_VALID(unit, reg, IPV6_RESVD_MC_PKT_TO_CPUf)) {
   1375             value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0;
   1376             soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl,
   1377                     IPV6_RESVD_MC_PKT_TO_CPUf, value);
   1378         }
   1379         if (SOC_REG_FIELD_VALID(unit, reg, IPV6_RESVD_MC_PKT_FWD_ACTIONf)) {
   1380             value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 :
   1381                    (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0);
   1382             soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl,
   1383                     IPV6_RESVD_MC_PKT_FWD_ACTIONf, value);
   1384         }
   1385     
   1386         pkt_action = protocol_pkt->ip4_mc_router_adv_action;
   1387         if (SOC_REG_FIELD_VALID(unit, reg, IPV4_MC_ROUTER_ADV_PKT_TO_CPUf)) {
   1388             value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0;
   1389             soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl,
   1390                     IPV4_MC_ROUTER_ADV_PKT_TO_CPUf, value);
   1391         }
   1392         if (SOC_REG_FIELD_VALID(unit, reg, 
   1393                                 IPV4_MC_ROUTER_ADV_PKT_FWD_ACTIONf)) {
   1394             value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 :
   1395                    (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0);
   1396             soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl,
   1397                     IPV4_MC_ROUTER_ADV_PKT_FWD_ACTIONf, value);
   1398         }
   1399     
   1400         pkt_action = protocol_pkt->ip6_mc_router_adv_action;
   1401         if (SOC_REG_FIELD_VALID(unit, reg, IPV6_MC_ROUTER_ADV_PKT_TO_CPUf)) {
   1402             value = pkt_action & BCM_VLAN_PROTO_PKT_TOCPU_ENABLE ? 1 : 0;
   1403             soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl,
   1404                     IPV6_MC_ROUTER_ADV_PKT_TO_CPUf, value);
   1405         }
   1406         if (SOC_REG_FIELD_VALID(unit, reg, 
   1407                                 IPV6_MC_ROUTER_ADV_PKT_FWD_ACTIONf)) {
   1408             value = pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE ? 2 :
   1409                    (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE ? 1 : 0);
   1410             soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl,
   1411                     IPV6_MC_ROUTER_ADV_PKT_FWD_ACTIONf, value);
   1412         }
   1413 
   1414         if (SOC_REG_FIELD_VALID(unit, reg, PFM_RULE_APPLYf)) {
   1415             value = protocol_pkt->flood_action_according_to_pfm ? 1 : 0;
   1416             soc_reg_field_set(unit, reg, &igmp_mld_pkt_ctrl,
   1417                         PFM_RULE_APPLYf, value);
   1418         }
   1419         BCM_IF_ERROR_RETURN(
   1420             _bcm_prot_pkt_ctrl_add(unit, prot_pkt_ctrl, igmp_mld_pkt_ctrl, 
   1421                                    &index));
   1422         if (old_protocol_pkt_index >= 0) { 
   1423             BCM_IF_ERROR_RETURN(_bcm_prot_pkt_ctrl_ref_count_get(
   1424                                    unit, old_protocol_pkt_index, &ref_count));
   1425             if (ref_count > 0) {
   1426                 BCM_IF_ERROR_RETURN(_bcm_prot_pkt_ctrl_delete(unit, 
   1427                                      old_protocol_pkt_index));
   1428             }
   1429         }
   1430         *protocol_pkt_index = index;
   1431         return BCM_E_NONE;
   1432     }
   1433 #endif /* BCM_TRX_SUPPORT */
   1434     return BCM_E_UNAVAIL;
   1435 }
   1436 
   1437 /*
   1438  * Function:
   1439  *    _vlan_profile_read
   1440  * 
   1441  * Purpose:
   1442  *    Read a vlan profile entry from vlan profile table.
   1443  *
   1444  * Parameters:
   1445  *     unit  - (IN) BCM device number.
   1446  *     index - (IN) Entry index.
   1447  *     entry - (IN) Vlan profile entry. 
   1448  *
   1449  * Return:
   1450  *    BCM_E_XXX
   1451  *
   1452  * Notes:
   1453  *      Only used as part of reload.
   1454  */
   1455 STATIC int 
   1456 _vlan_profile_read(int unit, int index, _vlan_profile_t *entry)
   1457 {
   1458     uint32              buf[SOC_MAX_MEM_FIELD_WORDS]; /* HW entry buffer.     */
   1459     uint32              value;                        /* Field specific value.*/
   1460     soc_mem_t           mem;          /* Vlan profile table memory.           */
   1461 #if defined (BCM_TRX_SUPPORT)
   1462     _trx_vlan_block_t   *block;       /* Vlan block profile pointer.          */
   1463     uint32 proto_index;
   1464 #endif /* BCM_TRX_SUPPORT */
   1465     int rv = BCM_E_NONE;
   1466 
   1467     /* Input parameters check. */
   1468     if ((NULL == entry) || (index < 0) ||
   1469         (index > soc_mem_index_max(unit, VLAN_PROFILE_TABm))) {
   1470         return (BCM_E_PARAM) ;
   1471     }
   1472 
   1473     /* Reset output buffer. */
   1474     sal_memset(entry, 0, sizeof(_vlan_profile_t));
   1475 
   1476     /* Reset hw buffer. */
   1477     sal_memset(buf, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32));
   1478     mem = VLAN_PROFILE_TABm;
   1479 
   1480     /* READ vlan profile table. */
   1481     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, buf);
   1482     if (BCM_FAILURE(rv)) {
   1483         return (rv);
   1484     }
   1485 
   1486     /* Enable/Disable MIM termination on a vlan. */
   1487     if (soc_mem_field_valid(unit, mem, MIM_TERM_ENABLEf)) {
   1488         if (0 == soc_mem_field32_get(unit, mem, buf, MIM_TERM_ENABLEf)) {
   1489             entry->flags |=  BCM_VLAN_MIM_TERM_DISABLE;
   1490         }
   1491     }
   1492 
   1493     /* Enable/Disable MPLS forwarding on a vlan. */
   1494     if (soc_mem_field_valid(unit, mem, MPLS_ENABLEf)) {
   1495         if (0 == soc_mem_field32_get(unit, mem, buf, MPLS_ENABLEf)) {
   1496             entry->flags |=  BCM_VLAN_MPLS_DISABLE;
   1497         }
   1498     }
   1499 
   1500     /* Drop non-unicast, broadcast or multicast packets that miss L2 lookup. */ 
   1501     if (SOC_MEM_FIELD_VALID(unit, mem, L2_NON_UCAST_DROPf)) {
   1502         if (soc_mem_field32_get(unit, mem, buf, L2_NON_UCAST_DROPf)) {
   1503             entry->flags |=  BCM_VLAN_NON_UCAST_DROP;
   1504         }
   1505     }
   1506 
   1507     /* Copy to cpu non-unicast, broadcast or multicast packets 
   1508      * that miss L2 lookup. 
   1509      */
   1510     if (SOC_MEM_FIELD_VALID(unit, mem, BCM_VLAN_NON_UCAST_TOCPU)) {
   1511         if (soc_mem_field32_get(unit, mem, buf, L2_NON_UCAST_TOCPUf)) {
   1512             entry->flags |=  BCM_VLAN_NON_UCAST_TOCPU;
   1513         }
   1514     }
   1515 
   1516     /* Drop packets that miss L2 lookup. */ 
   1517     if (SOC_MEM_FIELD_VALID(unit, mem, L2_MISS_DROPf)) {
   1518         if (soc_mem_field32_get(unit, mem, buf, L2_MISS_DROPf)) {
   1519             entry->flags |=  BCM_VLAN_UNKNOWN_UCAST_DROP;
   1520         }
   1521     }
   1522 
   1523     /* Copy to cpu packets that miss L2 lookup. */
   1524     if (SOC_REG_FIELD_VALID(unit, VLAN_PROFILE_TABr, L2_MISS_TOCPUf)) {
   1525         uint32 rval;
   1526         BCM_IF_ERROR_RETURN(
   1527             soc_reg32_get(unit, VLAN_PROFILE_TABr, REG_PORT_ANY, 0, &rval));
   1528         if (soc_reg_field_get(unit, VLAN_PROFILE_TABr, rval, L2_MISS_TOCPUf)) {
   1529             entry->flags |=  BCM_VLAN_UNKNOWN_UCAST_TOCPU;
   1530         }
   1531     } else if (SOC_MEM_FIELD_VALID(unit, mem, L2_MISS_TOCPUf)) {
   1532         if (soc_mem_field32_get(unit, mem, buf, L2_MISS_TOCPUf)) {
   1533             entry->flags |=  BCM_VLAN_UNKNOWN_UCAST_TOCPU;
   1534         }
   1535     }
   1536 
   1537     /* L3 Enable for IPv4 packets on the VLAN. */ 
   1538     if (SOC_MEM_FIELD_VALID(unit, mem, IPV4L3_ENABLEf)) {
   1539         if (0 == soc_mem_field32_get(unit, mem, buf, IPV4L3_ENABLEf)) {
   1540             entry->flags |=  BCM_VLAN_IP4_DISABLE;
   1541         }
   1542     }
   1543 
   1544     /* L3 Enable for IPv6 packets on the VLAN. */ 
   1545     if (SOC_MEM_FIELD_VALID(unit, mem, IPV6L3_ENABLEf)) {
   1546         if (0 == soc_mem_field32_get(unit, mem, buf, IPV6L3_ENABLEf)) {
   1547             entry->flags |=  BCM_VLAN_IP6_DISABLE;
   1548         }
   1549     }
   1550 
   1551     /* Enable L2-only forwarding of IPMCv4 packets on this VLAN.  */ 
   1552     if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV4_L2_ENABLEf)) {
   1553         if (0 == soc_mem_field32_get(unit, mem, buf, IPMCV4_L2_ENABLEf)) {
   1554             entry->flags |=  BCM_VLAN_IP4_MCAST_L2_DISABLE;
   1555         }
   1556     }
   1557 
   1558     /* Enable L2-only forwarding of IPMCv6 packets on this VLAN. */ 
   1559     if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV6_L2_ENABLEf)) {
   1560         if (0 == soc_mem_field32_get(unit, mem, buf, IPMCV6_L2_ENABLEf)) {
   1561             entry->flags |=  BCM_VLAN_IP6_MCAST_L2_DISABLE;
   1562         }
   1563     }
   1564 
   1565     /* IPMC Enable IPv4 packets on this VLAN.  */ 
   1566     if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV4_ENABLEf)) {
   1567         if (0 == soc_mem_field32_get(unit, mem, buf, IPMCV4_ENABLEf)) {
   1568             entry->flags |= BCM_VLAN_IP4_MCAST_DISABLE;
   1569         }
   1570     }
   1571 
   1572     /* IPMC Enable IPv6 packets on this VLAN.  */ 
   1573     if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV6_ENABLEf)) {
   1574         if (0 == soc_mem_field32_get(unit, mem, buf, IPMCV6_ENABLEf)) {
   1575             entry->flags |= BCM_VLAN_IP6_MCAST_DISABLE;
   1576         }
   1577     }
   1578 
   1579     if (soc_feature(unit, soc_feature_ipmc_unicast)) {
   1580         if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV4_UNICAST_MACDA_ENABLEf)) {
   1581             if (0 != soc_mem_field32_get(unit, mem, buf, 
   1582                     IPMCV4_UNICAST_MACDA_ENABLEf)) {
   1583                 entry->flags |= BCM_VLAN_IPMC4_UCAST_ENABLE;
   1584             }
   1585         }
   1586 
   1587         if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV6_UNICAST_MACDA_ENABLEf)) {
   1588             if (0 != soc_mem_field32_get(unit, mem, buf, 
   1589                     IPMCV6_UNICAST_MACDA_ENABLEf)) {
   1590                 entry->flags |= BCM_VLAN_IPMC6_UCAST_ENABLE;
   1591             }
   1592         }
   1593     }
   1594 
   1595     /* Enables copy to cpu when ICMP redirect packet is needed. */
   1596     if (SOC_MEM_FIELD_VALID(unit, mem, ICMP_REDIRECT_TOCPUf)) {
   1597         if (soc_mem_field32_get(unit, mem, buf, ICMP_REDIRECT_TOCPUf)) {
   1598             entry->flags |= BCM_VLAN_ICMP_REDIRECT_TOCPU;
   1599         }
   1600     }
   1601 
   1602     /* Unknown IPMC (IPMC miss) for IPv6 packets sent to CPU enable. */
   1603     if (SOC_MEM_FIELD_VALID(unit, mem, UNKNOWN_IPV6_MC_TOCPUf)) {
   1604         if (soc_mem_field32_get(unit, mem, buf, UNKNOWN_IPV6_MC_TOCPUf)) {
   1605             entry->flags |= BCM_VLAN_UNKNOWN_IP6_MCAST_TOCPU;
   1606         }
   1607     }
   1608 
   1609     /* Unknown IPMC (IPMC miss) for IPv4 packets sent to CPU enable. */
   1610     if (SOC_MEM_FIELD_VALID(unit, mem, UNKNOWN_IPV4_MC_TOCPUf)) {
   1611         if (soc_mem_field32_get(unit, mem, buf, UNKNOWN_IPV4_MC_TOCPUf)) {
   1612             entry->flags |= BCM_VLAN_UNKNOWN_IP4_MCAST_TOCPU;
   1613         }
   1614     }
   1615 
   1616     /* Outer tpid index Used when PORT_TABLE.OUTER_TPID_VERIFY, 
   1617      * is enabled and indicates which of the ING_OUTER_TPID[xx]
   1618      * register is expected to match for this VLAN
   1619      */ 
   1620     if (SOC_MEM_FIELD_VALID(unit, mem, OUTER_TPID_INDEX_MASKf)) {
   1621         int i, field_len;
   1622         value = soc_mem_field32_get(unit, mem, buf, OUTER_TPID_INDEX_MASKf);
   1623         field_len = soc_mem_field_length(unit, mem, OUTER_TPID_INDEX_MASKf);
   1624         for (i = 0; i < field_len; i++) {
   1625             if (1 << i == value) {
   1626                 value = i;
   1627                 break;
   1628             }
   1629         }
   1630         if (i == field_len) {
   1631             value = 0;
   1632         }
   1633     } else {
   1634     value = soc_mem_field32_get(unit, mem, buf, OUTER_TPID_INDEXf);
   1635     }
   1636     entry->outer_tpid= OUTER_TPID_ENTRY(unit, value); 
   1637 
   1638     /* Disable learning on this vlan. */
   1639     if (soc_mem_field32_get(unit, mem, buf, LEARN_DISABLEf)) {
   1640         entry->flags |= BCM_VLAN_LEARN_DISABLE;
   1641     }
   1642 
   1643     /* PFM value for IPv6 multicast lookups */
   1644     if (SOC_MEM_FIELD_VALID(unit, mem, L3_IPV6_PFMf)) {
   1645         value = soc_mem_field32_get(unit, mem, buf, L3_IPV6_PFMf);
   1646         rv = _bcm_vlan_mcast_pfm_to_flood_mode(unit, (int)value, 
   1647                                            &entry->ip6_mcast_flood_mode);
   1648         BCM_IF_ERROR_RETURN(rv);
   1649     }
   1650 
   1651     /* PFM value for IPv4 multicast lookups */
   1652     if (SOC_MEM_FIELD_VALID(unit, mem, L3_IPV4_PFMf)) {
   1653         value = soc_mem_field32_get(unit, mem, buf, L3_IPV4_PFMf);
   1654         rv =  _bcm_vlan_mcast_pfm_to_flood_mode(unit, (int)value, 
   1655                                             &entry->ip4_mcast_flood_mode);
   1656         BCM_IF_ERROR_RETURN(rv);
   1657     }
   1658 
   1659     /* PFM value for L2 multicast lookups */
   1660     value = soc_mem_field32_get(unit, mem, buf, L2_PFMf);
   1661     rv = _bcm_vlan_mcast_pfm_to_flood_mode(unit, (int)value, 
   1662                                            &entry->l2_mcast_flood_mode);
   1663     BCM_IF_ERROR_RETURN(rv);
   1664 
   1665 #if defined (BCM_HURRICANE3_SUPPORT)
   1666     if (SOC_MEM_FIELD_VALID(unit, mem, USE_VLAN_CMLf)) {
   1667         if (0 != soc_mem_field32_get(unit, mem, buf, USE_VLAN_CMLf)) {
   1668             entry->learn_flags = BCM_VLAN_LEARN_CONTROL_ENABLE;
   1669             value = soc_mem_field32_get(unit, mem, buf, CML_FLAGS_NEWf);
   1670             if (!(value & (1 << 0))) {
   1671                entry->learn_flags |= BCM_VLAN_LEARN_CONTROL_FWD;
   1672             }
   1673             if (value & (1 << 1)) {
   1674                entry->learn_flags |= BCM_VLAN_LEARN_CONTROL_CPU;
   1675             }
   1676             if (value & (1 << 2)) {
   1677                entry->learn_flags |= BCM_VLAN_LEARN_CONTROL_PENDING;
   1678             }
   1679             if (value & (1 << 3)) {
   1680                entry->learn_flags |= BCM_VLAN_LEARN_CONTROL_ARL;
   1681             }
   1682         } else {
   1683             entry->learn_flags = 0x0;
   1684         }
   1685     }
   1686 #endif /* BCM_HURRICANE3_SUPPORT */
   1687 
   1688 #if defined (BCM_TRIUMPH2_SUPPORT)
   1689     if (SOC_MEM_FIELD_VALID(unit, mem, TRUST_DOT1Pf)) {
   1690         if (soc_mem_field32_get(unit, mem, buf, TRUST_DOT1Pf)) {
   1691             entry->profile_flags |= _BCM_VLAN_PROFILE_TRUST_DOT1P;
   1692         }
   1693     }
   1694 
   1695     if (SOC_MEM_FIELD_VALID(unit, mem, TRUST_DOT1P_PTRf)) {
   1696         entry->trust_dot1p_ptr =
   1697             soc_mem_field32_get(unit, mem, buf, TRUST_DOT1P_PTRf);
   1698     }
   1699 #endif /* BCM_TRIUMPH2_SUPPORT */
   1700 
   1701 #if defined (BCM_TRX_SUPPORT)
   1702     if (SOC_MEM_FIELD_VALID (unit,mem, PROTOCOL_PKT_INDEXf)) {
   1703         proto_index = soc_mem_field32_get (unit, mem, buf, PROTOCOL_PKT_INDEXf);
   1704         rv = _bcm_xgs3_protocol_pkt_ctrl_get(unit,
   1705                                          proto_index, &entry->protocol_pkt);
   1706         if (BCM_FAILURE(rv) && (rv != BCM_E_UNAVAIL)) {
   1707             return (rv);
   1708         }
   1709     }
   1710 
   1711     if (SOC_MEM_IS_VALID(unit, VLAN_PROFILE_2m)) {
   1712         /* READ VLAN_PROFILE_2 portion. */
   1713         sal_memset(buf, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32));
   1714         mem = VLAN_PROFILE_2m;
   1715         block = &entry->block;
   1716 
   1717         /* READ vlan profile 2 table. */
   1718         rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, buf);
   1719         if (BCM_FAILURE(rv)) {
   1720             return (rv);
   1721         }
   1722 
   1723         /* Bitmap A  */
   1724         soc_mem_pbmp_field_get(unit, mem, buf, BLOCK_MASK_Af,
   1725                                &block->first_mask);
   1726 
   1727         /* Bitmap B  */
   1728         soc_mem_pbmp_field_get(unit, mem, buf, BLOCK_MASK_Bf,
   1729                                &block->second_mask);
   1730 
   1731         /* Broadcast mask select. */
   1732         block->broadcast_mask_sel = soc_mem_field32_get(unit, mem, buf, BCAST_MASK_SELf);
   1733 
   1734         /* Unknown unicast mask select. */
   1735         block->unknown_unicast_mask_sel = 
   1736             soc_mem_field32_get(unit, mem, buf, UNKNOWN_UCAST_MASK_SELf);
   1737 
   1738         /* Unknown multicast mask select. */
   1739         block->unknown_mulitcast_mask_sel = 
   1740             soc_mem_field32_get(unit, mem, buf, UNKNOWN_MCAST_MASK_SELf);
   1741 
   1742         /* Unknown multicast mask select. */
   1743         block->known_mulitcast_mask_sel = 
   1744             soc_mem_field32_get(unit, mem, buf, KNOWN_MCAST_MASK_SELf);
   1745     }
   1746 #endif /* BCM_TRX_SUPPORT */
   1747     return (BCM_E_NONE);
   1748 }
   1749 
   1750 /*
   1751  * Function : _vlan_profile_detach
   1752  *
   1753  * Purpose  : to de-initialize hardware VLAN_PROFILE_TAB and free memory
   1754  *            used to cache hardware table in RAM.
   1755  */
   1756 int
   1757 _bcm_xgs3_vlan_profile_detach(int unit)
   1758 {
   1759     sal_free(VLAN_PROFILE(unit));
   1760     VLAN_PROFILE(unit) = NULL; 
   1761 
   1762     return BCM_E_NONE;
   1763 }
   1764 
   1765 /*
   1766  * Function : _vlan_profile_init
   1767  *
   1768  * Purpose  : to initialize hardware VLAN_PROFILE_TAB and allocate memory
   1769  *            to cache hardware table in RAM.
   1770  *
   1771  * Note:
   1772  *      Allocate memory to cache the profile table and initialize it.
   1773  *      If memory to cache the profile table is already allocated, just
   1774  *      initialize the table.
   1775  */
   1776 STATIC int
   1777 _vlan_profile_init(int unit)
   1778 {
   1779     int alloc_size;   /* Memory allocation size.  */
   1780     int rv;           /* Operation return status. */
   1781 
   1782     if ((0 == SOC_WARM_BOOT(unit)) && (0 == SOC_IS_RCPU_ONLY(unit))) {
   1783         /* Clear the hardware table */
   1784         rv = soc_mem_clear(unit, VLAN_PROFILE_TABm, MEM_BLOCK_ALL, TRUE);
   1785         BCM_IF_ERROR_RETURN(rv);
   1786     }
   1787 
   1788     alloc_size = sizeof(_vlan_profile_t) * 
   1789         soc_mem_index_count(unit, VLAN_PROFILE_TABm);
   1790     if (VLAN_PROFILE(unit) == NULL) {
   1791         /* Allocate memory to cache VLAN Profile table */
   1792         VLAN_PROFILE(unit) = sal_alloc(alloc_size, "Cached VLAN Profile Table");
   1793         if (NULL == VLAN_PROFILE(unit)) {
   1794             return BCM_E_MEMORY;
   1795         }
   1796     }
   1797     sal_memset(VLAN_PROFILE(unit), 0, alloc_size);
   1798 
   1799     if (SOC_WARM_BOOT(unit)) {
   1800         int index;
   1801         int index_max = soc_mem_index_max(unit, VLAN_PROFILE_TABm);
   1802         for (index = 0; index <= index_max; index++) {
   1803             rv = _vlan_profile_read(unit, index,
   1804                                         &VLAN_PROFILE_ENTRY(unit, index));
   1805             BCM_IF_ERROR_RETURN(rv);
   1806         }
   1807     }
   1808 
   1809 #if defined(BCM_EASY_RELOAD_SUPPORT)
   1810     if (SOC_IS_RELOADING(unit)) {
   1811          if (NULL == VLAN_PROFILE_ER(unit)) {
   1812              alloc_size = sizeof(_vlan_profile_er_t) * BCM_VLAN_COUNT;
   1813  
   1814              VLAN_PROFILE_ER(unit) =
   1815                  sal_alloc(alloc_size, "Cached VLAN Profile Pointers");
   1816  
   1817              if (NULL == VLAN_PROFILE_ER(unit)) {
   1818                  sal_free(VLAN_PROFILE(unit));
   1819                  return BCM_E_MEMORY;
   1820              }
   1821          }
   1822          sal_memset(VLAN_PROFILE_ER(unit), 0, alloc_size);
   1823     }
   1824 #endif
   1825     return BCM_E_NONE;
   1826 }
   1827 
   1828 /*
   1829  * Function :
   1830  *    _vlan_profile_compare
   1831  *
   1832  * Purpose  :
   1833  *    Compare two vlan profiles.
   1834  *
   1835  * Parameters :
   1836  *     unit   - (IN) BCM device number.
   1837  *     first  - (IN) First vlan profile entry. 
   1838  *     second - (IN) Second vlan profile entry. 
   1839  *     equal  - (OUT) Profile is identical flag.
   1840  * 
   1841  * Return :
   1842  *    BCM_E_XXX
   1843  */
   1844 STATIC int 
   1845 _vlan_profile_compare(int unit, _vlan_profile_t *first, 
   1846                           _vlan_profile_t *second,  uint8 *equal) 
   1847 {
   1848     /* Input parameters check. */
   1849     if ((NULL == first) || (NULL == second) || (NULL == equal))  {
   1850         return (BCM_E_PARAM);
   1851     }
   1852 
   1853 #if defined (BCM_TRX_SUPPORT)
   1854     if (0 != sal_memcmp(&first->block, &second->block, 
   1855                         sizeof (_trx_vlan_block_t))) {
   1856         *equal = FALSE;
   1857     } else  
   1858 #endif /* BCM_TRX_SUPPORT */
   1859 
   1860     if ((first->outer_tpid != second->outer_tpid) ||
   1861         (first->flags != second->flags) ||
   1862         (first->ip6_mcast_flood_mode != second->ip6_mcast_flood_mode) ||
   1863         (first->ip4_mcast_flood_mode != second->ip4_mcast_flood_mode) ||
   1864         (first->l2_mcast_flood_mode != second->l2_mcast_flood_mode) ||
   1865         (first->qm_ptr != second->qm_ptr) ||
   1866         (first->trust_dot1p_ptr != second->trust_dot1p_ptr) ||
   1867         (first->profile_flags != second->profile_flags)) {
   1868         *equal = FALSE;
   1869     } else  {
   1870         *equal = TRUE;
   1871     }
   1872 
   1873 #if defined (BCM_TRX_SUPPORT)
   1874     if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl)
   1875         && (*equal == TRUE)) {
   1876         if (0 != sal_memcmp(&first->protocol_pkt, &second->protocol_pkt, 
   1877                         sizeof (bcm_vlan_protocol_packet_ctrl_t))) {
   1878             *equal = FALSE;
   1879         }
   1880     }
   1881 #endif /* BCM_TRX_SUPPORT */
   1882 
   1883 #if defined (BCM_HURRICANE3_SUPPORT)
   1884     if (SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, USE_VLAN_CMLf)
   1885         && (*equal == TRUE)) {
   1886         if (0 != sal_memcmp(&first->learn_flags, &second->learn_flags, 
   1887                         sizeof (uint32))) {
   1888             *equal = FALSE;
   1889         }
   1890     }
   1891 #endif /* BCM_HURRICANE3_SUPPORT */
   1892 
   1893     return (BCM_E_NONE);
   1894 }
   1895 
   1896 /*
   1897  * Function :
   1898  *    _vlan_profile_entry_init
   1899  *
   1900  * Purpose  :
   1901  *    Initialize sw vlan profile entry.
   1902  *
   1903  * Parameters :
   1904  *     unit   - (IN) BCM device number.
   1905  *     index  - (IN) Inserted entry index.
   1906  *     entry  - (IN) Inserted entry data.
   1907  * 
   1908  * Return :
   1909  *    BCM_E_XXX
   1910  */
   1911 STATIC int 
   1912 _vlan_profile_entry_init(int unit, int index, _vlan_profile_t *entry)
   1913 {
   1914     _vlan_profile_t *vte;
   1915 
   1916     /* Input parameters check. */
   1917     if (NULL == entry) {
   1918         return (BCM_E_PARAM); 
   1919     }
   1920     if ((index < 0) || 
   1921         (index > soc_mem_index_max(unit, VLAN_PROFILE_TABm))) {
   1922         return (BCM_E_PARAM); 
   1923     }
   1924 
   1925     vte = &VLAN_PROFILE_ENTRY(unit, index);
   1926     /* Vlan control vlan portion. */
   1927     vte->outer_tpid = entry->outer_tpid;
   1928     vte->flags = entry->flags;
   1929     vte->profile_flags = entry->profile_flags;
   1930     vte->ip6_mcast_flood_mode = entry->ip6_mcast_flood_mode;
   1931     vte->ip4_mcast_flood_mode = entry->ip4_mcast_flood_mode;
   1932     vte->l2_mcast_flood_mode  = entry->l2_mcast_flood_mode;
   1933     vte->qm_ptr               = entry->qm_ptr; 
   1934     vte->trust_dot1p_ptr      = entry->trust_dot1p_ptr; 
   1935 #if defined (BCM_TRX_SUPPORT)
   1936     /* Vlan block portion. */
   1937     sal_memcpy(&VLAN_PROFILE_ENTRY(unit, index).block, 
   1938                &entry->block, sizeof (_trx_vlan_block_t));
   1939 
   1940     if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl)) {
   1941         sal_memcpy(&VLAN_PROFILE_ENTRY(unit, index).protocol_pkt,
   1942                 &entry->protocol_pkt, sizeof (bcm_vlan_protocol_packet_ctrl_t));
   1943     }
   1944 #endif /* BCM_TRX_SUPPORT */
   1945 
   1946 #if defined (BCM_HURRICANE3_SUPPORT)
   1947     if (SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, USE_VLAN_CMLf)) {
   1948         sal_memcpy(&VLAN_PROFILE_ENTRY(unit, index).learn_flags,
   1949                 &entry->learn_flags, sizeof (uint32));
   1950     }
   1951 #endif /* BCM_HURRICANE3_SUPPORT */
   1952 
   1953     VLAN_PROFILE_REF_COUNT(unit, index) = 1;
   1954 
   1955     return (BCM_E_NONE);
   1956 }
   1957 
   1958 /*
   1959  * Function:
   1960  *    _vlan_profile_write
   1961  * 
   1962  * Purpose:
   1963  *    Write a vlan profile entry to vlan profile table.
   1964  *
   1965  * Parameters:
   1966  *     unit  - (IN) BCM device number.
   1967  *     index - (IN) Entry index.
   1968  *     entry - (IN) Vlan profile entry. 
   1969  *
   1970  * Return:
   1971  *    BCM_E_XXX
   1972  */
   1973 STATIC int 
   1974 _vlan_profile_write(int unit, int index, _vlan_profile_t *entry)
   1975 {
   1976     uint32              buf[SOC_MAX_MEM_FIELD_WORDS]; /* HW entry buffer.     */
   1977     uint32              value;                        /* Field specific value.*/
   1978     soc_mem_t           mem;          /* Vlan profile table memory.           */
   1979     int                 tpid_index;   /* Outer tpid index.                    */
   1980     int                 rv;           /* Operation return status.             */
   1981 #if defined (BCM_TRX_SUPPORT)
   1982     _trx_vlan_block_t   *block;       /* Vlan block profile pointer.          */
   1983     int protocol_pkt_index;
   1984 #endif /* BCM_TRX_SUPPORT */
   1985 
   1986     /* Input parameters check. */
   1987     if ((NULL == entry) || (index < 0) ||
   1988         (index > soc_mem_index_max(unit, VLAN_PROFILE_TABm))) {
   1989         return (BCM_E_PARAM);
   1990     }
   1991 
   1992 
   1993     /* Reset hw buffer. */
   1994     sal_memset(buf, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32));
   1995     mem = VLAN_PROFILE_TABm;
   1996 
   1997     /* Enable/Disable MIM termination on a vlan. */
   1998     if (soc_mem_field_valid(unit, mem, MIM_TERM_ENABLEf)) {
   1999         value = (entry->flags & BCM_VLAN_MIM_TERM_DISABLE) ? 0 : 1;
   2000         soc_mem_field32_set(unit, mem, buf, MIM_TERM_ENABLEf, value);
   2001     }
   2002 
   2003     /* Enable/Disable MPLS forwarding on a vlan. */
   2004     if (SOC_MEM_FIELD_VALID(unit, mem, MPLS_ENABLEf)) {
   2005         value = (entry->flags & BCM_VLAN_MPLS_DISABLE) ? 0 : 1;
   2006         soc_mem_field32_set(unit, mem, buf, MPLS_ENABLEf, value);
   2007     } 
   2008 
   2009     if (SOC_MEM_FIELD_VALID(unit, mem, PHB2_ENABLEf)) {
   2010         value = entry->profile_flags & _BCM_VLAN_PROFILE_PHB2_ENABLE ? 1 : 0;
   2011         soc_mem_field32_set(unit, mem, buf, PHB2_ENABLEf, value);
   2012     }
   2013 
   2014     if (SOC_MEM_FIELD_VALID(unit, mem, PHB2_USE_INNER_DOT1Pf)) {
   2015         value = entry->profile_flags & _BCM_VLAN_PROFILE_PHB2_USE_INNER_TAG ?
   2016             1 : 0;
   2017         soc_mem_field32_set(unit, mem, buf, PHB2_USE_INNER_DOT1Pf, value);
   2018     }
   2019 
   2020     if (SOC_MEM_FIELD_VALID(unit, mem, PHB2_ENABLEf)) {
   2021         value = entry->profile_flags & _BCM_VLAN_PROFILE_PHB2_ENABLE ? 1 : 0;
   2022         soc_mem_field32_set(unit, mem, buf, PHB2_ENABLEf, value);
   2023     }
   2024 
   2025     if (SOC_MEM_FIELD_VALID(unit, mem, PHB2_DOT1P_MAPPING_PTRf)) {
   2026         soc_mem_field32_set(unit, mem, buf, PHB2_DOT1P_MAPPING_PTRf,
   2027                             entry->qm_ptr);
   2028     }
   2029 
   2030     /* Drop non-unicast, broadcast or multicast packets that miss L2 lookup. */
   2031     if (SOC_MEM_FIELD_VALID(unit, mem, L2_NON_UCAST_DROPf)) {
   2032         value = (entry->flags & BCM_VLAN_NON_UCAST_DROP) ? 1 : 0;
   2033         soc_mem_field32_set(unit, mem, buf, L2_NON_UCAST_DROPf, value);
   2034     }
   2035 
   2036     /* Copy to cpu non-unicast, broadcast or multicast packets 
   2037      * that miss L2 lookup. 
   2038      */
   2039     if (SOC_MEM_FIELD_VALID(unit, mem, L2_NON_UCAST_TOCPUf)) {
   2040         value = (entry->flags & BCM_VLAN_NON_UCAST_TOCPU) ? 1 : 0;
   2041         soc_mem_field32_set(unit, mem, buf, L2_NON_UCAST_TOCPUf, value);
   2042     }
   2043 
   2044     /* Drop packets that miss L2 lookup. */ 
   2045     if (SOC_MEM_FIELD_VALID(unit, mem, L2_MISS_DROPf)) {
   2046         value = (entry->flags & BCM_VLAN_UNKNOWN_UCAST_DROP) ? 1 : 0;
   2047         soc_mem_field32_set(unit, mem, buf, L2_MISS_DROPf, value);
   2048     }
   2049 
   2050     /* Copy to cpu packets that miss L2 lookup. */ 
   2051     if (SOC_MEM_FIELD_VALID(unit, mem, L2_MISS_TOCPUf)) {
   2052         value = (entry->flags & BCM_VLAN_UNKNOWN_UCAST_TOCPU) ? 1 : 0;
   2053         soc_mem_field32_set(unit, mem, buf, L2_MISS_TOCPUf, value);
   2054     }
   2055 
   2056     /* L3 Enable for IPv4 packets on the VLAN. */ 
   2057     if (SOC_MEM_FIELD_VALID(unit, mem, IPV4L3_ENABLEf)) {
   2058         value = (entry->flags & BCM_VLAN_IP4_DISABLE) ? 0 : 1;
   2059         soc_mem_field32_set(unit, mem, buf, IPV4L3_ENABLEf, value);
   2060     }
   2061 
   2062     /* L3 Enable for IPv6 packets on the VLAN. */ 
   2063     if (SOC_MEM_FIELD_VALID(unit, mem, IPV6L3_ENABLEf)) {
   2064         value = (entry->flags & BCM_VLAN_IP6_DISABLE) ? 0 : 1;
   2065         soc_mem_field32_set(unit, mem, buf, IPV6L3_ENABLEf, value);
   2066     }
   2067 
   2068     /* Enable L2-only forwarding of IPMCv4 packets on this VLAN.  */ 
   2069     if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV4_L2_ENABLEf)) {
   2070         value = (entry->flags & BCM_VLAN_IP4_MCAST_L2_DISABLE) ? 0 : 1;
   2071         soc_mem_field32_set(unit, mem, buf, IPMCV4_L2_ENABLEf, value);
   2072     }
   2073 
   2074     /* Enable L2-only forwarding of IPMCv6 packets on this VLAN. */ 
   2075     if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV6_L2_ENABLEf)) {
   2076         value = (entry->flags & BCM_VLAN_IP6_MCAST_L2_DISABLE) ? 0 : 1;
   2077         soc_mem_field32_set(unit, mem, buf, IPMCV6_L2_ENABLEf, value);
   2078     }
   2079 
   2080 
   2081     /* IPMC Enable IPv4 packets on this VLAN.  */ 
   2082     if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV4_ENABLEf)) {
   2083         value = (entry->flags & BCM_VLAN_IP4_MCAST_DISABLE) ? 0 : 1;
   2084         soc_mem_field32_set(unit, mem, buf, IPMCV4_ENABLEf, value);
   2085     }
   2086 
   2087     /* IPMC Enable IPv6 packets on this VLAN.  */ 
   2088     if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV6_ENABLEf)) {
   2089         value = (entry->flags & BCM_VLAN_IP6_MCAST_DISABLE) ? 0 : 1;
   2090         soc_mem_field32_set(unit, mem, buf, IPMCV6_ENABLEf, value);
   2091     }
   2092 
   2093     if (soc_feature(unit, soc_feature_ipmc_unicast)) {
   2094         if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV4_UNICAST_MACDA_ENABLEf)) {
   2095             value = (entry->flags & BCM_VLAN_IPMC4_UCAST_ENABLE) ? 1 : 0;
   2096             soc_mem_field32_set(unit, mem, buf, 
   2097                     IPMCV4_UNICAST_MACDA_ENABLEf, value);
   2098         }
   2099 
   2100         if (SOC_MEM_FIELD_VALID(unit, mem, IPMCV6_UNICAST_MACDA_ENABLEf)) {
   2101             value = (entry->flags & BCM_VLAN_IPMC6_UCAST_ENABLE) ? 1 : 0;
   2102             soc_mem_field32_set(unit, mem, buf, 
   2103                     IPMCV6_UNICAST_MACDA_ENABLEf, value);
   2104         }
   2105     }
   2106 
   2107     /* Enable copy to cpu when ICMP redirect packet is needed. */ 
   2108     if (SOC_MEM_FIELD_VALID(unit, mem, ICMP_REDIRECT_TOCPUf)) {
   2109         value = (entry->flags & BCM_VLAN_ICMP_REDIRECT_TOCPU) ? 1 : 0;
   2110         soc_mem_field32_set(unit, mem, buf, ICMP_REDIRECT_TOCPUf, value);
   2111     }
   2112 
   2113     /* Unknown IPMC (IPMC miss) for IPv6 packets sent to CPU enable. */
   2114     if (SOC_MEM_FIELD_VALID(unit, mem, UNKNOWN_IPV6_MC_TOCPUf)) {
   2115         value = (entry->flags & BCM_VLAN_UNKNOWN_IP6_MCAST_TOCPU)? 1 : 0;
   2116         soc_mem_field32_set(unit, mem, buf, UNKNOWN_IPV6_MC_TOCPUf, value);
   2117     }
   2118 
   2119     /* Unknown IPMC (IPMC miss) for IPv4 packets sent to CPU enable. */
   2120     if (SOC_MEM_FIELD_VALID(unit, mem, UNKNOWN_IPV4_MC_TOCPUf)) {
   2121         value = (entry->flags & BCM_VLAN_UNKNOWN_IP4_MCAST_TOCPU)? 1 : 0;
   2122         soc_mem_field32_set(unit, mem, buf, UNKNOWN_IPV4_MC_TOCPUf, value);
   2123     }
   2124 
   2125     /* Outer tpid index Used when PORT_TABLE.OUTER_TPID_VERIFY, 
   2126      * is enabled and indicates which of the ING_OUTER_TPID[xx]
   2127      * register is expected to match for this VLAN
   2128      */ 
   2129     
   2130     if(!SOC_IS_SHADOW(unit)) {
   2131         rv = _bcm_fb2_outer_tpid_lkup(unit, entry->outer_tpid, &tpid_index);
   2132         BCM_IF_ERROR_RETURN(rv);
   2133         value = (uint32) tpid_index;
   2134         if (SOC_MEM_FIELD_VALID(unit, mem, OUTER_TPID_INDEX_MASKf)) {
   2135             soc_mem_field32_set(unit, mem, buf, OUTER_TPID_INDEX_MASKf,
   2136                                 1 << value);
   2137         } else {
   2138         soc_mem_field32_set(unit, mem, buf, OUTER_TPID_INDEXf, value);
   2139     }
   2140     }
   2141 
   2142     /* Disable learning on this vlan. */
   2143     if (SOC_MEM_FIELD_VALID(unit, mem, LEARN_DISABLEf)) {
   2144         value = (entry->flags & BCM_VLAN_LEARN_DISABLE) ? 1 : 0;
   2145         soc_mem_field32_set(unit, mem, buf, LEARN_DISABLEf, value);
   2146     }
   2147 
   2148     /* PFM value for IPv6 multicast lookups */
   2149     if (SOC_MEM_FIELD_VALID(unit, mem, L3_IPV6_PFMf)) {
   2150         rv = _bcm_vlan_mcast_flood_mode_to_pfm(unit, entry->ip6_mcast_flood_mode, 
   2151                                                (int *)&value);
   2152         BCM_IF_ERROR_RETURN(rv);
   2153         soc_mem_field32_set(unit, mem, buf, L3_IPV6_PFMf, value);
   2154     }
   2155 
   2156     /* PFM value for IPv4 multicast lookups */
   2157     if (SOC_MEM_FIELD_VALID(unit, mem, L3_IPV4_PFMf)) {
   2158         rv = _bcm_vlan_mcast_flood_mode_to_pfm(unit, entry->ip4_mcast_flood_mode,
   2159                                                (int *)&value);
   2160         BCM_IF_ERROR_RETURN(rv);
   2161         soc_mem_field32_set(unit, mem, buf, L3_IPV4_PFMf, value);
   2162     }
   2163 
   2164     /* PFM value for L2 multicast lookups */
   2165     rv = _bcm_vlan_mcast_flood_mode_to_pfm(unit, entry->l2_mcast_flood_mode,
   2166                                            (int *)&value);
   2167     BCM_IF_ERROR_RETURN(rv);
   2168     soc_mem_field32_set(unit, mem, buf, L2_PFMf, value);
   2169 
   2170 #if defined (BCM_TRX_SUPPORT)
   2171     /*Get the protocol_pkt_control register index  and program
   2172       in PROTOCOL_PKT_INDEX field*/
   2173     if (SOC_MEM_FIELD_VALID (unit,mem, PROTOCOL_PKT_INDEXf)) {
   2174         rv = _bcm_xgs3_protocol_pkt_ctrl_set(unit, -1,
   2175                 &entry->protocol_pkt, &protocol_pkt_index);
   2176         if (BCM_SUCCESS(rv)) {
   2177             value = (uint32)protocol_pkt_index;
   2178             soc_mem_field32_set(unit, mem, buf, PROTOCOL_PKT_INDEXf, value);
   2179         } else if (rv != BCM_E_UNAVAIL) {
   2180             return rv;
   2181         }
   2182     }
   2183 #endif /* BCM_TRX_SUPPORT */
   2184 
   2185 #if defined (BCM_TRIUMPH2_SUPPORT)
   2186     if (SOC_MEM_FIELD_VALID(unit, mem, TRUST_DOT1Pf)) {
   2187         value = entry->profile_flags & _BCM_VLAN_PROFILE_TRUST_DOT1P ? 1 : 0;
   2188         soc_mem_field32_set(unit, mem, buf, TRUST_DOT1Pf, value);
   2189     }
   2190 
   2191     if (SOC_MEM_FIELD_VALID(unit, mem, TRUST_DOT1P_PTRf)) {
   2192         soc_mem_field32_set(unit, mem, buf, TRUST_DOT1P_PTRf, 
   2193                                             entry->trust_dot1p_ptr);
   2194     }
   2195 #endif /* BCM_TRIUMPH2_SUPPORT */
   2196 
   2197 #if defined (BCM_HURRICANE3_SUPPORT)
   2198     if (SOC_MEM_FIELD_VALID(unit, mem, USE_VLAN_CMLf)) {
   2199         value = entry->learn_flags & BCM_VLAN_LEARN_CONTROL_ENABLE ? 1 : 0;
   2200         soc_mem_field32_set(unit, mem, buf, USE_VLAN_CMLf, value);
   2201 
   2202         if (value) {
   2203             value = 0;
   2204             if (!(entry->learn_flags & BCM_VLAN_LEARN_CONTROL_FWD)) {
   2205                value |= (1 << 0);
   2206             }
   2207             if (entry->learn_flags & BCM_VLAN_LEARN_CONTROL_CPU) {
   2208                value |= (1 << 1);
   2209             }
   2210             if (entry->learn_flags & BCM_VLAN_LEARN_CONTROL_PENDING) {
   2211                value |= (1 << 2);
   2212             }
   2213             if (entry->learn_flags & BCM_VLAN_LEARN_CONTROL_ARL) {
   2214                value |= (1 << 3);
   2215             }
   2216             soc_mem_field32_set(unit, mem, buf, CML_FLAGS_MOVEf, value);
   2217             soc_mem_field32_set(unit, mem, buf, CML_FLAGS_NEWf, value);
   2218         }
   2219     }
   2220 #endif /* BCM_HURRICANE3_SUPPORT */
   2221 
   2222     /* Write vlan profile table entry. */
   2223     rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, buf); 
   2224     BCM_IF_ERROR_RETURN(rv);
   2225 
   2226     /* Copy to cpu packets that miss L2 lookup. */
   2227     if (SOC_REG_FIELD_VALID(unit, VLAN_PROFILE_TABr, L2_MISS_TOCPUf)) {
   2228         value = (entry->flags & BCM_VLAN_UNKNOWN_UCAST_TOCPU) ? 1 : 0;
   2229         soc_reg_field32_modify(unit, VLAN_PROFILE_TABr, REG_PORT_ANY,
   2230                                L2_MISS_TOCPUf, value);
   2231     }
   2232 
   2233 #if defined (BCM_TRX_SUPPORT)
   2234     /* WRITE VLAN_PROFILE_2 portion. */
   2235     if (SOC_MEM_IS_VALID(unit, VLAN_PROFILE_2m)) {
   2236         sal_memset(buf, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32));
   2237         mem = VLAN_PROFILE_2m;
   2238         block = &entry->block;
   2239 
   2240         /* Bitmap A  */
   2241         soc_mem_pbmp_field_set(unit, mem, buf, BLOCK_MASK_Af,
   2242                                &block->first_mask);
   2243 
   2244         /* Bitmap B  */
   2245         soc_mem_pbmp_field_set(unit, mem, buf, BLOCK_MASK_Bf,
   2246                                &block->second_mask);
   2247 
   2248         /* Broadcast mask select. */
   2249         soc_mem_field32_set(unit, mem, buf, BCAST_MASK_SELf,
   2250                             block->broadcast_mask_sel);
   2251 
   2252         /* Unknown unicast mask select. */
   2253         if (soc_mem_field_valid(unit, VLAN_PROFILE_2m, 
   2254                                 UNKNOWN_UCAST_MASK_SELf)) {
   2255             soc_mem_field32_set(unit, mem, buf, UNKNOWN_UCAST_MASK_SELf,
   2256                             block->unknown_unicast_mask_sel);
   2257         }
   2258 
   2259         /* Unknown multicast mask select. */
   2260         if (soc_mem_field_valid(unit, VLAN_PROFILE_2m, 
   2261                                 UNKNOWN_MCAST_MASK_SELf)) {
   2262             soc_mem_field32_set(unit, mem, buf, UNKNOWN_MCAST_MASK_SELf, 
   2263                             block->unknown_mulitcast_mask_sel);
   2264         }
   2265 
   2266         /* Unknown multicast mask select. */
   2267         if (soc_mem_field_valid(unit, VLAN_PROFILE_2m, KNOWN_MCAST_MASK_SELf)) {
   2268             soc_mem_field32_set(unit, mem, buf, KNOWN_MCAST_MASK_SELf, 
   2269                             block->known_mulitcast_mask_sel);
   2270         }
   2271 
   2272         /* Write vlan profile 2 entry. */
   2273         rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, buf);
   2274         BCM_IF_ERROR_RETURN(rv);
   2275     }
   2276 #endif /* BCM_TRX_SUPPORT */
   2277 
   2278     return (BCM_E_NONE);
   2279 }
   2280 /*
   2281  * Function:
   2282  *    _bcm_vlan_profile_add
   2283  * 
   2284  * Purpose:
   2285  *    Add a new entry to vlan profile table
   2286  *
   2287  * Parameters:
   2288  *     unit  - (IN) BCM device number.
   2289  *     entry - (IN) Vlan profile entry. 
   2290  *     index - (OUT) Allocated/existing entry index.
   2291  *
   2292  * Return:
   2293  *    BCM_E_XXX
   2294  */
   2295 STATIC int 
   2296 _vlan_profile_add(int unit, _vlan_profile_t *entry, int *index) 
   2297 {
   2298     int   free_index = -1;    /* Unused proile index.    */
   2299     int   idx;                /* Vlan profiles iterator. */
   2300     int   idx_max;            /* Profile entry count.    */ 
   2301     uint8 equal;              /* Prifiles are equal flag.*/
   2302     int   rv;                 /* Operation return status.*/
   2303 
   2304     /* Input parameters check. */
   2305     if (NULL == entry) {
   2306         return (BCM_E_PARAM); 
   2307     }
   2308 
   2309     idx_max = soc_mem_index_max(unit, VLAN_PROFILE_TABm);
   2310     /* Search for an existing entry that has the same configuration.  */
   2311     for (idx = 0; idx <= idx_max; idx++) {
   2312         /* Compare profiles. */
   2313         rv = _vlan_profile_compare(unit, &VLAN_PROFILE_ENTRY(unit, idx),
   2314                                    entry, &equal);
   2315         BCM_IF_ERROR_RETURN(rv);
   2316         if (equal) {
   2317             VLAN_PROFILE_REF_COUNT(unit, idx)++; 
   2318 #if defined (BCM_TRX_SUPPORT)
   2319             if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl)) {
   2320                 int pkt_idx;
   2321 
   2322                 /* should only increase reference counter when called
   2323                  * on the existing entry
   2324                  */
   2325                 rv = _bcm_xgs3_protocol_pkt_ctrl_set(unit, -1,
   2326                             &entry->protocol_pkt, 
   2327                             &pkt_idx);
   2328                 BCM_IF_ERROR_RETURN(rv);
   2329             }
   2330 #endif /* BCM_TRX_SUPPORT */
   2331             *index = idx;
   2332             return (BCM_E_NONE);
   2333         }
   2334 
   2335         if ((-1 == free_index) && (0 == VLAN_PROFILE_REF_COUNT(unit, idx))) {
   2336             free_index = idx;
   2337         }
   2338     }
   2339 
   2340     /*  Entry not found & no free indexes. */
   2341     if (-1 == free_index) {
   2342         return BCM_E_RESOURCE;
   2343     }
   2344 
   2345     /* 
   2346      * Insert the new configuration into profile table
   2347      */
   2348     rv = _vlan_profile_write(unit, free_index, entry);
   2349     BCM_IF_ERROR_RETURN(rv);
   2350 
   2351     rv = _vlan_profile_entry_init(unit, free_index, entry);
   2352     BCM_IF_ERROR_RETURN(rv);
   2353 
   2354     *index = free_index;
   2355     return BCM_E_NONE;
   2356 }
   2357 
   2358 /*
   2359  * Function :
   2360  *    _vlan_profile_delete
   2361  *
   2362  * Parameters :
   2363  *     unit  - (IN) BCM device number.
   2364  *     index - (IN) Existing entry index.
   2365  * 
   2366  * Purpose  :
   2367  *    Remove an entry from vlan profile table.
   2368  *
   2369  * Return :
   2370  *    BCM_E_XXX
   2371  */
   2372 STATIC int
   2373 _vlan_profile_delete(int unit, int index) 
   2374 {
   2375     uint32  buf[SOC_MAX_MEM_FIELD_WORDS]; /* HW entry buffer.         */
   2376     int     rv;                           /* Operation return status. */
   2377 #if defined (BCM_TRX_SUPPORT)
   2378     vlan_profile_tab_entry_t entry;
   2379     uint32 prot_pkt_index;
   2380     int ref_count;
   2381 #endif /* BCM_TRX_SUPPORT */
   2382 
   2383     /* Input parameters check. */
   2384     if ((index < 0) || (index > soc_mem_index_max(unit, VLAN_PROFILE_TABm))) {
   2385         return (BCM_E_PARAM);
   2386     }
   2387 
   2388     /* Decrement profile reference counter. */
   2389     if (VLAN_PROFILE_REF_COUNT(unit, index) > 0) {
   2390         VLAN_PROFILE_REF_COUNT(unit, index)--;
   2391     }
   2392 
   2393 #if defined (BCM_TRX_SUPPORT)
   2394     if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl)
   2395         && SOC_MEM_FIELD_VALID (unit,VLAN_PROFILE_TABm, PROTOCOL_PKT_INDEXf)) {
   2396         BCM_IF_ERROR_RETURN
   2397            (soc_mem_read(unit, VLAN_PROFILE_TABm, MEM_BLOCK_ANY, index, &entry));
   2398         prot_pkt_index = soc_mem_field32_get(unit, VLAN_PROFILE_TABm, &entry,
   2399                                              PROTOCOL_PKT_INDEXf);
   2400         BCM_IF_ERROR_RETURN(_bcm_prot_pkt_ctrl_ref_count_get (unit,
   2401                                prot_pkt_index, &ref_count));
   2402         if (ref_count > 0) {
   2403             BCM_IF_ERROR_RETURN(_bcm_prot_pkt_ctrl_delete(unit,prot_pkt_index));
   2404         }
   2405     }
   2406 #endif /* BCM_TRX_SUPPORT */
   2407     if (0 == VLAN_PROFILE_REF_COUNT(unit, index)) {
   2408         /* Reset hw table entries. */
   2409         sal_memset(buf, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32));
   2410 #if defined (BCM_TRX_SUPPORT)
   2411         if (SOC_MEM_IS_VALID(unit, VLAN_PROFILE_2m)) {
   2412             rv = soc_mem_write(unit, VLAN_PROFILE_2m, MEM_BLOCK_ALL, index, buf);
   2413             BCM_IF_ERROR_RETURN(rv);
   2414         }
   2415 
   2416 #endif /* BCM_TRX_SUPPORT */
   2417 
   2418         rv = soc_mem_write(unit, VLAN_PROFILE_TABm, MEM_BLOCK_ALL, index, buf);
   2419         BCM_IF_ERROR_RETURN(rv);
   2420 
   2421         /* Reset sw vlan profile entry. */
   2422         sal_memset(&VLAN_PROFILE_ENTRY(unit, index), 0, sizeof(_vlan_profile_t));
   2423     }
   2424     return (BCM_E_NONE);
   2425 }
   2426 
   2427 #if defined (BCM_TRX_SUPPORT)
   2428 /*
   2429  * Function:
   2430  *    _vlan_protocol_pkt_ctrl_default_add
   2431  *
   2432  * Purpose:
   2433  *    Add default vlan protocol packet control value
   2434  *
   2435  * Parameters:
   2436  *     unit  - (IN)  BCM device number.
   2437  *     protocol_pkt - (OUT) protocol packet actions to be configured.
   2438  * Return:
   2439  *    BCM_E_XXX
   2440  */
   2441 STATIC int
   2442 _vlan_protocol_pkt_ctrl_default_add(int unit, bcm_vlan_protocol_packet_ctrl_t *protocol_pkt)
   2443 {
   2444     soc_reg_t reg = PROTOCOL_PKT_CONTROLr;
   2445 
   2446     if (!soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl)) {
   2447         return BCM_E_UNAVAIL;
   2448     }
   2449 
   2450     if (SOC_REG_FIELD_VALID(unit, reg, MMRP_FWD_ACTIONf)) {
   2451         protocol_pkt->mmrp_action = BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   2452     }
   2453     if (SOC_REG_FIELD_VALID(unit, reg, SRP_FWD_ACTIONf)) {
   2454         protocol_pkt->srp_action = BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   2455     }
   2456 
   2457     reg = IGMP_MLD_PKT_CONTROLr;
   2458     if (SOC_REG_FIELD_VALID(unit, reg, IGMP_REP_LEAVE_FWD_ACTIONf)) {
   2459         protocol_pkt->igmp_report_leave_action= BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   2460     }
   2461     if (SOC_REG_FIELD_VALID(unit, reg, IGMP_QUERY_FWD_ACTIONf)) {
   2462         protocol_pkt->igmp_query_action= BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   2463     }
   2464     if (SOC_REG_FIELD_VALID(unit, reg, IGMP_UNKNOWN_MSG_FWD_ACTIONf)) {
   2465         protocol_pkt->igmp_unknown_msg_action= BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   2466     }
   2467     if (SOC_REG_FIELD_VALID(unit, reg, MLD_REP_DONE_FWD_ACTIONf)) {
   2468         protocol_pkt->mld_report_done_action= BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   2469     }
   2470     if (SOC_REG_FIELD_VALID(unit, reg, MLD_QUERY_FWD_ACTIONf)) {
   2471         protocol_pkt->mld_query_action= BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   2472     }
   2473     if (SOC_REG_FIELD_VALID(unit, reg, IPV4_MC_ROUTER_ADV_PKT_FWD_ACTIONf)) {
   2474         protocol_pkt->ip4_mc_router_adv_action= BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   2475     }
   2476     if (SOC_REG_FIELD_VALID(unit, reg, IPV4_RESVD_MC_PKT_FWD_ACTIONf)) {
   2477         protocol_pkt->ip4_rsvd_mc_action= BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   2478     }
   2479     if (SOC_REG_FIELD_VALID(unit, reg, IPV6_RESVD_MC_PKT_FWD_ACTIONf)) {
   2480         protocol_pkt->ip6_rsvd_mc_action= BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   2481     }
   2482     if (SOC_REG_FIELD_VALID(unit, reg, IPV6_MC_ROUTER_ADV_PKT_FWD_ACTIONf)) {
   2483         protocol_pkt->ip6_mc_router_adv_action= BCM_VLAN_PROTO_PKT_FORWARD_ENABLE;
   2484     }
   2485 
   2486     return BCM_E_NONE;
   2487 
   2488 }
   2489 #endif /*BCM_TRX_SUPPORT*/
   2490 
   2491 /*
   2492  * Function:
   2493  *    _vlan_profile_default_add
   2494  * 
   2495  * Purpose:
   2496  *    Add a default entry to vlan profile table
   2497  *
   2498  * Parameters:
   2499  *     unit  - (IN)  BCM device number.
   2500  *     index - (OUT) Profile index.
   2501  * Return:
   2502  *    BCM_E_XXX
   2503  */
   2504 STATIC int 
   2505 _vlan_profile_default_add(int unit, int *index) 
   2506 {
   2507     int                     rv;        /* Operation return status. */
   2508     _vlan_profile_t         entry;     /* Vlan profile_entry.      */
   2509     bcm_vlan_mcast_flood_t  mode;      /* Mcast flood mode.        */
   2510 
   2511     /* Input parameters check. */
   2512     if (NULL == index) {
   2513         return (BCM_E_PARAM);
   2514     }
   2515 
   2516     /* Reset entry structure. */
   2517     sal_memset (&entry, 0, sizeof(_vlan_profile_t));
   2518 
   2519     /* Multicast flood mode. */
   2520     rv = _bcm_esw_vlan_flood_default_get(unit, &mode);
   2521     BCM_IF_ERROR_RETURN(rv);
   2522 
   2523     entry.ip6_mcast_flood_mode = mode;
   2524     entry.ip4_mcast_flood_mode = mode;
   2525     entry.l2_mcast_flood_mode = mode;
   2526 
   2527     /* Default outer tpid value. */
   2528     entry.outer_tpid = _bcm_fb2_outer_tpid_default_get(unit);
   2529 
   2530     /* Default VLAN Protocol Packet control */
   2531 #if defined (BCM_TRX_SUPPORT)
   2532     if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl)) {
   2533         BCM_IF_ERROR_RETURN
   2534             (_vlan_protocol_pkt_ctrl_default_add(unit, &entry.protocol_pkt));
   2535     }
   2536 #endif
   2537 
   2538     return  _vlan_profile_add (unit, &entry, index);
   2539 }
   2540 
   2541 /*
   2542  * Function:
   2543  *    _vlan_profile_update
   2544  * 
   2545  * Purpose:
   2546  *    Update existing vlan "profile" 
   2547  *
   2548  * Parameters:
   2549  *     unit    - (IN) BCM device number.
   2550  *     vlan    - (IN) VLAN id.
   2551  *     buf     - (IN) Vlan table entry.
   2552  *     profile - (IN) Updated profile
   2553  * Return:
   2554  *    BCM_E_XXX
   2555  */
   2556 STATIC int 
   2557 _vlan_profile_update(int unit, bcm_vlan_t vlan, _vlan_profile_t *profile)
   2558 {
   2559     uint32  buf[SOC_MAX_MEM_FIELD_WORDS]; /* HW entry buffer.     */
   2560     int rv;                       /* Operation return status.     */
   2561     int idx;                      /* Vlan profile index.          */
   2562     int oidx;                     /* Original vlan profile index. */
   2563     uint8 equal;                  /* Profiles are equal flag.     */
   2564 
   2565 
   2566     /* Input parameters check. */
   2567     if (NULL == profile) {
   2568         return (BCM_E_PARAM);
   2569     }
   2570 
   2571     rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int) vlan, buf);
   2572     BCM_IF_ERROR_RETURN(rv);
   2573 
   2574     BCM_IF_ERROR_RETURN(_bcm_vlan_valid_check(unit, VLAN_TABm, 
   2575                                          (vlan_tab_entry_t *)buf, vlan));
   2576 
   2577     /* Get original vlan profile. */
   2578     rv = _vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf,
   2579                                buf, vlan, &oidx);
   2580     BCM_IF_ERROR_RETURN(rv);
   2581 
   2582     /* Compare original profile with new one. */ 
   2583     rv = _vlan_profile_compare(unit, &VLAN_PROFILE_ENTRY(unit, oidx),
   2584                                profile, &equal);
   2585     BCM_IF_ERROR_RETURN(rv);
   2586 
   2587     if (TRUE == equal) {
   2588         return (BCM_E_NONE);
   2589     }
   2590 
   2591     /* Add new profile. */
   2592     rv = _vlan_profile_add(unit, profile, &idx);
   2593     if (BCM_SUCCESS(rv)) {
   2594     }
   2595     if (BCM_E_RESOURCE == rv) {
   2596         /* Check if we can update an existing profile. */
   2597         if (1 == VLAN_PROFILE_REF_COUNT(unit, oidx)) {
   2598             rv = _vlan_profile_write(unit, oidx, profile);
   2599             BCM_IF_ERROR_RETURN(rv);
   2600 
   2601             VLAN_PROFILE_ENTRY(unit, oidx) = *profile;
   2602             VLAN_PROFILE_REF_COUNT(unit, oidx) = 1;
   2603             idx = oidx;
   2604         }
   2605     } 
   2606     BCM_IF_ERROR_RETURN(rv);
   2607 
   2608     /* Set new vlan profile index. */
   2609     rv = _vlan_profile_idx_set(unit, VLAN_TABm, VLAN_PROFILE_PTRf,
   2610                                buf, vlan, idx);
   2611     BCM_IF_ERROR_RETURN(rv);
   2612 
   2613     /* Write back vlan table entry. */
   2614     rv = soc_mem_write(unit, VLAN_TABm, MEM_BLOCK_ALL, (int) vlan, buf);
   2615     BCM_IF_ERROR_RETURN(rv);
   2616 
   2617     /* Delete original vlan profile if new one was allocated. */
   2618     if (oidx != idx) {
   2619          rv = _vlan_profile_delete(unit, oidx);
   2620          BCM_IF_ERROR_RETURN(rv);
   2621     }
   2622     return (BCM_E_NONE);
   2623 }
   2624 
   2625 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
   2626 
   2627 #ifdef BCM_TRIUMPH2_SUPPORT
   2628 /*
   2629  * Function:
   2630  *    bcm_xgs3_vlan_mpls_table_init
   2631  *
   2632  * Purpose:
   2633  *      Initialize the VLAN_MPLS table with the default entry in it.
   2634  *
   2635  * Parameters:
   2636  *     unit  - (IN)  BCM device number.
   2637  *     vd  - (IN)  VLAN data.
   2638  *
   2639  * Return:
   2640  *    BCM_E_XXX
   2641  */
   2642 STATIC int
   2643 _bcm_xgs3_vlan_mpls_table_init(int unit, bcm_vlan_data_t *vd)
   2644 {
   2645     vlan_mpls_entry_t vlan_mpls;
   2646 
   2647     if ((SAL_BOOT_QUICKTURN || SAL_BOOT_PLISIM) && (!SAL_BOOT_BCMSIM) &&
   2648          !SOC_IS_HAWKEYE(unit) && !SOC_IS_KATANA2(unit)) {
   2649         LOG_CLI((BSL_META_U(unit,
   2650                             "SIMULATION: skipped VLAN_MPLS table clear "
   2651                             "(assuming hardware did it)\n")));
   2652     } else if (!SOC_IS_RCPU_ONLY(unit)) {
   2653         SOC_IF_ERROR_RETURN(soc_mem_clear(unit, VLAN_MPLSm, MEM_BLOCK_ALL, TRUE));
   2654     }
   2655 
   2656     sal_memset(&vlan_mpls, 0, sizeof(vlan_mpls_entry_t));
   2657     BCM_IF_ERROR_RETURN
   2658         (soc_mem_read(unit, VLAN_MPLSm, MEM_BLOCK_ANY, vd->vlan_tag,
   2659                       &vlan_mpls));
   2660 
   2661     soc_mem_field32_set(unit, VLAN_MPLSm, &vlan_mpls, L3_IIFf, vd->vlan_tag);
   2662 
   2663     if (soc_feature(unit, soc_feature_mpls)) {
   2664         soc_mem_field32_set(unit, VLAN_MPLSm, &vlan_mpls, MPLS_ENABLEf, 0x1);
   2665     }
   2666     if (soc_feature(unit, soc_feature_mim)) {
   2667         soc_mem_field32_set(unit, VLAN_MPLSm, &vlan_mpls, MIM_TERM_ENABLEf,
   2668                             0x1);
   2669     }
   2670 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   2671     if (soc_feature(unit, soc_feature_vlan_filter)) {
   2672         
   2673         soc_mem_field32_set(unit, VLAN_MPLSm, &vlan_mpls, EN_IFILTERf,
   2674                             0x1);
   2675     }
   2676 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   2677     BCM_IF_ERROR_RETURN
   2678         (soc_mem_write(unit, VLAN_MPLSm, MEM_BLOCK_ALL, vd->vlan_tag,
   2679                        &vlan_mpls));
   2680 
   2681     return BCM_E_NONE;
   2682 }
   2683 #endif
   2684 
   2685 /*
   2686  * Function:
   2687  *    bcm_xgs3_vlan_init
   2688  * 
   2689  * Purpose:
   2690  *      Initialize the VLAN tables with the default entry in it.
   2691  *
   2692  * Parameters:
   2693  *     unit  - (IN)  BCM device number.
   2694  * 
   2695  * Return:
   2696  *    BCM_E_XXX
   2697  */
   2698 static int
   2699 _bcm_xgs3_vlan_table_init(int unit, bcm_vlan_data_t *vd, soc_mem_t table)
   2700 {
   2701     vlan_tab_entry_t    ve;
   2702     bcm_pbmp_t          pbm;
   2703     int                 rv;
   2704 
   2705 #ifdef BCM_SHADOW_SUPPORT
   2706     /* No EGR_VLAN support for shadow */
   2707     if(SOC_IS_SHADOW(unit)) {
   2708         return BCM_E_NONE;
   2709     }
   2710 #endif
   2711 
   2712     assert(sizeof(vlan_tab_entry_t) >= sizeof(egr_vlan_entry_t));
   2713     assert(sizeof(vlan_tab_entry_t) >= sizeof(vlan_2_tab_entry_t));
   2714 
   2715     if ((SAL_BOOT_QUICKTURN || SAL_BOOT_PLISIM) && (!SAL_BOOT_BCMSIM) &&
   2716          !soc_mem_field32_get(unit, table,
   2717                               soc_mem_entry_null(unit, table), VALIDf) && 
   2718          !SOC_IS_HAWKEYE(unit) && !SOC_IS_KATANA2(unit)) {
   2719         LOG_CLI((BSL_META_U(unit,
   2720                             "SIMULATION: skipped VLAN table clear "
   2721                             "(assuming hardware did it)\n")));
   2722     } else if (!SOC_IS_RCPU_ONLY(unit)) {
   2723         SOC_IF_ERROR_RETURN(soc_mem_clear(unit, table, MEM_BLOCK_ALL, TRUE));
   2724     }
   2725 
   2726     sal_memcpy(&ve, soc_mem_entry_null(unit, table),
   2727                soc_mem_entry_words(unit, table) * 4);
   2728 
   2729     BCM_PBMP_ASSIGN(pbm, vd->ut_port_bitmap);
   2730 #ifdef BCM_KATANA2_SUPPORT
   2731     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
   2732         bcm_pbmp_t temp_pbm;
   2733 
   2734         BCM_PBMP_ASSIGN(temp_pbm, PBMP_E_ALL(unit));
   2735         BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &temp_pbm));
   2736 
   2737 #ifndef BCM_VLAN_NO_DEFAULT_ETHER
   2738         BCM_PBMP_OR(pbm, temp_pbm);
   2739 #endif /* BCM_VLAN_NO_DEFAULT_ETHER */
   2740     } else
   2741 #endif /* BCM_KATANA2_SUPPORT */
   2742     {
   2743 #ifndef BCM_VLAN_NO_DEFAULT_ETHER
   2744         BCM_PBMP_OR(pbm, PBMP_E_ALL(unit));
   2745 #endif /* BCM_VLAN_NO_DEFAULT_ETHER */
   2746     }
   2747 
   2748     if (TABLE_HAS_T_BITMAP(unit, table)) {
   2749 #if defined(BCM_TOMAHAWK3_SUPPORT)
   2750         if ((table == VLAN_TABLE(unit)) &&
   2751             soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) {
   2752 
   2753             /* Use profile based approach to the port bitmap */
   2754             uint32 profile_idx;
   2755 
   2756             /* Initialize the port bitmap profile table */
   2757             BCM_IF_ERROR_RETURN(_bcm_th3_vlan_pbmp_profile_init(unit));
   2758 
   2759             /* Insert the port bitmap into the profile table */
   2760             BCM_IF_ERROR_RETURN(
   2761                 _bcm_th3_vlan_pbmp_profile_entry_add(
   2762                     unit, vd->port_bitmap, &profile_idx));
   2763 
   2764             /* Set the corressponding profile index into the VLAN table */
   2765             soc_mem_field32_set(
   2766                 unit, table, &ve, PORT_BITMAP_PROFILE_PTRf, profile_idx);
   2767         } else
   2768 #endif /* BCM_TOMAHAWK3_SUPPORT */
   2769         {
   2770             soc_mem_pbmp_field_set(
   2771                 unit, table, &ve, PORT_BITMAPf, &vd->port_bitmap);
   2772         }
   2773 
   2774         if ((table == VLAN_TABLE(unit)) &&
   2775             SOC_MEM_FIELD_VALID(unit, table, ING_PORT_BITMAPf)) { 
   2776             soc_mem_pbmp_field_set(unit, table, &ve, ING_PORT_BITMAPf, 
   2777                                 &vd->port_bitmap); 
   2778         } 
   2779     }
   2780     /* This function will be called with VLAN_TABm, EGR_VLANm, and VLAN_2_TABm
   2781      * for TH2 and TH3. In TH2/TH3, VLAN_2_TABm has STGf while VLAN_TABm does
   2782      * not. The check is to prevent STGf being set wrongly.
   2783      */
   2784     if (SOC_MEM_FIELD_VALID(unit, table, STGf)) {
   2785     soc_mem_field32_set(unit, table, &ve, STGf, BCM_STG_DEFAULT);
   2786     }
   2787     soc_mem_field32_set(unit, table, &ve, VALIDf, 1);
   2788 
   2789 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
   2790     if (SOC_MEM_FIELD_VALID(unit, table, L3_IIFf)) {
   2791         uint32  l3_iif_value;
   2792         
   2793         if (soc_feature(unit, soc_feature_l3_iif_under_4k)) {
   2794             l3_iif_value = 0;
   2795         } else {
   2796             if (soc_feature(unit, soc_feature_l3_ingress_interface)) {
   2797                 l3_iif_value = vd->vlan_tag;
   2798             } else {
   2799                 /* L3_IIFf value should be 0 once device can't support L3 
   2800                  * ingress interface 
   2801                 */
   2802                 l3_iif_value = 0;
   2803             }
   2804         }
   2805        soc_mem_field32_set(unit, table, &ve, L3_IIFf, l3_iif_value);
   2806     }
   2807 #endif
   2808 #if defined(BCM_EASY_RELOAD_SUPPORT)
   2809     if (SOC_IS_RELOADING(unit)) { 
   2810         _bcm_vlan_valid_set(unit, table, vd->vlan_tag, 1);
   2811     }
   2812 #endif
   2813 
   2814     if (TABLE_HAS_UT_BITMAP(unit, table)) {
   2815         soc_mem_pbmp_field_set(unit, table, &ve, UT_BITMAPf, &pbm);
   2816     }
   2817 
   2818 #if defined(BCM_TRIDENT3_SUPPORT)
   2819     if (soc_feature(unit, soc_feature_vlan_filter)) {
   2820         if (table == VLAN_TABm && SOC_IS_TRIDENT3X(unit)) {
   2821             soc_mem_field32_set(unit, table, &ve, EN_IFILTERf, 0x1);
   2822         }
   2823     }
   2824 #endif /* BCM_TRIDENT3_SUPPORT */
   2825 
   2826     if ((table == EGR_VLANm && SOC_IS_FBX(unit)) ||
   2827         (table == VLAN_TABm && SOC_IS_KATANA2(unit))) {
   2828 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
   2829  || defined(BCM_RAVEN_SUPPORT)
   2830         if (soc_feature(unit, soc_feature_vlan_ctrl)) {
   2831             uint16                    tpid;
   2832             int                       tpid_index;
   2833 
   2834             tpid = _bcm_fb2_outer_tpid_default_get(unit);
   2835 
   2836             /* Add the default outer TPID entry twice during init so that
   2837              * the default entry does not get removed even when no table 
   2838              * entry is referencing to the default TPID entry.
   2839              */  
   2840             BCM_IF_ERROR_RETURN
   2841                 (_bcm_fb2_outer_tpid_entry_add(unit, tpid, &tpid_index));
   2842             BCM_IF_ERROR_RETURN
   2843                 (_bcm_fb2_outer_tpid_entry_add(unit, tpid, &tpid_index));
   2844             soc_mem_field32_set(unit, table, &ve, OUTER_TPID_INDEXf,
   2845                                 tpid_index); 
   2846         } 
   2847 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   2848 
   2849         if (soc_feature(unit, soc_feature_vlan_filter)) {
   2850             
   2851             soc_mem_field32_set(unit, table, &ve, EN_EFILTERf, 0x1);
   2852         }
   2853 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   2854 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
   2855     }
   2856 
   2857     if (TABLE_HAS_PFM(unit, table)) {
   2858 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
   2859  || defined(BCM_RAVEN_SUPPORT)
   2860         if (soc_feature(unit, soc_feature_vlan_ctrl)) {
   2861             int                       profile_index;
   2862 
   2863             BCM_IF_ERROR_RETURN (_vlan_profile_init(unit));
   2864             rv = _vlan_profile_default_add(unit, &profile_index);
   2865             BCM_IF_ERROR_RETURN(rv);
   2866 
   2867             rv = _vlan_profile_idx_set(unit, table, VLAN_PROFILE_PTRf,
   2868                                        (uint32 *)&ve, vd->vlan_tag, 
   2869                                        profile_index);
   2870             BCM_IF_ERROR_RETURN(rv);
   2871         } else
   2872 #endif
   2873         {
   2874             bcm_vlan_mcast_flood_t mode;
   2875             int pfm;
   2876 
   2877             rv = _bcm_esw_vlan_flood_default_get(unit, &mode);
   2878             BCM_IF_ERROR_RETURN(rv);
   2879 
   2880             rv = _bcm_vlan_mcast_flood_mode_to_pfm(unit, mode, &pfm);
   2881             BCM_IF_ERROR_RETURN(rv);
   2882             if (SOC_MEM_FIELD_VALID(unit, table, PFMf)) {
   2883             soc_mem_field32_set(unit, table, &ve, PFMf, pfm);
   2884         }
   2885     }
   2886     }
   2887 
   2888 #if defined(BCM_TRIDENT3_SUPPORT)
   2889     if (SOC_MEM_IS_VALID(unit, VLAN_ATTRS_1m)) {
   2890         vlan_attrs_1_entry_t vlan_attrs;
   2891         sal_memset(&vlan_attrs, 0, sizeof(vlan_attrs_1_entry_t));
   2892         BCM_IF_ERROR_RETURN
   2893             (soc_mem_read(unit, VLAN_ATTRS_1m, MEM_BLOCK_ANY, vd->vlan_tag, 
   2894                           &vlan_attrs));
   2895 
   2896         soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, STGf,
   2897                             BCM_STG_DEFAULT);
   2898         soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, VALIDf, 1);
   2899         soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, FID_IDf, 0);
   2900 
   2901         if (soc_feature(unit, soc_feature_mpls)) {
   2902             soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, MPLS_ENABLEf, 0x1);
   2903         }
   2904         if (soc_feature(unit, soc_feature_mim)) {
   2905             soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, MIM_TERM_ENABLEf, 0x1);
   2906         }
   2907         if (soc_feature(unit, soc_feature_vlan_filter)) {
   2908             
   2909             soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, EN_IFILTERf,
   2910                     0x1);
   2911         }
   2912         BCM_IF_ERROR_RETURN
   2913             (soc_mem_write(unit, VLAN_ATTRS_1m, MEM_BLOCK_ALL, vd->vlan_tag, 
   2914                            &vlan_attrs)); 
   2915     }
   2916     if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, L3_IIFf)) {
   2917         vlan_tab_entry_t vlan_tab;
   2918         sal_memset(&vlan_tab, 0, sizeof(vlan_tab_entry_t));
   2919         BCM_IF_ERROR_RETURN
   2920             (soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, vd->vlan_tag,
   2921                           &vlan_tab));
   2922 
   2923         soc_mem_field32_set(unit, VLAN_TABm, &vlan_tab, L3_IIFf,
   2924                             vd->vlan_tag);
   2925         BCM_IF_ERROR_RETURN
   2926             (soc_mem_write(unit, VLAN_TABm, MEM_BLOCK_ALL, vd->vlan_tag,
   2927                            &vlan_tab));
   2928     }
   2929 #endif
   2930 
   2931     BCM_IF_ERROR_RETURN
   2932         (soc_mem_write(unit, table, MEM_BLOCK_ALL, vd->vlan_tag, &ve));
   2933 
   2934 #if defined(BCM_TRIDENT3_SUPPORT)
   2935     if (table == EGR_VLANm &&
   2936         soc_feature(unit, soc_feature_vlan_vfi_untag_profile)) {
   2937         BCM_IF_ERROR_RETURN
   2938             (bcm_td3_vlan_vfi_untag_init(unit, vd->vlan_tag,
   2939                                          vd->ut_port_bitmap));
   2940     }
   2941 #endif
   2942 
   2943 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   2944     if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
   2945         BCM_IF_ERROR_RETURN(bcm_td2p_vlan_vfi_mbrship_port_set(
   2946             unit, vd->vlan_tag, (table == EGR_VLANm), TRUE, vd->port_bitmap));
   2947     }
   2948 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   2949 
   2950     return BCM_E_NONE;
   2951 }
   2952 
   2953 /*
   2954  * Function:
   2955  *      bcm_xgs3_vlan_create
   2956  * Purpose:
   2957  *      Create a VLAN entry in VLAN_TAB
   2958  */
   2959 
   2960 static int
   2961 _bcm_xgs3_vlan_table_create(int unit, bcm_vlan_t vid, int table)
   2962 {
   2963     vlan_tab_entry_t            vt;
   2964     int                         rv;
   2965 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
   2966     int       ingress_map_mode=0;
   2967 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */
   2968     int use_default = TRUE;  /* use default value for VLAN_TABm  */
   2969 
   2970     assert(sizeof(vlan_tab_entry_t) >= sizeof(egr_vlan_entry_t));
   2971     assert(sizeof(vlan_tab_entry_t) >= sizeof(vlan_2_tab_entry_t));
   2972 
   2973     /* Upper layer already checks that vid is valid */
   2974 
   2975     soc_mem_lock(unit, table);
   2976 
   2977     if ((rv = soc_mem_read(unit, table, MEM_BLOCK_ANY, (int) vid, &vt)) < 0) {
   2978         soc_mem_unlock(unit, table);
   2979         return rv;
   2980     }
   2981 
   2982     if (!SOC_IS_RELOADING(unit)) {
   2983         if (soc_mem_field32_get(unit, table, &vt, VALIDf) !=
   2984             soc_mem_field32_get(unit, table,
   2985                                 soc_mem_entry_null(unit, table), VALIDf)) {
   2986             if (!SOC_IS_KATANA2(unit)) {
   2987                 soc_mem_unlock(unit, table);
   2988                 return BCM_E_EXISTS;
   2989             }
   2990         }
   2991     }
   2992 
   2993     /* don't use default value if already pre-configured*/
   2994     if (SHR_BITGET(vlan_info[unit].pre_cfg_bmp.w,vid)) { 
   2995         use_default = FALSE;
   2996     }
   2997     /* This function will be called with VLAN_TABm, EGR_VLANm, and VLAN_2_TABm
   2998      * in TH2/TH3. In TH2/TH3, VLAN_2_TABm has STGf while VLAN_TABm does not.
   2999      * The check is to prevent STGf being set wrongly. The STG value doesn't
   3000      * matter much; it will get changed immediately after this routine completes
   3001      */
   3002     if (SOC_MEM_FIELD_VALID(unit, table, STGf)) {
   3003     soc_mem_field32_set(unit, table, &vt, STGf, 0);
   3004     }
   3005     soc_mem_field32_set(unit, table, &vt, VALIDf, 1);
   3006 
   3007 #if defined(BCM_EASY_RELOAD_SUPPORT)
   3008     if (SOC_IS_RELOADING(unit)) {
   3009         _bcm_vlan_valid_set(unit, table, vid, 1);
   3010     }
   3011 #endif
   3012 
   3013 #if defined(BCM_TOMAHAWK3_SUPPORT)
   3014     if ((table == VLAN_TABLE(unit)) &&
   3015             soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) {
   3016         pbmp_t pbmp;
   3017         uint32 profile_idx;
   3018 
   3019         /* Insert a profile entry with empty port bitmap */
   3020         SOC_PBMP_CLEAR(pbmp);
   3021         rv = _bcm_th3_vlan_pbmp_profile_entry_add(unit, pbmp, &profile_idx);
   3022         if (BCM_FAILURE(rv)) {
   3023             soc_mem_unlock(unit, table);
   3024             return rv;
   3025         }
   3026 
   3027         /* Set the corressponding profile index into the VLAN table entry */
   3028         soc_mem_field32_set(
   3029             unit, table, &vt, PORT_BITMAP_PROFILE_PTRf, profile_idx);
   3030     }
   3031 #endif /* BCM_TOMAHAWK3_SUPPORT */
   3032 
   3033 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_SCORPION_SUPPORT)
   3034     /* Set default vrf id if supported. */
   3035     if (use_default && SOC_MEM_FIELD_VALID(unit, table, VRF_IDf)) {
   3036         soc_mem_field32_set(unit, table, &vt, VRF_IDf, 0);
   3037     }
   3038 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_SCORPION_SUPPORT */
   3039 
   3040 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
   3041     /* Set L3_IIF, using vid as index into L3_IIF table */
   3042     if (SOC_MEM_FIELD_VALID(unit, table, L3_IIFf)) {
   3043         uint32 ingress_intf = 0;
   3044 
   3045         /* Check L3 Ingress Interface Map mode. */
   3046         if (soc_feature(unit, soc_feature_l3_ingress_interface)) {
   3047            BCM_IF_ERROR_RETURN(
   3048               bcm_xgs3_l3_ingress_intf_map_get(unit, &ingress_map_mode));
   3049 
   3050             if (ingress_map_mode) {
   3051                 if (soc_feature(unit, soc_feature_l3_iif_under_4k)) {
   3052                     ingress_intf = 0;
   3053                 } else {
   3054                     if (use_default) {
   3055                         ingress_intf = BCM_L3_INGRESS_INTERFACE_INVALID;
   3056                     }
   3057                 }
   3058             } else {
   3059                 ingress_intf = vid;
   3060             }
   3061         } else {
   3062             /* L3_IIFf for those device can't support L3 ingress interface 
   3063              * should be never referenced. Remaining the value at 0.
   3064              */
   3065             ingress_intf = 0;
   3066         }
   3067 
   3068         soc_mem_field32_set(unit, table, &vt, L3_IIFf, ingress_intf);
   3069     }
   3070 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */
   3071 
   3072     if (TABLE_HAS_UT_BITMAP(unit, table)) {
   3073         pbmp_t pbmp;
   3074         SOC_PBMP_CLEAR(pbmp);
   3075         soc_mem_pbmp_field_set(unit, table, &vt, UT_BITMAPf, &pbmp);
   3076     }
   3077 
   3078     if ((table == EGR_VLANm && SOC_IS_FBX(unit)) ||
   3079         (table == VLAN_TABm && SOC_IS_KATANA2(unit))) {
   3080 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
   3081  || defined(BCM_RAVEN_SUPPORT)
   3082         if (use_default && soc_feature(unit, soc_feature_vlan_ctrl)) {
   3083             uint16                    tpid;
   3084             int                       tpid_index;
   3085 
   3086             tpid = _bcm_fb2_outer_tpid_default_get(unit);
   3087 
   3088             _bcm_fb2_outer_tpid_tab_lock(unit);
   3089             rv =  _bcm_fb2_outer_tpid_entry_add(unit, tpid, &tpid_index);
   3090             _bcm_fb2_outer_tpid_tab_unlock(unit);
   3091     
   3092             if (BCM_SUCCESS(rv)) {
   3093                 soc_mem_field32_set(unit, table, &vt, OUTER_TPID_INDEXf,
   3094                                     tpid_index); 
   3095             }
   3096         } 
   3097 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   3098         if (soc_feature(unit, soc_feature_vlan_filter)) {
   3099             
   3100             soc_mem_field32_set(unit, table, &vt, EN_EFILTERf, 0x1);
   3101         }
   3102 #endif
   3103 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
   3104     }
   3105 
   3106 #if defined(BCM_TRIDENT3_SUPPORT)
   3107     if (soc_feature(unit, soc_feature_vlan_filter)) {
   3108         if (table == VLAN_TABm && SOC_IS_TRIDENT3X(unit)) {
   3109             soc_mem_field32_set(unit, table, &vt, EN_IFILTERf, 0x1);
   3110         }
   3111     }
   3112 #endif /* BCM_TRIDENT3_SUPPORT */
   3113 
   3114 #if defined(BCM_TRIDENT3_SUPPORT)
   3115     if (table == EGR_VLANm &&
   3116         soc_feature(unit, soc_feature_vlan_vfi_untag_profile)) {
   3117         pbmp_t pbmp;
   3118         SOC_PBMP_CLEAR(pbmp);
   3119         BCM_IF_ERROR_RETURN
   3120             (bcm_td3_vlan_vfi_untag_add(unit, vid, pbmp, pbmp));
   3121     }
   3122 #endif /* BCM_TRIDENT3_SUPPORT */
   3123 
   3124    /*
   3125      * Multicast flood setting
   3126      */
   3127     if (TABLE_HAS_PFM(unit, table)) {
   3128 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
   3129  || defined(BCM_RAVEN_SUPPORT)
   3130         if (soc_feature(unit, soc_feature_vlan_ctrl)) {
   3131 
   3132             if (use_default) {
   3133                 int    profile_index, rv;
   3134     
   3135                 rv = _vlan_profile_default_add(unit, &profile_index);
   3136                 if (BCM_FAILURE(rv)) {
   3137                     soc_mem_unlock(unit, table);
   3138                     return rv;
   3139                 }
   3140     
   3141                 rv = _vlan_profile_idx_set(unit, table, VLAN_PROFILE_PTRf,
   3142                                            (uint32 *)&vt, vid, profile_index);
   3143                 if (BCM_FAILURE(rv)) {
   3144                     soc_mem_unlock(unit, table);
   3145                     return rv;
   3146                 }
   3147     
   3148                 rv = soc_mem_write(unit, table, MEM_BLOCK_ALL, (int) vid, &vt);
   3149                 if (BCM_FAILURE(rv)) {
   3150                     _vlan_profile_delete(unit, profile_index);
   3151                 }
   3152                 soc_mem_unlock(unit, table);
   3153                 return rv;
   3154             }
   3155         } else 
   3156 #endif
   3157         {
   3158             bcm_vlan_mcast_flood_t mode;
   3159             int pfm;
   3160 
   3161             rv =_bcm_esw_vlan_flood_default_get(unit, &mode);
   3162             if (BCM_FAILURE(rv)) {
   3163                 soc_mem_unlock(unit, table);
   3164                 return rv;
   3165             }
   3166             rv = _bcm_vlan_mcast_flood_mode_to_pfm(unit, mode, &pfm);
   3167             if (BCM_FAILURE(rv)) {
   3168                 soc_mem_unlock(unit, table);
   3169                 return rv;
   3170             }
   3171 
   3172             if (SOC_MEM_FIELD_VALID(unit, table, PFMf)) {
   3173             soc_mem_field32_set(unit, table, &vt, PFMf, pfm);
   3174         }
   3175     }
   3176     }
   3177 
   3178     if (BCM_SUCCESS(rv)) {
   3179         rv = soc_mem_write(unit, table, MEM_BLOCK_ALL, (int) vid, &vt);
   3180     }
   3181 
   3182     soc_mem_unlock(unit, table);
   3183 
   3184     return rv;
   3185 }
   3186 
   3187 /*
   3188  * Function:
   3189  *      bcm_xgs3_vlan_destroy
   3190  * Purpose:
   3191  *      Clear a VLAN entry in VLAN_TAB
   3192  */
   3193 
   3194 static int
   3195 _bcm_xgs3_vlan_table_destroy(int unit, bcm_vlan_t vid, int table)
   3196 {
   3197     vlan_tab_entry_t            vt;
   3198     int                         rv;
   3199 
   3200     /* Upper layer already checks that vid is valid */
   3201 
   3202     soc_mem_lock(unit, table);
   3203 
   3204     if ((rv = soc_mem_read(unit, table, MEM_BLOCK_ANY, (int) vid, &vt)) < 0) {
   3205         soc_mem_unlock(unit, table);
   3206         return rv;
   3207     }
   3208 
   3209     if (_bcm_vlan_valid_check(unit, table, &vt, vid) == BCM_E_NOT_FOUND) {
   3210         soc_mem_unlock(unit, table);
   3211         return BCM_E_NOT_FOUND;
   3212     }
   3213 
   3214 #if defined(BCM_EASY_RELOAD_SUPPORT)
   3215     if (SOC_IS_RELOADING(unit)) {
   3216         _bcm_vlan_valid_set(unit, table, vid, 0);
   3217     }
   3218 #endif
   3219 
   3220 #if defined(BCM_TOMAHAWK3_SUPPORT)
   3221     if ((VLAN_TABLE(unit) == table) &&
   3222         soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) {
   3223         int profile_ptr =
   3224             soc_mem_field32_get(unit, table, &vt, PORT_BITMAP_PROFILE_PTRf);
   3225         rv = _bcm_th3_vlan_pbmp_profile_entry_delete(unit, profile_ptr);
   3226 
   3227         if (BCM_FAILURE(rv)) {
   3228             soc_mem_unlock(unit, table);
   3229             return rv;
   3230         }
   3231     }
   3232 #endif /* BCM_TOMAHAWK3_SUPPORT */
   3233 
   3234     rv = soc_mem_write(unit, table, MEM_BLOCK_ALL, (int) vid,
   3235                        soc_mem_entry_null(unit, table));
   3236     if (BCM_FAILURE(rv)) {
   3237         soc_mem_unlock(unit, table);
   3238         return rv;
   3239     }
   3240 
   3241 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
   3242     || defined(BCM_RAVEN_SUPPORT)
   3243     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
   3244         if (table == VLAN_TABm) {
   3245             int     profile_ptr, tpid_ptr;
   3246 
   3247             _bcm_fb2_outer_tpid_tab_lock(unit);
   3248 
   3249             rv = _vlan_profile_idx_get(unit, table, VLAN_PROFILE_PTRf,
   3250                                        (uint32 *)&vt, vid, &profile_ptr);
   3251             if (BCM_FAILURE(rv)) {
   3252                 _bcm_fb2_outer_tpid_tab_unlock(unit);
   3253                 soc_mem_unlock(unit, table);
   3254                 return rv;
   3255             }
   3256 
   3257             rv = _bcm_fb2_outer_tpid_lkup(unit, 
   3258                                           VLAN_PROFILE_ENTRY(unit, profile_ptr).outer_tpid,
   3259                                           &tpid_ptr);
   3260             if (BCM_FAILURE(rv)) {
   3261                 _bcm_fb2_outer_tpid_tab_unlock(unit);
   3262                 soc_mem_unlock(unit, table);
   3263                 return rv;
   3264             }
   3265 
   3266             rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_ptr);
   3267             if (BCM_FAILURE(rv)) {
   3268                 _bcm_fb2_outer_tpid_tab_unlock(unit);
   3269                 soc_mem_unlock(unit, table);
   3270                 return rv;
   3271             }
   3272 
   3273             rv = _vlan_profile_delete(unit, profile_ptr);
   3274             _bcm_fb2_outer_tpid_tab_unlock(unit);
   3275         }
   3276     }
   3277 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
   3278 
   3279 #if defined(BCM_TRIUMPH2_SUPPORT)
   3280     if (soc_feature(unit, soc_feature_gport_service_counters)) {
   3281         /* Release Service counter, if any */
   3282         _bcm_esw_flex_stat_handle_free(unit, _bcmFlexStatTypeService, vid);
   3283     }
   3284 #endif
   3285 
   3286     soc_mem_unlock(unit, table);
   3287     return rv;
   3288 }
   3289 
   3290 /*
   3291  * Function:
   3292  *      _bcm_xgs3_vlan_table_port_add
   3293  * Purpose:
   3294  *      Add ports to the VLAN bitmap in a VLAN_TAB entry.
   3295  */
   3296 int
   3297 _bcm_xgs3_vlan_table_port_add(int unit, bcm_vlan_t vid, pbmp_t pbmp,
   3298                               pbmp_t ubmp, pbmp_t ing_pbmp, int table)
   3299 {
   3300     vlan_tab_entry_t            vt;
   3301     int                         rv;
   3302     bcm_pbmp_t                  cur_pbmp;
   3303 
   3304     /* Only allow untagged ports on the vlan. */
   3305     SOC_PBMP_AND(ubmp, pbmp);
   3306 
   3307     /* Draco does not have room for CMIC/IPIC in ubmp */
   3308     SOC_PBMP_REMOVE(ubmp, PBMP_CMIC(unit));
   3309     SOC_PBMP_REMOVE(ubmp, PBMP_ST_ALL(unit));
   3310 
   3311     /* Upper layer already checks that vid is valid */
   3312 
   3313     soc_mem_lock(unit, table);
   3314 
   3315     if ((rv = soc_mem_read(unit, table, MEM_BLOCK_ANY, (int) vid, &vt)) < 0) {
   3316         soc_mem_unlock(unit, table);
   3317         return rv;
   3318     }
   3319 
   3320     if ((rv = _bcm_vlan_valid_check(unit, table, &vt, vid)) == BCM_E_NOT_FOUND) {
   3321         soc_mem_unlock(unit, table);
   3322         return rv;
   3323     }
   3324 
   3325     /*
   3326      * Update the entry for this VLAN.
   3327      */
   3328     if (TABLE_HAS_T_BITMAP(unit, table)) {
   3329 #if defined(BCM_TOMAHAWK3_SUPPORT)
   3330         if ((table == VLAN_TABLE(unit)) &&
   3331             soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) {
   3332             rv = _bcm_th3_vlan_pbmp_port_add(unit, &vt, &pbmp);
   3333             if (BCM_FAILURE(rv)) {
   3334                 soc_mem_unlock(unit, table);
   3335                 return rv;
   3336             }
   3337         } else
   3338 #endif /* BCM_TOMAHAWK3_SUPPORT */
   3339         {
   3340             soc_mem_pbmp_field_get(unit, table, &vt, PORT_BITMAPf, &cur_pbmp);
   3341             BCM_PBMP_OR(cur_pbmp, pbmp);
   3342             soc_mem_pbmp_field_set(unit, table, &vt, PORT_BITMAPf, &cur_pbmp);
   3343         }
   3344     }
   3345 
   3346     if (TABLE_HAS_UT_BITMAP(unit, table)) {
   3347         soc_mem_pbmp_field_get(unit, table, &vt, UT_BITMAPf, &cur_pbmp);
   3348         BCM_PBMP_REMOVE(cur_pbmp, pbmp);
   3349         BCM_PBMP_OR(cur_pbmp, ubmp);
   3350         soc_mem_pbmp_field_set(unit, table, &vt, UT_BITMAPf, &cur_pbmp);
   3351     }
   3352 
   3353     if (soc_mem_field_valid(unit, table, ING_PORT_BITMAPf)) {
   3354         soc_mem_pbmp_field_get(unit, table, &vt, ING_PORT_BITMAPf, &cur_pbmp);
   3355         BCM_PBMP_OR(cur_pbmp, ing_pbmp);
   3356         soc_mem_pbmp_field_set(unit, table, &vt, ING_PORT_BITMAPf, &cur_pbmp);
   3357     }
   3358 
   3359     rv = soc_mem_write(unit, table, MEM_BLOCK_ALL, (int) vid, &vt);
   3360 
   3361     soc_mem_unlock(unit, table);
   3362 
   3363     return rv;
   3364 }
   3365 
   3366 /*
   3367  * Function:
   3368  *      bcm_xgs3_vlan_port_remove
   3369  * Purpose:
   3370  *      Remove ports from the VLAN bitmap in a VLAN_TAB entry.
   3371  */
   3372 
   3373 int
   3374 _bcm_xgs3_vlan_table_port_remove(int unit, bcm_vlan_t vid, pbmp_t pbmp,
   3375                                  pbmp_t ubmp, pbmp_t ing_pbmp, int table)
   3376 {
   3377     vlan_tab_entry_t            vt;
   3378     int                         rv;
   3379     bcm_pbmp_t                  cur_pbmp;
   3380 
   3381     /* Upper layer already checks that vid is valid */
   3382 
   3383     soc_mem_lock(unit, table);
   3384 
   3385     if ((rv = soc_mem_read(unit, table, MEM_BLOCK_ANY, (int) vid, &vt)) < 0) {
   3386         soc_mem_unlock(unit, table);
   3387         return rv;
   3388     }
   3389 
   3390     if ((rv = _bcm_vlan_valid_check(unit, table, &vt, vid)) == BCM_E_NOT_FOUND) {
   3391         soc_mem_unlock(unit, table);
   3392         return rv;
   3393     }
   3394 
   3395     if (TABLE_HAS_T_BITMAP(unit, table)) {
   3396 #if defined(BCM_TOMAHAWK3_SUPPORT)
   3397         if ((table == VLAN_TABLE(unit)) &&
   3398             soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) {
   3399             rv = _bcm_th3_vlan_pbmp_port_remove(unit, &vt, &pbmp);
   3400             if (BCM_FAILURE(rv)) {
   3401                 soc_mem_unlock(unit, table);
   3402                 return rv;
   3403             }
   3404         } else
   3405 #endif /* BCM_TOMAHAWK3_SUPPORT */
   3406         {
   3407             soc_mem_pbmp_field_get(unit, table, &vt, PORT_BITMAPf, &cur_pbmp);
   3408             BCM_PBMP_REMOVE(cur_pbmp, pbmp);
   3409             soc_mem_pbmp_field_set(unit, table, &vt, PORT_BITMAPf, &cur_pbmp);
   3410         }
   3411     }
   3412 
   3413     if (TABLE_HAS_UT_BITMAP(unit, table)) {
   3414         soc_mem_pbmp_field_get(unit, table, &vt, UT_BITMAPf, &cur_pbmp);
   3415         BCM_PBMP_REMOVE(cur_pbmp, ubmp);
   3416         soc_mem_pbmp_field_set(unit, table, &vt, UT_BITMAPf, &cur_pbmp);
   3417     }
   3418 
   3419     if (soc_mem_field_valid(unit, table, ING_PORT_BITMAPf)) {
   3420         soc_mem_pbmp_field_get(unit, table, &vt, ING_PORT_BITMAPf, &cur_pbmp);
   3421         BCM_PBMP_REMOVE(cur_pbmp, ing_pbmp);
   3422         soc_mem_pbmp_field_set(unit, table, &vt, ING_PORT_BITMAPf, &cur_pbmp);
   3423     }
   3424 
   3425     rv = soc_mem_write(unit, table, MEM_BLOCK_ALL, (int) vid, &vt);
   3426 
   3427     soc_mem_unlock(unit, table);
   3428 
   3429     return rv;
   3430 }
   3431 
   3432 /*
   3433  * Function:
   3434  *      bcm_xgs3_vlan_table_port_get
   3435  * Purpose:
   3436  *      Read the port bitmap from a vlan entry. Both VLAN_TAB and EGR_VLAN
   3437  *      shall be identical, except for the untagged bitmap, which is only
   3438  *      available via EGR_VLAN.
   3439  */
   3440 
   3441 int
   3442 _bcm_xgs3_vlan_table_port_get(int unit, bcm_vlan_t vid, pbmp_t *pbmp,
   3443                               pbmp_t *ubmp, pbmp_t *ing_pbmp, uint32 table)
   3444 {
   3445     vlan_tab_entry_t            vt;
   3446 
   3447     /* Upper layer already checks that vid is valid */
   3448 
   3449     SOC_IF_ERROR_RETURN
   3450         (soc_mem_read(unit, table, MEM_BLOCK_ANY, (int) vid, &vt));
   3451 
   3452     BCM_IF_ERROR_RETURN(_bcm_vlan_valid_check(unit, table, &vt, vid));
   3453 
   3454     if (TABLE_HAS_T_BITMAP(unit, table)) {
   3455         if (pbmp != NULL) {
   3456 #if defined(BCM_TOMAHAWK3_SUPPORT)
   3457             if ((table == VLAN_TABLE(unit)) &&
   3458                 soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) {
   3459 
   3460                 int rv;
   3461                 uint32 profile_idx;
   3462 
   3463                 /* Retrieve the profile index from the VLAN table entry */
   3464                 profile_idx = soc_mem_field32_get(
   3465                     unit, VLAN_2_TABm, &vt, PORT_BITMAP_PROFILE_PTRf);
   3466 
   3467                 /* Based on the index retrieve the pbmp from the profile mem */
   3468                 rv = _bcm_th3_vlan_pbmp_profile_entry_get(  unit,
   3469                                                             profile_idx,
   3470                                                             pbmp);
   3471                 if (BCM_FAILURE(rv)) {
   3472                     return rv;
   3473                 }
   3474             } else
   3475 #endif /* BCM_TOMAHAWK3_SUPPORT */
   3476             {
   3477             soc_mem_pbmp_field_get(unit, table, &vt, PORT_BITMAPf, pbmp);
   3478         }
   3479     }
   3480     }
   3481 
   3482     if (soc_mem_field_valid(unit, table, UT_BITMAPf)) {
   3483         if (ubmp != NULL) {
   3484             soc_mem_pbmp_field_get(unit, table, &vt, UT_BITMAPf, ubmp);
   3485         }
   3486     }
   3487 
   3488     if (soc_mem_field_valid(unit, table, ING_PORT_BITMAPf)) {
   3489         if (ing_pbmp != NULL) {
   3490             soc_mem_pbmp_field_get(unit, table, &vt, ING_PORT_BITMAPf,
   3491                                    ing_pbmp);
   3492         }
   3493     }
   3494 
   3495     return BCM_E_NONE;
   3496 }
   3497 
   3498 /*
   3499  * Function:
   3500  *      bcm_xgs3_vlan_stg_get
   3501  * Purpose:
   3502  *      Read the STG number from a vlan entry.
   3503  */
   3504 
   3505 int
   3506 bcm_xgs3_vlan_stg_get(int unit, bcm_vlan_t vid, bcm_stg_t *stg_ptr)
   3507 {
   3508     vlan_tab_entry_t    vt;
   3509 
   3510 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   3511      if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
   3512          return bcm_td2p_vp_group_vlan_vpn_stg_get(unit, vid, FALSE, stg_ptr);
   3513      }
   3514 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   3515 
   3516     SOC_IF_ERROR_RETURN
   3517         (soc_mem_read(unit, VLAN_TABLE(unit), MEM_BLOCK_ANY, (int) vid, &vt));
   3518 
   3519     BCM_IF_ERROR_RETURN(_bcm_vlan_valid_check(unit, VLAN_TABLE(unit), &vt, vid));
   3520 
   3521     *stg_ptr = soc_mem_field32_get(unit, VLAN_TABLE(unit), &vt, STGf);
   3522 
   3523     return BCM_E_NONE;
   3524 }
   3525 
   3526 /*
   3527  * Function:
   3528  *      bcm_xgs3_vlan_stg_set
   3529  * Purpose:
   3530  *      Update the STG number for a VLAN_TAB entry.
   3531  */
   3532 
   3533 static int
   3534 _bcm_xgs3_vlan_table_stg_set(int unit, bcm_vlan_t vid,
   3535                               bcm_stg_t stg, int table)
   3536 {
   3537     vlan_tab_entry_t    vt;
   3538     int                 rv;
   3539 
   3540     /* Upper layer already checks that vid is valid */
   3541 
   3542     soc_mem_lock(unit, table);
   3543 
   3544     rv = soc_mem_read(unit, table, MEM_BLOCK_ANY, (int) vid, &vt);
   3545 
   3546     if (BCM_SUCCESS(rv)) {
   3547         rv = _bcm_vlan_valid_check(unit, table, &vt, vid);
   3548     }
   3549 
   3550     if (BCM_SUCCESS(rv)) {
   3551         soc_mem_field32_set(unit, table, &vt, STGf, stg);
   3552 
   3553         rv = soc_mem_write(unit, table, MEM_BLOCK_ALL, (int) vid, &vt);
   3554     }
   3555 
   3556     if (BCM_SUCCESS(rv) &&
   3557         SOC_MEM_IS_VALID(unit, VLAN_ATTRS_1m)) {
   3558         rv = soc_mem_field32_modify(unit, VLAN_ATTRS_1m, (int)vid, STGf, stg);
   3559     }
   3560 
   3561     soc_mem_unlock(unit, table);
   3562 
   3563     return rv;
   3564 }
   3565 
   3566 #ifdef BCM_KATANA_SUPPORT
   3567 /*
   3568  * Function :
   3569  *    _vlan_kt_cosq_map_set
   3570  * 
   3571  * Purpose  :
   3572  *    Set per vlan cosq number.
   3573  *
   3574  * Parameters:
   3575  *     unit  - (IN) BCM device number.
   3576  *     vid   - (IN) Vlan table entry buffer.
   3577  *     control - (IN) vlan control structure
   3578  * Return :
   3579  *    BCM_E_XXX
   3580  */
   3581 STATIC int
   3582 _vlan_kt_cosq_map_set(int unit, bcm_vlan_t vid, bcm_vlan_control_vlan_t *control)
   3583 {
   3584     vlan_cos_map_entry_t vcm;
   3585     int rv;
   3586 
   3587     rv = soc_mem_read(unit, VLAN_COS_MAPm, MEM_BLOCK_ANY, (int)vid, &vcm);
   3588     BCM_IF_ERROR_RETURN(rv);
   3589 
   3590     soc_mem_field32_set(unit, VLAN_COS_MAPm, &vcm, VALIDf, 
   3591                         ((control->flags & BCM_VLAN_COSQ_ENABLE) ? 1 : 0));
   3592 
   3593     if (control->flags & BCM_VLAN_COSQ_ENABLE) {
   3594 
   3595         if ((control->cosq < 0) || (control->cosq > 63)) {
   3596             return BCM_E_PARAM;
   3597         }
   3598         soc_mem_field32_set(unit, VLAN_COS_MAPm, &vcm, VLAN_COSf, control->cosq);
   3599         if ((((control->qos_map_id >> _BCM_QOS_MAP_SHIFT) !=
   3600                      _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE)) ||
   3601                      ((control->qos_map_id & _BCM_QOS_MAP_TYPE_MASK) >
   3602                                      _BCM_QOS_MAP_ING_QUEUE_OFFSET_MAX)) {
   3603             /* value of 0 is not a error case. It should set
   3604                                    the QUEUE_OFFSET_PROFILE_INDEXf to 0 */
   3605             if (control->qos_map_id != 0) {
   3606                 return (BCM_E_PARAM);
   3607             }
   3608         }
   3609         soc_mem_field32_set(unit, VLAN_COS_MAPm, &vcm,
   3610                      QUEUE_OFFSET_PROFILE_INDEXf,
   3611                      (control->qos_map_id & _BCM_QOS_MAP_TYPE_MASK));
   3612     }
   3613 
   3614     /* Write back updated buffer. */
   3615     rv = soc_mem_write(unit, VLAN_COS_MAPm, MEM_BLOCK_ALL, (int)vid, &vcm);
   3616     return (rv);
   3617 }
   3618 
   3619 /*
   3620  * Function :
   3621  *    _vlan_kt_cosq_map_get
   3622  * 
   3623  * Purpose  :
   3624  *    Get per vlan cosq number.
   3625  *
   3626  * Parameters:
   3627  *     unit  - (IN) BCM device number.
   3628  *     vid   - (IN) Vlan table entry buffer.
   3629  *     control- (OUT) vlan control structure.
   3630  * Return :
   3631  *    BCM_E_XXX
   3632  */
   3633 STATIC int
   3634 _vlan_kt_cosq_map_get(int unit, bcm_vlan_t vid, bcm_vlan_control_vlan_t *control) 
   3635 {
   3636     vlan_cos_map_entry_t vcm;
   3637     int rv;
   3638 
   3639     rv = soc_mem_read(unit, VLAN_COS_MAPm, MEM_BLOCK_ANY, (int)vid, &vcm);
   3640     if (BCM_FAILURE(rv)) {
   3641         return rv;
   3642     }
   3643 
   3644     if (0 == soc_mem_field32_get(unit, VLAN_COS_MAPm, &vcm, VALIDf)) {
   3645         return (BCM_E_NONE);
   3646     }
   3647 
   3648     control->flags |= BCM_VLAN_COSQ_ENABLE;
   3649     control->cosq = soc_mem_field32_get(unit, VLAN_COS_MAPm, &vcm, VLAN_COSf);
   3650     control->qos_map_id = _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE <<
   3651                                                                _BCM_QOS_MAP_SHIFT;
   3652     control->qos_map_id |= soc_mem_field32_get(unit, VLAN_COS_MAPm, &vcm,
   3653                                             QUEUE_OFFSET_PROFILE_INDEXf);
   3654     return (BCM_E_NONE);
   3655 }
   3656 #endif /* BCM_KATANA_SUPPORT */
   3657 
   3658 /*
   3659  * Function:
   3660  *      _bcm_xgs3_vlan_reload
   3661  * Purpose:
   3662  *      VLAN reload
   3663  */
   3664 
   3665 static int
   3666 _bcm_xgs3_vlan_table_reload(int unit, vbmp_t *bmp, int *count, int table)
   3667 {
   3668     vlan_tab_entry_t *vlan_entry, *vlan_tbl;
   3669     int index, total, vlan_tbl_size;
   3670     bcm_pbmp_t cur_pbmp;
   3671 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
   3672         || defined(BCM_RAVEN_SUPPORT)
   3673     int profile_ptr;
   3674     int outer_tpid, i;
   3675 #endif
   3676 #if defined(BCM_TRX_SUPPORT)
   3677     int   rv;                 /* Operation return status.*/
   3678     uint32  buf[SOC_MAX_MEM_FIELD_WORDS]; /* HW entry buffer.     */
   3679     uint32  value;
   3680 #endif
   3681 
   3682     vlan_tbl_size = sizeof(vlan_tab_entry_t) * \
   3683                     soc_mem_index_count(unit, table);
   3684     vlan_tbl = soc_cm_salloc(unit, vlan_tbl_size, "vlan tbl dma");
   3685     if (vlan_tbl == NULL) {
   3686         return BCM_E_MEMORY;
   3687     }
   3688 
   3689     sal_memset((void *)vlan_tbl, 0, vlan_tbl_size);
   3690     if (soc_mem_read_range(unit, table, MEM_BLOCK_ANY,
   3691                            soc_mem_index_min(unit, table),
   3692                            soc_mem_index_max(unit, table), vlan_tbl) < 0) {
   3693         soc_cm_sfree(unit, vlan_tbl);
   3694         return BCM_E_INTERNAL;
   3695     }
   3696 
   3697     soc_mem_lock(unit, table);
   3698 
   3699     total = *count;
   3700 
   3701     for (index = soc_mem_index_min(unit, table);
   3702          index <= soc_mem_index_max(unit, table); index++) {
   3703          vlan_entry = soc_mem_table_idx_to_pointer(unit, table,
   3704                                                    vlan_tab_entry_t *,
   3705                                                    vlan_tbl, index);
   3706 
   3707          if (soc_mem_field32_get(unit, table, vlan_entry, VALIDf)) {
   3708              if (TABLE_HAS_T_BITMAP(unit, table)) {
   3709 #if defined(BCM_TRX_SUPPORT) && defined(BCM_TOMAHAWK3_SUPPORT)
   3710                 if ((table == VLAN_TABLE(unit)) &&
   3711                     soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) {
   3712                     BCM_PBMP_CLEAR(cur_pbmp);
   3713                     profile_ptr =
   3714                         soc_mem_field32_get(
   3715                             unit, table, vlan_entry, PORT_BITMAP_PROFILE_PTRf);
   3716                     rv = _bcm_th3_vlan_pbmp_profile_entry_get(
   3717                                                 unit, profile_ptr, &cur_pbmp);
   3718                     if (BCM_FAILURE(rv)) {
   3719                         soc_mem_unlock(unit, table);
   3720                         soc_cm_sfree(unit, vlan_tbl);
   3721                         return rv;
   3722                     }
   3723                 } else
   3724 #endif /* BCM_TRX_SUPPORT && BCM_TOMAHAWK3_SUPPORT */
   3725                 {
   3726                     soc_mem_pbmp_field_get(
   3727                         unit, table, vlan_entry, PORT_BITMAPf, &cur_pbmp);
   3728                 }
   3729                  if (BCM_PBMP_IS_NULL(cur_pbmp)) {
   3730                     if ((EGR_VLANm != table) && !SHR_BITGET(bmp->w, index)) {
   3731                          
   3732                          continue;
   3733                      }
   3734                  }
   3735              }
   3736              if (!SHR_BITGET(bmp->w, index)) {
   3737                  SHR_BITSET(bmp->w, index);
   3738                  total++;
   3739              }
   3740  
   3741 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
   3742         || defined(BCM_RAVEN_SUPPORT)
   3743              profile_ptr = -1;
   3744              if (soc_mem_field_valid(unit, table, VLAN_PROFILE_PTRf)) {
   3745                  profile_ptr = soc_mem_field32_get(unit, table, vlan_entry, 
   3746                                                    VLAN_PROFILE_PTRf);
   3747              }
   3748 
   3749              if (profile_ptr >= 0) {
   3750                  VLAN_PROFILE_REF_COUNT(unit, profile_ptr)++;
   3751 
   3752                  outer_tpid = VLAN_PROFILE_ENTRY(unit, profile_ptr).outer_tpid;
   3753                  for (i = 0; i < BCM_MAX_TPID_ENTRIES; i++) {
   3754                      if (OUTER_TPID_ENTRY(unit, i) == outer_tpid) {
   3755                          OUTER_TPID_REF_COUNT(unit, i)++;
   3756                          break;
   3757                      }
   3758                 }
   3759 #if defined(BCM_TRX_SUPPORT)
   3760                 if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl) &&
   3761                     SOC_MEM_FIELD_VALID (unit,VLAN_PROFILE_TABm, PROTOCOL_PKT_INDEXf)) {
   3762                      
   3763                     rv = soc_mem_read(unit, VLAN_PROFILE_TABm, MEM_BLOCK_ANY, profile_ptr, buf);
   3764                     BCM_IF_ERROR_RETURN(rv);
   3765                     
   3766                     value = soc_mem_field32_get(unit, VLAN_PROFILE_TABm, buf, PROTOCOL_PKT_INDEXf);
   3767                     
   3768                     _bcm_prot_pkt_ctrl_reference(unit, value);
   3769                  }
   3770 #endif /*  BCM_TRX_SUPPORT  */             
   3771              }
   3772 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
   3773 
   3774 #if defined(BCM_TRIUMPH2_SUPPORT)
   3775              if (soc_feature(unit, soc_feature_gport_service_counters)) {
   3776                  if (soc_mem_field_valid(unit, table, SERVICE_CTR_IDXf)) {
   3777                      int fs_idx;
   3778                      fs_idx =
   3779                          soc_mem_field32_get(unit, table, vlan_entry,
   3780                                              SERVICE_CTR_IDXf);
   3781                      if (fs_idx) {
   3782                          _bcm_esw_flex_stat_reinit_add(unit,
   3783                                 _bcmFlexStatTypeService, fs_idx, index);
   3784                      }
   3785                  }
   3786              }
   3787 #endif
   3788         }
   3789     }
   3790 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT)
   3791     if ((VLAN_TABm == table) &&
   3792         soc_mem_field_valid(unit, VLAN_TABm, VLAN_PROFILE_PTRf)) {
   3793         /* Create a dummy reference to default outer TPID entry so
   3794          * that the default entry never gets removed.  */
   3795         OUTER_TPID_REF_COUNT(unit, 0)++;
   3796     }
   3797 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT */                                      
   3798     soc_mem_unlock(unit, table);
   3799     soc_cm_sfree(unit, vlan_tbl);
   3800     *count = total;
   3801 
   3802     return BCM_E_NONE;
   3803 }
   3804 
   3805 int
   3806 bcm_xgs3_vlan_init(int unit, bcm_vlan_data_t *vd)
   3807 {
   3808     if (SOC_IS_HAWKEYE(unit)) {
   3809         uint32 rval;
   3810         SOC_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &rval));
   3811         soc_reg_field_set(unit, VLAN_CTRLr, &rval, USE_LEARN_VIDf, 0);
   3812         soc_reg_field_set(unit, VLAN_CTRLr, &rval, LEARN_VIDf, 0);
   3813         SOC_IF_ERROR_RETURN(WRITE_VLAN_CTRLr(unit, rval));
   3814         
   3815         SOC_IF_ERROR_RETURN(READ_EGR_CONFIGr(unit, &rval));
   3816         soc_reg_field_set(unit, EGR_CONFIGr, &rval, USE_LEARN_VIDf, 0);
   3817         soc_reg_field_set(unit, EGR_CONFIGr, &rval, LEARN_VIDf, 0);
   3818         SOC_IF_ERROR_RETURN(WRITE_EGR_CONFIGr(unit, rval));
   3819     }
   3820 
   3821 #ifdef BCM_TRIUMPH2_SUPPORT
   3822     if (SOC_MEM_IS_VALID(unit, VLAN_MPLSm)) {
   3823         BCM_IF_ERROR_RETURN(_bcm_xgs3_vlan_mpls_table_init(unit, vd));
   3824     }
   3825 #endif
   3826 
   3827     /* Must call on EGR_VLANm before VLAN_TABm */
   3828     if (SOC_IS_FBX(unit) && SOC_MEM_IS_VALID(unit, EGR_VLANm)) {
   3829         BCM_IF_ERROR_RETURN(_bcm_xgs3_vlan_table_init(unit, vd, EGR_VLANm));
   3830     }
   3831 
   3832     BCM_IF_ERROR_RETURN(_bcm_xgs3_vlan_table_init(unit, vd, VLAN_TABm));
   3833     if (SOC_MEM_IS_VALID(unit,VLAN_2_TABm)) {
   3834         BCM_IF_ERROR_RETURN
   3835             (_bcm_xgs3_vlan_table_init(unit, vd, VLAN_2_TABm));
   3836     }
   3837     return BCM_E_NONE;
   3838 }
   3839 
   3840 int
   3841 bcm_xgs3_vlan_create(int unit, bcm_vlan_t vid)
   3842 {
   3843 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
   3844     int l3IntfMapMode=0;
   3845     soc_mem_t vlan_mem = VLAN_MPLSm;
   3846     uint32    entry[SOC_MAX_MEM_FIELD_WORDS];
   3847 
   3848 #if defined(BCM_TRIDENT3_SUPPORT)
   3849     if (SOC_IS_TRIDENT3X(unit)) {
   3850         vlan_mem = VLAN_TABm;
   3851     }
   3852 #endif
   3853     if (SOC_MEM_IS_VALID(unit, vlan_mem)) {
   3854         sal_memset (entry, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32));
   3855         BCM_IF_ERROR_RETURN
   3856             (soc_mem_read(unit, vlan_mem, MEM_BLOCK_ANY, vid, entry));
   3857         if (soc_feature(unit, soc_feature_l3_ingress_interface)) {
   3858           BCM_IF_ERROR_RETURN(bcm_xgs3_l3_ingress_intf_map_get(unit, &l3IntfMapMode));
   3859         }
   3860         if (l3IntfMapMode) {
   3861            /* don't use default if pre-configuration exists */
   3862            if (!SHR_BITGET(vlan_info[unit].pre_cfg_bmp.w,vid)) {
   3863                /* Disable 1:1 mapping */
   3864                if (soc_feature(unit, soc_feature_l3_iif_under_4k)) {
   3865                    /* use zero as invalid in case of IIF entries less than 4k */
   3866                    soc_mem_field32_set(unit, vlan_mem, entry, L3_IIFf, 0);
   3867                } else {
   3868                    soc_mem_field32_set(unit, vlan_mem, entry, L3_IIFf,
   3869                                    BCM_L3_INGRESS_INTERFACE_INVALID);
   3870                }
   3871            }
   3872         } else {
   3873             if ((soc_feature(unit, soc_feature_l3_iif_under_4k)) &&
   3874                     (soc_mem_field32_fit(unit, vlan_mem, L3_IIFf, vid) != SOC_E_NONE)) {
   3875                 /* use zero in case of IIF entries less than 4k and does not fit */
   3876                 soc_mem_field32_set(unit, vlan_mem, entry, L3_IIFf, 0);
   3877             }else {
   3878                 soc_mem_field32_set(unit, vlan_mem, entry, L3_IIFf, vid);
   3879             }
   3880         }
   3881 
   3882         if (SOC_MEM_FIELD_VALID(unit, vlan_mem, MPLS_ENABLEf) &&
   3883                 soc_feature(unit, soc_feature_mpls)) {
   3884             soc_mem_field32_set(unit, vlan_mem, entry, MPLS_ENABLEf, 0x1);
   3885         }
   3886 
   3887         if (SOC_MEM_FIELD_VALID(unit, vlan_mem, MIM_TERM_ENABLEf) &&
   3888                 soc_feature(unit, soc_feature_mim)) {
   3889             soc_mem_field32_set(unit, vlan_mem, entry, MIM_TERM_ENABLEf, 0x1);
   3890         }
   3891 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   3892         if (soc_feature(unit, soc_feature_vlan_filter)) {
   3893             
   3894             soc_mem_field32_set(unit, vlan_mem, entry, EN_IFILTERf,
   3895                     0x1);
   3896         }
   3897 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   3898         BCM_IF_ERROR_RETURN
   3899             (soc_mem_write(unit, vlan_mem, MEM_BLOCK_ALL, vid, entry));
   3900     }
   3901 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
   3902 
   3903 #if defined(BCM_TRIDENT3_SUPPORT)
   3904     if (SOC_MEM_IS_VALID(unit, VLAN_ATTRS_1m)) {
   3905         vlan_attrs_1_entry_t vlan_attrs;
   3906         sal_memset(&vlan_attrs, 0, sizeof(vlan_attrs_1_entry_t));
   3907         BCM_IF_ERROR_RETURN
   3908             (soc_mem_read(unit, VLAN_ATTRS_1m, MEM_BLOCK_ANY, vid, &vlan_attrs));
   3909 
   3910         soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, VALIDf, 0x1);
   3911 
   3912         if (soc_feature(unit, soc_feature_mpls)) {
   3913             soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, MPLS_ENABLEf, 0x1);
   3914         }
   3915         if (soc_feature(unit, soc_feature_mim)) {
   3916             soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, MIM_TERM_ENABLEf, 0x1);
   3917         }
   3918         if (soc_feature(unit, soc_feature_vlan_filter)) {
   3919             
   3920             soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, EN_IFILTERf, 0x1);
   3921         }
   3922         BCM_IF_ERROR_RETURN
   3923             (soc_mem_write(unit, VLAN_ATTRS_1m, MEM_BLOCK_ALL, vid, &vlan_attrs));
   3924     }
   3925 #endif
   3926 
   3927     /* Must call on EGR_VLANm before VLAN_TABm on Firebolt 2 */
   3928     if (SOC_IS_FBX(unit) && SOC_MEM_IS_VALID(unit, EGR_VLANm)) {
   3929         BCM_IF_ERROR_RETURN
   3930             (_bcm_xgs3_vlan_table_create(unit, vid, EGR_VLANm));
   3931     }
   3932     BCM_IF_ERROR_RETURN(_bcm_xgs3_vlan_table_create(unit, vid, VLAN_TABm));
   3933     if (SOC_MEM_IS_VALID(unit, VLAN_2_TABm)) {
   3934         BCM_IF_ERROR_RETURN
   3935             (_bcm_xgs3_vlan_table_create(unit, vid, VLAN_2_TABm));
   3936     }
   3937     return BCM_E_NONE;
   3938 }
   3939 
   3940 int
   3941 bcm_xgs3_vlan_destroy(int unit, bcm_vlan_t vid)
   3942 {
   3943 #ifdef BCM_TRIDENT3_SUPPORT
   3944     if (soc_feature(unit, soc_feature_vlan_vfi_untag_profile)) {
   3945         BCM_IF_ERROR_RETURN
   3946             (bcm_td3_vlan_vfi_untag_destroy(unit, vid));
   3947     }
   3948 #endif
   3949 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   3950     if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
   3951         BCM_IF_ERROR_RETURN
   3952             (bcm_td2p_vlan_vpn_membership_delete(unit, vid));
   3953     }
   3954 #endif
   3955 
   3956 #ifdef BCM_TRIUMPH2_SUPPORT
   3957     if (SOC_MEM_IS_VALID(unit, VLAN_MPLSm)) {
   3958          vlan_mpls_entry_t vlan_mpls;
   3959 
   3960          sal_memset(&vlan_mpls, 0, sizeof(vlan_mpls_entry_t));
   3961          BCM_IF_ERROR_RETURN
   3962               (soc_mem_write(unit, VLAN_MPLSm, MEM_BLOCK_ALL, vid, &vlan_mpls));
   3963     }
   3964 #endif
   3965 #ifdef BCM_TRIDENT3_SUPPORT
   3966     if (SOC_MEM_IS_VALID(unit, VLAN_ATTRS_1m)) {
   3967         vlan_attrs_1_entry_t vlan_attrs;
   3968 
   3969          sal_memset(&vlan_attrs, 0, sizeof(vlan_attrs_1_entry_t));
   3970          BCM_IF_ERROR_RETURN
   3971               (soc_mem_write(unit, VLAN_ATTRS_1m, MEM_BLOCK_ALL, vid, &vlan_attrs));
   3972     }
   3973 #endif
   3974     /* Must call on EGR_VLANm before VLAN_TABm on Firebolt 2 */
   3975     if (((SOC_IS_FBX(unit) && !SOC_IS_KATANA2(unit)) || (SAL_BOOT_BCMSIM || SAL_BOOT_PLISIM))
   3976            && (SOC_MEM_IS_VALID(unit, EGR_VLANm))) {
   3977  /* VLAN table in IP and EGR_VLAN table in EP are overlay memories and share the same physical memory.
   3978     In BCMSIM overlay of  memories is not possible, so need to explicity delete*/
   3979         BCM_IF_ERROR_RETURN
   3980             (_bcm_xgs3_vlan_table_destroy(unit, vid, EGR_VLANm));
   3981     }
   3982     if (SOC_MEM_IS_VALID(unit, VLAN_2_TABm)) {
   3983         BCM_IF_ERROR_RETURN(_bcm_xgs3_vlan_table_destroy(unit, vid, VLAN_2_TABm));
   3984     }
   3985     return _bcm_xgs3_vlan_table_destroy(unit, vid, VLAN_TABm);
   3986 }
   3987 
   3988 int
   3989 bcm_xgs3_vlan_port_add(int unit, bcm_vlan_t vid, pbmp_t pbmp, pbmp_t ubmp,
   3990                        pbmp_t ing_pbmp)
   3991 {
   3992     if (SOC_IS_FBX(unit)) {
   3993         /* Check for the presence of 'ING_PORT_BITMAPf', this could either
   3994            reside in VLAN_TABm or in the 'ING_VLAN_VFI_MEMBERSHIPm' if
   3995            'soc_feature_vlan_vfi_membership' is true */
   3996         if (!soc_mem_field_valid(unit, VLAN_TABLE(unit), ING_PORT_BITMAPf) &&
   3997             !(soc_feature(unit, soc_feature_vlan_vfi_membership))) {
   3998             BCM_PBMP_OR(pbmp, ing_pbmp);
   3999         }
   4000         if (SOC_MEM_IS_VALID(unit, EGR_VLANm) && BCM_VLAN_VALID(vid)) {
   4001             BCM_IF_ERROR_RETURN
   4002                 (_bcm_xgs3_vlan_table_port_add(unit, vid, pbmp, ubmp, ing_pbmp,
   4003                                                EGR_VLANm));
   4004         }
   4005     } else {
   4006         SOC_PBMP_OR(pbmp, ing_pbmp);
   4007     }
   4008 
   4009     if (BCM_VLAN_VALID(vid)) {
   4010         BCM_IF_ERROR_RETURN
   4011             (_bcm_xgs3_vlan_table_port_add(unit, vid, pbmp, ubmp,
   4012                         ing_pbmp, VLAN_TABLE(unit)));
   4013     }
   4014 #if defined(BCM_TRIDENT3_SUPPORT)
   4015     if (soc_feature(unit, soc_feature_vlan_vfi_untag_profile)) {
   4016         BCM_IF_ERROR_RETURN
   4017             (bcm_td3_vlan_vfi_untag_add(unit, vid, pbmp, ubmp));
   4018     }
   4019 #endif /* BCM_TRIDENT3_SUPPORT */
   4020 
   4021 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   4022     if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
   4023         BCM_IF_ERROR_RETURN(bcm_td2p_vlan_vfi_mbrship_port_set(
   4024                                     unit, vid, TRUE, TRUE, pbmp));
   4025         BCM_IF_ERROR_RETURN(bcm_td2p_vlan_vfi_mbrship_port_set(
   4026                                 unit, vid, FALSE, TRUE, ing_pbmp));
   4027     }
   4028 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   4029     return BCM_E_NONE;
   4030 }
   4031 
   4032 int
   4033 bcm_xgs3_vlan_port_remove(int unit, bcm_vlan_t vid, pbmp_t pbmp, pbmp_t ubmp,
   4034                           pbmp_t ing_pbmp)
   4035 {
   4036     if (SOC_IS_FBX(unit) && SOC_MEM_IS_VALID(unit, EGR_VLANm) &&
   4037         BCM_VLAN_VALID(vid)) {
   4038         BCM_IF_ERROR_RETURN
   4039             (_bcm_xgs3_vlan_table_port_remove(unit, vid, pbmp, ubmp,
   4040                                               ing_pbmp, EGR_VLANm));
   4041     }
   4042 
   4043     if (BCM_VLAN_VALID(vid)) {
   4044         BCM_IF_ERROR_RETURN
   4045             (_bcm_xgs3_vlan_table_port_remove(unit, vid, pbmp, ubmp,
   4046                                ing_pbmp, VLAN_TABLE(unit)));
   4047     }
   4048 		
   4049 #if defined(BCM_TRIDENT3_SUPPORT)
   4050     if (soc_feature(unit, soc_feature_vlan_vfi_untag_profile)) {
   4051         BCM_IF_ERROR_RETURN
   4052             (bcm_td3_vlan_vfi_untag_delete(unit, vid, ubmp));
   4053     }
   4054 #endif /* BCM_TRIDENT3_SUPPORT */
   4055 
   4056 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   4057     if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
   4058         BCM_IF_ERROR_RETURN(bcm_td2p_vlan_vfi_mbrship_port_set(
   4059                                     unit, vid, TRUE, FALSE, pbmp));
   4060         BCM_IF_ERROR_RETURN(bcm_td2p_vlan_vfi_mbrship_port_set(
   4061                                 unit, vid, FALSE, FALSE, ing_pbmp));
   4062     }
   4063 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   4064     return BCM_E_NONE;
   4065 }
   4066 
   4067 int
   4068 bcm_xgs3_vlan_port_get(int unit, bcm_vlan_t vid, pbmp_t *pbmp, pbmp_t *ubmp,
   4069                        pbmp_t *ing_pbmp)
   4070 {
   4071     pbmp_t local_pbmp, local_ing_pbmp;
   4072     BCM_PBMP_CLEAR(local_pbmp);
   4073     BCM_PBMP_CLEAR(local_ing_pbmp);
   4074     if (SOC_IS_FBX(unit)) {
   4075         if (BCM_VLAN_VALID(vid)) {
   4076             if (SOC_MEM_IS_VALID(unit, EGR_VLANm)) {
   4077                 BCM_IF_ERROR_RETURN
   4078                     (_bcm_xgs3_vlan_table_port_get(unit, vid, &local_pbmp, ubmp, NULL,
   4079                                                    EGR_VLANm));
   4080             }
   4081             /* coverity[result_independent_of_operands] */
   4082             if (!TABLE_HAS_T_BITMAP(unit, EGR_VLANm)) {
   4083                 BCM_IF_ERROR_RETURN
   4084                     (_bcm_xgs3_vlan_table_port_get(unit, vid, &local_pbmp, NULL,
   4085                                                    NULL, VLAN_TABLE(unit)));
   4086             }
   4087 
   4088             if (soc_mem_field_valid(unit, VLAN_TABLE(unit), ING_PORT_BITMAPf)) {
   4089                 BCM_IF_ERROR_RETURN
   4090                     (_bcm_xgs3_vlan_table_port_get(unit, vid, NULL, NULL,
   4091                                                    &local_ing_pbmp, VLAN_TABLE(unit)));
   4092             } else {
   4093                 BCM_PBMP_ASSIGN(local_ing_pbmp, local_pbmp);
   4094             }
   4095         }
   4096     } else {
   4097         if (BCM_VLAN_VALID(vid)) {
   4098             BCM_IF_ERROR_RETURN
   4099                 (_bcm_xgs3_vlan_table_port_get(unit, vid, &local_pbmp, ubmp, NULL,
   4100                                                VLAN_TABLE(unit)));
   4101                 BCM_PBMP_ASSIGN(local_ing_pbmp, local_pbmp);
   4102         }
   4103     }
   4104 
   4105 #if defined(BCM_TRIDENT3_SUPPORT)
   4106     if (soc_feature(unit, soc_feature_vlan_vfi_untag_profile)) {
   4107         BCM_IF_ERROR_RETURN
   4108             (bcm_td3_vlan_table_ut_port_get(unit, vid, ubmp));
   4109     }
   4110 #endif
   4111 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   4112     if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
   4113         BCM_IF_ERROR_RETURN(bcm_td2p_vlan_vfi_mbrship_port_get(
   4114                                     unit, vid, TRUE, &local_pbmp));
   4115         BCM_IF_ERROR_RETURN(bcm_td2p_vlan_vfi_mbrship_port_get(
   4116                                 unit, vid, FALSE, &local_ing_pbmp));
   4117     }
   4118 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   4119 
   4120     if (pbmp != NULL) {
   4121         BCM_PBMP_ASSIGN(*pbmp, local_pbmp);
   4122     }
   4123     if (ing_pbmp != NULL) {
   4124         BCM_PBMP_ASSIGN(*ing_pbmp, local_ing_pbmp);
   4125     }
   4126 
   4127     return BCM_E_NONE;
   4128 }
   4129 
   4130 int
   4131 bcm_xgs3_vlan_stg_set(int unit, bcm_vlan_t vid, bcm_stg_t stg)
   4132 {
   4133 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   4134     if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
   4135         BCM_IF_ERROR_RETURN(
   4136             bcm_td2p_vp_group_vlan_vpn_stg_set(unit, vid, TRUE, stg));
   4137 
   4138         return bcm_td2p_vp_group_vlan_vpn_stg_set(unit, vid, FALSE, stg);
   4139     }
   4140 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   4141 
   4142     if (SOC_IS_FBX(unit) && SOC_MEM_IS_VALID(unit, EGR_VLANm)) {
   4143         BCM_IF_ERROR_RETURN
   4144             (_bcm_xgs3_vlan_table_stg_set(unit, vid, stg, EGR_VLANm));
   4145     }
   4146 
   4147     return _bcm_xgs3_vlan_table_stg_set(unit, vid, stg, VLAN_TABLE(unit));
   4148 }
   4149 
   4150 int
   4151 bcm_xgs3_vlan_reload(int unit, vbmp_t *bmp, int *count)
   4152 {
   4153     int rv = BCM_E_NONE;
   4154 
   4155     if (SOC_IS_FBX(unit)) {
   4156 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
   4157  || defined(BCM_RAVEN_SUPPORT)
   4158         if (soc_feature(unit, soc_feature_vlan_ctrl)) {
   4159             BCM_IF_ERROR_RETURN(_vlan_profile_init(unit));
   4160         }
   4161 #endif
   4162 #if defined(BCM_TOMAHAWK3_SUPPORT)
   4163         if (soc_feature(unit, soc_feature_vlan_pbmp_profile_mgmt)) {
   4164             BCM_IF_ERROR_RETURN(_bcm_th3_vlan_pbmp_profile_init(unit));
   4165         }
   4166 #endif /* BCM_TOMAHAWK3_SUPPORT */
   4167 
   4168         if (SOC_MEM_IS_VALID(unit, EGR_VLANm)) {
   4169             rv = _bcm_xgs3_vlan_table_reload(unit, bmp, count, EGR_VLANm);
   4170         }
   4171     }
   4172 
   4173     if (BCM_SUCCESS(rv)) {
   4174         rv = _bcm_xgs3_vlan_table_reload(unit, bmp, count, VLAN_TABm);
   4175     }
   4176     if (BCM_SUCCESS(rv) && SOC_MEM_IS_VALID(unit, VLAN_2_TABm)) {
   4177         rv = _bcm_xgs3_vlan_table_reload(unit, bmp, count, VLAN_2_TABm);
   4178     }
   4179 
   4180     return rv;
   4181 }
   4182 
   4183 /*
   4184  * Function :
   4185  *    _bcm_xgs3_vlan_mcast_flood_set
   4186  * 
   4187  * Purpose  :
   4188  *    Set multicast flood mode. 
   4189  *
   4190  * Parameters:
   4191  *     unit  - (IN) BCM device number.
   4192  *     vlan  - (IN) Vlan id. 
   4193  *     mode  - (IN) Vlan flood mode.
   4194  *
   4195  * Return :
   4196  *    BCM_E_XXX
   4197  */
   4198 int _bcm_xgs3_vlan_mcast_flood_set(int unit,
   4199                             bcm_vlan_t vlan,
   4200                             bcm_vlan_mcast_flood_t mode)
   4201 {
   4202 
   4203     vlan_tab_entry_t    vt; 
   4204     int                 rv;
   4205     int                 pfm;
   4206 
   4207     /* Upper layer already checks that vid is valid */
   4208 
   4209     soc_mem_lock(unit, VLAN_TABm);
   4210 
   4211     rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int) vlan, &vt);
   4212     if (BCM_FAILURE(rv)) {
   4213         soc_mem_unlock(unit, VLAN_TABm);
   4214         return rv;
   4215     }
   4216 
   4217     if ((rv =_bcm_vlan_valid_check(unit, VLAN_TABm, &vt, vlan)) 
   4218         == BCM_E_NOT_FOUND) {
   4219         soc_mem_unlock(unit, VLAN_TABm);
   4220         return rv;
   4221     }
   4222 
   4223 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
   4224     || defined(BCM_RAVEN_SUPPORT)
   4225     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
   4226         int                  profile_ptr;
   4227         _vlan_profile_t      vpe;
   4228 
   4229         rv = _vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf,
   4230                                    (uint32 *)&vt, vlan, &profile_ptr);
   4231         if (BCM_FAILURE(rv)) {
   4232             soc_mem_unlock(unit, VLAN_TABm);
   4233             return rv;
   4234         }
   4235 
   4236         sal_memcpy(&vpe, &VLAN_PROFILE_ENTRY(unit, profile_ptr),  
   4237                    sizeof(_vlan_profile_t));
   4238         vpe.ip6_mcast_flood_mode = mode;
   4239         vpe.ip4_mcast_flood_mode = mode;
   4240         vpe.l2_mcast_flood_mode = mode;
   4241 
   4242         rv = _vlan_profile_update(unit, vlan, &vpe);
   4243         if (BCM_FAILURE(rv)) {
   4244             soc_mem_unlock(unit, VLAN_TABm);
   4245             return rv;
   4246         }
   4247     } else 
   4248 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
   4249     {
   4250         /*
   4251          * Update the multicast flood setting for this VLAN.
   4252          */
   4253         rv = _bcm_vlan_mcast_flood_mode_to_pfm(unit, mode, &pfm);
   4254         if (BCM_FAILURE(rv)) {
   4255             soc_mem_unlock(unit, VLAN_TABm);
   4256             return BCM_E_NOT_FOUND;
   4257         }
   4258         soc_mem_field32_set(unit, VLAN_TABm, &vt, PFMf, pfm);
   4259         rv = soc_mem_write(unit, VLAN_TABm, MEM_BLOCK_ALL, (int) vlan, &vt);
   4260     }
   4261 
   4262     soc_mem_unlock(unit, VLAN_TABm);
   4263 
   4264     if (TABLE_HAS_PFM(unit, EGR_VLANm)) {
   4265         soc_mem_lock(unit, EGR_VLANm);
   4266         if ((rv = soc_mem_read(unit, EGR_VLANm,
   4267                                MEM_BLOCK_ANY, (int) vlan, &vt)) < 0) {
   4268             soc_mem_unlock(unit, EGR_VLANm);
   4269             return rv;
   4270         }
   4271         soc_mem_field32_set(unit, EGR_VLANm, &vt, PFMf, mode);
   4272         rv = soc_mem_write(unit, EGR_VLANm, MEM_BLOCK_ALL, (int) vlan, &vt);
   4273         soc_mem_unlock(unit, EGR_VLANm);
   4274     }
   4275 
   4276     return rv;
   4277 }
   4278 
   4279 /*
   4280  * Function :
   4281  *    _bcm_xgs3_vlan_mcast_flood_get
   4282  * 
   4283  * Purpose  :
   4284  *    Get multicast flood mode. 
   4285  *
   4286  * Parameters:
   4287  *     unit  - (IN) BCM device number.
   4288  *     vlan  - (IN) Vlan id. 
   4289  *     mode  - (OUT) Vlan flood mode.
   4290  *
   4291  * Return :
   4292  *    BCM_E_XXX
   4293  */
   4294 int _bcm_xgs3_vlan_mcast_flood_get(int unit,
   4295                             bcm_vlan_t vlan,
   4296                             bcm_vlan_mcast_flood_t *mode)
   4297 {
   4298     vlan_tab_entry_t            vt;
   4299     int                         rv;
   4300 
   4301     /* Upper layer already checks that vid is valid */
   4302 
   4303     rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int) vlan, &vt);
   4304     if (BCM_FAILURE(rv)) {
   4305         return rv;
   4306     }
   4307 
   4308     BCM_IF_ERROR_RETURN(_bcm_vlan_valid_check(unit, VLAN_TABm, &vt, vlan));
   4309 
   4310     /*
   4311      * Get the multicast flood setting for this VLAN.
   4312      */
   4313 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
   4314     || defined(BCM_RAVEN_SUPPORT)
   4315     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
   4316         int index;
   4317         _vlan_profile_t *vpe;
   4318 
   4319         rv = _vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf,
   4320                                    (uint32 *)&vt, vlan, &index);
   4321         BCM_IF_ERROR_RETURN(rv);
   4322 
   4323         vpe   = &VLAN_PROFILE_ENTRY(unit, index);
   4324         *mode = vpe->l2_mcast_flood_mode;
   4325     } else 
   4326 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
   4327     {
   4328         if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, PFMf)) {
   4329         *mode = soc_mem_field32_get(unit, VLAN_TABm, &vt, PFMf);
   4330         } else {
   4331             *mode = 0;
   4332         }
   4333     }
   4334     rv = _bcm_vlan_mcast_pfm_to_flood_mode(unit, *mode, mode);
   4335     return rv;
   4336 }
   4337 #if defined (BCM_TRX_SUPPORT)
   4338 /*
   4339  * Function :
   4340  *    _vlan_control_trx_forwarding_mode_set
   4341  * 
   4342  * Purpose  :
   4343  *    Set cross - connect entry type.
   4344  *
   4345  * Parameters:
   4346  *     unit  - (IN) BCM device number.
   4347  *     buf   - (IN) Vlan table entry buffer.
   4348  *     type  - (IN) Entry type.
   4349  * Return :
   4350  *    BCM_E_XXX
   4351  */
   4352 STATIC int
   4353 _vlan_control_trx_forwarding_mode_set(int unit, uint32 *buf, 
   4354                                       bcm_vlan_forward_t type) 
   4355 {
   4356     uint32 value;
   4357 
   4358     /* Input parameters check. */
   4359     if (NULL == buf) {
   4360         return (BCM_E_PARAM);
   4361     }
   4362 
   4363     switch (type) {
   4364       case bcmVlanForwardBridging:
   4365           value = 0;
   4366           break;
   4367       case bcmVlanForwardSingleCrossConnect:
   4368           value = 1;
   4369           break;
   4370       case bcmVlanForwardDoubleCrossConnect:
   4371           value = 2;
   4372           break;
   4373       default: 
   4374           return (BCM_E_PARAM);
   4375     }
   4376     soc_mem_field32_set(unit, VLAN_TABm, buf, L2_ENTRY_KEY_TYPEf, value);
   4377     return (BCM_E_NONE);
   4378 }
   4379 
   4380 /*
   4381  * Function :
   4382  *    _vlan_control_trx_forwarding_mode_get
   4383  * 
   4384  * Purpose  :
   4385  *    Get cross - connect entry type.
   4386  *
   4387  * Parameters:
   4388  *     unit  - (IN) BCM device number.
   4389  *     buf   - (IN) Vlan table entry buffer.
   4390  *     type  - (OUT) Entry type.
   4391  * Return :
   4392  *    BCM_E_XXX
   4393  */
   4394 STATIC int
   4395 _vlan_control_trx_forwarding_mode_get(int unit, uint32 *buf, 
   4396                                       bcm_vlan_forward_t *type) 
   4397 {
   4398     uint32 value;
   4399 
   4400     /* Input parameters check. */
   4401     if ((NULL == buf) || (NULL == type)) {
   4402         return (BCM_E_PARAM);
   4403     }
   4404     value = soc_mem_field32_get(unit, VLAN_TABm, buf, L2_ENTRY_KEY_TYPEf);
   4405     switch (value) {
   4406       case 0x2:
   4407           *type = bcmVlanForwardDoubleCrossConnect;
   4408           break;
   4409       case 0x1:
   4410           *type  = bcmVlanForwardSingleCrossConnect;
   4411           break;
   4412       default:
   4413           *type = bcmVlanForwardBridging;
   4414           break;
   4415     }
   4416     return (BCM_E_NONE);
   4417 }
   4418 #endif /* BCM_TRX_SUPPORT */
   4419 
   4420 #ifdef BCM_TRIUMPH_SUPPORT
   4421 /*
   4422  * Function :
   4423  *    _vlan_cosq_map_set
   4424  * 
   4425  * Purpose  :
   4426  *    Set per vlan cosq number.
   4427  *
   4428  * Parameters:
   4429  *     unit  - (IN) BCM device number.
   4430  *     vid   - (IN) Vlan table entry buffer.
   4431  *     cosq  - (IN) VLAN control structure.
   4432  * Return :
   4433  *    BCM_E_XXX
   4434  */
   4435 STATIC int
   4436 _vlan_cosq_map_set(int unit, bcm_vlan_t vid, bcm_vlan_control_vlan_t *control)
   4437 {
   4438     vlan_cos_map_entry_t vcm;
   4439     int rv;
   4440     bcm_cos_queue_t cosq = 0;
   4441     rv = soc_mem_read(unit, VLAN_COS_MAPm, MEM_BLOCK_ANY, (int)vid, &vcm);
   4442     BCM_IF_ERROR_RETURN(rv);
   4443 
   4444     soc_mem_field32_set(unit, VLAN_COS_MAPm, &vcm, VALIDf, 
   4445                       ((control->flags & BCM_VLAN_COSQ_ENABLE) ? 1 : 0));
   4446 
   4447     if (control->flags & BCM_VLAN_COSQ_ENABLE) {
   4448 
   4449         /* Add 8 since VLAN COS queues are from 8..23 */
   4450         cosq = control->cosq + 8;
   4451         if ((cosq < 8) || (cosq > 23)) {
   4452             return BCM_E_PARAM;
   4453         }
   4454         soc_mem_field32_set(unit, VLAN_COS_MAPm, &vcm, VLAN_COSf, cosq);
   4455     }
   4456 
   4457     /* Write back updated buffer. */
   4458     rv = soc_mem_write(unit, VLAN_COS_MAPm, MEM_BLOCK_ALL, (int)vid, &vcm);
   4459     return (rv);
   4460 }
   4461 
   4462 /*
   4463  * Function :
   4464  *    _vlan_cosq_map_get
   4465  * 
   4466  * Purpose  :
   4467  *    Get per vlan cosq number.
   4468  *
   4469  * Parameters:
   4470  *     unit  - (IN) BCM device number.
   4471  *     vid   - (IN) Vlan table entry buffer.
   4472  *     control- (OUT) vlan control structure.
   4473  * Return :
   4474  *    BCM_E_XXX
   4475  */
   4476 STATIC int
   4477 _vlan_cosq_map_get(int unit, bcm_vlan_t vid, bcm_vlan_control_vlan_t *control) 
   4478 {
   4479     vlan_cos_map_entry_t vcm;
   4480     int rv;
   4481 
   4482     rv = soc_mem_read(unit, VLAN_COS_MAPm, MEM_BLOCK_ANY, (int)vid, &vcm);
   4483     if (BCM_FAILURE(rv)) {
   4484         return rv;
   4485     }
   4486 
   4487     if (0 == soc_mem_field32_get(unit, VLAN_COS_MAPm, &vcm, VALIDf)) {
   4488         return (BCM_E_NONE);
   4489     }
   4490 
   4491     control->flags |= BCM_VLAN_COSQ_ENABLE;
   4492     /* Subtract 8 since VLAN COS queues are from 8..23 */
   4493     control->cosq = soc_mem_field32_get(unit, VLAN_COS_MAPm, &vcm, VLAN_COSf) - 8;
   4494     return (BCM_E_NONE);
   4495 }
   4496 #endif /* BCM_TRIUMPH_SUPPORT */
   4497 
   4498 #if defined(INCLUDE_L3)
   4499 /*
   4500  * Function :
   4501  *     _bcm_xgs3_vlan_control_vpn_get
   4502  *
   4503  * Purpose  :
   4504  *     Reads VFI table and fills vlan_control
   4505  *
   4506  * Parameters:
   4507  *     unit    - (IN) BCM device number.
   4508  *     vid     - (IN) Vlan id.
   4509  *     valid_fields - (IN) Valid fields, BCM_VLAN_CONTROL_VLAN_XXX_MASK.
   4510  *     control - (OUT) Configuration structure.
   4511  *
   4512  * Return :
   4513  *    BCM_E_XXX
   4514  */
   4515  int
   4516  _bcm_xgs3_vlan_control_vpn_get(int unit, bcm_vlan_t vid, uint32 valid_fields,
   4517                                 bcm_vlan_control_vlan_t *control)
   4518 {
   4519     int rv;
   4520     int vfi;
   4521     int value;
   4522     vfi_entry_t vfi_entry;
   4523     soc_mem_t mem = VFIm;
   4524 
   4525     _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vid);
   4526 
   4527     /* Read the VFI memory */
   4528     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, (int)vfi, &vfi_entry);
   4529     if (!SOC_SUCCESS(rv)) {
   4530         return rv;
   4531     }
   4532 
   4533     /* Get the CLASS_ID */
   4534     if (valid_fields & BCM_VLAN_CONTROL_VLAN_IF_CLASS_MASK) {
   4535         if (soc_mem_field_valid(unit, mem, CLASS_IDf)) {
   4536             value = soc_mem_field32_get(unit, mem, &vfi_entry, CLASS_IDf);
   4537             control->if_class = value;
   4538             control->flags |= (control->if_class) ? BCM_VLAN_L2_CLASS_ID_ONLY : 0;
   4539         }
   4540     }
   4541 
   4542     return BCM_E_NONE;
   4543 }
   4544 #endif /* INCLUDE_L3 */
   4545 
   4546 uint32
   4547 _bcm_xgs3_vlan_mcast_idx_get(int unit, const void *entbuf, soc_field_t field)
   4548 {
   4549     uint32 fval = 0;
   4550     uint32 dest_type = 0;
   4551     soc_mem_t vtab = VLAN_TABm;
   4552     int fidx = 0;
   4553     soc_field_t idxfld;
   4554 
   4555     soc_field_t idx_f[3] = {
   4556         BC_IDXf,
   4557         UMC_IDXf,
   4558         UUC_IDXf
   4559     };
   4560     soc_field_t dst_idx_f[3] = {
   4561         BC_DESTINATIONf,
   4562         UMC_DESTINATIONf,
   4563         UUC_DESTINATIONf
   4564     };
   4565 
   4566     switch (field) {
   4567         case BC_IDXf:
   4568             fidx = 0;
   4569             break;
   4570         case UMC_IDXf:
   4571             fidx = 1;
   4572             break;
   4573         case UUC_IDXf:
   4574             fidx = 2;
   4575             break;
   4576         default:
   4577             return fval;
   4578             break;
   4579     }
   4580     if (soc_feature(unit, soc_feature_generic_dest)) {
   4581         idxfld = dst_idx_f[fidx];
   4582     } else {
   4583         idxfld = idx_f[fidx];
   4584     }
   4585 
   4586     if (SOC_MEM_FIELD_VALID(unit, vtab, idxfld)) {
   4587         if (soc_feature(unit, soc_feature_generic_dest)) {
   4588             fval = soc_mem_field32_dest_get(unit, vtab, entbuf, idxfld,
   4589                                             &dest_type);
   4590             if (dest_type != SOC_MEM_FIF_DEST_IPMC) {
   4591                 fval = 0;
   4592             }
   4593         } else {
   4594             fval = soc_mem_field32_get(unit, vtab, entbuf, idxfld);
   4595         }
   4596     }
   4597 
   4598     return fval;
   4599 }
   4600 
   4601 void
   4602 _bcm_xgs3_vlan_mcast_idx_set(int unit, void *entbuf, soc_field_t field,
   4603                              uint32 fval)
   4604 {
   4605     soc_mem_t vtab = VLAN_TABm;
   4606     int fidx = 0;
   4607     soc_field_t idxfld;
   4608 
   4609     soc_field_t idx_f[3] = {
   4610         BC_IDXf,
   4611         UMC_IDXf,
   4612         UUC_IDXf
   4613     };
   4614     soc_field_t dst_idx_f[3] = {
   4615         BC_DESTINATIONf,
   4616         UMC_DESTINATIONf,
   4617         UUC_DESTINATIONf
   4618     };
   4619 
   4620     switch (field) {
   4621         case BC_IDXf:
   4622             fidx = 0;
   4623             break;
   4624         case UMC_IDXf:
   4625             fidx = 1;
   4626             break;
   4627         case UUC_IDXf:
   4628             fidx = 2;
   4629             break;
   4630         default:
   4631             break;
   4632     }
   4633     if (soc_feature(unit, soc_feature_generic_dest)) {
   4634         idxfld = dst_idx_f[fidx];
   4635     } else {
   4636         idxfld = idx_f[fidx];
   4637     }
   4638 
   4639     if (SOC_MEM_FIELD_VALID(unit, vtab, idxfld)) {
   4640         if (soc_feature(unit, soc_feature_generic_dest)) {
   4641             soc_mem_field32_dest_set(unit, vtab, entbuf, idxfld,
   4642                                      SOC_MEM_FIF_DEST_IPMC, fval);
   4643         } else {
   4644             soc_mem_field32_set(unit, vtab, entbuf, idxfld, fval);
   4645         }
   4646     }
   4647 
   4648     return ;
   4649 }
   4650 
   4651 /*
   4652  * Function :
   4653  *    _bcm_xgs3_vlan_control_vlan_get
   4654  * 
   4655  * Purpose  :
   4656  *    Get vlan specific traffic forwarding parameters
   4657  *
   4658  * Parameters:
   4659  *     unit    - (IN) BCM device number.
   4660  *     vid     - (IN) Vlan id. 
   4661  *     valid_fields - (IN) Valid fields, BCM_VLAN_CONTROL_VLAN_XXX_MASK.
   4662  *     control - (IN) Configuration.
   4663  *
   4664  * Return :
   4665  *    BCM_E_XXX
   4666  */
   4667 int
   4668 _bcm_xgs3_vlan_control_vlan_get(int unit, bcm_vlan_t vid,
   4669                           uint32 valid_fields, bcm_vlan_control_vlan_t *control)
   4670 {
   4671     int  rv = BCM_E_UNAVAIL;
   4672 
   4673 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
   4674  || defined(BCM_RAVEN_SUPPORT)
   4675     int                          profile_index;
   4676     vlan_tab_entry_t             vt;
   4677     _vlan_profile_t              *vpt;
   4678 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
   4679     int enable;
   4680     int  ingress_map_mode=0;
   4681     _bcm_l3_ingress_intf_t iif;
   4682 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */
   4683     int pre_cfg = FALSE;
   4684 
   4685     if (!soc_feature(unit, soc_feature_vlan_ctrl)) {
   4686         return BCM_E_UNAVAIL;
   4687     }
   4688 
   4689     sal_memset(control, 0, sizeof(bcm_vlan_control_vlan_t));
   4690 
   4691 #if (defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || \
   4692      defined(BCM_GREYHOUND2_SUPPORT)) && defined(INCLUDE_L3)
   4693     if (_BCM_VPN_VFI_IS_SET(vid)) {
   4694         if (soc_feature(unit, soc_feature_vfi_profile)) {
   4695 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   4696             return bcmi_td2p_vlan_control_vpn_get(
   4697                     unit, vid, valid_fields, control);
   4698 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   4699         } else {
   4700 #ifdef BCM_GREYHOUND2_SUPPORT
   4701             if (soc_feature(unit, soc_feature_vxlan_lite_riot)) {
   4702                 return bcmi_gh2_vlan_control_vpn_get(unit, vid, valid_fields,
   4703                                                      control);
   4704             } else
   4705 #endif /* BCM_GREYHOUND2_SUPPORT */
   4706             {
   4707                 return _bcm_xgs3_vlan_control_vpn_get(unit, vid, valid_fields,
   4708                                                       control);
   4709             }
   4710         }
   4711     }
   4712 #endif /* (TRIDENT2PLUS || TOMAHAWK || GREYHOUND2) && INCLUDE_L3 */
   4713 
   4714     /* check if pre-configuration exists before vlan is created*/
   4715     if (!SHR_BITGET(vlan_info[unit].bmp.w, vid)) {
   4716         if (!SHR_BITGET(vlan_info[unit].pre_cfg_bmp.w,vid)) {
   4717             return BCM_E_PARAM;
   4718         } else {
   4719             pre_cfg = TRUE;
   4720         }
   4721     }
   4722 
   4723     soc_mem_lock(unit, VLAN_TABm);
   4724     /* Don't need to lock the cached outer TPID table.
   4725      * because the TPID entries referenced by the VLAN_TAB cannot
   4726      * be removed if the VLAN_TAB is lock.
   4727      */
   4728 
   4729     rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vid, &vt);
   4730     if (BCM_FAILURE(rv)) {
   4731         soc_mem_unlock(unit, VLAN_TABm);
   4732         return rv;
   4733     }
   4734 
   4735 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
   4736     if (soc_feature(unit, soc_feature_l3_ingress_interface)) {
   4737         rv = bcm_xgs3_l3_ingress_intf_map_get(unit, &ingress_map_mode);
   4738         if (BCM_FAILURE(rv)) {
   4739             soc_mem_unlock(unit, VLAN_TABm);
   4740             return rv;
   4741         }
   4742     }
   4743 #endif /* BCM_TRIUMPH_SUPPORT  && INCLUDE_L3 */
   4744 
   4745     /* Get VRF */
   4746     if (valid_fields & BCM_VLAN_CONTROL_VLAN_VRF_MASK) {
   4747         if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VRF_IDf)) {
   4748            control->vrf = soc_mem_field32_get(unit, VLAN_TABm, &vt, VRF_IDf);
   4749         }
   4750 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
   4751         else if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_l3) && 
   4752                 soc_feature(unit, soc_feature_l3_ingress_interface) && 
   4753                 SOC_MEM_IS_VALID(unit,L3_IIFm)) {
   4754             if (soc_feature(unit, soc_feature_no_vlan_vrf)) {
   4755                 /* 
   4756                  * Return E_UNAVAIL for those device can't support VID 1:1 
   4757                  * mapping to L3_IIFm to set VLAN based VRF_ID
   4758                  */
   4759 #if defined(BCM_GREYHOUND2_SUPPORT)
   4760                 if (SOC_IS_GREYHOUND2(unit)) {
   4761                     if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, L3_IIFf)) {
   4762                         if (soc_mem_field32_get(unit, VLAN_TABm, &vt, L3_IIFf)
   4763                             && (ingress_map_mode)) {
   4764                             iif.intf_id = soc_mem_field32_get(unit, VLAN_TABm,
   4765                                                               &vt, L3_IIFf);
   4766                             rv = _bcm_tr_l3_ingress_interface_get(unit, NULL,
   4767                                                                   &iif);
   4768                             if (BCM_FAILURE(rv)) {
   4769                                 soc_mem_unlock(unit, VLAN_TABm);
   4770                                 return rv;
   4771                             }
   4772                             control->vrf = iif.vrf;
   4773                         }
   4774                     }
   4775                 } else
   4776 #endif /* BCM_GREYHOUND2_SUPPORT */
   4777                 {
   4778                     soc_mem_unlock(unit, VLAN_TABm);
   4779                     return BCM_E_UNAVAIL;
   4780                 }
   4781             } else if (!ingress_map_mode) {
   4782             rv = _bcm_tr_l3_intf_vrf_get(unit, vid, &control->vrf);
   4783             if (BCM_FAILURE(rv)) {
   4784                 soc_mem_unlock(unit, VLAN_TABm);
   4785                 return rv;
   4786             }
   4787         }
   4788         }
   4789 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */
   4790     }
   4791 
   4792 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
   4793     if (soc_feature(unit, soc_feature_l3) && 
   4794             soc_feature(unit, soc_feature_l3_ingress_interface) &&
   4795             (!ingress_map_mode)) {
   4796         if (SOC_MEM_FIELD_VALID(unit, L3_IIFm, ALLOW_GLOBAL_ROUTEf) ||
   4797             SOC_IS_TD2_TT2(unit)) {
   4798             rv =  _bcm_tr_l3_intf_global_route_enable_get(unit, vid, &enable);
   4799             if (BCM_FAILURE(rv)) {
   4800                 soc_mem_unlock(unit, VLAN_TABm);
   4801                 return rv;
   4802             }
   4803             if (0 == enable) {
   4804                 control->flags |= BCM_VLAN_L3_VRF_GLOBAL_DISABLE;
   4805             }
   4806         }
   4807     }
   4808     if (valid_fields & BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK) {
   4809         if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, L3_IIFf) && 
   4810                 soc_feature(unit, soc_feature_l3_ingress_interface) && 
   4811                 soc_feature(unit, soc_feature_l3)) {
   4812 
   4813                 /* Get Vlan mapping */
   4814                 control->ingress_if = soc_mem_field32_get(unit,
   4815                            VLAN_TABm, &vt, L3_IIFf);
   4816         }
   4817     }
   4818 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */
   4819 #if defined(BCM_TRIUMPH2_SUPPORT) && defined (INCLUDE_L3)
   4820     if (soc_feature(unit, soc_feature_l3) 
   4821             && soc_feature(unit, soc_feature_l3_ingress_interface) 
   4822             && (!ingress_map_mode)) {
   4823         if (valid_fields & BCM_VLAN_CONTROL_VLAN_URPF_MODE_MASK) {
   4824             if (SOC_MEM_FIELD_VALID(unit, L3_IIFm, URPF_MODEf) ||
   4825                            soc_feature(unit, soc_feature_l3_iif_profile)) {
   4826                 rv = _bcm_tr2_l3_intf_urpf_mode_get(unit, vid, &control->urpf_mode);
   4827                 if (BCM_FAILURE(rv)) {
   4828                    soc_mem_unlock(unit, VLAN_TABm);
   4829                    return rv;
   4830                 }
   4831             }
   4832         }
   4833         if (SOC_MEM_FIELD_VALID(unit, L3_IIFm, URPF_DEFAULTROUTECHECKf) ||
   4834                    soc_feature(unit, soc_feature_l3_iif_profile)) {
   4835             rv =  _bcm_tr2_l3_intf_urpf_default_route_get(unit, vid, &enable);
   4836             if (BCM_FAILURE(rv)) {
   4837                 soc_mem_unlock(unit, VLAN_TABm);
   4838                 return rv;
   4839             }
   4840             if (0 == enable) {
   4841                 control->flags |= BCM_VLAN_L3_URPF_DEFAULT_ROUTE_CHECK_DISABLE;
   4842             }
   4843         }
   4844     }
   4845     if (soc_feature(unit, soc_feature_mpls)) {
   4846         int mpls_enable = 0;
   4847         if (SOC_MEM_IS_VALID(unit, VLAN_MPLSm)) {
   4848         vlan_mpls_entry_t vlan_mpls_entry;
   4849         sal_memset(&vlan_mpls_entry, 0, sizeof(vlan_mpls_entry_t));
   4850         rv = soc_mem_read(unit, VLAN_MPLSm, MEM_BLOCK_ANY, vid,
   4851             &vlan_mpls_entry);
   4852         if (BCM_FAILURE(rv)) {
   4853             soc_mem_unlock(unit, VLAN_TABm);
   4854             return rv;
   4855         }
   4856             mpls_enable = soc_mem_field32_get(unit, VLAN_MPLSm,
   4857                                 &vlan_mpls_entry, MPLS_ENABLEf);
   4858             if (0 == mpls_enable) {
   4859                 control->flags |= BCM_VLAN_MPLS_DISABLE;
   4860             }
   4861         }
   4862 #if defined(BCM_TRIDENT3_SUPPORT)
   4863         if (SOC_MEM_IS_VALID(unit, VLAN_ATTRS_1m)) {
   4864             vlan_attrs_1_entry_t vlan_attrs;
   4865             sal_memset(&vlan_attrs, 0, sizeof(vlan_attrs_1_entry_t));
   4866             rv = soc_mem_read(unit, VLAN_ATTRS_1m, MEM_BLOCK_ANY, vid,
   4867                               &vlan_attrs);
   4868             if (BCM_FAILURE(rv)) {
   4869                 soc_mem_unlock(unit, VLAN_TABm);
   4870                 return rv;
   4871             }
   4872             mpls_enable = soc_mem_field32_get(unit, VLAN_ATTRS_1m,
   4873                                               &vlan_attrs, MPLS_ENABLEf);
   4874             if (0 == mpls_enable) {
   4875                 control->flags |= BCM_VLAN_MPLS_DISABLE;
   4876             }
   4877         }
   4878 #endif
   4879     }
   4880 
   4881 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   4882     if (soc_feature(unit, soc_feature_vlan_filter)) {
   4883         vlan_tab_entry_t vlan_tab;
   4884         sal_memset(&vlan_tab, 0, sizeof(vlan_tab));
   4885         rv = soc_mem_read(unit, EGR_VLANm, MEM_BLOCK_ANY,
   4886                             vid, &vlan_tab);
   4887         if (BCM_FAILURE(rv)) {
   4888             soc_mem_unlock(unit, VLAN_TABm);
   4889             return rv;
   4890         }
   4891 
   4892         if (soc_mem_field32_get(unit, EGR_VLANm,
   4893                                 &vlan_tab, EN_EFILTERf) == 0) {
   4894             control->flags2 |= BCM_VLAN_FLAGS2_MEMBER_EGRESS_DISABLE;
   4895         }
   4896 
   4897         if (SOC_MEM_IS_VALID(unit, VLAN_ATTRS_1m)) {
   4898             vlan_attrs_1_entry_t vlan_attrs;
   4899             sal_memset(&vlan_attrs, 0, sizeof(vlan_attrs));
   4900             rv = soc_mem_read(unit, VLAN_ATTRS_1m, MEM_BLOCK_ANY,
   4901                                 vid, &vlan_attrs);
   4902             if (BCM_FAILURE(rv)) {
   4903                 soc_mem_unlock(unit, VLAN_TABm);
   4904                 return rv;
   4905             }
   4906 
   4907             if (soc_mem_field32_get(unit, VLAN_ATTRS_1m,
   4908                                     &vlan_attrs, EN_IFILTERf) == 0) {
   4909                 control->flags2 |= BCM_VLAN_FLAGS2_MEMBER_INGRESS_DISABLE;
   4910             }
   4911         } else if (SOC_MEM_IS_VALID(unit, VLAN_MPLSm)) {
   4912             vlan_mpls_entry_t vlan_mpls;
   4913             sal_memset(&vlan_mpls, 0, sizeof(vlan_mpls));
   4914             rv = soc_mem_read(unit, VLAN_MPLSm, MEM_BLOCK_ANY,
   4915                                 vid, &vlan_mpls);
   4916             if (BCM_FAILURE(rv)) {
   4917                 soc_mem_unlock(unit, VLAN_TABm);
   4918                 return rv;
   4919             }
   4920 
   4921             if (soc_mem_field32_get(unit, VLAN_MPLSm,
   4922                                     &vlan_mpls, EN_IFILTERf) == 0) {
   4923                 control->flags2 |= BCM_VLAN_FLAGS2_MEMBER_INGRESS_DISABLE;
   4924             }
   4925         }
   4926     }
   4927 #endif
   4928 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
   4929 #if defined(BCM_TRIDENT2_SUPPORT) && defined (INCLUDE_L3)
   4930     if (soc_feature(unit, soc_feature_l3_iif_profile) && (!ingress_map_mode)) {
   4931         rv = _bcm_td2_l3_intf_iif_profile_get(unit, vid, control);
   4932         if (BCM_FAILURE(rv)) {
   4933             soc_mem_unlock(unit, VLAN_TABm);
   4934             return rv;
   4935         }
   4936     }
   4937 
   4938 #endif /* BCM_TRIDENT2_SUPPORT */
   4939 #if defined(BCM_TRX_SUPPORT)
   4940     if (valid_fields & BCM_VLAN_CONTROL_VLAN_IF_CLASS_MASK) {
   4941         if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VLAN_CLASS_IDf)) {
   4942             control->if_class =
   4943                 soc_mem_field32_get(unit, VLAN_TABm, &vt, VLAN_CLASS_IDf);
   4944                 control->flags |= BCM_VLAN_L2_CLASS_ID_ONLY;
   4945         }
   4946     }
   4947 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
   4948     if (valid_fields & BCM_VLAN_CONTROL_VLAN_L3_IF_CLASS_MASK) {
   4949         if (soc_feature(unit, soc_feature_l3_ingress_interface)) {
   4950             if (!ingress_map_mode) {
   4951                 iif.intf_id = vid;
   4952                 rv = _bcm_tr_l3_ingress_interface_get(unit, NULL, &iif);
   4953                 if (BCM_FAILURE(rv)) {
   4954                     soc_mem_unlock(unit, VLAN_TABm);
   4955                     return rv;
   4956                 }
   4957                 control->l3_if_class = iif.if_class;
   4958                 control->flags |= BCM_VLAN_L3_CLASS_ID;
   4959             }
   4960         }
   4961     }
   4962 #endif  /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */
   4963     if (valid_fields & BCM_VLAN_CONTROL_VLAN_FORWARDING_MODE_MASK) {
   4964         if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, L2_ENTRY_KEY_TYPEf)) {
   4965             rv = _vlan_control_trx_forwarding_mode_get(unit, (uint32 *)&vt,
   4966                                                        &control->forwarding_mode);
   4967             if (BCM_FAILURE(rv)) {
   4968                 soc_mem_unlock(unit, VLAN_TABm);
   4969                 return rv;
   4970             }
   4971         }
   4972     }
   4973 #endif /* BCM_TRX_SUPPORT */
   4974 
   4975 #if defined(BCM_HELIX5_SUPPORT)
   4976     if (soc_feature(unit, soc_feature_vlan_wirelss_traffic_select)) {
   4977         rv = soc_mem_field32_get(unit, VLAN_TABm, &vt, WIRED_WIRELESSf);
   4978         if(rv == 0x1) {
   4979             control->flags2 |= BCM_VLAN_FLAGS2_WIRED_COS_MAP_SELECT;
   4980         }
   4981         if(rv == 0x2) {
   4982             control->flags2 |= BCM_VLAN_FLAGS2_WIRELESS_COS_MAP_SELECT;
   4983         }
   4984     }
   4985 #endif
   4986 #if defined(BCM_TRX_SUPPORT)
   4987     if (valid_fields & BCM_VLAN_CONTROL_VLAN_FORWARDING_VLAN_MASK) {
   4988         if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, FID_IDf)) {
   4989             control->forwarding_vlan = soc_mem_field32_get(unit, VLAN_TABm,
   4990                                                            &vt, FID_IDf);
   4991         }
   4992     }
   4993 #endif /* BCM_TRX_SUPPORT */
   4994 
   4995 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
   4996     if (valid_fields & BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK) {
   4997         if(soc_feature(unit, soc_feature_l3)) {
   4998             if (SOC_MEM_IS_VALID(unit, VLAN_MPLSm)) {
   4999                 vlan_mpls_entry_t vlan_mpls;
   5000 
   5001                 sal_memset(&vlan_mpls, 0, sizeof(vlan_mpls_entry_t));
   5002                 rv = soc_mem_read(unit, VLAN_MPLSm, MEM_BLOCK_ANY, vid,
   5003                                   &vlan_mpls);
   5004                 if (BCM_FAILURE(rv)) {
   5005                     soc_mem_unlock(unit, VLAN_TABm);
   5006                     return rv;
   5007                 }
   5008                 /* Get Vlan mapping */
   5009                 control->ingress_if = soc_mem_field32_get(unit, VLAN_MPLSm,
   5010                         &vlan_mpls, L3_IIFf);
   5011 
   5012 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_METROLITE_SUPPORT)
   5013                 if ((SOC_IS_MONTEREY(unit) || SOC_IS_METROLITE(unit)) &&
   5014                     soc_feature(unit, soc_feature_l3_ingress_interface) &&
   5015                     !soc_feature(unit, soc_feature_no_vlan_vrf) &&
   5016                     (valid_fields & BCM_VLAN_CONTROL_VLAN_VRF_MASK) &&
   5017                     (ingress_map_mode)) {
   5018 
   5019                     iif.intf_id = control->ingress_if;
   5020 
   5021                     rv = _bcm_tr_l3_ingress_interface_get(unit, NULL, &iif);
   5022                     if (BCM_FAILURE(rv)) {
   5023                         soc_mem_unlock(unit, VLAN_TABm);
   5024                         return rv;
   5025                     }
   5026 
   5027                     control->vrf = iif.vrf;
   5028                 }
   5029 #endif
   5030 #if defined(BCM_MONTEREY_SUPPORT)
   5031                 if ((SOC_IS_MONTEREY(unit) &&
   5032                     (ingress_map_mode) &&
   5033                     (valid_fields & BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK))) {
   5034                     BCM_IF_ERROR_RETURN(
   5035                             _bcm_td2_l3_intf_iif_profile_get(unit, control->ingress_if, control));
   5036                 }
   5037 #endif /* BCM_MONTEREY_SUPPORT */
   5038             }
   5039         }
   5040     }
   5041 
   5042     if (valid_fields & BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK) {
   5043         int idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vt, BC_IDXf);
   5044         if (idx) {
   5045             rv = _bcm_tr_multicast_ipmc_group_type_get(unit, idx,
   5046                     &control->broadcast_group);
   5047                 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
   5048                     soc_mem_unlock(unit, VLAN_TABm);
   5049                     return rv;
   5050                 }
   5051             }
   5052         }
   5053 
   5054     if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK) {
   5055         int idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vt, UMC_IDXf);
   5056         if (idx) {
   5057             rv = _bcm_tr_multicast_ipmc_group_type_get(unit, idx,
   5058                     &control->unknown_multicast_group);
   5059                 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
   5060                     soc_mem_unlock(unit, VLAN_TABm);
   5061                     return rv;
   5062                 }
   5063             }
   5064         }
   5065 
   5066     if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK) {
   5067         int idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vt, UUC_IDXf);
   5068         if (idx) {
   5069             rv = _bcm_tr_multicast_ipmc_group_type_get(unit, idx,
   5070                     &control->unknown_unicast_group);
   5071                 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
   5072                     soc_mem_unlock(unit, VLAN_TABm);
   5073                     return rv;
   5074                 }
   5075             }
   5076         }
   5077 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
   5078 
   5079 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
   5080     if (soc_feature(unit, soc_feature_trill)) {
   5081         if (valid_fields & BCM_VLAN_CONTROL_VLAN_TRILL_NONUNICAST_GROUP_MASK) {
   5082             if (soc_mem_field32_get(unit, VLAN_TABm,
   5083                         &vt, TRILL_DOMAIN_NONUC_REPL_INDEXf)) {
   5084                 _BCM_MULTICAST_GROUP_SET(control->trill_nonunicast_group,
   5085                     _BCM_MULTICAST_TYPE_TRILL,
   5086                     soc_mem_field32_get(unit, VLAN_TABm,
   5087                         &vt, TRILL_DOMAIN_NONUC_REPL_INDEXf));
   5088             }
   5089         }
   5090         if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm,
   5091                     TRILL_TRANSIT_IGMP_MLD_PAYLOAD_TO_CPUf)) {
   5092             if ( !soc_mem_field32_get(unit, VLAN_TABm, &vt,
   5093                         TRILL_TRANSIT_IGMP_MLD_PAYLOAD_TO_CPUf )) {
   5094                 control->flags |= BCM_VLAN_TRILL_IGMP_SNOOP_DISABLE;
   5095             }
   5096         }
   5097         /* Get per-Vlan trill_name */
   5098         if (valid_fields & BCM_VLAN_CONTROL_VLAN_SOURCE_TRILL_NAME_MASK) {
   5099             if (soc_mem_field_valid (unit, VLAN_TABm, TRILL_RBRIDGE_NICKNAME_INDEXf)) {
   5100                 rv = bcm_td_trill_source_trill_idx_name_get(unit,
   5101                                   soc_mem_field32_get(unit, VLAN_TABm,
   5102                                   &vt, TRILL_RBRIDGE_NICKNAME_INDEXf),
   5103                                   &control->source_trill_name);
   5104                 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
   5105                     soc_mem_unlock(unit, VLAN_TABm);
   5106                     return rv;
   5107                 }
   5108             }
   5109         }
   5110     }
   5111 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
   5112 
   5113 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
   5114     if (valid_fields & BCM_VLAN_CONTROL_VLAN_VP_MCAST_MASK) {
   5115         if (SHR_BITGET(vlan_info[unit].vp_mode, vid)) {
   5116             if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf) &&
   5117                 soc_mem_field32_get(unit, VLAN_TABm, &vt, VIRTUAL_PORT_ENf)) {
   5118                 control->vp_mc_ctrl = bcmVlanVPMcControlEnable;
   5119             } else {
   5120                 control->vp_mc_ctrl = bcmVlanVPMcControlDisable;
   5121             }
   5122         } else {
   5123             control->vp_mc_ctrl = bcmVlanVPMcControlAuto;
   5124         }
   5125     }
   5126 #endif
   5127 
   5128     if (pre_cfg == FALSE) {
   5129         /* after vlan is created */
   5130 
   5131         rv = _vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf,
   5132                       (uint32 *)&vt,  vid, &profile_index);
   5133         if (BCM_FAILURE(rv)) {
   5134             soc_mem_unlock(unit, VLAN_TABm);
   5135             return (rv);
   5136         }
   5137     } else {
   5138 #if defined(BCM_EASY_RELOAD_SUPPORT)
   5139         if (SOC_IS_RELOADING(unit)) {
   5140             /*
   5141              * Use VLAN_PROFILE_ER() as a write-through cache
   5142              * for VLAN profile pointers during easy reload
   5143              */
   5144             profile_index = VLAN_PROFILE_PTR_ER(unit, vid);
   5145         } else
   5146 #endif
   5147         {
   5148             profile_index = soc_mem_field32_get(unit, VLAN_TABm, &vt,
   5149                                        VLAN_PROFILE_PTRf);
   5150         }
   5151     }
   5152 
   5153     vpt = &VLAN_PROFILE_ENTRY(unit, profile_index);
   5154     control->flags |= vpt->flags;
   5155     if (valid_fields & BCM_VLAN_CONTROL_VLAN_OUTER_TPID_MASK) {
   5156         control->outer_tpid = vpt->outer_tpid;
   5157     }
   5158     if (valid_fields & BCM_VLAN_CONTROL_VLAN_IP6_MCAST_FLOOD_MODE_MASK) {
   5159         control->ip6_mcast_flood_mode = vpt->ip6_mcast_flood_mode;
   5160     }
   5161     if (valid_fields & BCM_VLAN_CONTROL_VLAN_IP4_MCAST_FLOOD_MODE_MASK) {
   5162         control->ip4_mcast_flood_mode = vpt->ip4_mcast_flood_mode;
   5163     }
   5164     if (valid_fields & BCM_VLAN_CONTROL_VLAN_L2_MCAST_FLOOD_MODE_MASK) {
   5165         control->l2_mcast_flood_mode = vpt->l2_mcast_flood_mode;
   5166     }
   5167 #if defined(BCM_TRX_SUPPORT)
   5168     if (valid_fields & BCM_VLAN_CONTROL_VLAN_PROTOCOL_PKT_MASK) {
   5169         if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl)
   5170             && SOC_MEM_FIELD_VALID (unit, VLAN_PROFILE_TABm,
   5171                                        PROTOCOL_PKT_INDEXf)) {
   5172             sal_memcpy(&control->protocol_pkt,
   5173                 &vpt->protocol_pkt, sizeof(bcm_vlan_protocol_packet_ctrl_t));
   5174         }
   5175     }
   5176 #endif /* BCM_TRX_SUPPORT */
   5177 
   5178 #if defined(BCM_HURRICANE3_SUPPORT)
   5179     if (SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, USE_VLAN_CMLf)) {
   5180         if (vpt->learn_flags & BCM_VLAN_LEARN_CONTROL_ENABLE) {
   5181             control->learn_flags = vpt->learn_flags;
   5182         } else {
   5183             control->learn_flags = 0x0;
   5184         }
   5185     }
   5186 #endif /* BCM_HURRICANE3_SUPPORT */
   5187 
   5188 #ifdef BCM_TRIUMPH_SUPPORT
   5189     if (valid_fields & BCM_VLAN_CONTROL_VLAN_COSQ_MASK) {
   5190         if (SOC_MEM_IS_VALID(unit, VLAN_COS_MAPm)) {
   5191 #if defined(BCM_KATANA_SUPPORT)
   5192             if (SOC_IS_KATANAX(unit)) {
   5193                 rv = _vlan_kt_cosq_map_get(unit, vid, control);
   5194             } else
   5195 #endif
   5196             {
   5197                 rv = _vlan_cosq_map_get(unit, vid, control);
   5198             }
   5199             if (BCM_FAILURE(rv)) {
   5200                 soc_mem_unlock(unit, VLAN_TABm);
   5201                 return (rv);
   5202             }
   5203         }
   5204     }
   5205 #endif
   5206 
   5207     if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm,
   5208                             ENABLE_IGMP_MLD_SNOOPINGf)) {
   5209         if (0 == soc_mem_field32_get(unit, VLAN_TABm, &vt,
   5210                                      ENABLE_IGMP_MLD_SNOOPINGf)) {
   5211             control->flags |= BCM_VLAN_IGMP_SNOOP_DISABLE;
   5212         }
   5213     }
   5214 
   5215 #if defined(INCLUDE_L3) && defined(BCM_TRIDENT2_SUPPORT)
   5216     if (valid_fields & BCM_VLAN_CONTROL_VLAN_NAT_REALM_ID_MASK) {
   5217         if (soc_feature(unit, soc_feature_nat) &&
   5218             SOC_MEM_IS_VALID(unit, L3_IIFm) &&
   5219             SOC_MEM_FIELD_VALID(unit, L3_IIFm, SRC_REALM_IDf) &&
   5220             (!ingress_map_mode)) {
   5221             rv = _bcm_tr_l3_intf_nat_realm_id_get(unit,
   5222                                 ingress_map_mode ? control->ingress_if : vid,
   5223                                 &control->nat_realm_id);
   5224             if (BCM_FAILURE(rv)) {
   5225                 soc_mem_unlock(unit, VLAN_TABm);
   5226                 return (rv);
   5227             }
   5228         }
   5229     }
   5230 #endif /* INCLUDE_L3  && BCM_TRIDENT2_SUPPORT */
   5231 
   5232 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   5233     if (soc_feature(unit, soc_feature_vfi_from_vlan_tables)) {
   5234             int vfi_index = -1;
   5235         if (SOC_MEM_IS_VALID(unit, VLAN_MPLSm) &&
   5236             SOC_MEM_FIELD_VALID(unit, VLAN_MPLSm, VFIf)) {
   5237             vlan_mpls_entry_t vlan_mpls;
   5238 
   5239             sal_memset(&vlan_mpls, 0, sizeof(vlan_mpls_entry_t));
   5240             soc_mem_lock(unit, VLAN_MPLSm);
   5241             rv = READ_VLAN_MPLSm(unit, MEM_BLOCK_ANY, vid, &vlan_mpls);
   5242             soc_mem_unlock(unit, VLAN_MPLSm);
   5243             if (BCM_FAILURE(rv)) {
   5244                 soc_mem_unlock(unit, VLAN_TABm);
   5245                 return rv;
   5246             }
   5247             vfi_index = soc_mem_field32_get(unit, VLAN_MPLSm,
   5248                                             &vlan_mpls, VFIf);
   5249         }
   5250 #if defined(BCM_TRIDENT3_SUPPORT)
   5251         else if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VFIf)) {
   5252             vfi_index = soc_mem_field32_get(unit, VLAN_TABm,
   5253                                             &vt, VFIf);
   5254         }
   5255 #endif/* BCM_TRIDENT3_SUPPORT && INCLUDE_L3 */
   5256             _BCM_VPN_SET(control->vpn, _BCM_VPN_TYPE_VFI, vfi_index);
   5257     }
   5258 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3*/
   5259 
   5260 #if defined(BCM_TSN_SR_SUPPORT)
   5261     if (soc_feature(unit, soc_feature_tsn_sr)) {
   5262         if (valid_fields & BCM_VLAN_CONTROL_VLAN_SR_FLAGS_MASK) {
   5263             if (soc_mem_field32_get(unit, VLAN_TABm, &vt, SR_ENABLEf)){
   5264                 control->sr_flags |= BCM_VLAN_CONTROL_SR_FLAG_ENABLE;
   5265                 if (soc_mem_field32_get(unit, VLAN_TABm, &vt, SR_LAN_IDf)){
   5266                     control->sr_flags |= BCM_VLAN_CONTROL_SR_FLAG_LAN_ID;
   5267                 }
   5268             }
   5269         }
   5270    }
   5271 #endif /* BCM_TSN_SR_SUPPORT*/
   5272 
   5273     soc_mem_unlock(unit, VLAN_TABm);
   5274 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
   5275     return rv;
   5276 }
   5277 
   5278 #if defined (BCM_TRX_SUPPORT)
   5279 STATIC int _vlan_protocol_pkt_action_validate(int pkt_action)
   5280 {
   5281     if ((pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE) &&
   5282          (pkt_action & BCM_VLAN_PROTO_PKT_DROP_ENABLE)) {
   5283         return BCM_E_PARAM;
   5284     }
   5285     return BCM_E_NONE;
   5286 }
   5287 #endif
   5288 
   5289 /*
   5290  * Function :
   5291  *    _bcm_xgs3_protocol_packet_actions_validate
   5292  *
   5293  * Purpose  :
   5294  *    Validate the protocol packet control actions 
   5295  *
   5296  * Parameters:
   5297  *     unit    - (IN) BCM device number.
   5298  *     pkt     - (IN) protocol packet control actions.
   5299  *
   5300  * Return :
   5301  *    BCM_E_XXX
   5302  */
   5303 int _bcm_xgs3_protocol_packet_actions_validate(int unit, 
   5304                 bcm_vlan_protocol_packet_ctrl_t *pkt)
   5305 {
   5306 #if defined (BCM_TRX_SUPPORT)
   5307     if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl)) {
   5308         int pkt_action;
   5309        
   5310         pkt_action = pkt->mmrp_action;
   5311         if (pkt_action) {
   5312             if (_vlan_protocol_pkt_action_validate(pkt_action)
   5313                     ==BCM_E_PARAM) {
   5314                 return BCM_E_PARAM;
   5315             }
   5316         }
   5317         pkt_action = pkt->srp_action;
   5318         if (pkt_action) {
   5319             if (_vlan_protocol_pkt_action_validate(pkt_action)
   5320                     == BCM_E_PARAM) {
   5321                 return BCM_E_PARAM;
   5322             }
   5323         }
   5324         pkt_action = pkt->arp_reply_action;
   5325         if ((pkt_action & BCM_VLAN_PROTO_PKT_FORWARD_ENABLE) ||
   5326             (pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE)) {
   5327             return BCM_E_PARAM;
   5328         }
   5329         pkt_action = pkt->arp_request_action;
   5330         if ((pkt_action & BCM_VLAN_PROTO_PKT_FORWARD_ENABLE) ||
   5331             (pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE)) {
   5332             return BCM_E_PARAM;
   5333         }
   5334         pkt_action = pkt->nd_action;
   5335         if ((pkt_action & BCM_VLAN_PROTO_PKT_FORWARD_ENABLE) ||
   5336             (pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE)) {
   5337             return BCM_E_PARAM;
   5338         }
   5339         pkt_action = pkt->dhcp_action;
   5340         if ((pkt_action & BCM_VLAN_PROTO_PKT_FORWARD_ENABLE) ||
   5341             (pkt_action & BCM_VLAN_PROTO_PKT_FLOOD_ENABLE)) {
   5342             return BCM_E_PARAM;
   5343         }
   5344         
   5345         pkt_action = pkt->igmp_report_leave_action;
   5346         if (pkt_action) {
   5347             if (_vlan_protocol_pkt_action_validate(pkt_action)
   5348                     == BCM_E_PARAM) {
   5349                 return BCM_E_PARAM;
   5350             }
   5351         }
   5352         pkt_action = pkt->igmp_query_action;
   5353         if (pkt_action) {
   5354             if (_vlan_protocol_pkt_action_validate(pkt_action)
   5355                     == BCM_E_PARAM) {
   5356                 return BCM_E_PARAM;
   5357             }
   5358         }
   5359         pkt_action = pkt->igmp_unknown_msg_action;
   5360         if (pkt_action) {
   5361             if (_vlan_protocol_pkt_action_validate(pkt_action)
   5362                     == BCM_E_PARAM) {
   5363                 return BCM_E_PARAM;
   5364             }
   5365         }
   5366         pkt_action = pkt->mld_report_done_action;
   5367         if (pkt_action) {
   5368             if (_vlan_protocol_pkt_action_validate(pkt_action)
   5369                     == BCM_E_PARAM) {
   5370                 return BCM_E_PARAM;
   5371             }
   5372         }
   5373         pkt_action = pkt->mld_query_action;
   5374         if (pkt_action) {
   5375             if (_vlan_protocol_pkt_action_validate(pkt_action)
   5376                     == BCM_E_PARAM) {
   5377                 return BCM_E_PARAM;
   5378             }
   5379         }
   5380         pkt_action = pkt->ip4_rsvd_mc_action;
   5381         if (pkt_action) {
   5382             if (_vlan_protocol_pkt_action_validate(pkt_action)
   5383                     == BCM_E_PARAM) {
   5384                 return BCM_E_PARAM;
   5385             }
   5386         }
   5387         pkt_action = pkt->ip6_rsvd_mc_action;
   5388         if (pkt_action) {
   5389             if (_vlan_protocol_pkt_action_validate(pkt_action)
   5390                     == BCM_E_PARAM) {
   5391                 return BCM_E_PARAM;
   5392             }
   5393         }
   5394         pkt_action = pkt->ip4_mc_router_adv_action;
   5395         if (pkt_action) {
   5396             if (_vlan_protocol_pkt_action_validate(pkt_action)
   5397                     == BCM_E_PARAM) {
   5398                 return BCM_E_PARAM;
   5399             }
   5400         }
   5401         pkt_action = pkt->ip6_mc_router_adv_action;
   5402         if (pkt_action) {
   5403             if (_vlan_protocol_pkt_action_validate(pkt_action)
   5404                     == BCM_E_PARAM) {
   5405                 return BCM_E_PARAM;
   5406             }
   5407         }
   5408         return BCM_E_NONE;
   5409     }
   5410 #endif
   5411     return BCM_E_UNAVAIL;
   5412 }
   5413 
   5414 #if defined(INCLUDE_L3)
   5415 
   5416 /*
   5417  * Function :
   5418  *    _bcm_xgs3_vlan_control_vpn_set
   5419  *
   5420  * Purpose  :
   5421  *    Configures various controls on the VFI.
   5422  *
   5423  * Parameters:
   5424  *     unit    - (IN) BCM device number.
   5425  *     vid     - (IN) Vlan id.
   5426  *     valid_fields - (IN) Valid fields, BCM_VLAN_CONTROL_VLAN_XXX_MASK.
   5427  *     control - (IN) Configuration structure.
   5428  *
   5429  * Return :
   5430  *    BCM_E_XXX
   5431  */
   5432 
   5433  int
   5434  _bcm_xgs3_vlan_control_vpn_set(int unit, bcm_vlan_t vid, uint32 valid_fields,
   5435                                 bcm_vlan_control_vlan_t *control)
   5436 {
   5437      int rv;
   5438      int vfi;
   5439      int value;
   5440      vfi_entry_t vfi_entry;
   5441      soc_mem_t mem = VFIm;
   5442 
   5443      _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, vid);
   5444 
   5445      /* Read the VFI memory */
   5446      MEM_LOCK(unit, mem);
   5447      rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, (int)vfi, &vfi_entry);
   5448      if (!SOC_SUCCESS(rv)) {
   5449          MEM_UNLOCK(unit, mem);
   5450          return rv;
   5451      }
   5452 
   5453      /* Program the VFI table */
   5454      if (control->flags & BCM_VLAN_L2_CLASS_ID_ONLY) {
   5455          if (soc_mem_field_valid(unit, mem, CLASS_IDf)) {
   5456              if (valid_fields & BCM_VLAN_CONTROL_VLAN_IF_CLASS_MASK) {
   5457                  if ((control->if_class < 0) ||
   5458                      (control->if_class > SOC_INTF_CLASS_MAX(unit))) {
   5459                      rv = BCM_E_PARAM;
   5460                  } else {
   5461                      value = control->if_class;
   5462                      soc_mem_field32_set(unit, mem, &vfi_entry, CLASS_IDf, value);
   5463                  }
   5464              } else {
   5465                  rv = BCM_E_PARAM;
   5466              }
   5467          }
   5468      }
   5469 
   5470      if (!SOC_SUCCESS(rv)) {
   5471          MEM_UNLOCK(unit, mem);
   5472          return rv;
   5473      }
   5474 
   5475      rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, vfi, &vfi_entry);
   5476 
   5477      MEM_UNLOCK(unit, mem);
   5478      return rv;
   5479 }
   5480 #endif /* INCLUDE_L3 */
   5481 
   5482 /*
   5483  * Function :
   5484  *    _bcm_xgs3_vlan_control_vlan_set
   5485  * 
   5486  * Purpose  :
   5487  *    Get vlan specific traffic forwarding parameters
   5488  *
   5489  * Parameters:
   5490  *     unit    - (IN) BCM device number.
   5491  *     vid     - (IN) Vlan id. 
   5492  *     valid_fields - (IN) Valid fields, BCM_VLAN_CONTROL_VLAN_XXX_MASK.
   5493  *     control - (OUT) Configuration.
   5494  *
   5495  * Return :
   5496  *    BCM_E_XXX
   5497  */
   5498 int
   5499 _bcm_xgs3_vlan_control_vlan_set(int unit, bcm_vlan_t vid,
   5500                           uint32 valid_fields, bcm_vlan_control_vlan_t *control)
   5501 {
   5502     int                rv = BCM_E_UNAVAIL;
   5503 
   5504 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
   5505     || defined(BCM_RAVEN_SUPPORT)
   5506     uint16             old_outer_tpid;
   5507     int                tpid_index = -1; /* used also as check flag for cleanup */
   5508     int                profile_index;
   5509     _vlan_profile_t    *old_vpt, vpt;
   5510     vlan_tab_entry_t   vt;
   5511     egr_vlan_entry_t   evt;
   5512     int                disable_mask;
   5513 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
   5514     int                ingress_map_mode=0;
   5515     int                if_class;
   5516 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */
   5517 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
   5518     int  trill_name_index=-1;
   5519 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
   5520     int iif_profile_valid;
   5521     int pre_cfg = FALSE;   /* pre-configuration flag */
   5522 
   5523     if (!soc_feature(unit, soc_feature_vlan_ctrl)) {
   5524         return (BCM_E_UNAVAIL);
   5525     }
   5526 
   5527 #if (defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || \
   5528      defined(BCM_GREYHOUND2_SUPPORT)) && defined(INCLUDE_L3)
   5529     if (_BCM_VPN_VFI_IS_SET(vid)) {
   5530         if (soc_feature(unit, soc_feature_vfi_profile)) {
   5531 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   5532             return bcmi_td2p_vlan_control_vpn_set(
   5533                         unit, vid, valid_fields, control);
   5534 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   5535         } else {
   5536 #ifdef BCM_GREYHOUND2_SUPPORT
   5537             if (soc_feature(unit, soc_feature_vxlan_lite_riot)) {
   5538                 return bcmi_gh2_vlan_control_vpn_set(unit, vid, valid_fields,
   5539                                                      control);
   5540             } else
   5541 #endif /* BCM_GREYHOUND2_SUPPORT */
   5542             {
   5543                 return _bcm_xgs3_vlan_control_vpn_set(unit, vid, valid_fields,
   5544                                                       control);
   5545             }
   5546         }
   5547     }
   5548 #endif /* (TRIDENT2PLUS || TOMAHAWK || GREYHOUND2) && INCLUDE_L3*/
   5549 
   5550     /* check if perform pre-configuration before vlan is created */
   5551     if (!SHR_BITGET(vlan_info[unit].bmp.w, vid)) {
   5552         pre_cfg = TRUE;
   5553     }
   5554 
   5555 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
   5556     if (soc_feature(unit, soc_feature_l3_ingress_interface)) {
   5557         BCM_IF_ERROR_RETURN(bcm_xgs3_l3_ingress_intf_map_get(unit, &ingress_map_mode));
   5558     }
   5559 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */
   5560 
   5561     if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit) ||
   5562         SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 
   5563         SOC_IS_GREYHOUND2(unit)) {
   5564         if(control->flags & ( BCM_VLAN_MPLS_DISABLE |
   5565                               BCM_VLAN_COSQ_ENABLE |
   5566                               BCM_VLAN_IGMP_SNOOP_DISABLE |
   5567                               BCM_VLAN_PIM_SNOOP_DISABLE |
   5568                               BCM_VLAN_USE_FABRIC_DISTRIBUTION |
   5569                               BCM_VLAN_TRILL_IGMP_SNOOP_DISABLE |
   5570                               BCM_VLAN_MIM_TERM_DISABLE)) {
   5571             return BCM_E_PARAM;
   5572         }
   5573     }
   5574 
   5575     if (!soc_feature(unit, soc_feature_l3_ingress_interface)) {
   5576         if(control->flags & BCM_VLAN_L3_CLASS_ID) {
   5577             return BCM_E_PARAM;
   5578         }
   5579     } else {
   5580 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
   5581         /* to check the ingress interface id */
   5582         if (valid_fields & BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK) {
   5583             /* VLAN_TABm.L3_IIFm can be assigned for ingress_map_mode=1 */
   5584             if (ingress_map_mode) {
   5585                 if (control->ingress_if > soc_mem_index_max(unit, L3_IIFm) ||
   5586                     control->ingress_if < soc_mem_index_min(unit, L3_IIFm) ) {
   5587                     return BCM_E_PARAM;
   5588                 }
   5589             }
   5590             /* cannot set l3 class id of vlan if ingress_map_mode=1 */
   5591             if(control->flags & BCM_VLAN_L3_CLASS_ID) {
   5592                 if (ingress_map_mode) {
   5593                     return BCM_E_PARAM;
   5594                 }
   5595                 if (!SOC_MEM_FIELD_VALID(unit, L3_IIFm, CLASS_IDf)) {
   5596                     return BCM_E_PARAM;
   5597                 }
   5598             }
   5599         }
   5600 #endif
   5601     }
   5602 
   5603 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
   5604     /* TIME-BEING ::: as soc_feature_service_queuing is FALSE for KATANA2 */
   5605     if (soc_feature(unit, soc_feature_service_queuing) || (SOC_IS_KATANA2(unit))) {
   5606         /* vlan cosq supported thru bcm_cosq_classifier_xxx() APIs */
   5607         if (control->flags & BCM_VLAN_COSQ_ENABLE) {
   5608             return BCM_E_UNAVAIL;
   5609         }
   5610     }
   5611 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_KATANA2_SUPPORT */
   5612 
   5613 
   5614     disable_mask = (BCM_VLAN_IP4_DISABLE |
   5615                     BCM_VLAN_IP6_DISABLE |
   5616                     BCM_VLAN_IP4_MCAST_DISABLE |
   5617                     BCM_VLAN_IP6_MCAST_DISABLE |
   5618                     BCM_VLAN_IP4_MCAST_L2_DISABLE |
   5619                     BCM_VLAN_IP6_MCAST_L2_DISABLE);
   5620 
   5621     iif_profile_valid = FALSE;
   5622 #if defined(BCM_TRIDENT2_SUPPORT) && defined (INCLUDE_L3)
   5623     if (soc_feature(unit, soc_feature_l3_iif_profile)) {
   5624         iif_profile_valid = TRUE;
   5625         if (!ingress_map_mode) {
   5626             BCM_IF_ERROR_RETURN(
   5627                 _bcm_td2_l3_intf_iif_profile_update(unit, vid, control));
   5628         }
   5629 #ifdef BCM_MONTEREY_SUPPORT
   5630         else if (SOC_IS_MONTEREY(unit) &&
   5631                  (valid_fields & BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK)) {
   5632             BCM_IF_ERROR_RETURN(
   5633                 _bcm_td2_l3_intf_iif_profile_update(unit, control->ingress_if, control));
   5634         }
   5635 #endif
   5636     }
   5637 #endif /* BCM_TRIDENT2_SUPPORT */
   5638 
   5639     if (control->flags & disable_mask) {
   5640 #if defined(BCM_TRX_SUPPORT) || defined(BCM_RAVEN_SUPPORT)
   5641         if (0 == SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, IPV4L3_ENABLEf) &&
   5642             !iif_profile_valid) {
   5643             /* This device does not have per-vlan enable controls */
   5644             return BCM_E_PARAM;
   5645         }
   5646 #else /* BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
   5647         return BCM_E_PARAM;
   5648 #endif /* BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
   5649     }
   5650 
   5651     if ((control->flags & BCM_VLAN_IGMP_SNOOP_DISABLE)
   5652         && !SOC_MEM_FIELD_VALID(unit, VLAN_TABm,
   5653                                 ENABLE_IGMP_MLD_SNOOPINGf)) {
   5654         return BCM_E_PARAM;
   5655     }
   5656 
   5657 
   5658     if (control->flags & (BCM_VLAN_PIM_SNOOP_DISABLE |
   5659                           BCM_VLAN_USE_FABRIC_DISTRIBUTION)) {
   5660         return BCM_E_PARAM;
   5661     }
   5662 
   5663     if ((control->flags &
   5664          (BCM_VLAN_MPLS_DISABLE | BCM_VLAN_COSQ_ENABLE)) &&
   5665         !SOC_IS_TR_VL(unit)) {
   5666         return BCM_E_PARAM;
   5667     }
   5668 
   5669     if ((control->flags & BCM_VLAN_MIM_TERM_DISABLE) && !SOC_IS_ENDURO(unit)) {
   5670         return BCM_E_PARAM;
   5671     }
   5672 
   5673     if (control->forwarding_vlan > BCM_VLAN_MAX) {
   5674         return BCM_E_PARAM;
   5675     }
   5676 
   5677 #if defined(BCM_TRX_SUPPORT) || defined(BCM_RAVEN_SUPPORT)
   5678     if ((control->forwarding_mode == bcmVlanForwardSingleCrossConnect) ||
   5679         (control->forwarding_mode == bcmVlanForwardDoubleCrossConnect)) {
   5680         /* No L2 learning for cross-connect */
   5681         if (0 == (control->flags & BCM_VLAN_LEARN_DISABLE)) {
   5682             return (BCM_E_PARAM);
   5683         }
   5684     }
   5685 #endif /* BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
   5686 
   5687 #if defined(BCM_TRX_SUPPORT)
   5688     if ((0 == SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, ICMP_REDIRECT_TOCPUf)) &&
   5689         (!iif_profile_valid) &&
   5690         (control->flags & BCM_VLAN_ICMP_REDIRECT_TOCPU)) {
   5691         return (BCM_E_PARAM);
   5692     }
   5693     if ((control->flags & BCM_VLAN_UNKNOWN_UCAST_TOCPU) &&
   5694         !SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, L2_MISS_TOCPUf)) {
   5695         return BCM_E_PARAM;
   5696     }
   5697     if ((control->flags & BCM_VLAN_UNKNOWN_UCAST_DROP) &&
   5698         !SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, L2_MISS_DROPf)) {
   5699         return BCM_E_PARAM;
   5700     }
   5701     if ((control->flags & BCM_VLAN_NON_UCAST_TOCPU) &&
   5702         !SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm,
   5703                              L2_NON_UCAST_TOCPUf)) {
   5704         return BCM_E_PARAM;
   5705     }
   5706     if ((control->flags & BCM_VLAN_NON_UCAST_DROP) &&
   5707         !SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm,
   5708                              L2_NON_UCAST_DROPf)) {
   5709         return BCM_E_PARAM;
   5710     }
   5711     if (control->if_class < 0 || control->if_class > SOC_INTF_CLASS_MAX(unit)){
   5712         return BCM_E_PARAM;
   5713     }
   5714     if (control->l3_if_class < 0 ||
   5715         control->l3_if_class > SOC_INTF_CLASS_MAX(unit)){
   5716         return BCM_E_PARAM;
   5717     }
   5718 #endif /* BCM_TRX_SUPPORT */
   5719 
   5720     /* validate parameter protocol_pkt */
   5721     if (valid_fields & BCM_VLAN_CONTROL_VLAN_PROTOCOL_PKT_MASK) {
   5722         if (SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, PROTOCOL_PKT_INDEXf)) {
   5723 #if defined(BCM_TRIDENT_SUPPORT)
   5724             bcm_vlan_protocol_packet_ctrl_t zero_protocol_pkt;
   5725             bcm_vlan_control_vlan_t dft_control;
   5726             sal_memset(&zero_protocol_pkt, 0,
   5727                        sizeof(bcm_vlan_protocol_packet_ctrl_t));
   5728             bcm_vlan_control_vlan_t_init(&dft_control);
   5729 #if defined(BCM_TRX_SUPPORT)
   5730             BCM_IF_ERROR_RETURN(_vlan_protocol_pkt_ctrl_default_add
   5731                                              (unit, &dft_control.protocol_pkt));
   5732 #endif /*BCM_TRX_SUPPORT*/
   5733             if (sal_memcmp(&zero_protocol_pkt, &control->protocol_pkt,
   5734                 sizeof(bcm_vlan_protocol_packet_ctrl_t)) &&
   5735                 sal_memcmp(&dft_control.protocol_pkt, &control->protocol_pkt,
   5736                 sizeof(bcm_vlan_protocol_packet_ctrl_t))) {
   5737                 if (SOC_IS_TRIDENT(unit) &&
   5738                     !SOC_MEM_FIELD_VALID(unit, VLAN_TABm,
   5739                                          ENABLE_IGMP_MLD_SNOOPINGf)) {
   5740                     return BCM_E_UNAVAIL;
   5741                 }
   5742             }
   5743 #endif /* BCM_TRIDENT_SUPPORT */
   5744             rv = _bcm_xgs3_protocol_packet_actions_validate(unit,
   5745                                          &control->protocol_pkt);
   5746             if (BCM_FAILURE(rv) && (rv != BCM_E_UNAVAIL)) {
   5747                 return rv;
   5748             }
   5749         }
   5750 #if defined(BCM_TRX_SUPPORT)
   5751         else {
   5752             bcm_vlan_protocol_packet_ctrl_t tmp_protocol_pkt;
   5753             sal_memset(&tmp_protocol_pkt, 0, sizeof(bcm_vlan_protocol_packet_ctrl_t));
   5754             if (sal_memcmp(&tmp_protocol_pkt, &control->protocol_pkt,
   5755                 sizeof(bcm_vlan_protocol_packet_ctrl_t))) {
   5756                 return BCM_E_UNAVAIL;
   5757             }
   5758         }
   5759 #endif /* BCM_TRX_SUPPORT */
   5760     }
   5761 
   5762 #if defined(BCM_TRIUMPH_SUPPORT)
   5763     if (valid_fields & BCM_VLAN_CONTROL_VLAN_COSQ_MASK) {
   5764         if (SOC_MEM_IS_VALID(unit, VLAN_COS_MAPm)) {
   5765 #if defined(BCM_KATANA_SUPPORT)
   5766             if (SOC_IS_KATANAX(unit)) {
   5767                 rv = _vlan_kt_cosq_map_set(unit, vid, control);
   5768             } else
   5769 #endif
   5770             {
   5771                 rv = _vlan_cosq_map_set(unit, vid, control);
   5772             }
   5773             BCM_IF_ERROR_RETURN(rv);
   5774         }
   5775     }
   5776 #if defined(INCLUDE_L3)
   5777     /* Check L3 Ingress Interface Map mode. */
   5778     if (soc_feature(unit, soc_feature_l3) && 
   5779             soc_feature(unit, soc_feature_l3_ingress_interface) && 
   5780             (!ingress_map_mode)) {
   5781         if (valid_fields & BCM_VLAN_CONTROL_VLAN_IF_CLASS_MASK) {
   5782             if (!(control->flags & BCM_VLAN_L2_CLASS_ID_ONLY ) ||
   5783                  (control->flags & BCM_VLAN_L3_CLASS_ID)) {
   5784                if_class = control->if_class;
   5785                if (valid_fields & BCM_VLAN_CONTROL_VLAN_L3_IF_CLASS_MASK) {
   5786                    if (control->flags & BCM_VLAN_L3_CLASS_ID) {
   5787                        if_class = control->l3_if_class;
   5788                    }
   5789                }
   5790                if ((SOC_MEM_FIELD_VALID(unit, VLAN_TABm, L3_IIFf) ||
   5791                    SOC_MEM_FIELD_VALID(unit, VLAN_MPLSm, L3_IIFf)) &&
   5792                    SOC_MEM_IS_VALID(unit, L3_IIFm)) {
   5793                    rv =  _bcm_tr_l3_intf_class_set(unit, vid, if_class);
   5794                    BCM_IF_ERROR_RETURN(rv);
   5795                }
   5796             }
   5797         }
   5798         if (SOC_MEM_FIELD_VALID(unit, L3_IIFm, ALLOW_GLOBAL_ROUTEf)) {
   5799              rv =  _bcm_tr_l3_intf_global_route_enable_set(unit, vid,
   5800                           (0 == (control->flags & BCM_VLAN_L3_VRF_GLOBAL_DISABLE)));
   5801              BCM_IF_ERROR_RETURN(rv);
   5802         }
   5803     }
   5804 
   5805     if (valid_fields & BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK) {
   5806         if ((soc_feature(unit, soc_feature_l3) && (ingress_map_mode) && 
   5807                 soc_feature(unit, soc_feature_l3_ingress_interface)) ||
   5808                 (BCM_VLAN_VALID(control->forwarding_vlan ) &&
   5809                 (control->ingress_if <= soc_mem_index_max(unit, L3_IIFm))) ) {
   5810             if (SOC_MEM_IS_VALID(unit, VLAN_MPLSm)) {
   5811                 vlan_mpls_entry_t vlan_mpls;
   5812 
   5813                 sal_memset(&vlan_mpls, 0, sizeof(vlan_mpls_entry_t));
   5814                 BCM_IF_ERROR_RETURN
   5815                     (soc_mem_read(unit, VLAN_MPLSm, MEM_BLOCK_ANY, vid,
   5816                               &vlan_mpls));
   5817                 /* Configure Vlan mapping */
   5818                 soc_mem_field32_set(unit, VLAN_MPLSm, &vlan_mpls,
   5819                         L3_IIFf, control->ingress_if);
   5820 
   5821                 BCM_IF_ERROR_RETURN
   5822                     (soc_mem_write(unit, VLAN_MPLSm, MEM_BLOCK_ALL, vid,
   5823                                &vlan_mpls));
   5824             }
   5825         }
   5826     }
   5827 #if defined(BCM_TRIDENT2_SUPPORT)
   5828     if (valid_fields & BCM_VLAN_CONTROL_VLAN_NAT_REALM_ID_MASK) {
   5829         /* set the src realm id in L3_IIF table */
   5830         if (soc_feature(unit, soc_feature_nat) && (SOC_MEM_IS_VALID(unit, L3_IIFm))
   5831             && (SOC_MEM_FIELD_VALID(unit, L3_IIFm, SRC_REALM_IDf)) &&
   5832             (!ingress_map_mode)) {
   5833             /* validate realm id param */
   5834             if ((control->nat_realm_id < 0) || (control->nat_realm_id > 3)) {
   5835                 return BCM_E_PARAM;
   5836             }
   5837             BCM_IF_ERROR_RETURN(_bcm_tr_l3_intf_nat_realm_id_set(unit, vid,
   5838                                     control->nat_realm_id));
   5839             if(control->flags & BCM_VLAN_SRC_DST_NAT_REALM_ID) {
   5840                 BCM_IF_ERROR_RETURN(
   5841                     _bcm_td2_nh_nat_id_update_by_vlan(
   5842                         unit, vid, control->nat_realm_id));
   5843             }
   5844         }
   5845     }
   5846 #endif /* BCM_TRIDENT2_SUPPORT */
   5847 #endif /* INCLUDE_L3 */
   5848 #endif /* BCM_TRIUMPH_SUPPORT */
   5849 
   5850 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
   5851     if (soc_feature(unit, soc_feature_l3) && 
   5852             soc_feature(unit, soc_feature_l3_ingress_interface) &&
   5853             (!ingress_map_mode)) {
   5854         if (SOC_MEM_FIELD_VALID(unit, L3_IIFm, URPF_DEFAULTROUTECHECKf) ||
   5855                             soc_feature(unit, soc_feature_l3_iif_profile)) {
   5856             rv =  _bcm_tr2_l3_intf_urpf_default_route_set(unit, vid,
   5857                         (0 == (control->flags & BCM_VLAN_L3_URPF_DEFAULT_ROUTE_CHECK_DISABLE)));
   5858             BCM_IF_ERROR_RETURN(rv);
   5859             if (valid_fields & BCM_VLAN_CONTROL_VLAN_URPF_MODE_MASK) {
   5860                 if (SOC_MEM_FIELD_VALID(unit, L3_IIFm, URPF_MODEf) ||
   5861                                 soc_feature(unit, soc_feature_l3_iif_profile)) {
   5862                     rv =  _bcm_tr2_l3_intf_urpf_mode_set(unit, vid,
   5863                                                          control->urpf_mode);
   5864                     BCM_IF_ERROR_RETURN(rv);
   5865                 }
   5866             }
   5867         }
   5868     }
   5869     if (soc_feature(unit, soc_feature_mpls)) {
   5870         if (SOC_MEM_IS_VALID(unit, VLAN_MPLSm)) {
   5871         vlan_mpls_entry_t vlan_mpls_entry;
   5872         sal_memset(&vlan_mpls_entry, 0, sizeof(vlan_mpls_entry_t));
   5873         BCM_IF_ERROR_RETURN
   5874             (soc_mem_read(unit, VLAN_MPLSm, MEM_BLOCK_ANY, vid,
   5875                 &vlan_mpls_entry));
   5876         soc_mem_field32_set(unit, VLAN_MPLSm,
   5877             &vlan_mpls_entry, MPLS_ENABLEf,
   5878             (control->flags & BCM_VLAN_MPLS_DISABLE) ? 0x0 : 0x1);
   5879         BCM_IF_ERROR_RETURN
   5880             (soc_mem_write(unit, VLAN_MPLSm, MEM_BLOCK_ALL, vid,
   5881                 &vlan_mpls_entry));
   5882     }
   5883 #if defined(BCM_TRIDENT3_SUPPORT)
   5884         if (SOC_MEM_IS_VALID(unit, VLAN_ATTRS_1m)) {
   5885             vlan_attrs_1_entry_t vlan_attrs;
   5886             sal_memset(&vlan_attrs, 0, sizeof(vlan_attrs));
   5887             BCM_IF_ERROR_RETURN
   5888                 (soc_mem_read(unit, VLAN_ATTRS_1m, MEM_BLOCK_ANY, vid,
   5889                     &vlan_attrs));
   5890             soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, MPLS_ENABLEf,
   5891                 (control->flags & BCM_VLAN_MPLS_DISABLE) ? 0x0 : 0x1);
   5892             soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, FID_IDf,
   5893                                 control->forwarding_vlan);
   5894             BCM_IF_ERROR_RETURN
   5895                 (soc_mem_write(unit, VLAN_ATTRS_1m, MEM_BLOCK_ALL, vid,
   5896                     &vlan_attrs));
   5897         }
   5898 #endif
   5899     }
   5900 
   5901 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   5902     if (soc_feature(unit, soc_feature_vlan_filter)) {
   5903         vlan_tab_entry_t vlan_tab;
   5904         sal_memset(&vlan_tab, 0, sizeof(vlan_tab));
   5905         BCM_IF_ERROR_RETURN
   5906             (soc_mem_read(unit, EGR_VLANm, MEM_BLOCK_ANY, vid,
   5907                 &vlan_tab));
   5908         soc_mem_field32_set(unit, EGR_VLANm, &vlan_tab, EN_EFILTERf,
   5909             (control->flags2 & BCM_VLAN_FLAGS2_MEMBER_EGRESS_DISABLE) ? 0x0 : 0x1);
   5910         BCM_IF_ERROR_RETURN
   5911             (soc_mem_write(unit, EGR_VLANm, MEM_BLOCK_ALL, vid,
   5912                 &vlan_tab));
   5913 
   5914         if (SOC_MEM_IS_VALID(unit, VLAN_ATTRS_1m)) {
   5915             vlan_attrs_1_entry_t vlan_attrs;
   5916             sal_memset(&vlan_attrs, 0, sizeof(vlan_attrs));
   5917             BCM_IF_ERROR_RETURN
   5918                 (soc_mem_read(unit, VLAN_ATTRS_1m, MEM_BLOCK_ANY, vid,
   5919                     &vlan_attrs));
   5920             soc_mem_field32_set(unit, VLAN_ATTRS_1m, &vlan_attrs, EN_IFILTERf,
   5921                 (control->flags2 & BCM_VLAN_FLAGS2_MEMBER_INGRESS_DISABLE) ? 0x0 : 0x1);
   5922             BCM_IF_ERROR_RETURN
   5923                 (soc_mem_write(unit, VLAN_ATTRS_1m, MEM_BLOCK_ALL, vid,
   5924                     &vlan_attrs));
   5925         } else if (SOC_MEM_IS_VALID(unit, VLAN_MPLSm)) {
   5926             vlan_mpls_entry_t vlan_mpls;
   5927             sal_memset(&vlan_mpls, 0, sizeof(vlan_mpls_entry_t));
   5928             BCM_IF_ERROR_RETURN
   5929                 (soc_mem_read(unit, VLAN_MPLSm, MEM_BLOCK_ANY, vid,
   5930                     &vlan_mpls));
   5931             soc_mem_field32_set(unit, VLAN_MPLSm, &vlan_mpls, EN_IFILTERf,
   5932                 (control->flags2 & BCM_VLAN_FLAGS2_MEMBER_INGRESS_DISABLE) ? 0x0 : 0x1);
   5933             BCM_IF_ERROR_RETURN
   5934                 (soc_mem_write(unit, VLAN_MPLSm, MEM_BLOCK_ALL, vid,
   5935                     &vlan_mpls));
   5936         }
   5937     }
   5938 #endif
   5939 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
   5940 
   5941     soc_mem_lock(unit, VLAN_TABm);
   5942     _bcm_fb2_outer_tpid_tab_lock(unit);
   5943 
   5944     if (pre_cfg == FALSE) {
   5945         /* after vlan is created */
   5946         rv = _vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf,
   5947                                NULL, vid, &profile_index);
   5948         if (BCM_FAILURE(rv)) {
   5949             _bcm_fb2_outer_tpid_tab_unlock(unit);
   5950             soc_mem_unlock(unit, VLAN_TABm);
   5951             return (rv);
   5952         }
   5953         old_vpt        = &VLAN_PROFILE_ENTRY(unit, profile_index);
   5954         vpt            = *old_vpt;
   5955         old_outer_tpid = old_vpt->outer_tpid;
   5956 
   5957     } else {  /* before vlan is created */
   5958         uint16 dft_tpid;
   5959 
   5960         rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vid, &vt);
   5961         if (BCM_FAILURE(rv)) {
   5962             _bcm_fb2_outer_tpid_tab_unlock(unit);
   5963             soc_mem_unlock(unit, VLAN_TABm);
   5964             return (rv);
   5965         }
   5966 
   5967 #if defined(BCM_EASY_RELOAD_SUPPORT)
   5968         if (SOC_IS_RELOADING(unit)) {
   5969             /*
   5970              * Use VLAN_PROFILE_ER() as a write-through cache
   5971              * for VLAN profile pointers during easy reload
   5972              */
   5973             profile_index = VLAN_PROFILE_PTR_ER(unit, vid);
   5974         } else
   5975 #endif
   5976         {
   5977             profile_index = soc_mem_field32_get(unit, VLAN_TABm, &vt,
   5978                                            VLAN_PROFILE_PTRf);
   5979         }
   5980         old_vpt        = &VLAN_PROFILE_ENTRY(unit, profile_index);
   5981         vpt            = *old_vpt;
   5982         old_outer_tpid = old_vpt->outer_tpid;
   5983 
   5984         /* check if first time doing pre-configuration */
   5985         if (!SHR_BITGET(vlan_info[unit].pre_cfg_bmp.w,vid)) {
   5986             /* no profile added, hence no valid tpid  */
   5987             dft_tpid = _bcm_fb2_outer_tpid_default_get(unit);
   5988             rv = _bcm_fb2_outer_tpid_entry_add(unit, dft_tpid,
   5989                                            &tpid_index);
   5990             if (BCM_FAILURE(rv)) {
   5991                 _bcm_fb2_outer_tpid_tab_unlock(unit);
   5992                 soc_mem_unlock(unit, VLAN_TABm);
   5993                 return (rv);
   5994             }
   5995             old_outer_tpid = dft_tpid;
   5996         }
   5997     }
   5998 
   5999     if (valid_fields & BCM_VLAN_CONTROL_VLAN_OUTER_TPID_MASK) {
   6000         /* If old TPID and new TPID are different, deletes the old entry
   6001          * and adds the new entry.
   6002          */
   6003         if (old_outer_tpid != control->outer_tpid) {
   6004             if (!SOC_MEM_IS_VALID(unit, EGR_VLANm)) {
   6005                 _bcm_fb2_outer_tpid_tab_unlock(unit);
   6006                 soc_mem_unlock(unit, VLAN_TABm);
   6007                 return BCM_E_UNAVAIL;
   6008             }
   6009 
   6010             rv = soc_mem_read(unit, EGR_VLANm, MEM_BLOCK_ANY, (int)vid, &evt);
   6011             if (BCM_FAILURE(rv)) {
   6012                 _bcm_fb2_outer_tpid_tab_unlock(unit);
   6013                 soc_mem_unlock(unit, VLAN_TABm);
   6014                 return (rv);
   6015             }
   6016 
   6017             rv = _bcm_fb2_outer_tpid_lkup(unit, old_outer_tpid, &tpid_index);
   6018             if (BCM_FAILURE(rv)) {
   6019                 _bcm_fb2_outer_tpid_tab_unlock(unit);
   6020                 soc_mem_unlock(unit, VLAN_TABm);
   6021                 return (rv);
   6022             }
   6023 
   6024             rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index);
   6025             if (BCM_FAILURE(rv)) {
   6026                 _bcm_fb2_outer_tpid_tab_unlock(unit);
   6027                 soc_mem_unlock(unit, VLAN_TABm);
   6028                 return (rv);
   6029             }
   6030 
   6031             rv = _bcm_fb2_outer_tpid_entry_add(unit, control->outer_tpid,
   6032                                                &tpid_index);
   6033             if (BCM_FAILURE(rv)) {
   6034                 (void)_bcm_fb2_outer_tpid_entry_add(unit, old_outer_tpid,
   6035                                                     &tpid_index);
   6036                 _bcm_fb2_outer_tpid_tab_unlock(unit);
   6037                 soc_mem_unlock(unit, VLAN_TABm);
   6038                 return (rv);
   6039             }
   6040 
   6041             soc_mem_field32_set(unit, EGR_VLANm, &evt, OUTER_TPID_INDEXf, tpid_index);
   6042             rv = WRITE_EGR_VLANm(unit, MEM_BLOCK_ALL, (int)vid, &evt);
   6043             if (BCM_FAILURE(rv)) {
   6044                 _bcm_fb2_outer_tpid_tab_unlock(unit);
   6045                 soc_mem_unlock(unit, VLAN_TABm);
   6046                 return (rv);
   6047             }
   6048         }
   6049     }
   6050     vpt.flags = control->flags;
   6051     if (valid_fields & BCM_VLAN_CONTROL_VLAN_OUTER_TPID_MASK) {
   6052         vpt.outer_tpid = control->outer_tpid;
   6053     } else {
   6054         vpt.outer_tpid = old_outer_tpid;
   6055     }
   6056     if (valid_fields & BCM_VLAN_CONTROL_VLAN_IP6_MCAST_FLOOD_MODE_MASK) {
   6057         vpt.ip6_mcast_flood_mode = control->ip6_mcast_flood_mode;
   6058     }
   6059     if (valid_fields & BCM_VLAN_CONTROL_VLAN_IP4_MCAST_FLOOD_MODE_MASK) {
   6060         vpt.ip4_mcast_flood_mode = control->ip4_mcast_flood_mode;
   6061     }
   6062     if (valid_fields & BCM_VLAN_CONTROL_VLAN_L2_MCAST_FLOOD_MODE_MASK) {
   6063         vpt.l2_mcast_flood_mode = control->l2_mcast_flood_mode;
   6064     }
   6065 #if defined(BCM_TRX_SUPPORT)
   6066     if (valid_fields & BCM_VLAN_CONTROL_VLAN_PROTOCOL_PKT_MASK) {
   6067         if (soc_feature (unit, soc_feature_vlan_protocol_pkt_ctrl)
   6068             && SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm,
   6069                                       PROTOCOL_PKT_INDEXf)) {
   6070             sal_memcpy(&vpt.protocol_pkt, &control->protocol_pkt,
   6071                         sizeof(bcm_vlan_protocol_packet_ctrl_t));
   6072         }
   6073     }
   6074 #endif /* BCM_TRX_SUPPORT */
   6075 
   6076     if (!SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, USE_VLAN_CMLf) &&
   6077         (control->learn_flags != 0)) {
   6078         _bcm_fb2_outer_tpid_tab_unlock(unit);
   6079         soc_mem_unlock(unit, VLAN_TABm);
   6080         return BCM_E_UNAVAIL;
   6081     }
   6082 #if defined(BCM_HURRICANE3_SUPPORT)
   6083     else if (SOC_MEM_FIELD_VALID(unit, VLAN_PROFILE_TABm, USE_VLAN_CMLf)) {
   6084         if (control->learn_flags &
   6085             ~(BCM_VLAN_LEARN_CONTROL_ENABLE |
   6086                BCM_VLAN_LEARN_CONTROL_ARL |
   6087                BCM_VLAN_LEARN_CONTROL_CPU |
   6088                BCM_VLAN_LEARN_CONTROL_FWD |
   6089                BCM_VLAN_LEARN_CONTROL_PENDING)) {
   6090             _bcm_fb2_outer_tpid_tab_unlock(unit);
   6091             soc_mem_unlock(unit, VLAN_TABm);
   6092             return BCM_E_PARAM;
   6093         }
   6094         vpt.learn_flags= control->learn_flags;
   6095     }
   6096 #endif /* BCM_HURRICANE3_SUPPORT */
   6097 
   6098     /* Update the vlan profile table only if the old and new entries are
   6099      * different.
   6100      */
   6101     if (pre_cfg == FALSE) {
   6102         /* after vlan is created */
   6103         rv = _vlan_profile_update(unit, vid, &vpt);
   6104 
   6105     } else {  /* before vlan is created */
   6106         uint8 equal;
   6107         int idx;
   6108 
   6109         /* Compare original profile with new one. */
   6110         rv = _vlan_profile_compare(unit, &VLAN_PROFILE_ENTRY(unit, profile_index),
   6111                                &vpt, &equal);
   6112         if (rv == BCM_E_NONE && (equal != TRUE)) {
   6113             /* Add new profile. */
   6114             rv = _vlan_profile_add(unit, &vpt, &idx);
   6115 
   6116             if (BCM_SUCCESS(rv)) {
   6117                 /* Set new vlan profile index. */
   6118                 soc_mem_field32_set(unit, VLAN_TABm, &vt, VLAN_PROFILE_PTRf, idx);
   6119 
   6120                 /* Write back vlan table entry. */
   6121                 rv = soc_mem_write(unit, VLAN_TABm, MEM_BLOCK_ALL, (int)vid, &vt);
   6122                 if (BCM_SUCCESS(rv)) {
   6123                     /* Delete original vlan profile if new one was allocated and
   6124                        the original one is valid. */
   6125                     if (SHR_BITGET(vlan_info[unit].pre_cfg_bmp.w,vid) &&
   6126                          (profile_index != idx)) {
   6127                          rv = _vlan_profile_delete(unit, profile_index);
   6128                     }
   6129                 }
   6130             }
   6131         }
   6132     }
   6133     if (BCM_FAILURE(rv)) {
   6134         if (-1 != tpid_index) {
   6135             _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index);
   6136         }
   6137         (void)_bcm_fb2_outer_tpid_entry_add(unit, old_outer_tpid, &tpid_index);
   6138         _bcm_fb2_outer_tpid_tab_unlock(unit);
   6139         soc_mem_unlock(unit, VLAN_TABm);
   6140         return (rv);
   6141     }
   6142 
   6143     _bcm_fb2_outer_tpid_tab_unlock(unit);
   6144 
   6145     rv = soc_mem_read(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vid, &vt);
   6146     if (BCM_FAILURE(rv)) {
   6147         soc_mem_unlock(unit, VLAN_TABm);
   6148         return (rv);
   6149     }
   6150 
   6151     if (valid_fields & BCM_VLAN_CONTROL_VLAN_VRF_MASK) {
   6152         if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VRF_IDf)) {
   6153             soc_mem_field32_set(unit, VLAN_TABm, &vt, VRF_IDf, control->vrf);
   6154         }
   6155 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
   6156         else if (SOC_IS_TR_VL(unit) && soc_feature(unit, soc_feature_l3) && 
   6157                 soc_feature(unit, soc_feature_l3_ingress_interface) && 
   6158                 SOC_MEM_IS_VALID(unit,L3_IIFm)) {
   6159             if (soc_feature(unit, soc_feature_no_vlan_vrf)) {
   6160                 /* 
   6161                  * Return E_UNAVAIL for those device can't support VID 1:1 
   6162                  * mapping to L3_IIFm to set VLAN based VRF_ID
   6163                  */
   6164                 soc_mem_unlock(unit, VLAN_TABm);
   6165                 return BCM_E_UNAVAIL;
   6166             } else if (!ingress_map_mode) {
   6167             rv = _bcm_tr_l3_intf_vrf_bind(unit, vid, control->vrf);
   6168             if (BCM_FAILURE(rv)) {
   6169                 soc_mem_unlock(unit, VLAN_TABm);
   6170                 return rv;
   6171             }
   6172         }
   6173         }
   6174 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */
   6175     }
   6176 
   6177 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
   6178     if (valid_fields & BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK) {
   6179         if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, L3_IIFf) && 
   6180                 soc_feature(unit, soc_feature_l3_ingress_interface) && 
   6181                 soc_feature(unit, soc_feature_l3)) {
   6182             if (ingress_map_mode) {
   6183                 /* Configure Vlan mapping */
   6184                 soc_mem_field32_set(unit, VLAN_TABm, &vt,
   6185                             L3_IIFf, control->ingress_if);
   6186             }
   6187         }
   6188     }
   6189 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */
   6190 
   6191 #if defined(BCM_TRX_SUPPORT) || defined(BCM_RAVEN_SUPPORT)
   6192     if (valid_fields & BCM_VLAN_CONTROL_VLAN_FORWARDING_VLAN_MASK) {
   6193         if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, FID_IDf)) {
   6194             soc_mem_field32_set(unit, VLAN_TABm, &vt, FID_IDf,
   6195                                 control->forwarding_vlan);
   6196         } else {
   6197               /* For Raven and Hawkeye devices FID_ID is not valid.*/
   6198               soc_mem_unlock(unit, VLAN_TABm);
   6199               return BCM_E_UNAVAIL;
   6200         }
   6201     }
   6202 #endif /* BCM_TRX_SUPPORT */
   6203 #if defined(BCM_TRX_SUPPORT)
   6204     /* if_class is set for any of below conditions:
   6205      * BCM_VLAN_L2_CLASS_ID_ONLY and BCM_VLAN_L3_CLASS_ID are not set
   6206      * Only BCM_VLAN_L2_CLASS_ID_ONLY is set
   6207      * When both BCM_VLAN_L2_CLASS_ID_ONLY and BCM_VLAN_L3_CLASS_ID are set */
   6208     if (valid_fields & BCM_VLAN_CONTROL_VLAN_IF_CLASS_MASK) {
   6209         if (!((!(control->flags & BCM_VLAN_L2_CLASS_ID_ONLY)) &&
   6210              (control->flags & BCM_VLAN_L3_CLASS_ID))) {
   6211             if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VLAN_CLASS_IDf)) {
   6212                 soc_mem_field32_set(unit, VLAN_TABm, &vt, VLAN_CLASS_IDf,
   6213                                     control->if_class);
   6214             }
   6215         }
   6216     }
   6217 #endif /* BCM_TRX_SUPPORT */
   6218 #if defined(BCM_TRX_SUPPORT)
   6219     if (valid_fields & BCM_VLAN_CONTROL_VLAN_FORWARDING_MODE_MASK) {
   6220         if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, L2_ENTRY_KEY_TYPEf)) {
   6221             rv = _vlan_control_trx_forwarding_mode_set(unit, (uint32 *)&vt,
   6222                                                        control->forwarding_mode);
   6223             if (BCM_FAILURE(rv)) {
   6224                 soc_mem_unlock(unit, VLAN_TABm);
   6225                 return rv;
   6226             }
   6227         }
   6228     }
   6229 #endif /* BCM_TRX_SUPPORT */
   6230 
   6231 #if defined(BCM_HELIX5_SUPPORT)
   6232     if (soc_feature(unit, soc_feature_vlan_wirelss_traffic_select)) {
   6233 
   6234         if (control->flags2 & BCM_VLAN_FLAGS2_WIRED_COS_MAP_SELECT &&
   6235             control->flags2 & BCM_VLAN_FLAGS2_WIRELESS_COS_MAP_SELECT) {
   6236             return BCM_E_PARAM;
   6237         }
   6238         if (control->flags2 & BCM_VLAN_FLAGS2_WIRED_COS_MAP_SELECT) {
   6239             soc_mem_field32_set(unit, VLAN_TABm, &vt, WIRED_WIRELESSf, 0x1);
   6240         }
   6241 
   6242         if (control->flags2 & BCM_VLAN_FLAGS2_WIRELESS_COS_MAP_SELECT) {
   6243             soc_mem_field32_set(unit, VLAN_TABm, &vt, WIRED_WIRELESSf, 0x2);
   6244         }
   6245     }
   6246 #endif
   6247 
   6248 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
   6249 
   6250     if (valid_fields & BCM_VLAN_CONTROL_VLAN_VP_MCAST_MASK) {
   6251         /* Should update manual_vpctrl before trill setting */
   6252     	if (control->vp_mc_ctrl != bcmVlanVPMcControlAuto) {
   6253             SHR_BITSET(vlan_info[unit].vp_mode, vid);
   6254         } else {
   6255             SHR_BITCLR(vlan_info[unit].vp_mode, vid);
   6256         }
   6257     }
   6258 
   6259     if (valid_fields & BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK) {
   6260             if (0 == control->broadcast_group) {
   6261             _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, BC_IDXf, 0);
   6262         }
   6263     }
   6264     if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK) {
   6265             if (0 == control->unknown_multicast_group) {
   6266             _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UMC_IDXf, 0);
   6267         }
   6268     }
   6269     if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK) {
   6270             if (0 == control->unknown_unicast_group) {
   6271             _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UUC_IDXf, 0);
   6272         }
   6273     }
   6274 
   6275     if (soc_feature(unit, soc_feature_wlan)) {
   6276         if (valid_fields & BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK) {
   6277             if (_BCM_MULTICAST_IS_WLAN(control->broadcast_group)) {
   6278                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, BC_IDXf,
   6279                     _BCM_MULTICAST_ID_GET(control->broadcast_group));
   6280             }
   6281         }
   6282         if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK) {
   6283             if (_BCM_MULTICAST_IS_WLAN(control->unknown_multicast_group)) {
   6284                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UMC_IDXf,
   6285                     _BCM_MULTICAST_ID_GET(control->unknown_multicast_group));
   6286             }
   6287         }
   6288         if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK) {
   6289             if (_BCM_MULTICAST_IS_WLAN(control->unknown_unicast_group)) {
   6290                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UUC_IDXf,
   6291                     _BCM_MULTICAST_ID_GET(control->unknown_unicast_group));
   6292             }
   6293         }
   6294     }
   6295 
   6296     if (soc_feature(unit, soc_feature_vlan_vp)) {
   6297         if (valid_fields & BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK) {
   6298             if (_BCM_MULTICAST_IS_VLAN(control->broadcast_group)) {
   6299                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, BC_IDXf,
   6300                     _BCM_MULTICAST_ID_GET(control->broadcast_group));
   6301             }
   6302         }
   6303         if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK) {
   6304             if (_BCM_MULTICAST_IS_VLAN(control->unknown_multicast_group)) {
   6305                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UMC_IDXf,
   6306                     _BCM_MULTICAST_ID_GET(control->unknown_multicast_group));
   6307             }
   6308         }
   6309         if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK) {
   6310             if (_BCM_MULTICAST_IS_VLAN(control->unknown_unicast_group)) {
   6311                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UUC_IDXf,
   6312                     _BCM_MULTICAST_ID_GET(control->unknown_unicast_group));
   6313             }
   6314         }
   6315    }
   6316 #endif /* (BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
   6317 
   6318 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
   6319     if (soc_feature(unit, soc_feature_trill)) {
   6320         if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm,
   6321               TRILL_TRANSIT_IGMP_MLD_PAYLOAD_TO_CPUf)) {
   6322               if (control->flags & BCM_VLAN_TRILL_IGMP_SNOOP_DISABLE) {
   6323                    soc_mem_field32_set(unit, VLAN_TABm, &vt,
   6324                         TRILL_TRANSIT_IGMP_MLD_PAYLOAD_TO_CPUf, 0x0);
   6325               } else {
   6326                    soc_mem_field32_set(unit, VLAN_TABm, &vt,
   6327                         TRILL_TRANSIT_IGMP_MLD_PAYLOAD_TO_CPUf, 0x1);
   6328               }
   6329         }
   6330 
   6331         if (valid_fields & BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK) {
   6332             if (_BCM_MULTICAST_IS_VLAN(control->broadcast_group)) {
   6333                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, BC_IDXf,
   6334                     _BCM_MULTICAST_ID_GET(control->broadcast_group));
   6335             }
   6336         }
   6337         if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK) {
   6338             if (_BCM_MULTICAST_IS_VLAN(control->unknown_multicast_group)) {
   6339                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UMC_IDXf,
   6340                     _BCM_MULTICAST_ID_GET(control->unknown_multicast_group));
   6341             }
   6342         }
   6343         if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK) {
   6344             if (_BCM_MULTICAST_IS_VLAN(control->unknown_unicast_group)) {
   6345                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UUC_IDXf,
   6346                     _BCM_MULTICAST_ID_GET(control->unknown_unicast_group));
   6347             }
   6348         }
   6349 
   6350         if (valid_fields & BCM_VLAN_CONTROL_VLAN_TRILL_NONUNICAST_GROUP_MASK) {
   6351             if (BCM_SUCCESS(bcm_td_trill_multicast_check(unit,
   6352                             control->trill_nonunicast_group))) { 
   6353                 /*  Obtain matching l3mc for given l2mc  */
   6354                 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm,
   6355                         TRILL_DOMAIN_NONUC_REPL_INDEXf)) {
   6356                              soc_mem_field32_set(unit, VLAN_TABm, &vt,
   6357                                 TRILL_DOMAIN_NONUC_REPL_INDEXf,
   6358                                 _BCM_MULTICAST_ID_GET(control->trill_nonunicast_group));
   6359                 }
   6360                 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm,
   6361                         BC_TRILL_NETWORK_RECEIVERS_PRESENTf)) {
   6362                              soc_mem_field32_set(unit, VLAN_TABm, &vt,
   6363                                        BC_TRILL_NETWORK_RECEIVERS_PRESENTf, 0x1);
   6364                 }
   6365                 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm,
   6366                         UMC_TRILL_NETWORK_RECEIVERS_PRESENTf)) {
   6367                              soc_mem_field32_set(unit, VLAN_TABm, &vt,
   6368                                        UMC_TRILL_NETWORK_RECEIVERS_PRESENTf, 0x1);
   6369                 }
   6370                 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm,
   6371                         UUC_TRILL_NETWORK_RECEIVERS_PRESENTf)) {
   6372                              soc_mem_field32_set(unit, VLAN_TABm, &vt,
   6373                                        UUC_TRILL_NETWORK_RECEIVERS_PRESENTf, 0x1);
   6374                 }
   6375                 rv = bcm_td_trill_vlan_multicast_group_add(unit, vid, &vt);
   6376             } else {
   6377                 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm,
   6378                         TRILL_DOMAIN_NONUC_REPL_INDEXf)) {
   6379                              soc_mem_field32_set(unit, VLAN_TABm, &vt,
   6380                                 TRILL_DOMAIN_NONUC_REPL_INDEXf, 0);
   6381                 }
   6382                 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm,
   6383                         BC_TRILL_NETWORK_RECEIVERS_PRESENTf)) {
   6384                              soc_mem_field32_set(unit, VLAN_TABm, &vt,
   6385                                        BC_TRILL_NETWORK_RECEIVERS_PRESENTf, 0);
   6386                 }
   6387                 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm,
   6388                         UMC_TRILL_NETWORK_RECEIVERS_PRESENTf)) {
   6389                              soc_mem_field32_set(unit, VLAN_TABm, &vt,
   6390                                        UMC_TRILL_NETWORK_RECEIVERS_PRESENTf, 0);
   6391                 }
   6392                 if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm,
   6393                         UUC_TRILL_NETWORK_RECEIVERS_PRESENTf)) {
   6394                              soc_mem_field32_set(unit, VLAN_TABm, &vt,
   6395                                        UUC_TRILL_NETWORK_RECEIVERS_PRESENTf, 0);
   6396                 }
   6397                 rv = bcm_td_trill_vlan_multicast_group_delete(unit, vid, &vt);
   6398             }
   6399 
   6400             /* Specify per-Vlan trill_name */
   6401             if (BCM_SUCCESS(rv)) {
   6402                 if (valid_fields & BCM_VLAN_CONTROL_VLAN_SOURCE_TRILL_NAME_MASK) {
   6403                     if (control->source_trill_name &&
   6404                         soc_mem_field_valid (unit, VLAN_TABm, TRILL_RBRIDGE_NICKNAME_INDEXf)) {
   6405                         rv = bcm_td_trill_source_trill_name_idx_get(unit,
   6406                                   control->source_trill_name, &trill_name_index);
   6407                         if (BCM_SUCCESS(rv)) {
   6408                                soc_mem_field32_set(unit, VLAN_TABm, &vt,
   6409                                     TRILL_RBRIDGE_NICKNAME_INDEXf,
   6410                                     trill_name_index);
   6411                         }
   6412                     }
   6413                 }
   6414             } else {
   6415                 soc_mem_unlock(unit, VLAN_TABm);
   6416                 return (rv);
   6417             }
   6418         }
   6419     }
   6420 
   6421     if (soc_feature(unit, soc_feature_niv)) {
   6422         if (valid_fields & BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK) {
   6423             if (_BCM_MULTICAST_IS_NIV(control->broadcast_group)) {
   6424                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, BC_IDXf,
   6425                     _BCM_MULTICAST_ID_GET(control->broadcast_group));
   6426             }
   6427         }
   6428         if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK) {
   6429             if (_BCM_MULTICAST_IS_NIV(control->unknown_multicast_group)) {
   6430                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UMC_IDXf,
   6431                     _BCM_MULTICAST_ID_GET(control->unknown_multicast_group));
   6432             }
   6433         }
   6434         if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK) {
   6435             if (_BCM_MULTICAST_IS_NIV(control->unknown_unicast_group)) {
   6436                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UUC_IDXf,
   6437                     _BCM_MULTICAST_ID_GET(control->unknown_unicast_group));
   6438             }
   6439         }
   6440     }
   6441 
   6442     if (soc_feature(unit, soc_feature_l3) && soc_property_get(unit, spn_L3_ENABLE, 1)) {
   6443         if (valid_fields & BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK) {
   6444             if (_BCM_MULTICAST_IS_L3(control->broadcast_group)) {
   6445                 soc_mem_field32_set(unit, VLAN_TABm, &vt, BC_IDXf,
   6446                                     _BCM_MULTICAST_ID_GET
   6447                                     (control->broadcast_group));
   6448             }
   6449         }
   6450         if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK) {
   6451             if (_BCM_MULTICAST_IS_L3(control->unknown_multicast_group)) {
   6452                 soc_mem_field32_set(unit, VLAN_TABm, &vt, UMC_IDXf,
   6453                                     _BCM_MULTICAST_ID_GET
   6454                                     (control->unknown_multicast_group));
   6455             }
   6456         }
   6457         if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK) {
   6458             if (_BCM_MULTICAST_IS_L3(control->unknown_unicast_group)) {
   6459                 soc_mem_field32_set(unit, VLAN_TABm, &vt, UUC_IDXf,
   6460                                     _BCM_MULTICAST_ID_GET
   6461                                     (control->unknown_unicast_group));
   6462             }
   6463         }
   6464     }
   6465 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
   6466 
   6467 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
   6468     if (soc_feature(unit, soc_feature_port_extension)) {
   6469         if (valid_fields & BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK) {
   6470             if (_BCM_MULTICAST_IS_EXTENDER(control->broadcast_group)) {
   6471                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, BC_IDXf,
   6472                     _BCM_MULTICAST_ID_GET(control->broadcast_group));
   6473             }
   6474         }
   6475         if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK) {
   6476             if (_BCM_MULTICAST_IS_EXTENDER(control->unknown_multicast_group)) {
   6477                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UMC_IDXf,
   6478                     _BCM_MULTICAST_ID_GET(control->unknown_multicast_group));
   6479             }
   6480         }
   6481         if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK) {
   6482             if (_BCM_MULTICAST_IS_EXTENDER(control->unknown_unicast_group)) {
   6483                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UUC_IDXf,
   6484                     _BCM_MULTICAST_ID_GET(control->unknown_unicast_group));
   6485             }
   6486         }
   6487     }
   6488 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */
   6489 
   6490 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   6491     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) {
   6492         if (valid_fields & BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK) {
   6493             if (_BCM_MULTICAST_IS_SUBPORT(control->broadcast_group)) {
   6494                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, BC_IDXf,
   6495                     _BCM_MULTICAST_ID_GET(control->broadcast_group));
   6496             }
   6497         }
   6498         if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK) {
   6499             if (_BCM_MULTICAST_IS_SUBPORT(control->unknown_multicast_group)) {
   6500                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UMC_IDXf,
   6501                     _BCM_MULTICAST_ID_GET(control->unknown_multicast_group));
   6502             }
   6503         }
   6504         if (valid_fields & BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK) {
   6505             if (_BCM_MULTICAST_IS_SUBPORT(control->unknown_unicast_group)) {
   6506                 _bcm_xgs3_vlan_mcast_idx_set(unit, &vt, UUC_IDXf,
   6507                     _BCM_MULTICAST_ID_GET(control->unknown_unicast_group));
   6508             }
   6509         }
   6510     }
   6511 #endif /* defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3) */
   6512 
   6513 
   6514 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
   6515     if (valid_fields & BCM_VLAN_CONTROL_VLAN_VP_MCAST_MASK) {
   6516         if (control->vp_mc_ctrl == bcmVlanVPMcControlEnable) {
   6517             if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) {
   6518                 int i, mc_idx;
   6519                 bcm_pbmp_t vlan_pbmp, vlan_ubmp, pbmp, l3_pbmp;
   6520                 soc_field_t group_type[3] = {BC_IDXf, UMC_IDXf, UUC_IDXf};
   6521 #if defined(BCM_HGPROXY_COE_SUPPORT)
   6522                 bcm_port_t         port_iter;
   6523                 int                port_type;
   6524 #endif
   6525                 /* Also need to copy the physical port members to the L2_BITMAP of
   6526                  * the IPMC entry for each group once we've gone virtual */
   6527                 rv = mbcm_driver[unit]->mbcm_vlan_port_get
   6528                    (unit, vid, &vlan_pbmp, &vlan_ubmp, NULL);
   6529 
   6530                 if (rv < 0) {
   6531                     soc_mem_unlock(unit, VLAN_TABm);
   6532                     return rv;
   6533                 }
   6534 #if defined(BCM_HGPROXY_COE_SUPPORT)
   6535                 /* Coe cascaded port should be removed from l2bmap of L3_IPMC. */
   6536                 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, PORT_TYPEf)) {
   6537                     BCM_PBMP_ITER(vlan_pbmp, port_iter) {
   6538                         rv = _bcm_esw_port_tab_get(unit, port_iter,
   6539                                                    PORT_TYPEf, &port_type);
   6540                         if (rv < 0) {
   6541                             soc_mem_unlock(unit, VLAN_TABm);
   6542                             return rv;
   6543                         }
   6544                         if (port_type == _BCM_COE_PORT_TYPE_CASCADED) {
   6545                             BCM_PBMP_PORT_REMOVE(vlan_pbmp, port_iter);
   6546                         }
   6547                     }
   6548                 }
   6549 #endif
   6550                 /* Deal with each group */
   6551                 for (i = 0; i < 3; i++) {
   6552                     mc_idx = _bcm_xgs3_vlan_mcast_idx_get(unit, &vt,
   6553                                                 group_type[i]);
   6554                     rv = _bcm_esw_multicast_ipmc_read(unit, mc_idx, &pbmp,
   6555                                                      &l3_pbmp);
   6556                     if (rv < 0) {
   6557                         soc_mem_unlock(unit, VLAN_TABm);
   6558                         return rv;
   6559                     }
   6560 
   6561                     if (BCM_PBMP_IS_NULL(pbmp)) {
   6562                         rv = _bcm_esw_multicast_ipmc_write(unit, mc_idx, vlan_pbmp,
   6563                                                           l3_pbmp, TRUE);
   6564                         if (rv < 0) {
   6565                             soc_mem_unlock(unit, VLAN_TABm);
   6566                             return rv;
   6567                         }
   6568                     }
   6569                 }
   6570                 soc_mem_field32_set(unit, VLAN_TABm, &vt, VIRTUAL_PORT_ENf, 1);
   6571             }
   6572         } else if (control->vp_mc_ctrl == bcmVlanVPMcControlDisable) {
   6573             if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VIRTUAL_PORT_ENf)) {
   6574                 soc_mem_field32_set(unit, VLAN_TABm, &vt, VIRTUAL_PORT_ENf, 0);
   6575             }
   6576         }
   6577     }
   6578 
   6579 #endif /* defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) */
   6580 
   6581 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(INCLUDE_L3)
   6582     if (soc_feature(unit, soc_feature_vfi_from_vlan_tables)) {
   6583         if (_BCM_VPN_VFI_IS_SET (control->vpn)) {
   6584                 int vfi_index = -1, num_vfi = -1;
   6585                 _BCM_VPN_GET(vfi_index, _BCM_VPN_TYPE_VFI, control->vpn);
   6586                 num_vfi = soc_mem_index_count(unit, VFIm);
   6587                 if (vfi_index > (num_vfi-1)) {
   6588                     soc_mem_unlock(unit, VLAN_TABm);
   6589                     return BCM_E_PARAM;
   6590                 }
   6591                 if (vfi_index &&
   6592                     (!_bcm_vfi_used_get(unit, vfi_index, _bcmVfiTypeAny))) {
   6593                     soc_mem_unlock(unit, VLAN_TABm);
   6594                     return BCM_E_NOT_FOUND;
   6595                 }
   6596             if (SOC_MEM_IS_VALID(unit, VLAN_MPLSm) &&
   6597                 SOC_MEM_FIELD_VALID(unit, VLAN_MPLSm, VFIf)) {
   6598                 rv = soc_mem_field32_modify(unit, VLAN_MPLSm, vid, VFIf, vfi_index); 
   6599                 if (BCM_FAILURE(rv)) {
   6600                     soc_mem_unlock(unit, VLAN_TABm);
   6601                     return rv;
   6602                 }
   6603                 }
   6604 #if defined(BCM_TRIDENT3_SUPPORT)
   6605             else if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, VFIf)) {
   6606                 soc_mem_field32_set(unit, VLAN_TABm, &vt, VFIf, vfi_index);
   6607             }
   6608 #endif/* BCM_TRIDENT3_SUPPORT */
   6609         } else if (control->vpn) {
   6610             soc_mem_unlock(unit, VLAN_TABm);
   6611             return (BCM_E_PARAM);
   6612         }
   6613     }
   6614 #endif /* BCM_TRIDENT2PLUS_SUPPORT && INCLUDE_L3 */
   6615 
   6616 #if defined(BCM_TSN_SR_SUPPORT)
   6617     if (soc_feature(unit, soc_feature_tsn_sr)) {
   6618         if (valid_fields & BCM_VLAN_CONTROL_VLAN_SR_FLAGS_MASK) {
   6619             int i;
   6620             void *entbuf;
   6621             soc_mem_t mem[2] = {VLAN_TABm, EGR_VLANm};
   6622 
   6623             if ((!(control->sr_flags & BCM_VLAN_CONTROL_SR_FLAG_ENABLE)) &&
   6624                   (control->sr_flags & BCM_VLAN_CONTROL_SR_FLAG_LAN_ID)) {
   6625                 soc_mem_unlock(unit, VLAN_TABm);
   6626                 return BCM_E_PARAM;
   6627             }
   6628 
   6629             for (i = 0; i < 2; i++){
   6630                 if (1 == i) {
   6631                     /* handle egress vlan table, skip it if there is no such table */
   6632                     entbuf = &evt;
   6633                     if(SOC_MEM_IS_VALID(unit, mem[i])){
   6634                         rv = soc_mem_read(unit, mem[i], MEM_BLOCK_ANY,
   6635                                           (int)vid, &evt);
   6636                         if (BCM_FAILURE(rv)) {
   6637                             soc_mem_unlock(unit, VLAN_TABm);
   6638                             return (rv);
   6639                         }
   6640                     } else {
   6641                         break;
   6642                     }
   6643                 } else {
   6644                     entbuf = &vt;
   6645                 }
   6646                 if (control->sr_flags & BCM_VLAN_CONTROL_SR_FLAG_ENABLE) {
   6647                     soc_mem_field32_set(unit, mem[i], entbuf, SR_ENABLEf, 1);
   6648                     soc_mem_field32_set(unit, mem[i], entbuf, SR_LAN_ID_VALIDf, 1);
   6649                     if (control->sr_flags & BCM_VLAN_CONTROL_SR_FLAG_LAN_ID) {
   6650                         soc_mem_field32_set(unit, mem[i], entbuf, SR_LAN_IDf, 1);
   6651                     } else {
   6652                         soc_mem_field32_set(unit, mem[i], entbuf, SR_LAN_IDf, 0);
   6653                     }
   6654                 } else {
   6655                     soc_mem_field32_set(unit, mem[i], entbuf, SR_ENABLEf, 0);
   6656                     soc_mem_field32_set(unit, mem[i], entbuf, SR_LAN_ID_VALIDf, 0);
   6657                 }
   6658                 if (1 == i) {
   6659                     /* handle egress vlan table */
   6660                     rv = soc_mem_write(unit, mem[i], MEM_BLOCK_ANY,
   6661                                        (int)vid, entbuf);
   6662                     if (BCM_FAILURE(rv)) {
   6663                         soc_mem_unlock(unit, VLAN_TABm);
   6664                         return (rv);
   6665                     }
   6666                 }
   6667             }
   6668         }
   6669    }
   6670 #endif /* BCM_TSN_SR_SUPPORT*/
   6671 
   6672 
   6673 
   6674     if (SOC_MEM_FIELD_VALID(unit, VLAN_TABm, ENABLE_IGMP_MLD_SNOOPINGf)) {
   6675         soc_mem_field32_set(unit, VLAN_TABm, &vt, ENABLE_IGMP_MLD_SNOOPINGf,
   6676                       (0 == (control->flags & BCM_VLAN_IGMP_SNOOP_DISABLE)));
   6677     }
   6678 
   6679     rv = soc_mem_write(unit, VLAN_TABm, MEM_BLOCK_ANY, (int)vid, &vt);
   6680     soc_mem_unlock(unit, VLAN_TABm);
   6681     if (BCM_SUCCESS(rv) && (pre_cfg == TRUE)) {
   6682         SHR_BITSET(vlan_info[unit].pre_cfg_bmp.w,vid);
   6683     }
   6684 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAPTOR_SUPPORT */
   6685     return (rv);
   6686 }
   6687 
   6688 #if defined (BCM_TRX_SUPPORT)
   6689 /*
   6690  * Function :
   6691  *    _vlan_block_mask_create
   6692  *
   6693  * Purpose  :
   6694  *    Compose block mask based 
   6695  *
   6696  * Parameters:
   6697  *     unit        - (IN)  BCM device number.
   6698  *     first_mask  - (IN)  First mask.
   6699  *     second_mask - (IN)  Second mask.
   6700  *     select      - (IN)  Mask select. 
   6701  *     result_mask - (OUT) Output mask.     
   6702  * Return :
   6703  *    BCM_E_XXX
   6704  */
   6705 int
   6706 _vlan_block_mask_create(int unit, bcm_pbmp_t first_mask, 
   6707                          bcm_pbmp_t second_mask, 
   6708                          uint8 select, bcm_pbmp_t *result_mask)
   6709 {
   6710     /* Input parameters check */
   6711     if (NULL == result_mask) {
   6712         return (BCM_E_PARAM);
   6713     }
   6714 
   6715     switch (select) {
   6716       case 0:
   6717           BCM_PBMP_CLEAR(*result_mask);
   6718           break;
   6719       case 1:
   6720           BCM_PBMP_ASSIGN(*result_mask, first_mask);
   6721           break;
   6722       case 2:
   6723           BCM_PBMP_ASSIGN(*result_mask, second_mask);
   6724           break;
   6725       case 3:
   6726           BCM_PBMP_ASSIGN(*result_mask, first_mask);
   6727           BCM_PBMP_OR(*result_mask, second_mask);
   6728           break;
   6729       default:
   6730           return (BCM_E_PARAM);
   6731     }
   6732     return (BCM_E_NONE);
   6733 }
   6734 
   6735 /*
   6736  * Function :
   6737  *    _bcm_trx_vlan_block_get
   6738  * 
   6739  * Purpose  :
   6740  *    Get vlan specific traffic blocking parameters
   6741  *
   6742  * Parameters:
   6743  *     unit    - (IN) BCM device number.
   6744  *     vid     - (IN) Vlan id. 
   6745  *     block   - (IN) Block configuration.
   6746  *
   6747  * Return :
   6748  *    BCM_E_XXX
   6749  */
   6750 int
   6751 _bcm_trx_vlan_block_get (int unit, bcm_vlan_t vid, bcm_vlan_block_t *block)
   6752 {
   6753     _trx_vlan_block_t  *hw_block; /* Vlan block profile.      */
   6754     int                rv;        /* Operation return status. */
   6755     int                idx;       /* Vlan profile index.      */
   6756 
   6757     /* Input parameters check. */
   6758     if (NULL == block) {
   6759         return (BCM_E_PARAM);
   6760     }
   6761 
   6762     /* Get original vlan profile. */
   6763     rv = _vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf,
   6764                                NULL, vid, &idx);
   6765     BCM_IF_ERROR_RETURN(rv);
   6766 
   6767     hw_block = &VLAN_PROFILE_ENTRY(unit, idx).block;
   6768 
   6769     rv = _vlan_block_mask_create (unit, hw_block->first_mask, 
   6770                                   hw_block->second_mask, 
   6771                                   hw_block->broadcast_mask_sel, 
   6772                                   &block->broadcast);
   6773     BCM_IF_ERROR_RETURN(rv);
   6774 
   6775     rv = _vlan_block_mask_create (unit, hw_block->first_mask, 
   6776                                   hw_block->second_mask, 
   6777                                   hw_block->unknown_unicast_mask_sel, 
   6778                                   &block->unknown_unicast);
   6779     BCM_IF_ERROR_RETURN(rv);
   6780 
   6781     rv = _vlan_block_mask_create (unit, 
   6782                                   hw_block->first_mask, 
   6783                                   hw_block->second_mask, 
   6784                                   hw_block->unknown_mulitcast_mask_sel, 
   6785                                   &block->unknown_multicast);
   6786     BCM_IF_ERROR_RETURN(rv);
   6787 
   6788     rv = _vlan_block_mask_create (unit, 
   6789                                   hw_block->first_mask, 
   6790                                   hw_block->second_mask, 
   6791                                   hw_block->known_mulitcast_mask_sel, 
   6792                                   &block->known_multicast);
   6793     BCM_IF_ERROR_RETURN(rv);
   6794 
   6795     return (BCM_E_NONE);
   6796 }
   6797 
   6798 /* Number of lookup types in bcm_vlan_block_t structure. */
   6799 #define _BCM_VLAN_BLOCK_LOOKUP_TYPES (4)
   6800 
   6801 /*
   6802  * Function :
   6803  *    _vlan_block_bitmap_min
   6804  * 
   6805  * Purpose  :
   6806  *    Find shortest bitmap. 
   6807  *
   6808  * Parameters:
   6809  *     unit    - (IN) BCM device number.
   6810  *     array   - (IN) Bitmaps array. 
   6811  *     arr_sz  - (IN) Array size. 
   6812  *     min_pbm - (OUT) Shortest bitmap.
   6813  *
   6814  * Return :
   6815  *    BCM_E_XXX
   6816  */
   6817 int
   6818 _vlan_block_bitmap_min(int unit, bcm_pbmp_t *array, 
   6819                        int arr_size, bcm_pbmp_t *min_pbm)
   6820 {      
   6821     int  idx;       /* Bitmaps array iteration index. */
   6822     int  min;       /* Mask length minimum.           */
   6823     int  mask_len;  /* Bitmap length.                 */
   6824 
   6825     if (NULL == array) {
   6826         return (BCM_E_PARAM);
   6827     }
   6828     BCM_PBMP_CLEAR(*min_pbm);
   6829     min = 0;
   6830     for (idx = 0; idx < arr_size; idx++) {
   6831 
   6832         BCM_PBMP_COUNT(array[idx], mask_len);
   6833         if (0 == mask_len) {
   6834             continue;
   6835         } else {
   6836             if ((0 == min) || ((0 != min) && (mask_len < min)))  {
   6837                 min = mask_len;
   6838                 BCM_PBMP_ASSIGN(*min_pbm, array[idx]);
   6839             }
   6840         }
   6841     }
   6842     return (BCM_E_NONE);
   6843 }
   6844 
   6845 /*
   6846  * Function :
   6847  *    _vlan_block_bitmap_clear
   6848  * 
   6849  * Purpose  :
   6850  *    Clear those masks in the array that exactly match the given mask. 
   6851  *
   6852  * Parameters:
   6853  *     unit    - (IN)     BCM device number.
   6854  *     array   - (IN/OUT) Bitmaps array 
   6855  *     arr_sz  - (IN)     Array size. 
   6856  *     mask    - (IN)     Mask.
   6857  *
   6858  * Return :
   6859  *    BCM_E_XXX
   6860  */
   6861 int
   6862 _vlan_block_bitmap_clear(int unit, bcm_pbmp_t *array, 
   6863                        int arr_size, bcm_pbmp_t mask)
   6864 {      
   6865     int  idx;       /* Bitmaps array iteration index. */
   6866 
   6867     if (NULL == array) {
   6868         return (BCM_E_PARAM);
   6869     }
   6870 
   6871     for (idx = 0; idx < arr_size; idx++) {
   6872         if (BCM_PBMP_EQ(array[idx], mask)) {
   6873             BCM_PBMP_CLEAR(array[idx]);
   6874         }
   6875     }
   6876     return (BCM_E_NONE);
   6877 }
   6878 
   6879 /*
   6880  * Function :
   6881  *    _vlan_block_select_get
   6882  * 
   6883  * Purpose  :
   6884  *    Identify block mask combination which will produce 
   6885  *    requested block mask 
   6886  * Parameters:
   6887  *     unit        - (IN) BCM device number.
   6888  *     req         - (IN) Requested mask.
   6889  *     first       - (IN) Bitmaps array. 
   6890  *     second      - (IN) Bitmaps array.
   6891  *     select      - (OUT)Block mask.
   6892  * Return :
   6893  *    BCM_E_XXX
   6894  */
   6895 int
   6896 _vlan_block_select_get(int unit, bcm_pbmp_t request, 
   6897                        bcm_pbmp_t first, 
   6898                        bcm_pbmp_t second, 
   6899                        uint8 *sel)
   6900 {      
   6901     bcm_pbmp_t or_mask;
   6902 
   6903     /* Input parameters check. */
   6904     if (NULL == sel) {
   6905         return (BCM_E_PARAM);
   6906     }
   6907 
   6908     if (BCM_PBMP_IS_NULL(request)) {
   6909         *sel = 0;
   6910     } else if (BCM_PBMP_EQ(first, request)) {
   6911         *sel = 0x1;
   6912     } else if (BCM_PBMP_EQ(second, request)) {
   6913         *sel = 0x2;
   6914     } else {
   6915         BCM_PBMP_ASSIGN(or_mask, first);
   6916         BCM_PBMP_OR(or_mask, second);
   6917         if (BCM_PBMP_EQ(or_mask, request)) {
   6918             *sel = 0x3; 
   6919         } else {
   6920             return (BCM_E_RESOURCE);
   6921         }
   6922     }
   6923     return (BCM_E_NONE);
   6924 }
   6925 
   6926 /*
   6927  * Function :
   6928  *    _bcm_trx_vlan_block_set
   6929  * 
   6930  * Purpose  :
   6931  *    sjt vlan specific traffic blocking parameters
   6932  *
   6933  * Parameters:
   6934  *     unit    - (IN) BCM device number.
   6935  *     vid     - (IN) Vlan id. 
   6936  *     block   - (IN) Block configuration.
   6937  *
   6938  * Return :
   6939  *    BCM_E_XXX
   6940  */
   6941 int
   6942 _bcm_trx_vlan_block_set (int unit, bcm_vlan_t vid, bcm_vlan_block_t *block)
   6943 {
   6944     bcm_pbmp_t         array[_BCM_VLAN_BLOCK_LOOKUP_TYPES];
   6945     _trx_vlan_block_t  hw_block;       /* HW block structure.      */
   6946     _vlan_profile_t    profile;        /* Original vlan profile.   */
   6947     int                profile_idx;    /* Profile index.           */
   6948     int                rv;             /* Operation return status. */
   6949 
   6950     /* Input parameters check. */
   6951     if (NULL == block) {
   6952         return (BCM_E_PARAM);
   6953     }
   6954 
   6955     /* Store block mask in a array. */
   6956     BCM_PBMP_ASSIGN(array[0], block->broadcast);
   6957     BCM_PBMP_ASSIGN(array[1], block->unknown_unicast);
   6958     BCM_PBMP_ASSIGN(array[2], block->unknown_multicast);
   6959     BCM_PBMP_ASSIGN(array[3], block->known_multicast);
   6960 
   6961     /* Select first  shortest mask. */
   6962 
   6963     /* Coverity
   6964      * The index coverity thinks outside of boundary is actually for 
   6965      * the field pbits of the pbmp structure.
   6966      */
   6967     /* coverity[overrun-buffer-val: FALSE] */
   6968     rv = _vlan_block_bitmap_min(unit, array,
   6969                                 _BCM_VLAN_BLOCK_LOOKUP_TYPES,
   6970                                 &hw_block.first_mask);
   6971     BCM_IF_ERROR_RETURN(rv);
   6972 
   6973     /* Clear those masks in the array that exactly match the shortest mask. */
   6974     /* coverity[overrun-buffer-val: FALSE] */
   6975     rv = _vlan_block_bitmap_clear(unit, array,
   6976                                   _BCM_VLAN_BLOCK_LOOKUP_TYPES,
   6977                                   hw_block.first_mask);
   6978     BCM_IF_ERROR_RETURN(rv);
   6979 
   6980     /* Select second shortest mask. */
   6981     /* coverity[overrun-buffer-val: FALSE] */
   6982     rv = _vlan_block_bitmap_min(unit, array,
   6983                                 _BCM_VLAN_BLOCK_LOOKUP_TYPES,
   6984                                 &hw_block.second_mask);
   6985     BCM_IF_ERROR_RETURN(rv);
   6986 
   6987 
   6988     /* Get mask selector for each lookup type. */
   6989     rv = _vlan_block_select_get(unit, block->broadcast, hw_block.first_mask,
   6990                                 hw_block.second_mask, &hw_block.broadcast_mask_sel);
   6991     BCM_IF_ERROR_RETURN(rv);
   6992 
   6993     rv = _vlan_block_select_get(unit, block->unknown_unicast, hw_block.first_mask,
   6994                                 hw_block.second_mask, &hw_block.unknown_unicast_mask_sel);
   6995     BCM_IF_ERROR_RETURN(rv);
   6996 
   6997     rv = _vlan_block_select_get(unit, block->unknown_multicast, hw_block.first_mask,
   6998                                 hw_block.second_mask, &hw_block.unknown_mulitcast_mask_sel);
   6999     BCM_IF_ERROR_RETURN(rv);
   7000 
   7001     rv = _vlan_block_select_get(unit, block->known_multicast, hw_block.first_mask,
   7002                                 hw_block.second_mask, &hw_block.known_mulitcast_mask_sel);
   7003     BCM_IF_ERROR_RETURN(rv);
   7004 
   7005     /* Get original vlan profile. */
   7006     rv = _vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf,
   7007                                NULL, vid, &profile_idx);
   7008     BCM_IF_ERROR_RETURN(rv);
   7009 
   7010     profile = VLAN_PROFILE_ENTRY(unit, profile_idx);
   7011     profile.block = hw_block;
   7012 
   7013     /* Update vlan profile. */
   7014     rv = _vlan_profile_update(unit, vid, &profile);
   7015     BCM_IF_ERROR_RETURN(rv);
   7016 
   7017     return (BCM_E_NONE);
   7018 }
   7019 
   7020 #endif /* BCM_TRX_SUPPORT */
   7021 
   7022 #ifdef BCM_TRIUMPH2_SUPPORT
   7023 /*
   7024  * Function:
   7025  *    _bcm_tr2_vlan_qmid_set
   7026  * Purpose:
   7027  *    Set vlan queue mapping pointer in vlan profile table
   7028  * Parameters:
   7029  *     unit            device number
   7030  *     vlan            vlan idenetifier
   7031  *     qm_ptr          queue mapping identifier (use -1 to disable)
   7032  *     use_inner_tag   use priority from inner tag
   7033  * Return:
   7034  *    BCM_E_XXX
   7035  */
   7036 int
   7037 _bcm_tr2_vlan_qmid_set(int unit, bcm_vlan_t vlan, int qmid,
   7038                        int use_inner_tag)
   7039 {
   7040     _vlan_profile_t profile;
   7041     int profile_idx;
   7042     uint32 profile_flags;
   7043 
   7044     BCM_IF_ERROR_RETURN
   7045         (_vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf, NULL,
   7046                                vlan, &profile_idx));
   7047 
   7048     profile = VLAN_PROFILE_ENTRY(unit, profile_idx);
   7049     profile_flags = profile.profile_flags;
   7050     profile_flags &= ~(_BCM_VLAN_PROFILE_PHB2_ENABLE |
   7051                        _BCM_VLAN_PROFILE_PHB2_USE_INNER_TAG);
   7052     if (qmid >= 0) {
   7053         profile_flags |= _BCM_VLAN_PROFILE_PHB2_ENABLE;
   7054     } else {
   7055         qmid = 0;
   7056     }
   7057     if (use_inner_tag) {
   7058         profile_flags |= _BCM_VLAN_PROFILE_PHB2_USE_INNER_TAG;
   7059     }
   7060 
   7061     if (profile.qm_ptr == qmid && profile.profile_flags == profile_flags) {
   7062         return BCM_E_NONE;
   7063     }
   7064 
   7065     profile.profile_flags = profile_flags;
   7066     profile.qm_ptr = qmid;
   7067     BCM_IF_ERROR_RETURN(_vlan_profile_update(unit, vlan, &profile));
   7068 
   7069     return BCM_E_NONE;
   7070 }
   7071 
   7072 /*
   7073  * Function:
   7074  *    _bcm_tr2_vlan_qmid_get
   7075  * Purpose:
   7076  *    get vlan queue mapping pointer in vlan profile table
   7077  * Parameters:
   7078  *     unit            device number
   7079  *     vlan            vlan idenetifier
   7080  *     qm_ptr          (OUT) queue mapping identifier (use -1 to disable)
   7081  *     use_inner_tag   (OUT) use priority from inner tag
   7082  * Return:
   7083  *    BCM_E_XXX
   7084  */
   7085 int
   7086 _bcm_tr2_vlan_qmid_get(int unit, bcm_vlan_t vlan, int *qmid,
   7087                        int *use_inner_tag)
   7088 {
   7089     _vlan_profile_t profile;
   7090     int profile_idx;
   7091 
   7092     if (qmid == NULL || use_inner_tag == NULL) {
   7093         return BCM_E_PARAM;
   7094     }
   7095 
   7096     BCM_IF_ERROR_RETURN
   7097         (_vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf, NULL,
   7098                                vlan, &profile_idx));
   7099 
   7100     profile = VLAN_PROFILE_ENTRY(unit, profile_idx);
   7101     if (profile.profile_flags & _BCM_VLAN_PROFILE_PHB2_ENABLE) {
   7102         *qmid = profile.qm_ptr;
   7103     } else {
   7104         *qmid = -1;
   7105 	return BCM_E_NOT_FOUND;
   7106     }
   7107     if (profile.profile_flags & _BCM_VLAN_PROFILE_PHB2_USE_INNER_TAG) {
   7108         *use_inner_tag = 1;
   7109     } else {
   7110         *use_inner_tag = 0;
   7111     }
   7112 
   7113     return BCM_E_NONE;
   7114 }
   7115 
   7116 /*
   7117  * Function:
   7118  *    _bcm_tr2_qos_pvmid_set
   7119  * Purpose:
   7120  *    Set vlan port vlan mapping pointer in vlan profile table
   7121  * Parameters:
   7122  *     unit            device number
   7123  *     vlan            vlan idenetifier
   7124  *     pvm_ptr         port vlan mapping identifier (use -1 to disable)
   7125  * Return:
   7126  *    BCM_E_XXX
   7127  */
   7128 int
   7129 _bcm_tr2_qos_pvmid_set(int unit, bcm_vlan_t vlan, int pvmid)
   7130 {
   7131     int rv;
   7132     _vlan_profile_t profile;
   7133     int profile_idx;
   7134     uint32 profile_flags;
   7135 
   7136     soc_mem_lock(unit, VLAN_TABm);
   7137 
   7138     rv = _vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf, NULL,
   7139                                vlan, &profile_idx);
   7140     if (BCM_FAILURE(rv)) {
   7141         soc_mem_unlock(unit, VLAN_TABm);
   7142         return rv;
   7143     }
   7144 
   7145     profile = VLAN_PROFILE_ENTRY(unit, profile_idx);
   7146     profile_flags = profile.profile_flags;
   7147     profile_flags &= ~_BCM_VLAN_PROFILE_TRUST_DOT1P;
   7148     if (pvmid >= 0) {
   7149         profile_flags |= _BCM_VLAN_PROFILE_TRUST_DOT1P;
   7150     } else {
   7151         pvmid = 0;
   7152     }
   7153 
   7154     if (profile.trust_dot1p_ptr == pvmid && 
   7155         profile.profile_flags == profile_flags) {
   7156         soc_mem_unlock(unit, VLAN_TABm);
   7157         return BCM_E_NONE;
   7158     }
   7159 
   7160     profile.profile_flags = profile_flags;
   7161     profile.trust_dot1p_ptr = pvmid;
   7162 
   7163     rv = _vlan_profile_update(unit, vlan, &profile);
   7164 
   7165     soc_mem_unlock(unit, VLAN_TABm);
   7166 
   7167     return rv;
   7168 }
   7169 
   7170 /*
   7171  * Function:
   7172  *    _bcm_tr2_qos_pvmid_get
   7173  * Purpose:
   7174  *    get vlan port vlan mapping pointer in vlan profile table
   7175  * Parameters:
   7176  *     unit            device number
   7177  *     vlan            vlan idenetifier
   7178  *     pvm_ptr         (OUT) port vlan mapping identifier (use -1 to disable)
   7179  * Return:
   7180  *    BCM_E_XXX
   7181  */
   7182 int
   7183 _bcm_tr2_qos_pvmid_get(int unit, bcm_vlan_t vlan, int *pvmid)
   7184 {
   7185     int rv;
   7186     _vlan_profile_t profile;
   7187     int profile_idx;
   7188 
   7189     if (pvmid == NULL) {
   7190         return BCM_E_PARAM;
   7191     }
   7192 
   7193     soc_mem_lock(unit, VLAN_TABm);
   7194 
   7195     rv = _vlan_profile_idx_get(unit, VLAN_TABm, VLAN_PROFILE_PTRf, NULL,
   7196                                vlan, &profile_idx);
   7197     if (BCM_FAILURE(rv)) {
   7198         soc_mem_unlock(unit, VLAN_TABm);
   7199         return rv;
   7200     }
   7201 
   7202     profile = VLAN_PROFILE_ENTRY(unit, profile_idx);
   7203     if (profile.profile_flags & _BCM_VLAN_PROFILE_TRUST_DOT1P) {
   7204         *pvmid = profile.trust_dot1p_ptr;
   7205     } else {
   7206         *pvmid = -1;
   7207     }
   7208 
   7209     soc_mem_unlock(unit, VLAN_TABm);
   7210 
   7211     return BCM_E_NONE;
   7212 }
   7213 #endif /* BCM_TRIUMPH2_SUPPORT */
   7214 
   7215 /*
   7216  * Function:
   7217  *      _bcm_fb_vlan_translate_add
   7218  * Purpose:
   7219  *      Helper function to bcm_esw_vlan_translate_add to add vlan translation 
   7220  *      for Firebolt
   7221  * Parameters:
   7222  *      unit - StrataSwitch PCI device unit number (driver internal).
   7223  *      port - port numebr
   7224  *      old_vid - Old VLAN ID to has translation for
   7225  *      new_vid - New VLAN ID that packet will get
   7226  *      prio    - Priority
   7227  *      xtable  - Memory to use for Firebolt
   7228  * Returns:
   7229  *      BCM_E_NONE - Translation found, new_vid nad prio will have the values.
   7230  *      BCM_E_NOT_FOUND - Translation does not exist
   7231  *      BCM_E_XXX  - Other error
   7232  * Notes:
   7233  *      None.
   7234  */
   7235 int
   7236 _bcm_fb_vlan_translate_add(int unit, int port, bcm_vlan_t old_vid,
   7237                            bcm_vlan_t new_vid, int prio,
   7238                            int xtable)
   7239 {
   7240     vlan_xlate_entry_t  vtent;
   7241     int                 index_min, index_max;
   7242     soc_mem_t           mem;
   7243     int                 addvid;
   7244     uint32              *vtcachep, vtcache;
   7245     uint32              ve_valid, ve_port, ve_vid, ve_add;
   7246     int                 empty, match, slot, i, rv;
   7247 
   7248     if (!soc_feature(unit, soc_feature_vlan_translation)) {
   7249         return BCM_E_UNAVAIL;
   7250     }
   7251 
   7252     switch (xtable) {
   7253     case BCM_VLAN_XLATE_ING:
   7254         mem = VLAN_XLATEm;
   7255         addvid = 0;
   7256         break;
   7257     case BCM_VLAN_XLATE_EGR:
   7258         mem = EGR_VLAN_XLATEm;
   7259         addvid = -1;
   7260         break;
   7261     case BCM_VLAN_XLATE_DTAG:
   7262         mem = VLAN_XLATEm;
   7263         addvid = 1;
   7264         break;
   7265     default:
   7266         return BCM_E_INTERNAL;
   7267     }
   7268 
   7269     if (((port < 0) || (old_vid == BCM_VLAN_NONE)) && port != -1) {
   7270         return BCM_E_PARAM;
   7271     }
   7272 
   7273 #ifdef BCM_KATANA2_SUPPORT
   7274     if ((port != -1) && ((soc_feature(unit, soc_feature_linkphy_coe) &&
   7275           BCM_PBMP_MEMBER (SOC_INFO(unit).linkphy_pp_port_pbm, port)) ||
   7276          (soc_feature(unit, soc_feature_subtag_coe) &&
   7277           BCM_PBMP_MEMBER (SOC_INFO(unit).subtag_pp_port_pbm, port)))) {
   7278     } else
   7279 #endif
   7280     if (port >= 0 && !SOC_PORT_VALID(unit, port)) {
   7281         return BCM_E_PORT;
   7282     }
   7283 
   7284     if ((prio != -1) && ((prio & ~BCM_PRIO_MASK) != 0)) {
   7285         return BCM_E_PARAM;
   7286     }
   7287 
   7288     index_min = soc_mem_index_min(unit, mem);
   7289     index_max = soc_mem_index_max(unit, mem);
   7290 
   7291     soc_mem_lock(unit, mem);
   7292 
   7293     /* get vt cache, allocate if necessary */
   7294     if (mem == EGR_VLAN_XLATEm) {
   7295         vtcachep = vlan_info[unit].egr_trans;
   7296     } else {
   7297         vtcachep = vlan_info[unit].ing_trans;
   7298     }
   7299     if (vtcachep == NULL) {
   7300         vtcachep = sal_alloc(sizeof(*vtcachep) * (index_max+1),
   7301                              "vlan trans cache");
   7302         if (vtcachep == NULL) {
   7303             soc_mem_unlock(unit, mem);
   7304             return BCM_E_MEMORY;
   7305         }
   7306         sal_memset(vtcachep, 0, sizeof(*vtcachep) * (index_max+1));
   7307         if (mem == EGR_VLAN_XLATEm) {
   7308             vlan_info[unit].egr_trans = vtcachep;
   7309         } else {
   7310             vlan_info[unit].ing_trans = vtcachep;
   7311         }
   7312     }
   7313 
   7314     /* search vt cache for match */
   7315     match = empty = -1;
   7316     for (i = index_min; i <= index_max; i++) {
   7317         vtcache = vtcachep[i];
   7318         ve_valid = BCM_VTCACHE_VALID_GET(vtcache);
   7319         if (empty < 0 && !ve_valid) {
   7320             empty = i;
   7321         }
   7322         ve_port = BCM_VTCACHE_PORT_GET(vtcache);
   7323         if ((int)ve_port != port) {
   7324             continue;
   7325         }
   7326         ve_vid = BCM_VTCACHE_VID_GET(vtcache);
   7327         if (ve_vid != old_vid) {
   7328             continue;
   7329         }
   7330         if (addvid >= 0) {
   7331             ve_add = BCM_VTCACHE_ADD_GET(vtcache);
   7332             if ((int)ve_add != addvid) {
   7333                 soc_mem_unlock(unit, mem);
   7334                 return BCM_E_EXISTS;
   7335             }
   7336         }
   7337         match = i;
   7338         break;
   7339     }
   7340 
   7341     if (match != -1) {
   7342         slot = match;
   7343     } else if (empty != -1) {
   7344         slot = empty;
   7345     } else {
   7346         soc_mem_unlock(unit, mem);
   7347         return BCM_E_FULL;
   7348     }
   7349 
   7350     sal_memset(&vtent, 0, sizeof(vtent));
   7351 
   7352     soc_mem_field32_set(unit, mem, &vtent, VALIDf, 1);
   7353     if (port == -1) { 
   7354         soc_mem_field32_set(unit, mem, &vtent, PORTf, 0);
   7355     } else {
   7356         soc_mem_field32_set(unit, mem, &vtent, PORTf, port);
   7357     }
   7358     soc_mem_field32_set(unit, mem, &vtent, OLD_VLAN_IDf, old_vid);
   7359     soc_mem_field32_set(unit, mem, &vtent, NEW_VLAN_IDf, new_vid);
   7360     if (soc_mem_field_valid(unit, mem, MASKf)) {
   7361         if (port == -1) { 
   7362             if (mem == VLAN_XLATEm) {
   7363                 soc_mem_field32_set(unit, mem, &vtent, MASKf, 0x1ffe0);
   7364             } else {  /* mem == EGR_VLAN_XLATEm */
   7365                 soc_mem_field32_set(unit, mem, &vtent, MASKf, 0xfff);
   7366             }
   7367         } else {
   7368             soc_mem_field32_set(unit, mem, &vtent, MASKf, 
   7369                             (1 << soc_mem_field_length(unit, mem, MASKf)) - 1);
   7370         }
   7371     }
   7372 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_SCORPION_SUPPORT)
   7373     if (soc_mem_field_valid(unit, mem, RESERVED_MASKf)) {
   7374         soc_mem_field32_set(unit, mem, &vtent, RESERVED_MASKf, 0);
   7375     }
   7376     if (soc_mem_field_valid(unit, mem, RESERVED_DATAf)) {
   7377         soc_mem_field32_set(unit, mem, &vtent, RESERVED_DATAf, 0);
   7378     }
   7379     if (soc_mem_field_valid(unit, mem, RESERVED_KEYf)) {
   7380         soc_mem_field32_set(unit, mem, &vtent, RESERVED_KEYf, 0);
   7381     }
   7382 #endif /* BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */
   7383 
   7384     if (prio >= 0) {
   7385         soc_mem_field32_set(unit, mem, &vtent, RPEf, 1);
   7386         soc_mem_field32_set(unit, mem, &vtent, PRIf, prio);
   7387     }
   7388     if (addvid >= 0) {
   7389         soc_mem_field32_set(unit, mem, &vtent, ADD_VIDf, addvid);
   7390     }
   7391 
   7392     rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, slot, &vtent);
   7393     if (rv >= 0) {
   7394         vtcache = 0;
   7395         BCM_VTCACHE_VALID_SET(vtcache, 1);
   7396         BCM_VTCACHE_PORT_SET(vtcache, port);
   7397         BCM_VTCACHE_VID_SET(vtcache, old_vid);
   7398         if (addvid >= 0) {
   7399             BCM_VTCACHE_ADD_SET(vtcache, addvid);
   7400         }
   7401         vtcachep[slot] = vtcache;
   7402     }
   7403     soc_mem_unlock(unit, mem);
   7404     return rv;
   7405 }
   7406 
   7407 /*
   7408  * Function:
   7409  *      _bcm_fb_vlan_translate_delete
   7410  * Purpose:
   7411  *      Helper function to bcm_esw_vlan_translate_delete to delete vlan 
   7412  *      translation for Firebolt family
   7413  * Parameters:
   7414  *      unit - StrataSwitch PCI device unit number (driver internal).
   7415  *      port - port numebr can be wildcarded (port = -1)
   7416  *      old_vid - Old VLAN ID to delete translation for can be wildcarded (old_vid = BCM_VLAN_NONE)
   7417  *      xtable  - Memory table
   7418  * Returns:
   7419  *      BCM_E_NONE - Translation found, new_vid nad prio will have the values.
   7420  *      BCM_E_NOT_FOUND - Translation does not exist
   7421  *      BCM_E_XXX  - Other error
   7422  * Notes:
   7423  *      None.
   7424  */
   7425 int
   7426 _bcm_fb_vlan_translate_delete(int unit, int port, bcm_vlan_t old_vid,
   7427                               int xtable)
   7428 {
   7429     soc_mem_t           mem;
   7430     int                 addvid, index_min, index_max, rv;
   7431     int                 nmatch, nwrongadd, i;
   7432     vlan_xlate_entry_t  vtempty;
   7433     uint32              *vtcachep, vtcache;
   7434     uint32              ve_valid, ve_port, ve_vid, ve_add;
   7435 
   7436     if (!soc_feature(unit, soc_feature_vlan_translation)) {
   7437         return BCM_E_UNAVAIL;
   7438     }
   7439 
   7440     switch (xtable) {
   7441     case BCM_VLAN_XLATE_ING:
   7442         mem = VLAN_XLATEm;
   7443         addvid = 0;
   7444         break;
   7445     case BCM_VLAN_XLATE_EGR:
   7446         mem = EGR_VLAN_XLATEm;
   7447         addvid = -1;
   7448         break;
   7449     case BCM_VLAN_XLATE_DTAG:
   7450         mem = VLAN_XLATEm;
   7451         addvid = 1;
   7452         break;
   7453     default:
   7454         return BCM_E_INTERNAL;
   7455     }
   7456 
   7457 #ifdef BCM_KATANA2_SUPPORT
   7458     if ((soc_feature(unit, soc_feature_linkphy_coe) &&
   7459           BCM_PBMP_MEMBER (SOC_INFO(unit).linkphy_pp_port_pbm, port)) ||
   7460          (soc_feature(unit, soc_feature_subtag_coe) &&
   7461           BCM_PBMP_MEMBER (SOC_INFO(unit).subtag_pp_port_pbm, port))) {
   7462     } else
   7463 #endif
   7464     if (port >= 0 && !SOC_PORT_VALID(unit, port)) {
   7465         return BCM_E_PORT;
   7466     }
   7467 
   7468     soc_mem_lock(unit, mem);
   7469 
   7470     /* get vt cache */
   7471     if (mem == EGR_VLAN_XLATEm) {
   7472         vtcachep = vlan_info[unit].egr_trans;
   7473     } else {
   7474         vtcachep = vlan_info[unit].ing_trans;
   7475     }
   7476     if (vtcachep == NULL) {             /* vt cache empty */
   7477         soc_mem_unlock(unit, mem);
   7478         return BCM_E_NOT_FOUND;
   7479     }
   7480 
   7481     index_min = soc_mem_index_min(unit, mem);
   7482     index_max = soc_mem_index_max(unit, mem);
   7483     rv = BCM_E_NOT_FOUND;
   7484     sal_memset(&vtempty, 0, sizeof(vtempty));
   7485 
   7486     /* search vt cache for matches */
   7487     nmatch = nwrongadd = 0;
   7488     for (i = index_min; i <= index_max; i++) {
   7489         vtcache = vtcachep[i];
   7490         ve_valid = BCM_VTCACHE_VALID_GET(vtcache);
   7491         if (!ve_valid) {
   7492             continue;
   7493         }
   7494         if (port >= 0) {
   7495             ve_port = BCM_VTCACHE_PORT_GET(vtcache);
   7496             if ((int)ve_port != port) {
   7497                 continue;
   7498             }
   7499         }
   7500         if (old_vid != BCM_VLAN_NONE) {
   7501             ve_vid = BCM_VTCACHE_VID_GET(vtcache);
   7502             if (ve_vid != old_vid) {
   7503                 continue;
   7504             }
   7505         }
   7506         if (addvid >= 0) {
   7507             ve_add = BCM_VTCACHE_ADD_GET(vtcache);
   7508             if ((int)ve_add != addvid) {
   7509                 nwrongadd += 1;
   7510                 continue;
   7511             }
   7512         }
   7513 
   7514         /* matched entry, delete it */
   7515         nmatch += 1;
   7516         rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, i, &vtempty);
   7517         if (rv < 0) {
   7518             break;
   7519         }
   7520         vtcachep[i] = 0;
   7521     }
   7522 
   7523     soc_mem_unlock(unit, mem);
   7524     if (nmatch == 0 && nwrongadd == 1 &&
   7525         port >= 0 && old_vid != BCM_VLAN_NONE) {
   7526         rv = BCM_E_EXISTS;      /* specific delete that only missed addvid */
   7527     }
   7528     return rv;
   7529 }
   7530 
   7531 /*
   7532  * Function:
   7533  *      _bcm_fb_vlan_translate_delete
   7534  * Purpose:
   7535  *      Helper function to bcm_esw_vlan_translate_delete to delete vlan 
   7536  *      translation for Firebolt family
   7537  * Parameters:
   7538  *      unit - StrataSwitch PCI device unit number (driver internal).
   7539  *      port - port numebr can be wildcarded (port = -1)
   7540  *      old_vid - Old VLAN ID to delete translation for can be wildcarded (old_vid = BCM_VLAN_NONE)
   7541  *      xtable  - Memory table
   7542  * Returns:
   7543  *      BCM_E_NONE - Translation found, new_vid nad prio will have the values.
   7544  *      BCM_E_NOT_FOUND - Translation does not exist
   7545  *      BCM_E_XXX  - Other error
   7546  * Notes:
   7547  *      None.
   7548  */
   7549 STATIC int 
   7550 _bcm_fb_vlan_translate_get_cb(int unit, void *trvs_info, int *stop)
   7551 {
   7552 
   7553     _bcm_vlan_translate_data_t      *get_info;
   7554     _bcm_vlan_translate_traverse_t  *trvs_str;
   7555     bcm_vlan_t                      old_vlan, new_vlan;
   7556     bcm_port_t                      port;
   7557     bcm_module_t                    modid;
   7558     bcm_trunk_t                     trunk;
   7559     int                             id;
   7560 
   7561     if ((NULL == trvs_info) || (NULL == stop)){
   7562         return BCM_E_PARAM;
   7563     }
   7564     trvs_str = (_bcm_vlan_translate_traverse_t *)trvs_info;
   7565     if (BCM_VLAN_INVALID != trvs_str->outer_vlan) {
   7566         old_vlan = trvs_str->outer_vlan;
   7567     } else {
   7568         old_vlan = trvs_str->inner_vlan;
   7569     }
   7570 
   7571     if (BCM_VLAN_INVALID != trvs_str->action->new_outer_vlan) {
   7572         new_vlan = trvs_str->action->new_outer_vlan;
   7573     } else {
   7574         new_vlan = trvs_str->action->new_inner_vlan;
   7575     }
   7576 
   7577     get_info = (_bcm_vlan_translate_data_t *)trvs_str->user_data;
   7578 
   7579     BCM_IF_ERROR_RETURN(
   7580         _bcm_esw_gport_resolve(unit, trvs_str->gport, &modid, &port, 
   7581                                &trunk, &id));
   7582 
   7583     if ((port == get_info->port) && (old_vlan == get_info->old_vlan)) {
   7584         *(get_info->new_vlan) = new_vlan;
   7585         *(get_info->prio) = trvs_str->action->priority;
   7586         *stop = TRUE;
   7587     } else {
   7588         *stop = FALSE;
   7589     }
   7590     return (BCM_E_NONE);
   7591 }
   7592 
   7593 /*
   7594  * Function:
   7595  *      _bcm_fb_vlan_translate_delete
   7596  * Purpose:
   7597  *      Helper function to bcm_esw_vlan_translate_delete to delete vlan 
   7598  *      translation for Firebolt family
   7599  * Parameters:
   7600  *      unit - StrataSwitch PCI device unit number (driver internal).
   7601  *      port - port numebr can be wildcarded (port = -1)
   7602  *      old_vid - Old VLAN ID to delete translation for can be wildcarded (old_vid = BCM_VLAN_NONE)
   7603  *      xtable  - Memory table
   7604  * Returns:
   7605  *      BCM_E_NONE - Translation found, new_vid nad prio will have the values.
   7606  *      BCM_E_NOT_FOUND - Translation does not exist
   7607  *      BCM_E_XXX  - Other error
   7608  * Notes:
   7609  *      None.
   7610  */
   7611 int
   7612 _bcm_fb_vlan_translate_get(int unit, int port, bcm_vlan_t old_vid,
   7613                            bcm_vlan_t *new_vid, int *prio, int xtable)
   7614 {
   7615     _bcm_vlan_translate_data_t          get_info;
   7616     _bcm_vlan_translate_traverse_t      trvs_st;
   7617     bcm_vlan_action_set_t               action;
   7618     soc_mem_t                           mem;
   7619     bcm_vlan_t                          new_vlan;
   7620     int                                 priority;
   7621 
   7622     if (!SOC_PORT_ADDRESSABLE(unit, port)) {
   7623         return BCM_E_PORT;
   7624     }
   7625     if (!soc_feature(unit, soc_feature_vlan_translation)) {
   7626         return BCM_E_UNAVAIL;
   7627     }
   7628 
   7629     if ((NULL == new_vid) || (NULL == prio)){
   7630         return BCM_E_PARAM;
   7631     }
   7632     
   7633     sal_memset(&get_info, 0, sizeof(_bcm_vlan_translate_data_t));
   7634     sal_memset(&trvs_st, 0, sizeof(_bcm_vlan_translate_traverse_t));
   7635     sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t));
   7636     
   7637     new_vlan = BCM_VLAN_INVALID;
   7638     priority = -1;
   7639     get_info.old_vlan = old_vid;
   7640     get_info.port = port;
   7641     get_info.new_vlan = &new_vlan;
   7642     get_info.prio = &priority;
   7643 
   7644     trvs_st.user_data = (void *)&get_info;
   7645     trvs_st.action = &action;
   7646     trvs_st.user_cb_st = NULL;
   7647     trvs_st.int_cb = _bcm_fb_vlan_translate_get_cb;
   7648 
   7649     switch (xtable) {
   7650     case BCM_VLAN_XLATE_ING:
   7651         mem = VLAN_XLATEm;
   7652         break;
   7653     case BCM_VLAN_XLATE_EGR:
   7654         mem = EGR_VLAN_XLATEm;
   7655         break;
   7656     case BCM_VLAN_XLATE_DTAG:
   7657         mem = VLAN_XLATEm;
   7658         break;
   7659     default:
   7660         return BCM_E_INTERNAL;
   7661     }
   7662 
   7663     BCM_IF_ERROR_RETURN(
   7664     _bcm_esw_vlan_translate_traverse_mem(unit, mem, &trvs_st));
   7665     if ((BCM_VLAN_INVALID != new_vlan) && (-1 != priority) ){
   7666         *new_vid = new_vlan;
   7667         *prio = priority;
   7668         return BCM_E_NONE;
   7669     }
   7670 
   7671     return BCM_E_NOT_FOUND;
   7672 }
   7673 
   7674 
   7675 /*
   7676  * Function   :
   7677  *      _bcm_fb_vlan_translate_parse
   7678  * Description   :
   7679  *      Helper function for an API to parse a vlan translate 
   7680  *      entry for Firebolt and call given call back.
   7681  * Parameters   :
   7682  *      unit            (IN) BCM unit number
   7683  *      trvs_info       (IN/OUT) Traverse structure that contain all relevant info
   7684  */
   7685 int 
   7686 _bcm_fb_vlan_translate_parse(int unit, soc_mem_t mem, uint32* vent,
   7687                              _bcm_vlan_translate_traverse_t *trvs_info)
   7688 {
   7689     bcm_port_t  port;
   7690     int rv = BCM_E_UNAVAIL;
   7691 
   7692     if (!soc_feature(unit, soc_feature_vlan_translation)) {
   7693         return rv;
   7694     }
   7695 
   7696     port = soc_mem_field32_get(unit, mem , vent, PORTf);
   7697     rv = bcm_esw_port_gport_get(unit, port, &(trvs_info->gport));
   7698     BCM_IF_ERROR_RETURN(rv);
   7699 
   7700     trvs_info->outer_vlan = soc_mem_field32_get(unit, mem, vent, OLD_VLAN_IDf);
   7701     trvs_info->action->new_outer_vlan = soc_mem_field32_get(unit, mem, vent, 
   7702                                                             NEW_VLAN_IDf);
   7703     trvs_info->action->priority = soc_mem_field32_get(unit, mem, vent, PRIf);
   7704     return (rv);
   7705 }
   7706 
   7707 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
   7708  || defined(BCM_RAPTOR_SUPPORT)
   7709 #ifndef BCM_SW_STATE_DUMP_DISABLE
   7710 void _bcm_fb2_vlan_profile_sw_dump(int unit)
   7711 {
   7712     int index;
   7713     int index_max;
   7714     int outer_tpid, flags;
   7715     int ip4_mcast_mode, ip6_mcast_mode, l2_mcast_mode, ref_count;
   7716     int outer_tpid_entry, outer_tpid_ref_count;
   7717 
   7718     LOG_CLI((BSL_META_U(unit,
   7719                         "\nSW Information VLAN Profile - Unit %d\n"), unit));
   7720 
   7721     index_max = soc_mem_index_max(unit, VLAN_PROFILE_TABm);
   7722     for (index = 0; index <= index_max; index++) {
   7723         outer_tpid = VLAN_PROFILE_ENTRY(unit, index).outer_tpid;
   7724         flags = VLAN_PROFILE_ENTRY(unit, index).flags;
   7725         ip6_mcast_mode = VLAN_PROFILE_ENTRY(unit, index).ip6_mcast_flood_mode;
   7726         ip4_mcast_mode = VLAN_PROFILE_ENTRY(unit, index).ip4_mcast_flood_mode;
   7727         l2_mcast_mode = VLAN_PROFILE_ENTRY(unit, index).l2_mcast_flood_mode;
   7728         ref_count = VLAN_PROFILE_REF_COUNT (unit, index);
   7729 
   7730         if (outer_tpid == 0 && flags == 0 &&
   7731             ip6_mcast_mode == 0 && ip4_mcast_mode == 0 &&
   7732             l2_mcast_mode == 0 && ref_count == 0) {
   7733             continue;
   7734         } 
   7735         LOG_CLI((BSL_META_U(unit, " Index = 0x%x, "), index));
   7736         LOG_CLI((BSL_META_U(unit, " TPID = 0x%x, "), outer_tpid));
   7737         LOG_CLI((BSL_META_U(unit, " Flags = 0x%x, "), flags));
   7738         LOG_CLI((BSL_META_U(unit, " IP6 PFM = 0x%x, "), ip6_mcast_mode));
   7739         LOG_CLI((BSL_META_U(unit, " IP4 PFM = 0x%x, "), ip4_mcast_mode));
   7740         LOG_CLI((BSL_META_U(unit, " L2 PFM = 0x%x, "), l2_mcast_mode));
   7741         LOG_CLI((BSL_META_U(unit, " Ref count  = %d\n"), ref_count));
   7742     }
   7743 
   7744     LOG_CLI((BSL_META_U(unit,
   7745                         "\nSW Information outer TPIDs - Unit %d\n"), unit));
   7746 
   7747     for (index = 0; index < BCM_MAX_TPID_ENTRIES; index++) {
   7748         outer_tpid_entry = OUTER_TPID_ENTRY(unit, index);
   7749         outer_tpid_ref_count = OUTER_TPID_REF_COUNT(unit, index);
   7750 
   7751         if (outer_tpid_entry == 0 &&
   7752             outer_tpid_ref_count == 0) {
   7753             continue;
   7754         }
   7755 
   7756         LOG_CLI((BSL_META_U(unit, " Index = 0x%x, "), index));
   7757         LOG_CLI((BSL_META_U(unit, " TPID = 0x%x, "), outer_tpid_entry));
   7758         LOG_CLI((BSL_META_U(unit, " Ref count = %d\n"), outer_tpid_ref_count));
   7759     }
   7760 }
   7761 #endif /* BCM_SW_STATE_DUMP_DISABLE */
   7762 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT \
   7763           || BCM_RAPTOR_SUPPORT */