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

port.c (115689B)


      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 
      8 #include <soc/defs.h>
      9 
     10 #include <assert.h>
     11 
     12 #include <sal/core/libc.h>
     13 #if defined(BCM_TRIDENT_SUPPORT)
     14 
     15 #include <shared/util.h>
     16 #include <soc/mem.h>
     17 #include <soc/cm.h>
     18 #include <soc/drv.h>
     19 #include <soc/register.h>
     20 #include <soc/memory.h>
     21 #include <soc/hash.h>
     22 #include <bcm/port.h>
     23 #include <bcm/error.h>
     24 #include <bcm_int/esw/firebolt.h>
     25 #include <bcm_int/esw/trident.h>
     26 #include <bcm_int/esw/port.h>
     27 #include <bcm_int/esw/trx.h>
     28 #include <bcm_int/esw/xgs3.h>
     29 #include <bcm_int/esw/stack.h>
     30 #include <bcm_int/esw/virtual.h>
     31 #include <bcm_int/esw_dispatch.h>
     32 #if defined(BCM_KATANA2_SUPPORT)
     33 #include <bcm_int/esw/katana2.h>
     34 #endif
     35 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
     36 #include <bcm_int/esw/trident2plus.h>
     37 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
     38 #if defined(BCM_TRIDENT3_SUPPORT)
     39 #include <bcm_int/esw/trident3.h>
     40 #include <bcm_int/esw/flow.h>
     41 #endif /* BCM_TRIDENT3_SUPPORT */
     42 #if defined(BCM_HGPROXY_COE_SUPPORT)
     43 #include <bcm_int/esw/subport.h>
     44 #endif /* BCM_HGPROXY_COE_SUPPORT */
     45 #include <bcm_int/common/lock.h>
     46 
     47 STATIC soc_profile_mem_t *_bcm_td_egr_mask_profile[BCM_MAX_NUM_UNITS];
     48 STATIC soc_profile_mem_t *_bcm_td_sys_cfg_profile[BCM_MAX_NUM_UNITS];
     49 
     50 int
     51 bcm_td_port_reinit(int unit)
     52 {
     53     soc_profile_mem_t *profile;
     54     uint32 entry[SOC_MAX_MEM_WORDS];
     55     uint32 profile_index;
     56     bcm_module_t modid;
     57     bcm_port_t port;
     58     system_config_table_entry_t *sys_cfg_entry;
     59     int tpid_enable, tpid_index;
     60     int is_local;
     61 
     62 #ifdef BCM_TOMAHAWK3_SUPPORT
     63     /* Tomahawk 3 doesn't support stacking, so it's only going
     64      * to have its local ports
     65      */
     66     if (SOC_IS_TOMAHAWK3(unit)) {
     67         profile = _bcm_td_egr_mask_profile[unit];
     68         BCM_IF_ERROR_RETURN
     69             (soc_profile_mem_reference(unit, profile, 0,
     70                                  160));
     71     } else
     72 #endif
     73     {
     74         /* EGR_MASK profile */
     75         if (SOC_MEM_IS_VALID(unit, EGR_MASK_MODBASEm)) {
     76             profile = _bcm_td_egr_mask_profile[unit];
     77             for (modid = 0; modid <= SOC_MODID_MAX(unit); modid++) {
     78                 BCM_IF_ERROR_RETURN
     79                     (soc_mem_read(unit, EGR_MASK_MODBASEm, MEM_BLOCK_ALL, modid,
     80                                   entry));
     81                 profile_index = soc_mem_field32_get(unit, EGR_MASK_MODBASEm, entry,
     82                                                     BASEf);
     83                 SOC_IF_ERROR_RETURN
     84                     (soc_profile_mem_reference(unit, profile, profile_index,
     85                                                SOC_PORT_ADDR_MAX(unit) + 1));
     86             }
     87         }
     88     }
     89 
     90     /* SYSTEM_CONFIG_TABLE profile */
     91     if (SOC_MEM_IS_VALID(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
     92         profile = _bcm_td_sys_cfg_profile[unit];
     93         for (modid = 0; modid <= SOC_MODID_MAX(unit); modid++) {
     94             BCM_IF_ERROR_RETURN
     95                 (soc_mem_read(unit, SYSTEM_CONFIG_TABLE_MODBASEm, MEM_BLOCK_ALL,
     96                               modid, entry));
     97             profile_index = soc_mem_field32_get(unit, SYSTEM_CONFIG_TABLE_MODBASEm,
     98                                                 entry, BASEf);
     99             SOC_IF_ERROR_RETURN
    100                 (soc_profile_mem_reference(unit, profile, profile_index,
    101                                            SOC_PORT_ADDR_MAX(unit) + 1));
    102 
    103             BCM_IF_ERROR_RETURN
    104                 (_bcm_esw_modid_is_local(unit, modid, &is_local));
    105             if (is_local) {
    106                 continue;
    107             }
    108 
    109             /* Increment outer tpid reference count for non-local ports.
    110              * The local ports' outer tpid reference count is taken care
    111              * of by _bcm_fb2_outer_tpid_init.
    112              */
    113             for (port = 0; port <= SOC_PORT_ADDR_MAX(unit); port++) {
    114                 sys_cfg_entry = SOC_PROFILE_MEM_ENTRY(unit, profile,
    115                         system_config_table_entry_t *, profile_index + port);
    116                 tpid_enable = soc_SYSTEM_CONFIG_TABLEm_field32_get(unit,
    117                         sys_cfg_entry, OUTER_TPID_ENABLEf);
    118                 for (tpid_index = 0; tpid_index < 4; tpid_index++) {
    119                     if (tpid_enable & (1 << tpid_index)) {
    120                         BCM_IF_ERROR_RETURN
    121                             (_bcm_fb2_outer_tpid_tab_ref_count_add(unit,
    122                                                              tpid_index, 1));
    123                     }
    124                 }
    125             }
    126         }
    127     }
    128 
    129     return BCM_E_NONE;
    130 }
    131 
    132 union {
    133 #ifdef BCM_TOMAHAWK_SUPPORT
    134     /* Note: This code applies to TH as well so the numbers are 
    135      *       bumped up from 128 to 256
    136      */
    137     egr_mask_entry_t egr_mask[256];
    138     system_config_table_entry_t sys_cfg[256];
    139 #else
    140     egr_mask_entry_t egr_mask[128];
    141     system_config_table_entry_t sys_cfg[128];
    142 #endif
    143     uint32 w[1];
    144 } entry;
    145 
    146 int
    147 bcm_td_port_init(int unit)
    148 {
    149     soc_mem_t mem;
    150     int entry_words;
    151     void *entries[1];
    152     int modid, port, index;
    153     uint32 profile_index;
    154     uint16 tpid;
    155     bcm_pbmp_t bmp;
    156 #if defined(BCM_KATANA2_SUPPORT)
    157     int speed;
    158     soc_pbmp_t my_pbmp_xport_xe;
    159 #endif
    160 
    161     /* Create profile for EGR_MASK table */
    162     if (_bcm_td_egr_mask_profile[unit] == NULL) {
    163         _bcm_td_egr_mask_profile[unit] =
    164             sal_alloc(sizeof(soc_profile_mem_t), "EGR_MASK profile");
    165         if (_bcm_td_egr_mask_profile[unit] == NULL) {
    166             return BCM_E_MEMORY;
    167         }
    168         soc_profile_mem_t_init(_bcm_td_egr_mask_profile[unit]);
    169     }
    170     mem = EGR_MASKm;
    171     entry_words = sizeof(egr_mask_entry_t) / sizeof(uint32);
    172     BCM_IF_ERROR_RETURN
    173         (soc_profile_mem_create(unit, &mem, &entry_words, 1,
    174                                 _bcm_td_egr_mask_profile[unit]));
    175 
    176     /* Create profile for SYSTEM_CONFIG_TABLE table */
    177     if (SOC_MEM_IS_VALID(unit, SYSTEM_CONFIG_TABLEm)) {
    178         if (_bcm_td_sys_cfg_profile[unit] == NULL) {
    179             _bcm_td_sys_cfg_profile[unit] =
    180                 sal_alloc(sizeof(soc_profile_mem_t),
    181                           "SYSTEM_CONFIG_TABLE profile");
    182             if (_bcm_td_sys_cfg_profile[unit] == NULL) {
    183                 return BCM_E_MEMORY;
    184             }
    185             soc_profile_mem_t_init(_bcm_td_sys_cfg_profile[unit]);
    186         }
    187         mem = SYSTEM_CONFIG_TABLEm;
    188         entry_words = sizeof(system_config_table_entry_t) / sizeof(uint32);
    189         BCM_IF_ERROR_RETURN
    190             (soc_profile_mem_create(unit, &mem, &entry_words, 1,
    191                                     _bcm_td_sys_cfg_profile[unit]));
    192     }
    193 
    194 #ifdef BCM_WARM_BOOT_SUPPORT
    195     if (SOC_WARM_BOOT(unit)) {
    196         return bcm_td_port_reinit(unit);
    197     }
    198 #endif /* BCM_WARM_BOOT_SUPPORT */
    199 
    200     entries[0] = &entry;
    201 
    202     /* Add default entries for EGR_MASK profile */
    203     sal_memset(entry.egr_mask, 0, sizeof(entry.egr_mask));
    204 
    205     /* TH3 doesn't support stacking, so egr_mask memory only covers its ports */
    206     if (SOC_IS_TOMAHAWK3(unit)) {
    207         BCM_IF_ERROR_RETURN
    208             (soc_profile_mem_add(unit, _bcm_td_egr_mask_profile[unit], entries,
    209                                  160, &profile_index));
    210     } else {
    211         BCM_IF_ERROR_RETURN
    212             (soc_profile_mem_add(unit, _bcm_td_egr_mask_profile[unit], entries,
    213                                  SOC_PORT_ADDR_MAX(unit) + 1, &profile_index));
    214         for (modid = 1; modid <= SOC_MODID_MAX(unit); modid++) {
    215             SOC_IF_ERROR_RETURN
    216                 (soc_profile_mem_reference(unit, _bcm_td_egr_mask_profile[unit],
    217                                        profile_index,
    218                                        SOC_PORT_ADDR_MAX(unit) + 1));
    219     }
    220 
    221     }
    222     /* EGR_MASK_MODBASE should be 0 for all modid which should match with the
    223      * allocated default profile index */
    224 
    225 #if defined(BCM_TRIDENT3_SUPPORT)
    226     if (SOC_IS_TRIDENT3X(unit)) {
    227         return bcm_td3_port_init(unit);
    228     }
    229 #endif
    230 
    231     if (SOC_MEM_IS_VALID(unit, SYSTEM_CONFIG_TABLEm)) {
    232         /* Add default entries for SYSTEM_CONFIG_TABLE profile */
    233         tpid = _bcm_fb2_outer_tpid_default_get(unit);
    234         BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_lkup(unit, tpid, &index));
    235 
    236         sal_memset(entry.sys_cfg, 0, sizeof(entry.sys_cfg));
    237         for (port = 0; port <= SOC_PORT_ADDR_MAX(unit); port++) {
    238             soc_mem_field32_set(unit, SYSTEM_CONFIG_TABLEm, &entry.sys_cfg[port],
    239                     OUTER_TPID_ENABLEf, 1 << index);
    240 
    241             /* INNER_TPID_ENABLE => {
    242              * MAXBIT => 4, MINBIT => 4,
    243              * DESC => "Indicates if INNER TPID comparison is allowed.
    244              * This is needed for Transparent Bridging."
    245              * } */
    246 
    247             if (soc_feature(unit, soc_feature_inner_tpid_enable)) {
    248                 soc_mem_field32_set(unit, SYSTEM_CONFIG_TABLEm,
    249                         &entry.sys_cfg[port], INNER_TPID_ENABLEf, 1);
    250             }
    251         }
    252     
    253         BCM_IF_ERROR_RETURN
    254             (soc_profile_mem_add(unit, _bcm_td_sys_cfg_profile[unit], entries,
    255                                  SOC_PORT_ADDR_MAX(unit) + 1, &profile_index));
    256         for (modid = 1; modid <= SOC_MODID_MAX(unit); modid++) {
    257             SOC_IF_ERROR_RETURN
    258                 (soc_profile_mem_reference(unit, _bcm_td_sys_cfg_profile[unit],
    259                                            profile_index,
    260                                            SOC_PORT_ADDR_MAX(unit) + 1));
    261         }
    262         /* SYSTEM_CONFIG_TABLE_MODBASE should be 0 for all modid which should
    263          * match with the allocated default profile index */
    264 
    265         /* Update the TPID index reference count for all (module, port) except
    266          * for local (module, port). The TPID index reference count for
    267          * local (module, port) will be updated during port module init,
    268          * when default outer TPID will be set for each local port.
    269          */
    270         BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_tab_ref_count_add(unit, index,
    271                     (SOC_MODID_MAX(unit) + 1 - NUM_MODID(unit)) *
    272                     (SOC_PORT_ADDR_MAX(unit) + 1)));
    273 
    274     }
    275     if (SOC_IS_KATANA(unit) || SOC_IS_TRIUMPH3(unit)) {
    276         SOC_PBMP_CLEAR(bmp);
    277         SOC_PBMP_ASSIGN(bmp, PBMP_ALL(unit));
    278 
    279         PBMP_ITER(bmp, port) {
    280             BCM_IF_ERROR_RETURN
    281                 (soc_mem_field32_modify(unit, PORT_TABm, port, TRUST_DSCP_PTRf,
    282                                         port));
    283             if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, STORM_CONTROL_PTRf)) {
    284                 BCM_IF_ERROR_RETURN
    285                     (soc_mem_field32_modify(unit, PORT_TABm, port,
    286                             STORM_CONTROL_PTRf, port));
    287             }
    288         }
    289     }
    290 
    291 #if defined(BCM_KATANA2_SUPPORT)
    292     if (SOC_IS_KATANA2(unit) && 
    293         SOC_MEM_FIELD_VALID(unit, PORT_TABm, STORM_CONTROL_PTRf)) {
    294         
    295         SOC_PBMP_CLEAR(bmp);
    296         for (port = 0; port<(SOC_INFO(unit).lb_port) + 1; port++) {
    297             SOC_PBMP_PORT_ADD(bmp,port);
    298         }
    299         _bcm_kt2_subport_pbmp_update(unit, &bmp);
    300 
    301         PBMP_ITER(bmp, port) {
    302             BCM_IF_ERROR_RETURN(
    303                 soc_mem_field32_modify(unit, PORT_TABm, port,
    304                                        STORM_CONTROL_PTRf, port));
    305         }
    306         /* programming PORT_TABLE.TRUST_DSCP_PTR is
    307          * handled in _bcm_common_init for KT2*/
    308     }
    309     if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) {
    310         SOC_PBMP_CLEAR(my_pbmp_xport_xe);
    311         my_pbmp_xport_xe = soc_property_get_pbmp_default(unit, spn_PBMP_XPORT_XE,
    312                                                          my_pbmp_xport_xe);
    313         SOC_PBMP_CLEAR(bmp);
    314         SOC_PBMP_ASSIGN(bmp, PBMP_ALL(unit));
    315         PBMP_ITER(bmp, port) {
    316             if (SOC_PBMP_MEMBER(my_pbmp_xport_xe, port)) {
    317                 SOC_IF_ERROR_RETURN(soc_phyctrl_speed_get(unit, port, &speed));
    318                 if (speed == 21000) {
    319                     /* 21G HG ports support IEEE encapsulation to speed upto 20G */
    320                     speed = 20000;
    321                 } else if (speed >= 10000) {
    322                     speed = 10000;
    323                 } else {
    324                     speed = 1000;
    325                 }
    326                 /* Update speed for the new xe port */
    327                 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_set(unit, port, speed));
    328             }
    329         }
    330     }
    331 #endif
    332 
    333 
    334     return BCM_E_NONE;
    335 }
    336 
    337 /*
    338  * Function:
    339  *      bcm_td_port_deinit
    340  * Description:
    341  *      Deallocate resources of port module
    342  * Parameters:
    343  *      unit         - (IN) Device number
    344  * Return Value:
    345  *      BCM_E_XXX
    346  * Note:
    347  */
    348 int
    349 bcm_td_port_deinit(int unit)
    350 {
    351     /* Cleanup profile for EGR_MASK table */
    352     if (_bcm_td_egr_mask_profile[unit] != NULL) {
    353         SOC_IF_ERROR_RETURN(soc_profile_mem_destroy(unit,
    354                                 _bcm_td_egr_mask_profile[unit]));
    355         sal_free(_bcm_td_egr_mask_profile[unit]);
    356         _bcm_td_egr_mask_profile[unit] = NULL;
    357     }
    358 
    359     /* Cleanup profile for SYSTEM_CONFIG_TABLE table */
    360     if (_bcm_td_sys_cfg_profile[unit] != NULL) {
    361         SOC_IF_ERROR_RETURN(soc_profile_mem_destroy(unit,
    362                                 _bcm_td_sys_cfg_profile[unit]));
    363         sal_free(_bcm_td_sys_cfg_profile[unit]);
    364         _bcm_td_sys_cfg_profile[unit] = NULL;
    365     }
    366 
    367     return BCM_E_NONE;
    368 }
    369 
    370 /*
    371  * Function:
    372  *      bcm_td_port_ing_pri_cng_set
    373  * Description:
    374  *      Set packet priority and cfi to internal priority and color mapping
    375  * Parameters:
    376  *      unit         - (IN) Device number
    377  *      port         - (IN) Port number
    378  *      untagged     - (IN) For untagged packet (ignore pkt_pri, cfi argumnet)
    379  *      pkt_pri      - (IN) Packet priority (802.1p cos)
    380  *      cfi          - (IN) Packet CFI
    381  *      int_pri      - (IN) Internal priority
    382  *      color        - (IN) Color
    383  * Return Value:
    384  *      BCM_E_XXX
    385  * Note:
    386  *      When both pkt_pri and cfi are -1, the setting is for untagged packet
    387  */
    388 int
    389 bcm_td_port_ing_pri_cng_set(int unit, bcm_port_t port, int untagged,
    390                             int pkt_pri, int cfi,
    391                             int int_pri, bcm_color_t color)
    392 {
    393     port_tab_entry_t         pent;
    394     ing_pri_cng_map_entry_t  map[16];
    395     ing_untagged_phb_entry_t phb;
    396     void                     *entries[2];
    397     uint32                   profile_index, old_profile_index;
    398     int                      index;
    399     int                      pkt_pri_cur, pkt_pri_min, pkt_pri_max;
    400     int                      cfi_cur, cfi_min, cfi_max;
    401     int                      rv = BCM_E_NONE;
    402 
    403     if (pkt_pri < 0) {
    404         pkt_pri_min = 0;
    405         pkt_pri_max = 7;
    406     } else {
    407         pkt_pri_min = pkt_pri;
    408         pkt_pri_max = pkt_pri;
    409     }
    410 
    411     if (cfi < 0) {
    412         cfi_min = 0;
    413         cfi_max = 1;
    414     } else {
    415         cfi_min = cfi;
    416         cfi_max = cfi;
    417     }
    418     
    419     /* Lock the port table */
    420     soc_mem_lock(unit, PORT_TABm); 
    421 
    422     /* Get profile index from port table. */
    423     rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY,
    424                         SOC_PORT_MOD_OFFSET(unit, port), &pent);
    425     if (BCM_FAILURE(rv)) {
    426         goto cleanup_bcm_td_port_ing_pri_cng_set;
    427     }
    428 
    429     old_profile_index =
    430         soc_mem_field32_get(unit, PORT_TABm, &pent, TRUST_DOT1P_PTRf) * 16;
    431 
    432     entries[0] = map;
    433     entries[1] = &phb;
    434 
    435     rv = _bcm_ing_pri_cng_map_entry_get(unit, old_profile_index, 16, entries);
    436     if (BCM_FAILURE(rv)) {
    437         goto cleanup_bcm_td_port_ing_pri_cng_set;
    438     }
    439 
    440     if (untagged) {
    441         if (int_pri >= 0) {
    442             soc_mem_field32_set(unit, ING_UNTAGGED_PHBm, &phb, PRIf, int_pri);
    443         }
    444         if (color >= 0) {
    445             soc_mem_field32_set(unit, ING_UNTAGGED_PHBm, &phb, CNGf,
    446                                 _BCM_COLOR_ENCODING(unit, color));
    447         }
    448     } else {
    449         for (pkt_pri_cur = pkt_pri_min; pkt_pri_cur <= pkt_pri_max;
    450              pkt_pri_cur++) {
    451             for (cfi_cur = cfi_min; cfi_cur <= cfi_max; cfi_cur++) {
    452                 index = (pkt_pri_cur << 1) | cfi_cur;
    453                 if (int_pri >= 0) {
    454                     soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &map[index],
    455                                         PRIf, int_pri);
    456                 }
    457                 if (color >= 0) {
    458                     soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &map[index],
    459                                         CNGf,
    460                                         _BCM_COLOR_ENCODING(unit, color));
    461                 }
    462             }
    463         }
    464     }
    465 
    466     rv = _bcm_ing_pri_cng_map_entry_add(unit, entries, 16, &profile_index);
    467     if (BCM_FAILURE(rv)) {
    468         goto cleanup_bcm_td_port_ing_pri_cng_set;
    469     }
    470 
    471     if (profile_index != old_profile_index) {
    472         soc_mem_field32_set(unit, PORT_TABm, &pent, TRUST_DOT1P_PTRf,
    473                             profile_index / 16);
    474         rv = soc_mem_write(unit, PORT_TABm, MEM_BLOCK_ALL,
    475                            SOC_PORT_MOD_OFFSET(unit, port), &pent);
    476         if (BCM_FAILURE(rv)) {
    477             goto cleanup_bcm_td_port_ing_pri_cng_set;
    478         }
    479     }
    480 
    481     if (old_profile_index != 0) {
    482         rv = _bcm_ing_pri_cng_map_entry_delete(unit, old_profile_index);
    483         if (BCM_FAILURE(rv)) {
    484             goto cleanup_bcm_td_port_ing_pri_cng_set;
    485         }
    486     }
    487 cleanup_bcm_td_port_ing_pri_cng_set:
    488     /* Release port table lock */
    489     soc_mem_unlock(unit, PORT_TABm);
    490     return rv;
    491 }
    492 
    493 /*
    494  * Function:
    495  *      bcm_td_port_ing_pri_cng_get
    496  * Description:
    497  *      Get packet priority and cfi to internal priority and color mapping
    498  * Parameters:
    499  *      unit         - (IN) Device number
    500  *      port         - (IN) Port number
    501  *      untagged     - (IN) For untagged packet (ignore pkt_pri, cfi argumnet)
    502  *      pkt_pri      - (IN) Packet priority (802.1p cos)
    503  *      cfi          - (IN) Packet CFI
    504  *      int_pri      - (OUT) Internal priority
    505  *      color        - (OUT) Color
    506  * Return Value:
    507  *      BCM_E_XXX
    508  * Note:
    509  *      When both pkt_pri and cfi are -1, the setting is for untagged packet
    510  */
    511 int
    512 bcm_td_port_ing_pri_cng_get(int unit, bcm_port_t port, int untagged,
    513                             int pkt_pri, int cfi,
    514                             int *int_pri, bcm_color_t *color)
    515 {
    516     port_tab_entry_t         pent;
    517     ing_pri_cng_map_entry_t  map[16];
    518     ing_untagged_phb_entry_t phb;
    519     void                     *entries[2];
    520     uint32                   profile_index;
    521     int                      index;
    522     int                      hw_color;
    523 
    524     BCM_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY,
    525                                      SOC_PORT_MOD_OFFSET(unit, port), &pent));
    526 
    527     profile_index =
    528         soc_mem_field32_get(unit, PORT_TABm, &pent, TRUST_DOT1P_PTRf) * 16;
    529 
    530     entries[0] = map;
    531     entries[1] = &phb;
    532 
    533     BCM_IF_ERROR_RETURN
    534         (_bcm_ing_pri_cng_map_entry_get(unit, profile_index, 16, entries));
    535     if (untagged) {
    536         if (int_pri != NULL) {
    537             *int_pri = soc_mem_field32_get(unit, ING_UNTAGGED_PHBm, &phb,
    538                                            PRIf);
    539         }
    540         if (color != NULL) {
    541             hw_color = soc_mem_field32_get(unit, ING_UNTAGGED_PHBm, &phb,
    542                                            CNGf);
    543             *color = _BCM_COLOR_DECODING(unit, hw_color);
    544         }
    545     } else {
    546         index = (pkt_pri << 1) | cfi;
    547         if (int_pri != NULL) {
    548             *int_pri = soc_mem_field32_get(unit, ING_PRI_CNG_MAPm, &map[index],
    549                                            PRIf);
    550         }
    551         if (color != NULL) {
    552             hw_color = soc_mem_field32_get(unit, ING_PRI_CNG_MAPm, &map[index],
    553                                            CNGf);
    554             *color = _BCM_COLOR_DECODING(unit, hw_color);
    555         }
    556     }
    557 
    558     return BCM_E_NONE;
    559 }
    560 
    561 int
    562 bcm_td_port_egress_set(int unit, bcm_port_t port, int modid, bcm_pbmp_t pbmp)
    563 {
    564     soc_profile_mem_t *profile;
    565     egr_mask_modbase_entry_t base_entry;
    566     egr_mask_entry_t *mask_entries;
    567     void *entries[1];
    568     uint32 old_index, index;
    569     bcm_pbmp_t mask_pbmp;
    570     bcm_module_t modid_min, modid_max, cur_modid;
    571     bcm_port_t port_min, port_max, cur_port;
    572     bcm_trunk_t tid;
    573     int id, rv;
    574     bcm_pbmp_t pbmp_all, temp_pbmp_all;
    575     bcm_module_t my_modid;
    576     int modid_is_local;
    577     int egr_mask_modbase_index;
    578     bcm_module_t hw_mod;
    579     bcm_port_t hw_port;
    580     int mod_port_map_done = 0;
    581 
    582     profile = _bcm_td_egr_mask_profile[unit];
    583 
    584     BCM_PBMP_CLEAR(temp_pbmp_all);
    585     BCM_PBMP_ASSIGN(temp_pbmp_all, PBMP_PORT_ALL(unit));
    586 #ifdef BCM_KATANA2_SUPPORT
    587     if (soc_feature(unit, soc_feature_linkphy_coe) ||
    588         soc_feature(unit, soc_feature_subtag_coe)) {
    589         _bcm_kt2_subport_pbmp_update (unit, &temp_pbmp_all);
    590     }
    591     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
    592         BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &temp_pbmp_all));
    593     }
    594 #endif
    595 
    596     BCM_PBMP_NEGATE(mask_pbmp, pbmp);
    597     BCM_PBMP_ASSIGN(pbmp_all,PBMP_CMIC(unit));  /* CPU port */
    598     BCM_PBMP_OR(pbmp_all,temp_pbmp_all);
    599     BCM_PBMP_AND(mask_pbmp, pbmp_all);
    600 
    601     if (BCM_GPORT_IS_SET(port)) {
    602         BCM_IF_ERROR_RETURN
    603             (_bcm_esw_gport_resolve(unit, port, &modid_min, &port_min, &tid,
    604                                     &id));
    605 
    606 #if defined(BCM_HGPROXY_COE_SUPPORT)
    607         if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
    608             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
    609         } else
    610 #endif
    611 
    612 #ifdef BCM_KATANA2_SUPPORT
    613         if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port)) {
    614         } else
    615 #endif
    616         if (-1 != id || -1 != tid) {
    617             return BCM_E_PORT;
    618         }
    619         modid_max = modid_min;
    620         port_max = port_min;
    621         /* For devices with multiple module IDs, _bcm_esw_gport_resolve
    622          * had already performed module and port mapping.
    623          */
    624         mod_port_map_done = 1;
    625     } else {
    626         if (modid < -1 || modid > SOC_MODID_MAX(unit)) {
    627             return BCM_E_PARAM;
    628         } else if (modid == -1) {
    629             modid_min = 0;
    630             modid_max = SOC_MODID_MAX(unit);
    631         } else {
    632             modid_min = modid;
    633             modid_max = modid;
    634         }
    635         if (port < -1 || port > SOC_PORT_ADDR_MAX(unit)) {
    636             return BCM_E_PARAM;
    637         } else if (port == -1) {
    638             port_min = 0;
    639             port_max = SOC_PORT_ADDR_MAX(unit);
    640         } else {
    641             port_min = port;
    642             port_max = port;
    643         }
    644     }
    645 
    646     BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
    647 
    648     mask_entries = sal_alloc(sizeof(egr_mask_entry_t) * 256,
    649                              "port egress mask entries");
    650     if (mask_entries == NULL)
    651     {
    652         return BCM_E_MEMORY;
    653     }
    654     entries[0] = mask_entries;
    655 
    656     if (SOC_MEM_IS_VALID(unit, EGR_MASK_MODBASEm)) {
    657         soc_mem_lock(unit, EGR_MASK_MODBASEm);
    658     }
    659 
    660     rv = BCM_E_NONE;
    661     for (cur_modid = modid_min; cur_modid <= modid_max; cur_modid++) {
    662 
    663         rv = _bcm_esw_modid_is_local(unit, cur_modid, &modid_is_local);
    664         if (BCM_FAILURE(rv)) {
    665             break;
    666         }
    667         if (modid_is_local) {
    668             egr_mask_modbase_index = my_modid;
    669         } else {
    670             egr_mask_modbase_index = cur_modid;
    671         }
    672 
    673         old_index = 0;
    674         if (SOC_MEM_IS_VALID(unit, EGR_MASK_MODBASEm)) {
    675             rv = soc_mem_read(unit, EGR_MASK_MODBASEm, MEM_BLOCK_ALL,
    676                     egr_mask_modbase_index, &base_entry);
    677             if (BCM_FAILURE(rv)) {
    678                 break;
    679             }
    680             old_index = soc_mem_field32_get(unit, EGR_MASK_MODBASEm, &base_entry,
    681                                         BASEf);
    682         }
    683         if (SOC_IS_TOMAHAWK3(unit)) {
    684             rv = soc_profile_mem_get(unit, profile, old_index,
    685                                  160, entries);
    686         } else {
    687             rv = soc_profile_mem_get(unit, profile, old_index,
    688                                  SOC_PORT_ADDR_MAX(unit) + 1, entries);
    689         }
    690         if (BCM_FAILURE(rv)) {
    691             break;
    692         }
    693         for (cur_port = port_min; cur_port <= port_max; cur_port++) {
    694             if (modid_is_local && (NUM_MODID(unit) > 1) && !mod_port_map_done) {
    695                 if (cur_port <= SOC_MODPORT_MAX(unit)) {
    696                     rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET,
    697                             cur_modid, cur_port, &hw_mod, &hw_port);
    698                     if (BCM_FAILURE(rv)) {
    699                         break;
    700                     }
    701                 } else {
    702                     break;
    703                 }
    704             } else {
    705                 hw_port = cur_port;
    706             }
    707 
    708             soc_mem_pbmp_field_set(unit, EGR_MASKm,
    709                     &mask_entries[hw_port], EGRESS_MASKf, &mask_pbmp);
    710         }
    711         if (BCM_FAILURE(rv)) {
    712             break;
    713         }
    714         if (SOC_IS_TOMAHAWK3(unit)) {
    715             rv = soc_profile_mem_delete(unit, profile, old_index);
    716 
    717             rv = soc_profile_mem_add(unit, profile, entries,
    718                                  160, &index);
    719             if (BCM_FAILURE(rv)) {
    720                 break;
    721             }
    722             sal_free(mask_entries);
    723             return rv;
    724         } else {
    725             rv = soc_profile_mem_add(unit, profile, entries,
    726                                  SOC_PORT_ADDR_MAX(unit) + 1, &index);
    727         }
    728 
    729         if (BCM_FAILURE(rv)) {
    730             break;
    731         }
    732         if (SOC_MEM_IS_VALID(unit, EGR_MASK_MODBASEm)) {
    733             rv = soc_mem_field32_modify(unit, EGR_MASK_MODBASEm,
    734                 egr_mask_modbase_index, BASEf, index);
    735             if (BCM_FAILURE(rv)) {
    736                 break;
    737             }
    738         }
    739         rv = soc_profile_mem_delete(unit, profile, old_index);
    740         if (BCM_FAILURE(rv)) {
    741             break;
    742         }
    743     }
    744     if (SOC_MEM_IS_VALID(unit, EGR_MASK_MODBASEm)) {
    745         soc_mem_unlock(unit, EGR_MASK_MODBASEm);
    746     }
    747 
    748     sal_free(mask_entries);
    749     return rv;
    750 }
    751 
    752 int
    753 bcm_td_port_egress_get(int unit, bcm_port_t port, int modid, bcm_pbmp_t *pbmp)
    754 {
    755     soc_profile_mem_t *profile;
    756     egr_mask_modbase_entry_t base_entry;
    757     egr_mask_entry_t *mask_entries;
    758     void *entries[1];
    759     uint32 index;
    760     bcm_pbmp_t mask_pbmp, temp_pbmp_all;
    761     bcm_module_t local_modid;
    762     bcm_port_t local_port;
    763     bcm_trunk_t tid;
    764     int id, rv;
    765 
    766     profile = _bcm_td_egr_mask_profile[unit];
    767 
    768     if (BCM_GPORT_IS_SET(port)) {
    769         BCM_IF_ERROR_RETURN
    770             (_bcm_esw_gport_resolve(unit, port, &local_modid, &local_port,
    771                                     &tid, &id));
    772 
    773 #if defined(BCM_HGPROXY_COE_SUPPORT)
    774         if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
    775             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
    776         } else
    777 #endif
    778 
    779 #ifdef BCM_KATANA2_SUPPORT
    780         if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port)) {
    781         } else
    782 #endif
    783         if (-1 != id || -1 != tid) {
    784             return BCM_E_PORT;
    785         }
    786     } else {
    787         if (modid < 0 || modid > SOC_MODID_MAX(unit) ||
    788             port < 0 || port > SOC_PORT_ADDR_MAX(unit)) {
    789             return BCM_E_PARAM;
    790         } else {
    791             PORT_DUALMODID_VALID(unit, port);
    792             BCM_IF_ERROR_RETURN(_bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET,
    793                         modid, port, &local_modid, &local_port));
    794         }
    795     }
    796 
    797     index = 0;
    798     if (SOC_MEM_IS_VALID(unit, EGR_MASK_MODBASEm)) {
    799         BCM_IF_ERROR_RETURN
    800             (soc_mem_read(unit, EGR_MASK_MODBASEm, MEM_BLOCK_ALL, local_modid,
    801                       &base_entry));
    802         index = soc_mem_field32_get(unit, EGR_MASK_MODBASEm, &base_entry, BASEf);
    803     }
    804     mask_entries = sal_alloc(sizeof(egr_mask_entry_t) * 256,
    805                              "port egress mask entries");
    806     if (mask_entries == NULL)
    807     {
    808         return BCM_E_MEMORY;
    809     }
    810     entries[0] = mask_entries;
    811     if (SOC_IS_TOMAHAWK3(unit)) {
    812         rv = soc_profile_mem_get(unit, profile, index, 160,
    813                              entries);
    814     } else {
    815         rv = soc_profile_mem_get(unit, profile, index, SOC_PORT_ADDR_MAX(unit) + 1,
    816                              entries);
    817     }
    818     if (BCM_FAILURE(rv))
    819     {
    820         sal_free(mask_entries);
    821         return rv;
    822     }
    823     soc_mem_pbmp_field_get(unit, EGR_MASKm, &mask_entries[local_port],
    824                            EGRESS_MASKf, &mask_pbmp);
    825 
    826     BCM_PBMP_CLEAR(temp_pbmp_all);
    827     BCM_PBMP_ASSIGN(temp_pbmp_all, PBMP_ALL(unit));
    828 #ifdef BCM_KATANA2_SUPPORT
    829     if (soc_feature(unit, soc_feature_linkphy_coe) ||
    830         soc_feature(unit, soc_feature_subtag_coe)) {
    831         _bcm_kt2_subport_pbmp_update (unit, &temp_pbmp_all);
    832     }
    833     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
    834         rv = _bcm_kt2_flexio_pbmp_update(unit, &temp_pbmp_all);
    835         if (BCM_FAILURE(rv))
    836         {
    837             sal_free(mask_entries);
    838             return rv;
    839         }
    840     }
    841 #endif
    842 
    843     BCM_PBMP_NEGATE(*pbmp, mask_pbmp);
    844     BCM_PBMP_AND(*pbmp, temp_pbmp_all);
    845     BCM_PBMP_REMOVE(*pbmp, PBMP_LB(unit));
    846     BCM_PBMP_REMOVE(*pbmp, PBMP_RDB_ALL(unit));
    847     BCM_PBMP_REMOVE(*pbmp, PBMP_MACSEC_ALL(unit));
    848     BCM_PBMP_REMOVE(*pbmp, PBMP_FAE_ALL(unit));
    849 
    850     sal_free(mask_entries);
    851     return BCM_E_NONE;
    852 }
    853 
    854 /*
    855  * Function:
    856  *      _bcm_td_mod_port_tpid_enable_write
    857  * Description:
    858  *      Write the Tag Protocol ID enables for a (module, port).
    859  * Parameters:
    860  *      unit - Device number
    861  *      mod  - Module ID
    862  *      port - Port number
    863  *      tpid_enable - Tag Protocol ID enables
    864  * Return Value:
    865  *      BCM_E_XXX
    866  */
    867 int
    868 _bcm_td_mod_port_tpid_enable_write(int unit, bcm_module_t mod,
    869         bcm_port_t port, int tpid_enable)
    870 {
    871     int rv = BCM_E_NONE;
    872     system_config_table_modbase_entry_t modbase_entry;
    873     system_config_table_entry_t *entry_array;
    874     void *entries;
    875     uint32 old_profile_index, new_profile_index;
    876     int i;
    877     bcm_gport_t gport;
    878 
    879     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLEm)) {
    880         SOC_IF_ERROR_RETURN
    881         (READ_SYSTEM_CONFIG_TABLE_MODBASEm(unit, MEM_BLOCK_ANY, mod,
    882                                            &modbase_entry));
    883         old_profile_index = soc_SYSTEM_CONFIG_TABLE_MODBASEm_field32_get(unit,
    884                 &modbase_entry, BASEf);
    885 
    886         entry_array = sal_alloc(sizeof(system_config_table_entry_t) *
    887                 (SOC_PORT_ADDR_MAX(unit) + 1), "system config table entry array");
    888         if (entry_array == NULL) {
    889             return BCM_E_MEMORY;
    890         }
    891 
    892         for (i = 0; i <= SOC_PORT_ADDR_MAX(unit); i++) {
    893            sal_memcpy(&entry_array[i],
    894                    SOC_PROFILE_MEM_ENTRY(unit, _bcm_td_sys_cfg_profile[unit],
    895                        void *, old_profile_index + i),
    896                    sizeof(system_config_table_entry_t));
    897         }
    898 
    899         soc_SYSTEM_CONFIG_TABLEm_field32_set(unit, &entry_array[port],
    900                 OUTER_TPID_ENABLEf, tpid_enable);
    901 
    902         entries = entry_array;
    903         rv = soc_profile_mem_add(unit, _bcm_td_sys_cfg_profile[unit], &entries,
    904                                  SOC_PORT_ADDR_MAX(unit) + 1, &new_profile_index);
    905         if (BCM_FAILURE(rv)) {
    906             sal_free(entry_array);
    907             return rv;
    908         }
    909 
    910         soc_SYSTEM_CONFIG_TABLE_MODBASEm_field32_set(unit, &modbase_entry,
    911                 BASEf, new_profile_index);
    912         rv = WRITE_SYSTEM_CONFIG_TABLE_MODBASEm(unit, MEM_BLOCK_ALL, mod,
    913                                                &modbase_entry);
    914         if (BCM_FAILURE(rv)) {
    915             sal_free(entry_array);
    916             return rv;
    917         }
    918 
    919         rv = soc_profile_mem_delete(unit, _bcm_td_sys_cfg_profile[unit],
    920                                     old_profile_index);
    921         sal_free(entry_array);
    922     } else {
    923         if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, OUTER_TPID_ENABLEf)) {
    924             gport = _bcm_esw_port_gport_get_from_modport(unit, mod,
    925                                                         port);
    926             rv = _bcm_trx_source_trunk_map_set(unit, gport, OUTER_TPID_ENABLEf,
    927                                               tpid_enable);
    928         }
    929     }
    930     return rv;
    931 }
    932 
    933 /*
    934  * Function:
    935  *      _bcm_td_mod_port_tpid_enable_read
    936  * Description:
    937  *      Get the Tag Protocol ID enables for a (module, port).
    938  * Parameters:
    939  *      unit - Device number
    940  *      mod  - Module ID
    941  *      port - Port number
    942  *      tpid_enable - (OUT) Tag Protocol ID enables
    943  * Return Value:
    944  *      BCM_E_XXX
    945  */
    946 int
    947 _bcm_td_mod_port_tpid_enable_read(int unit, bcm_module_t mod, bcm_port_t port,
    948         int *tpid_enable)
    949 {
    950     system_config_table_modbase_entry_t modbase_entry;
    951     system_config_table_entry_t sys_cfg_entry;
    952     int base;
    953     bcm_gport_t gport;
    954 
    955     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLEm)) {
    956         SOC_IF_ERROR_RETURN
    957             (READ_SYSTEM_CONFIG_TABLE_MODBASEm(unit, MEM_BLOCK_ANY, mod,
    958                                                &modbase_entry));
    959         base = soc_SYSTEM_CONFIG_TABLE_MODBASEm_field32_get(unit, &modbase_entry,
    960                 BASEf);
    961 
    962         SOC_IF_ERROR_RETURN
    963             (READ_SYSTEM_CONFIG_TABLEm(unit, MEM_BLOCK_ANY, base + port,
    964                                        &sys_cfg_entry));
    965         *tpid_enable = soc_SYSTEM_CONFIG_TABLEm_field32_get(unit, &sys_cfg_entry,
    966                 OUTER_TPID_ENABLEf);
    967     } else {
    968         gport = _bcm_esw_port_gport_get_from_modport(unit, mod,
    969                                                     port);
    970         BCM_IF_ERROR_RETURN(
    971             _bcm_trx_source_trunk_map_get(unit, gport, OUTER_TPID_ENABLEf,
    972                                            (uint32 *)tpid_enable));
    973     }
    974 
    975     return BCM_E_NONE;
    976 }
    977 
    978 /*
    979  * Function:
    980  *      _bcm_td_mod_port_tpid_set
    981  * Description:
    982  *      Set the Tag Protocol ID for a (module, port).
    983  * Parameters:
    984  *      unit - Device number
    985  *      mod  - Module ID
    986  *      port - Port number
    987  *      tpid - Tag Protocol ID
    988  * Return Value:
    989  *      BCM_E_XXX
    990  */
    991 int
    992 _bcm_td_mod_port_tpid_set(int unit, bcm_module_t mod, bcm_port_t port,
    993         uint16 tpid)
    994 {
    995     int rv = BCM_E_NONE;
    996     int tpid_enable, tpid_index;
    997 
    998     _bcm_fb2_outer_tpid_tab_lock(unit);
    999 
   1000     rv = _bcm_td_mod_port_tpid_enable_read(unit, mod, port, &tpid_enable);
   1001     if (BCM_FAILURE(rv)) {
   1002         _bcm_fb2_outer_tpid_tab_unlock(unit);
   1003         return rv;
   1004     }
   1005 
   1006     tpid_index = 0;
   1007     while (tpid_enable) {
   1008         if (tpid_enable & 1) {
   1009             rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index);
   1010             if (BCM_FAILURE(rv)) {
   1011                 _bcm_fb2_outer_tpid_tab_unlock(unit);
   1012                 return rv;
   1013             }
   1014         }
   1015         tpid_enable = tpid_enable >> 1;
   1016         tpid_index++;
   1017     }
   1018 
   1019     rv = _bcm_fb2_outer_tpid_entry_add(unit, tpid, &tpid_index);
   1020     if (BCM_FAILURE(rv)) {
   1021         _bcm_fb2_outer_tpid_tab_unlock(unit);
   1022         return rv;
   1023     }
   1024 
   1025     tpid_enable = 1 << tpid_index;
   1026     rv = _bcm_td_mod_port_tpid_enable_write(unit, mod, port, tpid_enable);
   1027     if (BCM_FAILURE(rv)) {
   1028         _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index);
   1029     }
   1030 
   1031     _bcm_fb2_outer_tpid_tab_unlock(unit);
   1032     return rv;
   1033 }
   1034 
   1035 /*
   1036  * Function:
   1037  *      _bcm_td_mod_port_tpid_get
   1038  * Description:
   1039  *      Retrieve the Tag Protocol ID for a (module, port).
   1040  * Parameters:
   1041  *      unit - Device number
   1042  *      mod  - Module ID 
   1043  *      port - Port number
   1044  *      tpid - (OUT) Tag Protocol ID
   1045  * Return Value:
   1046  *      BCM_E_XXX
   1047  */
   1048 int
   1049 _bcm_td_mod_port_tpid_get(int unit, bcm_module_t mod, bcm_port_t port,
   1050         uint16 *tpid)
   1051 {
   1052     int tpid_enable, tpid_index;
   1053 
   1054     BCM_IF_ERROR_RETURN
   1055         (_bcm_td_mod_port_tpid_enable_read(unit, mod, port, &tpid_enable));
   1056 
   1057     tpid_index = 0;
   1058     while (tpid_enable) {
   1059         if (tpid_enable & 1) {
   1060             return _bcm_fb2_outer_tpid_entry_get(unit, tpid, tpid_index);
   1061         }
   1062         tpid_enable = tpid_enable >> 1;
   1063         tpid_index++;
   1064     }
   1065 
   1066     return BCM_E_NOT_FOUND;
   1067 }
   1068 
   1069 /*
   1070  * Function:
   1071  *      _bcm_td_mod_port_tpid_add
   1072  * Description:
   1073  *      Add TPID for a (module, port).
   1074  * Parameters:
   1075  *      unit - (IN) Device number
   1076  *      mod  - (IN) Module ID
   1077  *      port - (IN) Port number
   1078  *      tpid - (IN) Tag Protocol ID
   1079  * Return Value:
   1080  *      BCM_E_XXX
   1081  */
   1082 int
   1083 _bcm_td_mod_port_tpid_add(int unit, bcm_module_t mod, bcm_port_t port, 
   1084                       uint16 tpid)
   1085 {
   1086     int rv = BCM_E_NONE;
   1087     int remove_tpid = FALSE;
   1088     int tpid_enable, index;
   1089 
   1090     _bcm_fb2_outer_tpid_tab_lock(unit);
   1091 
   1092     rv = _bcm_td_mod_port_tpid_enable_read(unit, mod, port, &tpid_enable);
   1093     if (BCM_FAILURE(rv)) {
   1094         _bcm_fb2_outer_tpid_tab_unlock(unit);
   1095         return rv;
   1096     }
   1097 
   1098     rv = _bcm_fb2_outer_tpid_lkup(unit, tpid, &index);
   1099     if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
   1100         _bcm_fb2_outer_tpid_tab_unlock(unit);
   1101         return rv;
   1102     }
   1103 
   1104     if (rv == BCM_E_NOT_FOUND || !(tpid_enable & (1 << index))) {
   1105         rv = _bcm_fb2_outer_tpid_entry_add(unit, tpid, &index);
   1106         if (BCM_FAILURE(rv)) {
   1107             _bcm_fb2_outer_tpid_tab_unlock(unit);
   1108             return rv;
   1109         }
   1110         remove_tpid = TRUE;
   1111     }
   1112 
   1113     tpid_enable |= (1 << index);
   1114     rv = _bcm_td_mod_port_tpid_enable_write(unit, mod, port, tpid_enable);
   1115     if (BCM_FAILURE(rv)) {
   1116         if (remove_tpid) {
   1117             _bcm_fb2_outer_tpid_entry_delete(unit, index);
   1118         }
   1119     }
   1120 
   1121     _bcm_fb2_outer_tpid_tab_unlock(unit);
   1122     return rv;
   1123 }
   1124 
   1125 /*
   1126  * Function:
   1127  *      _bcm_td_mod_port_tpid_delete
   1128  * Description:
   1129  *      Delete TPID for a (module, port).
   1130  * Parameters:
   1131  *      unit - (IN) Device number
   1132  *      mod  - (IN) Module ID
   1133  *      port - (IN) Port number
   1134  *      tpid - (IN) Tag Protocol ID
   1135  * Return Value:
   1136  *      BCM_E_XXX
   1137  */
   1138 int
   1139 _bcm_td_mod_port_tpid_delete(int unit, bcm_module_t mod, bcm_port_t port,
   1140         uint16 tpid)
   1141 {
   1142     int rv = BCM_E_NONE;
   1143     int index, tpid_enable;
   1144 
   1145     _bcm_fb2_outer_tpid_tab_lock(unit);
   1146 
   1147     rv = _bcm_fb2_outer_tpid_lkup(unit, tpid, &index);
   1148     if (BCM_FAILURE(rv)) {
   1149         _bcm_fb2_outer_tpid_tab_unlock(unit);
   1150         return rv;
   1151     } 
   1152 
   1153     rv = _bcm_td_mod_port_tpid_enable_read(unit, mod, port, &tpid_enable);
   1154     if (BCM_FAILURE(rv)) {
   1155         _bcm_fb2_outer_tpid_tab_unlock(unit);
   1156         return rv;
   1157     }
   1158 
   1159     if (tpid_enable & (1 << index)) {
   1160         tpid_enable &= ~(1 << index);
   1161         rv = _bcm_td_mod_port_tpid_enable_write(unit, mod, port, tpid_enable);
   1162     } else {
   1163         rv = BCM_E_NOT_FOUND;
   1164     }
   1165     if (BCM_FAILURE(rv)) {
   1166         _bcm_fb2_outer_tpid_tab_unlock(unit);
   1167         return rv;
   1168     }
   1169 
   1170     rv = _bcm_fb2_outer_tpid_entry_delete(unit, index);
   1171     _bcm_fb2_outer_tpid_tab_unlock(unit);
   1172     return rv;
   1173 }
   1174 
   1175 /*
   1176  * Function:
   1177  *      _bcm_td_mod_port_tpid_delete_all
   1178  * Description:
   1179  *      Delete all TPID for a (module, port).
   1180  * Parameters:
   1181  *      unit - (IN) Device number
   1182  *      mod  - (IN) Module ID
   1183  *      port - (IN) Port number
   1184  * Return Value:
   1185  *      BCM_E_XXX
   1186  */
   1187 int 
   1188 _bcm_td_mod_port_tpid_delete_all(int unit, bcm_module_t mod, bcm_port_t port)
   1189 {
   1190     int rv = BCM_E_NONE;
   1191     int tpid_enable, tpid_index;
   1192 
   1193     _bcm_fb2_outer_tpid_tab_lock(unit);
   1194 
   1195     rv = _bcm_td_mod_port_tpid_enable_read(unit, mod, port, &tpid_enable);
   1196     if (BCM_FAILURE(rv)) {
   1197         _bcm_fb2_outer_tpid_tab_unlock(unit);
   1198         return rv;
   1199     }
   1200 
   1201     rv = _bcm_td_mod_port_tpid_enable_write(unit, mod, port, 0);
   1202     if (BCM_FAILURE(rv)) {
   1203         _bcm_fb2_outer_tpid_tab_unlock(unit);
   1204         return rv;
   1205     }
   1206 
   1207     tpid_index = 0;
   1208     while (tpid_enable) {
   1209         if (tpid_enable & 1) {
   1210             rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index);
   1211             if (BCM_FAILURE(rv)) {
   1212                 _bcm_fb2_outer_tpid_tab_unlock(unit);
   1213                 return rv;
   1214             }
   1215         }
   1216         tpid_enable = tpid_enable >> 1;
   1217         tpid_index++;
   1218     }
   1219 
   1220     _bcm_fb2_outer_tpid_tab_unlock(unit);
   1221     return rv;
   1222 }
   1223 
   1224 /*
   1225  * Function:
   1226  *      bcm_td_port_niv_type_set
   1227  * Description:
   1228  *      Set NIV port type.
   1229  * Parameters:
   1230  *      unit - (IN) Device number
   1231  *      port - (IN) Port number
   1232  *      value - (IN) NIV port type 
   1233  * Return Value:
   1234  *      BCM_E_XXX
   1235  */
   1236 int
   1237 bcm_td_port_niv_type_set(int unit, bcm_port_t port, int value)
   1238 {
   1239     int mod_port_index;
   1240     int pt_vt_key_type_value;
   1241 
   1242     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
   1243                 DISCARD_IF_VNTAG_NOT_PRESENTf, 0));
   1244     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
   1245                 DISCARD_IF_VNTAG_PRESENTf, 0));
   1246     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
   1247                 VNTAG_ACTIONS_IF_PRESENTf, VNTAG_NOOP));
   1248     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
   1249                 VNTAG_ACTIONS_IF_NOT_PRESENTf, VNTAG_NOOP));
   1250     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
   1251                 TX_DEST_PORT_ENABLEf, 0));
   1252     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
   1253                 NIV_VIF_LOOKUP_ENABLEf, 0));
   1254     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
   1255                 NIV_RPF_CHECK_ENABLEf, 0));
   1256     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
   1257                 NIV_UPLINK_PORTf, 0));
   1258     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
   1259                 VT_ENABLEf, 0));
   1260     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
   1261                 DISABLE_VLAN_CHECKSf, 0));
   1262     BCM_IF_ERROR_RETURN(_bcm_esw_pt_vtkey_type_value_get(unit,
   1263                 VLXLT_HASH_KEY_TYPE_IVID, &pt_vt_key_type_value));
   1264     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
   1265                 _BCM_CPU_TABS_ETHER, VT_KEY_TYPE_2f,
   1266                 pt_vt_key_type_value));
   1267 
   1268     BCM_IF_ERROR_RETURN(_bcm_esw_egr_port_tab_set(unit, port,
   1269                 VNTAG_ACTIONS_IF_PRESENTf, VNTAG_NOOP));
   1270     BCM_IF_ERROR_RETURN(_bcm_esw_egr_port_tab_set(unit, port,
   1271                 NIV_PRUNE_ENABLEf, 0));
   1272     BCM_IF_ERROR_RETURN(_bcm_esw_egr_port_tab_set(unit, port,
   1273                 NIV_UPLINK_PORTf, 0));
   1274 
   1275     BCM_IF_ERROR_RETURN(
   1276         _bcm_esw_src_mod_port_table_index_get_from_port(unit, port,
   1277                                                         &mod_port_index));
   1278     SOC_IF_ERROR_RETURN(soc_mem_field32_modify(unit, EGR_GPP_ATTRIBUTESm,
   1279                 mod_port_index, SRC_IS_NIV_UPLINK_PORTf, 0));
   1280 
   1281     switch (value) {
   1282         case BCM_PORT_NIV_TYPE_NONE:
   1283             /* Everything is set to defaults above */
   1284             break;
   1285 
   1286         case BCM_PORT_NIV_TYPE_SWITCH:
   1287             BCM_IF_ERROR_RETURN(_bcm_esw_pt_vtkey_type_value_get(unit,
   1288                         VLXLT_HASH_KEY_TYPE_VIF, &pt_vt_key_type_value));
   1289             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
   1290                         _BCM_CPU_TABS_ETHER, VT_KEY_TYPE_2f,
   1291                         pt_vt_key_type_value));
   1292 #if defined(BCM_TRIUMPH3_SUPPORT)
   1293             if (soc_mem_field_valid(unit, PORT_TABm, VT_PORT_TYPE_SELECT_2f) ||
   1294                 soc_mem_field_valid(unit, LPORT_TABm, VT_PORT_TYPE_SELECT_2f)) {
   1295                 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
   1296                     _BCM_CPU_TABS_ETHER, VT_PORT_TYPE_SELECT_2f, 1));
   1297             } else if (soc_mem_field_valid(unit, PORT_TABm, VT_PORT_TYPE_SELECTf)) {
   1298                 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
   1299                     _BCM_CPU_TABS_ETHER, VT_PORT_TYPE_SELECTf, 1));
   1300             } else
   1301 #endif /* BCM_TRIUMPH3_SUPPORT */
   1302             {
   1303                 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
   1304                             _BCM_CPU_TABS_ETHER, VT_KEY_TYPE_USE_GLPf, 1));
   1305             }
   1306             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
   1307                         _BCM_CPU_TABS_ETHER, VT_ENABLEf, 1));
   1308             break;
   1309 
   1310         case BCM_PORT_NIV_TYPE_UPLINK:
   1311             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
   1312                         _BCM_CPU_TABS_ETHER, DISCARD_IF_VNTAG_NOT_PRESENTf, 1));
   1313             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
   1314                         _BCM_CPU_TABS_ETHER, NIV_VIF_LOOKUP_ENABLEf, 1));
   1315             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
   1316                         _BCM_CPU_TABS_ETHER, NIV_UPLINK_PORTf, 1));
   1317             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
   1318                         _BCM_CPU_TABS_ETHER, DISABLE_VLAN_CHECKSf, 1));
   1319             BCM_IF_ERROR_RETURN(_bcm_esw_egr_port_tab_set(unit, port,
   1320                         NIV_UPLINK_PORTf, 1));
   1321             SOC_IF_ERROR_RETURN(soc_mem_field32_modify(unit,
   1322                         EGR_GPP_ATTRIBUTESm, mod_port_index,
   1323                         SRC_IS_NIV_UPLINK_PORTf, 1));
   1324             break;
   1325 
   1326         case BCM_PORT_NIV_TYPE_DOWNLINK_ACCESS:
   1327             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
   1328                         _BCM_CPU_TABS_ETHER, DISCARD_IF_VNTAG_PRESENTf, 1));
   1329             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
   1330                         _BCM_CPU_TABS_ETHER, VNTAG_ACTIONS_IF_NOT_PRESENTf,
   1331                         VNTAG_ADD));
   1332             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
   1333                         _BCM_CPU_TABS_ETHER, TX_DEST_PORT_ENABLEf, 1));
   1334             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
   1335                         _BCM_CPU_TABS_ETHER, DISABLE_VLAN_CHECKSf, 1));
   1336             BCM_IF_ERROR_RETURN(_bcm_esw_egr_port_tab_set(unit, port,
   1337                         VNTAG_ACTIONS_IF_PRESENTf, VNTAG_DELETE));
   1338             BCM_IF_ERROR_RETURN(_bcm_esw_egr_port_tab_set(unit, port,
   1339                         NIV_PRUNE_ENABLEf, 1));
   1340             break;
   1341 
   1342         case BCM_PORT_NIV_TYPE_DOWNLINK_TRANSIT:
   1343             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
   1344                         _BCM_CPU_TABS_ETHER, DISCARD_IF_VNTAG_NOT_PRESENTf, 1));
   1345             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
   1346                         _BCM_CPU_TABS_ETHER, TX_DEST_PORT_ENABLEf, 1));
   1347             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
   1348                         _BCM_CPU_TABS_ETHER, NIV_RPF_CHECK_ENABLEf, 1));
   1349             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
   1350                         _BCM_CPU_TABS_ETHER, DISABLE_VLAN_CHECKSf, 1));
   1351             break;
   1352 
   1353         default:
   1354             return BCM_E_PARAM;
   1355     }
   1356 
   1357     return BCM_E_NONE;
   1358 }
   1359 
   1360 /*
   1361  * Function:
   1362  *      bcm_td_port_niv_type_get
   1363  * Description:
   1364  *      Get NIV port type.
   1365  * Parameters:
   1366  *      unit - (IN) Device number
   1367  *      port - (IN) Port number
   1368  *      value - (OUT) NIV port type 
   1369  * Return Value:
   1370  *      BCM_E_XXX
   1371  */
   1372 int
   1373 bcm_td_port_niv_type_get(int unit, bcm_port_t port, int *value)
   1374 {
   1375     int rv = BCM_E_NONE;
   1376     int vt_key_type, vt_enable, uplink, rpf_enable, prune_enable;
   1377     int vt_key_type_value;
   1378 
   1379     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_get(unit,
   1380                 port, VT_KEY_TYPE_2f, &vt_key_type_value));
   1381     BCM_IF_ERROR_RETURN(_bcm_esw_pt_vtkey_type_get(unit,
   1382                 vt_key_type_value, &vt_key_type));
   1383 
   1384     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_get(unit,
   1385                 port, VT_ENABLEf, &vt_enable));
   1386 
   1387     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_get(unit,
   1388                 port, NIV_UPLINK_PORTf, &uplink));
   1389 
   1390     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_get(unit,
   1391                 port, NIV_RPF_CHECK_ENABLEf, &rpf_enable));
   1392 
   1393     BCM_IF_ERROR_RETURN(_bcm_esw_egr_port_tab_get(unit,
   1394                 port, NIV_PRUNE_ENABLEf, &prune_enable));
   1395 
   1396     if (vt_enable && (vt_key_type == VLXLT_HASH_KEY_TYPE_VIF)) {
   1397         *value = BCM_PORT_NIV_TYPE_SWITCH;
   1398     } else if (uplink) {
   1399         *value = BCM_PORT_NIV_TYPE_UPLINK;
   1400     } else if (rpf_enable) {
   1401         *value = BCM_PORT_NIV_TYPE_DOWNLINK_TRANSIT;
   1402     } else if (prune_enable) {
   1403         *value = BCM_PORT_NIV_TYPE_DOWNLINK_ACCESS;
   1404     } else {
   1405         *value = BCM_PORT_NIV_TYPE_NONE;
   1406     }
   1407 
   1408     return rv;
   1409 }
   1410 
   1411 #ifdef INCLUDE_L3
   1412 /*
   1413  * Function:
   1414  *      _bcm_td_dvp_group_get 
   1415  * Purpose:
   1416  *      Get VP group gport from DVP 
   1417  * Parameters:
   1418  *      unit        - (IN) Device number.
   1419  *      gport       - (IN) Gport number of DVP 
   1420  *      dvp         - (IN) Extracted VP from Gport 
   1421  *      vpg_gport   - (OUT) vp group gport 
   1422  * Returns:
   1423  *      BCM_E_xxx
   1424  * Notes:
   1425  */
   1426 int
   1427 _bcm_td_dvp_group_get(int unit, bcm_gport_t gport, int dvp, bcm_gport_t *vpg_gport)
   1428 {
   1429     int rv = BCM_E_UNAVAIL;
   1430 #if defined(BCM_KATANA2_SUPPORT)
   1431     if (soc_feature(unit, soc_feature_dvp_group_pruning)) {
   1432         int vpg;
   1433         egr_dvp_attribute_entry_t dvp_entry;
   1434 
   1435         SOC_IF_ERROR_RETURN
   1436             (READ_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ANY, dvp, &dvp_entry));
   1437 
   1438         vpg = soc_EGR_DVP_ATTRIBUTEm_field32_get(unit, &dvp_entry,
   1439                 VP_GROUP_PTRf);
   1440 
   1441         if (BCM_GPORT_IS_VLAN_PORT(gport)) {
   1442             BCM_GPORT_VLAN_PORT_ID_SET(*vpg_gport, vpg);
   1443         }else if (BCM_GPORT_IS_NIV_PORT(gport)) {
   1444             BCM_GPORT_NIV_PORT_ID_SET(*vpg_gport, vpg);
   1445         }else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) {
   1446             BCM_GPORT_EXTENDER_PORT_ID_SET(*vpg_gport, vpg);
   1447         }else if (BCM_GPORT_IS_VXLAN_PORT(gport)) {
   1448             BCM_GPORT_VXLAN_PORT_ID_SET(*vpg_gport, vpg);
   1449         }else if (BCM_GPORT_IS_MIM_PORT(gport)) {
   1450             BCM_GPORT_MIM_PORT_ID_SET(*vpg_gport, vpg);
   1451         }else if (BCM_GPORT_IS_MPLS_PORT(gport)) {
   1452             BCM_GPORT_MPLS_PORT_ID_SET(*vpg_gport, vpg);
   1453         }else {
   1454             return BCM_E_PARAM;
   1455         }
   1456         rv = BCM_E_NONE;
   1457     }
   1458 #endif
   1459     return rv;
   1460 }
   1461 
   1462 /*
   1463  * Function:
   1464  *      _bcm_td_dvp_group_set 
   1465  * Purpose:
   1466  *      Set VP group for DVP 
   1467  * Parameters:
   1468  *      unit        - (IN) Device number.
   1469  *      gport       - (IN) Gport number of DVP 
   1470  *      dvp         - (IN) Extracted VP from Gport 
   1471  *      vpg_gport   - (IN) vp group gport 
   1472  * Returns:
   1473  *      BCM_E_xxx
   1474  * Notes:
   1475  */
   1476 int
   1477 _bcm_td_dvp_group_set(int unit, bcm_gport_t gport, int dvp, bcm_gport_t vpg_gport)
   1478 {
   1479     int rv = BCM_E_UNAVAIL;
   1480 #if defined(BCM_KATANA2_SUPPORT)
   1481     if (soc_feature(unit, soc_feature_dvp_group_pruning)) {
   1482         int vpg;
   1483         egr_dvp_attribute_entry_t dvp_entry;
   1484 
   1485         if ((BCM_GPORT_IS_VLAN_PORT(gport) && 
   1486                     !BCM_GPORT_IS_VLAN_PORT(vpg_gport)) ||
   1487                 (BCM_GPORT_IS_NIV_PORT(gport) &&
   1488                  !BCM_GPORT_IS_NIV_PORT(vpg_gport)) ||
   1489                 (BCM_GPORT_IS_EXTENDER_PORT(gport) &&
   1490                  !BCM_GPORT_IS_EXTENDER_PORT(vpg_gport)) ||
   1491                 (BCM_GPORT_IS_VXLAN_PORT(gport) &&
   1492                  !BCM_GPORT_IS_VXLAN_PORT(vpg_gport)) ||
   1493                 (BCM_GPORT_IS_MIM_PORT(gport) &&
   1494                  !BCM_GPORT_IS_MIM_PORT(vpg_gport)) ||
   1495                 (BCM_GPORT_IS_MPLS_PORT(gport) &&
   1496                  !BCM_GPORT_IS_MPLS_PORT(vpg_gport))) {
   1497             return BCM_E_PARAM;
   1498         }
   1499         if (BCM_GPORT_IS_VLAN_PORT(vpg_gport)) {
   1500             vpg = BCM_GPORT_VLAN_PORT_ID_GET(vpg_gport);
   1501             if (!_bcm_vp_used_get(unit, vpg, _bcmVpTypeVlan)) {
   1502                 return BCM_E_NOT_FOUND;
   1503             }
   1504         }else if (BCM_GPORT_IS_NIV_PORT(vpg_gport)) {
   1505             vpg = BCM_GPORT_NIV_PORT_ID_GET(vpg_gport);
   1506             if(!_bcm_vp_used_get(unit, vpg, _bcmVpTypeNiv)) {
   1507                 return BCM_E_NOT_FOUND;
   1508             }
   1509         }else if (BCM_GPORT_IS_EXTENDER_PORT(vpg_gport)) {
   1510             vpg = BCM_GPORT_EXTENDER_PORT_ID_GET(vpg_gport);
   1511             if(!_bcm_vp_used_get(unit, vpg, _bcmVpTypeExtender)) {
   1512                 return BCM_E_NOT_FOUND;
   1513             }
   1514         }else if (BCM_GPORT_IS_VXLAN_PORT(vpg_gport)) {
   1515             vpg = BCM_GPORT_VXLAN_PORT_ID_GET(vpg_gport);
   1516             if (!_bcm_vp_used_get(unit, vpg, _bcmVpTypeVxlan)) {
   1517                 return BCM_E_PARAM;
   1518             }
   1519         }else if (BCM_GPORT_IS_MIM_PORT(vpg_gport)) {
   1520             vpg = BCM_GPORT_MIM_PORT_ID_GET(vpg_gport);
   1521             if (!_bcm_vp_used_get(unit, vpg, _bcmVpTypeMim)) {
   1522                 return BCM_E_PARAM;
   1523             }
   1524         }else if (BCM_GPORT_IS_MPLS_PORT(vpg_gport)) {
   1525             vpg = BCM_GPORT_MPLS_PORT_ID_GET(vpg_gport);
   1526             if (!_bcm_vp_used_get(unit, vpg, _bcmVpTypeMpls)) {
   1527                 return BCM_E_PARAM;
   1528             }
   1529         }else {
   1530             return BCM_E_PARAM;
   1531         }
   1532         SOC_IF_ERROR_RETURN
   1533             (READ_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ANY, dvp, &dvp_entry));
   1534         soc_EGR_DVP_ATTRIBUTEm_field32_set(unit, &dvp_entry,
   1535                 VP_GROUP_PTRf, vpg);
   1536         SOC_IF_ERROR_RETURN
   1537             (WRITE_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ALL, dvp, &dvp_entry));
   1538         rv = BCM_E_NONE;
   1539     }
   1540 #endif 
   1541     return rv;
   1542 }
   1543 
   1544 /*
   1545  * Function:
   1546  *      _bcm_td_port_vif_match_multi_get
   1547  * Purpose:
   1548  *      Get all the matches for an existing vif
   1549  * Parameters:
   1550  *      unit        - (IN)  Device number.
   1551  *      gport       - (IN)  Gport number
   1552  *      size        - (IN)  Number of elements in match array
   1553  *      match_array - (OUT) Match array
   1554  *      count       - (OUT) Match count
   1555  * Returns:
   1556  *      BCM_E_xxx
   1557  * Notes:
   1558  */
   1559 int
   1560 _bcm_td_port_vif_match_multi_get(int unit, bcm_gport_t gport, int size,
   1561                                  bcm_port_match_info_t *match_array,
   1562                                  int *count)
   1563 {
   1564     int                    rv = BCM_E_NONE;
   1565     int                    vp, tmp_vp;
   1566     uint8                  *vt_buf = NULL;
   1567     int                    index, index_min, index_max;
   1568     void                   *vent = NULL;
   1569     int                    action;
   1570     bcm_gport_t            match_gport = 0;
   1571     int                    key_type_value, key_type;
   1572     int                    cnt = 0;
   1573     bcm_module_t           mod_out, mod_in;
   1574     bcm_port_t             port_out, port_in;
   1575     soc_mem_t              vx_mem = VLAN_XLATEm;
   1576 
   1577     if (soc_mem_is_valid(unit, VLAN_XLATE_1_DOUBLEm)) {
   1578         vx_mem = VLAN_XLATE_1_DOUBLEm;
   1579     }
   1580 
   1581     /* Parameter checks */
   1582     if ((size < 0) || (count == NULL)) {
   1583         return BCM_E_PARAM;
   1584     }
   1585 
   1586     if ((size > 0) && (match_array == NULL)) {
   1587         return BCM_E_PARAM;
   1588     }
   1589 
   1590     if (BCM_GPORT_IS_NIV_PORT(gport)) {
   1591         vp = BCM_GPORT_NIV_PORT_ID_GET(gport);
   1592         if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv))) {
   1593             return BCM_E_NOT_FOUND;
   1594         }
   1595     } else {
   1596         return BCM_E_NOT_FOUND;
   1597     }
   1598 
   1599     vt_buf = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, vx_mem),
   1600                            "VLAN_XLATE buffer");
   1601 
   1602     if (NULL == vt_buf) {
   1603         return BCM_E_MEMORY;
   1604     }
   1605 
   1606     index_min = soc_mem_index_min(unit, vx_mem);
   1607     index_max = soc_mem_index_max(unit, vx_mem);
   1608 
   1609     soc_mem_lock(unit, vx_mem);
   1610     if ((rv = soc_mem_read_range(unit, vx_mem, MEM_BLOCK_ANY,
   1611                                  index_min, index_max, vt_buf)) < 0) {
   1612         goto cleanup;
   1613     }
   1614 
   1615     for (index = index_min; index <= index_max; index++) {
   1616         vent = soc_mem_table_idx_to_pointer(unit, vx_mem,
   1617                                             void *,
   1618                                             vt_buf, index);
   1619         if (soc_feature(unit, soc_feature_base_valid)) {
   1620             if (soc_mem_field32_get(unit, vx_mem, vent, BASE_VALID_0f) != 3 ||
   1621                     soc_mem_field32_get(unit, vx_mem, vent, BASE_VALID_1f) != 7) {
   1622                 continue;
   1623             }
   1624         } else {
   1625             if (soc_mem_field32_get(unit, vx_mem, vent, VALIDf) == 0) {
   1626                 continue;
   1627             }
   1628         }
   1629         action = soc_mem_field32_get(unit, vx_mem, vent, VIF__MPLS_ACTIONf);
   1630         if (action != 1) {
   1631             continue; /* Entry is not for an SVP */
   1632         }
   1633         tmp_vp = soc_mem_field32_get(unit, vx_mem, vent, VIF__SOURCE_VPf);
   1634         if (vp != tmp_vp) {
   1635             continue;
   1636         }
   1637 
   1638         if ((size > 0) && (size > cnt)) {
   1639             key_type_value = (int)soc_mem_field32_get(unit, vx_mem, vent,
   1640                                                               KEY_TYPEf);
   1641             rv = _bcm_esw_vlan_xlate_key_type_get(unit, key_type_value,
   1642                                                   &key_type);
   1643             if (BCM_FAILURE(rv)) {
   1644                 goto cleanup;
   1645             }
   1646             sal_memset(match_array, 0, sizeof(bcm_port_match_info_t));
   1647             match_array->match_vlan = BCM_VLAN_INVALID;
   1648             switch (key_type) {
   1649                 case VLXLT_HASH_KEY_TYPE_VIF_VLAN:
   1650                     if (match_array->match_vlan == BCM_VLAN_INVALID) {
   1651                         match_array->match_vlan =
   1652                             soc_mem_field32_get(unit, vx_mem, vent, VIF__VLANf);
   1653                     }
   1654                 case VLXLT_HASH_KEY_TYPE_VIF:
   1655                     if (match_array->match_vlan == BCM_VLAN_INVALID) {
   1656                         match_array->match_vlan = BCM_VLAN_NONE;
   1657                     }
   1658 
   1659                     if (soc_mem_field32_get(unit, vx_mem, vent, VIF__Tf)) {
   1660                         BCM_GPORT_TRUNK_SET(
   1661                             match_gport,
   1662                             soc_mem_field32_get(unit, vx_mem, vent,
   1663                                                         VIF__TGIDf));
   1664                     } else {
   1665                         mod_in = soc_mem_field32_get(unit, vx_mem, vent,
   1666                                                              VIF__MODULE_IDf);
   1667                         port_in = soc_mem_field32_get(unit, vx_mem, vent,
   1668                                                               VIF__PORT_NUMf);
   1669                         rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET,
   1670                                                      mod_in, port_in,
   1671                                                      &mod_out, &port_out);
   1672                         BCM_GPORT_MODPORT_SET(match_gport, mod_out, port_out);
   1673                     }
   1674 
   1675                     if (BCM_GPORT_IS_NIV_PORT(gport)) {
   1676                         if (match_array->match_vlan == BCM_VLAN_NONE) {
   1677                             match_array->match =
   1678                                 BCM_PORT_MATCH_PORT_NIV_PORT_VIF;
   1679                         } else {
   1680                             match_array->match =
   1681                                 BCM_PORT_MATCH_PORT_NIV_PORT_VIF_VLAN;
   1682                         }
   1683                         match_array->niv_port_vif =
   1684                             soc_mem_field32_get(unit, vx_mem, vent,
   1685                                                         VIF__SRC_VIFf);
   1686                     }
   1687 
   1688                     match_array->port = match_gport;
   1689                     match_array++;
   1690                     break;
   1691                 default:
   1692                     rv = BCM_E_PARAM;
   1693                     goto cleanup;
   1694             }
   1695         }
   1696         cnt++;
   1697     }
   1698     *count = cnt;
   1699 cleanup:
   1700     if (vt_buf) {
   1701         soc_cm_sfree(unit, vt_buf);
   1702     }
   1703     soc_mem_unlock(unit, vx_mem);
   1704     return rv;
   1705 }
   1706 
   1707 /*
   1708  * Function:
   1709  *      bcm_td_vp_control_set
   1710  * Purpose:
   1711  *      Set per virtual port controls.
   1712  * Parameters:
   1713  *      unit - (IN) BCM device number
   1714  *      port - (IN) VP gport number
   1715  *      type - (IN) Control type
   1716  *      value - (IN) Value to be set
   1717  * Returns:
   1718  *      BCM_E_XXX
   1719  */
   1720 int
   1721 bcm_td_vp_control_set(int unit, bcm_gport_t gport,
   1722                       bcm_port_control_t type, int value)
   1723 {
   1724     int rv;
   1725     int vp = -1;
   1726 #ifdef BCM_TRIDENT2_SUPPORT
   1727     bcm_niv_egress_t niv_egress;
   1728     int              count;
   1729     bcm_gport_t port = BCM_GPORT_INVALID;
   1730     soc_field_t      field;
   1731     bcm_extender_egress_t extender_egress;
   1732     _bcm_vp_info_t vp_info;
   1733 #endif
   1734     bcm_niv_port_t niv_port;
   1735     bcm_vlan_port_t vlan_port;
   1736     bcm_extender_port_t ext_port;
   1737     source_vp_entry_t svp_entry;
   1738     egr_dvp_attribute_entry_t dvp_entry;
   1739     int cml = 0;
   1740 
   1741     if (BCM_GPORT_IS_VLAN_PORT(gport)) {
   1742         vp = BCM_GPORT_VLAN_PORT_ID_GET(gport);
   1743         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) {
   1744             return BCM_E_NOT_FOUND;
   1745         }
   1746         bcm_vlan_port_t_init(&vlan_port);
   1747         vlan_port.vlan_port_id = gport;
   1748         BCM_IF_ERROR_RETURN(
   1749             bcm_esw_vlan_port_find(unit, &vlan_port));
   1750 #ifdef BCM_TRIDENT2_SUPPORT
   1751         port = vlan_port.port;
   1752 #endif
   1753     } else if (BCM_GPORT_IS_NIV_PORT(gport)) {
   1754         vp = BCM_GPORT_NIV_PORT_ID_GET(gport);
   1755         if(!_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv)) {
   1756             return BCM_E_NOT_FOUND;
   1757         }
   1758         bcm_niv_port_t_init(&niv_port);
   1759         niv_port.niv_port_id = gport;
   1760         BCM_IF_ERROR_RETURN(
   1761             bcm_esw_niv_port_get(unit, &niv_port));
   1762 #ifdef BCM_TRIDENT2_SUPPORT
   1763         if (niv_port.flags & BCM_NIV_PORT_MATCH_NONE) {
   1764             port = BCM_GPORT_INVALID;
   1765             bcm_niv_egress_t_init(&niv_egress);
   1766             rv = bcm_trident_niv_egress_get(unit, niv_port.niv_port_id,
   1767                                             1, &niv_egress, &count);
   1768             if (BCM_SUCCESS(rv)) {
   1769                 if (!(niv_egress.flags & BCM_NIV_EGRESS_MULTICAST)) {
   1770                     port = niv_egress.port;
   1771                 } 
   1772             }
   1773         } else {
   1774             port = niv_port.port;
   1775         }
   1776 #endif
   1777     } else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) {
   1778         vp = BCM_GPORT_EXTENDER_PORT_ID_GET(gport);
   1779         if(!_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender)) {
   1780             return BCM_E_NOT_FOUND;
   1781         }
   1782         bcm_extender_port_t_init(&ext_port);
   1783         ext_port.extender_port_id = gport;
   1784         BCM_IF_ERROR_RETURN(
   1785             bcm_esw_extender_port_get(unit, &ext_port));
   1786 #ifdef BCM_TRIDENT2_SUPPORT
   1787         if (ext_port.flags & BCM_EXTENDER_PORT_MATCH_NONE) {
   1788             bcm_extender_egress_t_init(&extender_egress);
   1789             BCM_IF_ERROR_RETURN(bcm_esw_extender_egress_get_all(unit,
   1790                         ext_port.extender_port_id, 1, &extender_egress, &count));
   1791             if (count == 0) {
   1792                 /* No Extender egress object has been added to VP yet. */
   1793                 return BCM_E_CONFIG;
   1794             }
   1795             if (extender_egress.flags & BCM_EXTENDER_EGRESS_MULTICAST) {
   1796                 return BCM_E_PARAM;
   1797             }
   1798             port = extender_egress.port;
   1799         } else {
   1800             port = ext_port.port;
   1801         }
   1802 #endif
   1803     } else if (BCM_GPORT_IS_TRUNK(gport)) {
   1804         BCM_IF_ERROR_RETURN(
   1805             _bcm_esw_trunk_tid_to_vp_lag_vp(unit, 
   1806                             BCM_GPORT_TRUNK_GET(gport), &vp));
   1807 #ifdef BCM_TRIDENT2_SUPPORT
   1808         port = BCM_GPORT_INVALID;
   1809 #endif        
   1810 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
   1811 	} else if (BCM_GPORT_IS_MPLS_PORT(gport)) {
   1812         vp = BCM_GPORT_MPLS_PORT_ID_GET(gport);
   1813         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
   1814             return BCM_E_PARAM;
   1815         }
   1816 #endif
   1817 #ifdef BCM_TRIDENT2_SUPPORT
   1818         port = BCM_GPORT_INVALID;
   1819     } else if (BCM_GPORT_IS_VXLAN_PORT(gport)) {
   1820         vp = BCM_GPORT_VXLAN_PORT_ID_GET(gport);
   1821         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) {
   1822             return BCM_E_PARAM;
   1823         }
   1824         port = BCM_GPORT_INVALID;
   1825     } else if (BCM_GPORT_IS_MIM_PORT(gport)) {
   1826         vp = BCM_GPORT_MIM_PORT_ID_GET(gport);
   1827         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
   1828             return BCM_E_PARAM;
   1829         }
   1830         port = BCM_GPORT_INVALID;
   1831     } else if (BCM_GPORT_IS_L2GRE_PORT(gport)) {
   1832         vp = BCM_GPORT_L2GRE_PORT_ID_GET(gport);
   1833         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre)) {
   1834             return BCM_E_PARAM;
   1835         }
   1836         port = BCM_GPORT_INVALID;
   1837 #ifdef BCM_TRIDENT3_SUPPORT
   1838     } else if (BCM_GPORT_IS_FLOW_PORT(gport)) {
   1839         vp = BCM_GPORT_FLOW_PORT_ID_GET(gport);
   1840         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeFlow)) {
   1841             return BCM_E_PARAM;
   1842         }
   1843         port = BCM_GPORT_INVALID;
   1844 #endif
   1845 #endif
   1846 #ifdef BCM_HGPROXY_COE_SUPPORT
   1847     } else if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   1848         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) {
   1849 #endif
   1850     } else { 
   1851         return BCM_E_PARAM;
   1852     }
   1853 
   1854     rv = BCM_E_UNAVAIL;
   1855 
   1856     switch (type) {
   1857         case bcmPortControlBridge:
   1858             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, DISABLE_VP_PRUNINGf)) {
   1859                 SOC_IF_ERROR_RETURN
   1860                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   1861                 soc_SOURCE_VPm_field32_set(unit, &svp_entry,
   1862                         DISABLE_VP_PRUNINGf, value ? 1 : 0);
   1863                 SOC_IF_ERROR_RETURN
   1864                     (WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry));
   1865                 rv = BCM_E_NONE;
   1866             }
   1867             if (SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm,
   1868                         DISABLE_VP_PRUNINGf)) {
   1869                 SOC_IF_ERROR_RETURN
   1870                     (READ_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ANY, vp, &dvp_entry));
   1871                 soc_EGR_DVP_ATTRIBUTEm_field32_set(unit, &dvp_entry,
   1872                         DISABLE_VP_PRUNINGf, value ? 1 : 0);
   1873                 SOC_IF_ERROR_RETURN
   1874                     (WRITE_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ALL, vp, &dvp_entry));
   1875                 rv = BCM_E_NONE;
   1876             } 
   1877             break;
   1878 
   1879         case bcmPortControlIP4:
   1880 #ifdef BCM_TRIDENT2_SUPPORT
   1881             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, IPV4L3_ENABLEf)) {
   1882                 SOC_IF_ERROR_RETURN
   1883                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   1884                 soc_SOURCE_VPm_field32_set(unit, &svp_entry,
   1885                         IPV4L3_ENABLEf, value ? 1 : 0);
   1886                 SOC_IF_ERROR_RETURN
   1887                     (WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry));
   1888                 rv = BCM_E_NONE;
   1889             }
   1890 #endif /* BCM_TRIDENT2_SUPPORT */
   1891             break;
   1892 
   1893         case bcmPortControlIP6:
   1894 #ifdef BCM_TRIDENT2_SUPPORT
   1895             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, IPV6L3_ENABLEf)) {
   1896                 SOC_IF_ERROR_RETURN
   1897                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   1898                 soc_SOURCE_VPm_field32_set(unit, &svp_entry,
   1899                         IPV6L3_ENABLEf, value ? 1 : 0);
   1900                 SOC_IF_ERROR_RETURN
   1901                     (WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry));
   1902                 rv = BCM_E_NONE;
   1903             }
   1904 #endif /* BCM_TRIDENT2_SUPPORT */
   1905             break;
   1906 
   1907         case bcmPortControlIP4Mcast:
   1908 #ifdef BCM_TRIDENT2_SUPPORT
   1909             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, IPMCV4_ENABLEf)) {
   1910                 SOC_IF_ERROR_RETURN
   1911                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   1912                 soc_SOURCE_VPm_field32_set(unit, &svp_entry,
   1913                         IPMCV4_ENABLEf, value ? 1 : 0);
   1914                 SOC_IF_ERROR_RETURN
   1915                     (WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry));
   1916                 rv = BCM_E_NONE;
   1917             }
   1918 #endif /* BCM_TRIDENT2_SUPPORT */
   1919             break;
   1920 
   1921         case bcmPortControlIP6Mcast:
   1922 #ifdef BCM_TRIDENT2_SUPPORT
   1923             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, IPMCV6_ENABLEf)) {
   1924                 SOC_IF_ERROR_RETURN
   1925                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   1926                 soc_SOURCE_VPm_field32_set(unit, &svp_entry,
   1927                         IPMCV6_ENABLEf, value ? 1 : 0);
   1928                 SOC_IF_ERROR_RETURN
   1929                     (WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry));
   1930                 rv = BCM_E_NONE;
   1931             }
   1932 #endif /* BCM_TRIDENT2_SUPPORT */
   1933             break;
   1934 
   1935         case bcmPortControlIP4McastL2:
   1936 #ifdef BCM_TRIDENT2_SUPPORT
   1937             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, IPMCV4_L2_ENABLEf)) {
   1938                 SOC_IF_ERROR_RETURN
   1939                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   1940                 soc_SOURCE_VPm_field32_set(unit, &svp_entry,
   1941                         IPMCV4_L2_ENABLEf, value ? 1 : 0);
   1942                 SOC_IF_ERROR_RETURN
   1943                     (WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry));
   1944                 rv = BCM_E_NONE;
   1945             }
   1946 #endif /* BCM_TRIDENT2_SUPPORT */
   1947             break;
   1948 
   1949         case bcmPortControlIP6McastL2:
   1950 #ifdef BCM_TRIDENT2_SUPPORT
   1951             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, IPMCV6_L2_ENABLEf)) {
   1952                 SOC_IF_ERROR_RETURN
   1953                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   1954                 soc_SOURCE_VPm_field32_set(unit, &svp_entry,
   1955                         IPMCV6_L2_ENABLEf, value ? 1 : 0);
   1956                 SOC_IF_ERROR_RETURN
   1957                     (WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry));
   1958                 rv = BCM_E_NONE;
   1959             }
   1960 #endif /* BCM_TRIDENT2_SUPPORT */
   1961             break;
   1962 
   1963         case bcmPortControlL3Ingress:
   1964 #ifdef BCM_TRIDENT2_SUPPORT
   1965             BCM_IF_ERROR_RETURN(
   1966                 _bcm_esw_port_gport_validate(unit, port, &port));
   1967             if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, L3_IIFf)) {
   1968                 if ((value >= 1) && (value < soc_mem_index_count(unit, L3_IIFm))) {
   1969                     rv = _bcm_trx_source_trunk_map_set(unit, port, L3_IIFf, value);
   1970                     BCM_IF_ERROR_RETURN(rv);
   1971                     if (soc_mem_field_valid(unit, PORT_TABm, PORT_OPERATIONf)) {
   1972                         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
   1973                                 PORT_OPERATIONf, 0x2);
   1974                     }
   1975                 } else {
   1976                     if (soc_mem_field_valid(unit, PORT_TABm, PORT_OPERATIONf)) {
   1977                         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
   1978                                 PORT_OPERATIONf, 0x0);
   1979                     }
   1980                 }
   1981             } 
   1982 #endif /* BCM_TRIDENT2_SUPPORT */
   1983             break;
   1984 
   1985 #ifdef BCM_TRIDENT2_SUPPORT
   1986         case bcmPortControlFcoeRouteEnable:
   1987             if (soc_feature(unit, soc_feature_fcoe)) {
   1988                 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, FCOE_ROUTE_ENABLEf)) {
   1989                     SOC_IF_ERROR_RETURN(
   1990                         READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   1991                     soc_SOURCE_VPm_field32_set(unit, &svp_entry,
   1992                                                FCOE_ROUTE_ENABLEf, 
   1993                                                (value) ? 1 : 0);
   1994                     SOC_IF_ERROR_RETURN(
   1995                         WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry));
   1996                     rv = BCM_E_NONE;
   1997                 }     
   1998                 if (SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm, 
   1999                                         FCOE_ROUTE_ENABLEf)) {
   2000                     SOC_IF_ERROR_RETURN(
   2001                         READ_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ANY, vp, 
   2002                                                 &dvp_entry));
   2003                     soc_EGR_DVP_ATTRIBUTEm_field32_set(unit, &dvp_entry,
   2004                                                        FCOE_ROUTE_ENABLEf, 
   2005                                                        (value) ? 1 : 0);
   2006                     SOC_IF_ERROR_RETURN(
   2007                         WRITE_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ALL, vp, 
   2008                                                  &dvp_entry));
   2009                     rv = BCM_E_NONE;
   2010                 }
   2011             }
   2012             break;
   2013 
   2014         case bcmPortControlFcoeVftEnable:
   2015             if (soc_feature(unit, soc_feature_fcoe)) {
   2016                 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, FCOE_VFT_ENABLEf)) {
   2017                     SOC_IF_ERROR_RETURN(
   2018                         READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2019                     soc_SOURCE_VPm_field32_set(unit, &svp_entry,
   2020                                                FCOE_VFT_ENABLEf, 
   2021                                                (value) ? 1 : 0);
   2022                     SOC_IF_ERROR_RETURN(
   2023                         WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry));
   2024                     rv = BCM_E_NONE;
   2025                 }     
   2026             }
   2027             break;
   2028 
   2029         case bcmPortControlFcoeZoneCheckEnable:
   2030             if (soc_feature(unit, soc_feature_fcoe)) {
   2031                 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, 
   2032                                         FCOE_ZONE_CHECK_ENABLEf)) {
   2033                     SOC_IF_ERROR_RETURN(
   2034                         READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2035                     soc_SOURCE_VPm_field32_set(unit, &svp_entry,
   2036                                                FCOE_ZONE_CHECK_ENABLEf, 
   2037                                                (value) ? 1 : 0);
   2038                     SOC_IF_ERROR_RETURN(
   2039                         WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry));
   2040                     rv = BCM_E_NONE;
   2041                 }     
   2042             }
   2043             break;
   2044 
   2045         case bcmPortControlFcoeSourceBindCheckEnable:
   2046             if (soc_feature(unit, soc_feature_fcoe)) {
   2047                 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, 
   2048                                         FCOE_SRC_BIND_CHECK_ENABLEf)) {
   2049                     SOC_IF_ERROR_RETURN(
   2050                         READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2051                     soc_SOURCE_VPm_field32_set(unit, &svp_entry,
   2052                                                FCOE_SRC_BIND_CHECK_ENABLEf, 
   2053                                                (value) ? 1 : 0);
   2054                     SOC_IF_ERROR_RETURN(
   2055                         WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry));
   2056                     rv = BCM_E_NONE;
   2057                 }     
   2058             }
   2059             break;
   2060 
   2061         case bcmPortControlFcoeFpmaPrefixCheckEnable:
   2062             if (soc_feature(unit, soc_feature_fcoe)) {
   2063                 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm,
   2064                                         FCOE_SRC_FPMA_PREFIX_CHECK_ENABLEf)) {
   2065                     SOC_IF_ERROR_RETURN(
   2066                         READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2067                     soc_SOURCE_VPm_field32_set(unit, &svp_entry,
   2068                                             FCOE_SRC_FPMA_PREFIX_CHECK_ENABLEf, 
   2069                                             (value) ? 1 : 0);
   2070                     SOC_IF_ERROR_RETURN(
   2071                         WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry));
   2072                     rv = BCM_E_NONE;
   2073                 }     
   2074             }
   2075             break;
   2076 
   2077         case bcmPortControlFcoeDoNotLearn:
   2078             if (soc_feature(unit, soc_feature_fcoe)) {
   2079                 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, FCOE_DO_NOT_LEARNf)) {
   2080                     SOC_IF_ERROR_RETURN(
   2081                         READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2082                     soc_SOURCE_VPm_field32_set(unit, &svp_entry,
   2083                                                FCOE_DO_NOT_LEARNf, 
   2084                                                (value) ? 1 : 0);
   2085                     SOC_IF_ERROR_RETURN(
   2086                         WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry));
   2087                     rv = BCM_E_NONE;
   2088                 }     
   2089             }
   2090             break;
   2091 
   2092         case bcmPortControlFcoeNetworkPort:
   2093             if (soc_feature(unit, soc_feature_fcoe)) {
   2094                 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, FCOE_NETWORK_PORTf)) {
   2095                     SOC_IF_ERROR_RETURN(
   2096                         READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2097                     soc_SOURCE_VPm_field32_set(unit, &svp_entry,
   2098                                                FCOE_NETWORK_PORTf, 
   2099                                                (value) ? 1 : 0);
   2100                     SOC_IF_ERROR_RETURN(
   2101                         WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry));
   2102                     rv = BCM_E_NONE;
   2103                 }     
   2104             }
   2105             break;
   2106 
   2107 #endif /* BCM_TRIDENT2_SUPPORT */
   2108 
   2109         case bcmPortControlMcastGroupRemap:
   2110             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, NETWORK_PORTf)) {
   2111                 rv = soc_mem_field32_modify(unit, SOURCE_VPm, vp,
   2112                         NETWORK_PORTf, value ? 1 : 0);
   2113             }
   2114             break;
   2115 
   2116         case bcmPortControlVlanVpGroupIngress:
   2117             if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership)) {
   2118                 int field_width;
   2119                 int index = vp;
   2120                 soc_mem_t mem = SOURCE_VPm;
   2121                 soc_field_t field = VLAN_MEMBERSHIP_PROFILEf;
   2122 #ifdef BCM_HGPROXY_COE_SUPPORT
   2123                 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   2124                     _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) {
   2125                     int portid = -1;
   2126                     int modid = -1;
   2127                     int trunk = -1;
   2128                     int id = -1;
   2129                     mem = SOURCE_TRUNK_MAP_TABLEm;
   2130 
   2131                     BCM_IF_ERROR_RETURN(
   2132                         _bcm_esw_gport_resolve(unit, gport, &modid, &portid,
   2133                                                &trunk, &id));
   2134                     BCM_IF_ERROR_RETURN(
   2135                         _bcm_esw_src_mod_port_table_index_get(
   2136                             unit, modid, portid, &index));
   2137                 }
   2138 #endif
   2139                 field_width = soc_mem_field_length(unit, mem, field);
   2140                 if ((value >= (1 << field_width)) ||
   2141                     (value < 0)) {
   2142                     return BCM_E_PARAM;
   2143                 }
   2144 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   2145                 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
   2146                     rv = bcm_td2p_ing_vp_group_unmanaged_set(unit,TRUE);
   2147                 } else
   2148 #endif
   2149                 {
   2150                     rv = bcm_td_ing_vp_group_unmanaged_set(unit,TRUE);
   2151                 }
   2152                 if (rv == BCM_E_NONE) {
   2153                     SOC_IF_ERROR_RETURN(
   2154                         soc_mem_field32_modify(unit, mem, index,
   2155                                                field, value));
   2156                 }
   2157             }
   2158             break;
   2159 
   2160         case bcmPortControlVlanVpGroupEgress:
   2161             if (soc_feature(unit,soc_feature_vp_group_egress_vlan_membership)) {
   2162                 int field_width;
   2163                 int index = vp;
   2164                 soc_mem_t mem = EGR_DVP_ATTRIBUTEm;
   2165                 soc_field_t field;
   2166 #if defined(BCM_KATANA2_SUPPORT)
   2167                 if(SOC_IS_SABER2(unit)) {
   2168                     field = VLAN_MEMBERSHIP_PROFILEf;
   2169                 } else 
   2170 #endif
   2171                 {
   2172                     field = COMMON__VLAN_MEMBERSHIP_PROFILEf;
   2173                 }
   2174 #ifdef BCM_HGPROXY_COE_SUPPORT
   2175                 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   2176                     _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) {
   2177                     int portid = -1;
   2178                     int modid = -1;
   2179                     int trunk = -1;
   2180                     int id = -1;
   2181                     mem = EGR_GPP_ATTRIBUTESm;
   2182                     field = VLAN_MEMBERSHIP_PROFILEf;
   2183 
   2184                     BCM_IF_ERROR_RETURN(
   2185                         _bcm_esw_gport_resolve(unit, gport, &modid, &portid,
   2186                                                &trunk, &id));
   2187                     BCM_IF_ERROR_RETURN(
   2188                         _bcm_esw_src_mod_port_table_index_get(
   2189                             unit, modid, portid, &index));
   2190                 }
   2191 #endif
   2192                 field_width = soc_mem_field_length(unit, mem, field);
   2193                 if ((value >= (1 << field_width)) ||
   2194                     (value < 0)) {
   2195                     return BCM_E_PARAM;
   2196                 }
   2197 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   2198                 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
   2199                     rv = bcm_td2p_egr_vp_group_unmanaged_set(unit,TRUE);
   2200                 } else
   2201 #endif
   2202                 {
   2203                     rv = bcm_td_egr_vp_group_unmanaged_set(unit,TRUE);
   2204                 }
   2205 
   2206                 if (rv == BCM_E_NONE) {
   2207                     if (mem == EGR_DVP_ATTRIBUTEm) {
   2208                         SOC_IF_ERROR_RETURN(
   2209                             READ_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ANY,
   2210                                                     index, &dvp_entry));
   2211                         BCM_IF_ERROR_RETURN(
   2212                             _td_egr_dvp_attribute_field_name_get(
   2213                                 unit, &dvp_entry,
   2214                                 VLAN_MEMBERSHIP_PROFILEf, &field));
   2215                         soc_EGR_DVP_ATTRIBUTEm_field32_set(
   2216                             unit, &dvp_entry, field, value);
   2217                         SOC_IF_ERROR_RETURN(
   2218                             WRITE_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ALL,
   2219                                                      index, &dvp_entry));
   2220                     } else {
   2221                         SOC_IF_ERROR_RETURN(
   2222                             soc_mem_field32_modify(unit, mem, index,
   2223                                                    field, value));
   2224                     }
   2225                 }
   2226             }
   2227             break;
   2228 
   2229         case bcmPortControlL2Learn:
   2230             if (!(value & BCM_PORT_LEARN_FWD)) {
   2231                cml |= (1 << 0);
   2232             }
   2233             if (value & BCM_PORT_LEARN_CPU) {
   2234                cml |= (1 << 1);
   2235             }
   2236             if (value & BCM_PORT_LEARN_PENDING) {
   2237                cml |= (1 << 2);
   2238             }
   2239             if (value & BCM_PORT_LEARN_ARL) {
   2240                cml |= (1 << 3);
   2241             }
   2242 
   2243             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, CML_FLAGS_NEWf)) {
   2244                 SOC_IF_ERROR_RETURN(
   2245                     READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2246                 soc_SOURCE_VPm_field32_set(unit, &svp_entry,
   2247                     CML_FLAGS_NEWf, cml);
   2248                 SOC_IF_ERROR_RETURN(
   2249                     WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry));
   2250                 rv = BCM_E_NONE;
   2251             }
   2252             break;
   2253 
   2254         case bcmPortControlL2Move:
   2255             if (!(value & BCM_PORT_LEARN_FWD)) {
   2256                cml |= (1 << 0);
   2257             }
   2258             if (value & BCM_PORT_LEARN_CPU) {
   2259                cml |= (1 << 1);
   2260             }
   2261             if (value & BCM_PORT_LEARN_PENDING) {
   2262                cml |= (1 << 2);
   2263             }
   2264             if (value & BCM_PORT_LEARN_ARL) {
   2265                cml |= (1 << 3);
   2266             }
   2267 
   2268             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, CML_FLAGS_MOVEf)) {
   2269                 SOC_IF_ERROR_RETURN(
   2270                     READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2271                 soc_SOURCE_VPm_field32_set(unit, &svp_entry,
   2272                     CML_FLAGS_MOVEf, cml);
   2273                 SOC_IF_ERROR_RETURN(
   2274                     WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry));
   2275                 rv = BCM_E_NONE;
   2276             }
   2277             break;
   2278 
   2279         case bcmPortControlDoNotCheckVlan:
   2280 #ifdef BCM_TRIDENT2_SUPPORT
   2281             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, DISABLE_VLAN_CHECKSf)) {
   2282                 SOC_IF_ERROR_RETURN(soc_mem_field32_modify(unit, SOURCE_VPm, vp,
   2283                        DISABLE_VLAN_CHECKSf, value ? 1 : 0));
   2284                 rv = BCM_E_NONE;
   2285             }
   2286 #endif /* BCM_TRIDENT2_SUPPORT */
   2287             break;
   2288         case bcmPortControlDoNotCheckVlanEgress:
   2289 #if defined(BCM_TRIDENT2_SUPPORT)
   2290             BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
   2291 
   2292             field = COMMON__DISABLE_VLAN_CHECKf;
   2293             if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) {
   2294                 if (BCM_GPORT_IS_TRILL_PORT(gport)) {
   2295                     field = TRILL__DISABLE_VLAN_CHECKf;
   2296                 } else if (BCM_GPORT_IS_VXLAN_PORT(gport)) {
   2297                     field = VXLAN__DISABLE_VLAN_CHECKf;
   2298                 } else if (BCM_GPORT_IS_L2GRE_PORT(gport)) {
   2299                     field = L2GRE__DISABLE_VLAN_CHECKf;
   2300 #if defined(BCM_TRIDENT3_SUPPORT)
   2301                 } else if (BCM_GPORT_IS_FLOW_PORT(gport)) {
   2302                     uint32 data_type;
   2303 
   2304                     SOC_IF_ERROR_RETURN(READ_EGR_DVP_ATTRIBUTEm(unit,
   2305                           MEM_BLOCK_ANY, vp, &dvp_entry));
   2306                     data_type = soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTEm,
   2307                                  &dvp_entry, DATA_TYPEf);
   2308                     if (data_type == _BCM_FLOW_VXLAN_EGRESS_DEST_VP_TYPE) {
   2309                         field = VXLAN__DISABLE_VLAN_CHECKf;
   2310                     } else if (data_type ==
   2311                                    _BCM_FLOW_L2GRE_EGRESS_DEST_VP_TYPE) {
   2312                         field = L2GRE__DISABLE_VLAN_CHECKf;
   2313                     } else if (data_type >
   2314                                 _BCM_FLOW_L2GRE_EGRESS_DEST_VP_TYPE) {
   2315                         return BCM_E_UNAVAIL;
   2316                     }
   2317 #endif
   2318                 }
   2319             }
   2320             if (SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm, field)) {
   2321                 SOC_IF_ERROR_RETURN(soc_mem_field32_modify(unit,
   2322                                     EGR_DVP_ATTRIBUTEm, vp, field,
   2323                                     value ? 1 : 0));
   2324                 rv = BCM_E_NONE;
   2325             }
   2326 #endif
   2327             break;
   2328         case bcmPortControlDvpGroupKnockoutEnable:
   2329 #if defined(BCM_KATANA2_SUPPORT)
   2330             if (soc_feature(unit, soc_feature_dvp_group_pruning)) {
   2331                 SOC_IF_ERROR_RETURN
   2332                     (READ_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ANY, vp, &dvp_entry));
   2333                 soc_EGR_DVP_ATTRIBUTEm_field32_set(unit, &dvp_entry,
   2334                         ENABLE_VP_GROUP_PRUNINGf, value ? 1 : 0);
   2335                 SOC_IF_ERROR_RETURN
   2336                     (WRITE_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ALL, vp, &dvp_entry));
   2337                 rv = BCM_E_NONE;
   2338             }
   2339 #endif
   2340             break;
   2341         case bcmPortControlDvpGroupId:
   2342 #if defined(BCM_KATANA2_SUPPORT)
   2343             if (soc_feature(unit, soc_feature_dvp_group_pruning)) {
   2344                 /* coverity[negative_returns: FALSE] */
   2345                 rv = _bcm_td_dvp_group_set(unit, gport, vp, value);
   2346             }
   2347 #endif
   2348             break;
   2349 #if defined(BCM_KATANA2_SUPPORT)
   2350         case bcmPortControlOamLookupWithDvp:
   2351             if (SOC_IS_KATANA2(unit)) {
   2352                 rv = _bcm_kt2_port_control_oam_loopkup_with_dvp_set(unit,
   2353                         gport, value);
   2354             }
   2355             break;
   2356 #endif
   2357         case bcmPortControlTpidSrc:
   2358             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, TPID_SOURCEf)) {
   2359                 switch(value) {
   2360                     case bcmPortTpidSrcVp:
   2361                         SOC_IF_ERROR_RETURN(soc_mem_field32_modify(unit, SOURCE_VPm, vp,
   2362                                             TPID_SOURCEf, 0));
   2363                         rv = BCM_E_NONE;
   2364                         break;
   2365                     case bcmPortTpidSrcVpn:
   2366                         SOC_IF_ERROR_RETURN(soc_mem_field32_modify(unit, SOURCE_VPm, vp,
   2367                                             TPID_SOURCEf, 1));
   2368                         rv = BCM_E_NONE;
   2369                         break;
   2370                     case bcmPortTpidSrcPort:
   2371                         SOC_IF_ERROR_RETURN(soc_mem_field32_modify(unit, SOURCE_VPm, vp,
   2372                                             TPID_SOURCEf, 2));
   2373                         rv = BCM_E_NONE;
   2374                         break;
   2375                     case bcmPortTpidSrcTrillPayload:
   2376                         SOC_IF_ERROR_RETURN(soc_mem_field32_modify(unit, SOURCE_VPm, vp,
   2377                                             TPID_SOURCEf, 3));
   2378                         rv = BCM_E_NONE;
   2379                         break;
   2380                     default:
   2381                         rv = BCM_E_PARAM;
   2382                         break;
   2383                 }
   2384             }
   2385             break;
   2386         default:
   2387             break;
   2388     }
   2389 
   2390     return rv;
   2391 }
   2392 
   2393 /*
   2394  * Function:
   2395  *      bcm_td_vp_control_get
   2396  * Purpose:
   2397  *      Get per virtual port controls.
   2398  * Parameters:
   2399  *      unit - (IN) BCM device number
   2400  *      port - (IN) VP gport number
   2401  *      type - (IN) Control type
   2402  *      value - (OUT) Current value 
   2403  * Returns:
   2404  *      BCM_E_XXX
   2405  */
   2406 int
   2407 bcm_td_vp_control_get(int unit, bcm_gport_t gport,
   2408                        bcm_port_control_t type, int *value)
   2409 {
   2410     int rv;
   2411     int vp = -1;
   2412 #ifdef BCM_TRIDENT2_SUPPORT
   2413     bcm_niv_egress_t niv_egress;
   2414     int              count;
   2415     bcm_gport_t port = BCM_GPORT_INVALID;
   2416     soc_field_t      field;
   2417     bcm_extender_egress_t extender_egress;
   2418     _bcm_vp_info_t vp_info;
   2419 #endif
   2420     bcm_niv_port_t niv_port;
   2421     bcm_vlan_port_t vlan_port;
   2422     bcm_extender_port_t ext_port;
   2423     source_vp_entry_t svp_entry;
   2424     uint32 flags=0, val=0;
   2425     egr_dvp_attribute_entry_t dvp_entry;
   2426 
   2427     if (BCM_GPORT_IS_VLAN_PORT(gport)) {
   2428         vp = BCM_GPORT_VLAN_PORT_ID_GET(gport);
   2429         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) {
   2430             return BCM_E_NOT_FOUND;
   2431         }
   2432         bcm_vlan_port_t_init(&vlan_port);
   2433         vlan_port.vlan_port_id = gport;
   2434         BCM_IF_ERROR_RETURN(
   2435             bcm_esw_vlan_port_find(unit, &vlan_port));
   2436 #ifdef BCM_TRIDENT2_SUPPORT
   2437         port = vlan_port.port;
   2438 #endif
   2439     } else if (BCM_GPORT_IS_NIV_PORT(gport)) {
   2440         vp = BCM_GPORT_NIV_PORT_ID_GET(gport);
   2441         if(!_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv)) {
   2442             return BCM_E_NOT_FOUND;
   2443         }
   2444         bcm_niv_port_t_init(&niv_port);
   2445         niv_port.niv_port_id = gport;
   2446         BCM_IF_ERROR_RETURN(
   2447             bcm_esw_niv_port_get(unit, &niv_port));
   2448 #ifdef BCM_TRIDENT2_SUPPORT
   2449         if (niv_port.flags & BCM_NIV_PORT_MATCH_NONE) {
   2450             port = BCM_GPORT_INVALID;
   2451             bcm_niv_egress_t_init(&niv_egress);
   2452             rv = bcm_trident_niv_egress_get(unit, niv_port.niv_port_id,
   2453                                             1, &niv_egress, &count);
   2454             if (BCM_SUCCESS(rv)) {
   2455                 if (!(niv_egress.flags & BCM_NIV_EGRESS_MULTICAST)) {
   2456                     port = niv_egress.port;
   2457                 } 
   2458             }
   2459         } else {
   2460             port = niv_port.port;
   2461         }
   2462 #endif
   2463     } else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) {
   2464         vp = BCM_GPORT_EXTENDER_PORT_ID_GET(gport);
   2465         if(!_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender)) {
   2466             return BCM_E_NOT_FOUND;
   2467         }
   2468         bcm_extender_port_t_init(&ext_port);
   2469         ext_port.extender_port_id = gport;
   2470         BCM_IF_ERROR_RETURN(
   2471             bcm_esw_extender_port_get(unit, &ext_port));
   2472 #ifdef BCM_TRIDENT2_SUPPORT
   2473                 if (ext_port.flags & BCM_EXTENDER_PORT_MATCH_NONE) {
   2474                     bcm_extender_egress_t_init(&extender_egress);
   2475                     BCM_IF_ERROR_RETURN(bcm_esw_extender_egress_get_all(unit,
   2476                                 ext_port.extender_port_id, 1, &extender_egress, &count));
   2477                     if (count == 0) {
   2478                         /* No Extender egress object has been added to VP yet. */
   2479                         return BCM_E_CONFIG;
   2480                     }
   2481                     if (extender_egress.flags & BCM_EXTENDER_EGRESS_MULTICAST) {
   2482                         return BCM_E_PARAM;
   2483                     }
   2484                     port = extender_egress.port;
   2485                 } else {
   2486                     port = ext_port.port;
   2487                 }
   2488 #endif
   2489 
   2490     } else if (BCM_GPORT_IS_TRUNK(gport)) {
   2491         BCM_IF_ERROR_RETURN(
   2492             _bcm_esw_trunk_tid_to_vp_lag_vp(unit, 
   2493                             BCM_GPORT_TRUNK_GET(gport), &vp));
   2494 #ifdef BCM_TRIDENT2_SUPPORT
   2495         port = BCM_GPORT_INVALID;
   2496 #endif 
   2497 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
   2498 	} else if (BCM_GPORT_IS_MPLS_PORT(gport)) {
   2499         vp = BCM_GPORT_MPLS_PORT_ID_GET(gport);
   2500         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
   2501             return BCM_E_PARAM;
   2502         }
   2503 #endif
   2504 #ifdef BCM_TRIDENT2_SUPPORT
   2505         port = BCM_GPORT_INVALID;
   2506     } else if (BCM_GPORT_IS_VXLAN_PORT(gport)) {
   2507         vp = BCM_GPORT_VXLAN_PORT_ID_GET(gport);
   2508         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) {
   2509             return BCM_E_PARAM;
   2510         }
   2511         port = BCM_GPORT_INVALID;
   2512     } else if (BCM_GPORT_IS_MIM_PORT(gport)) {
   2513         vp = BCM_GPORT_MIM_PORT_ID_GET(gport);
   2514         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
   2515             return BCM_E_PARAM;
   2516         }
   2517         port = BCM_GPORT_INVALID;
   2518     } else if (BCM_GPORT_IS_L2GRE_PORT(gport)) {
   2519         vp = BCM_GPORT_L2GRE_PORT_ID_GET(gport);
   2520         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre)) {
   2521             return BCM_E_PARAM;
   2522         }
   2523         port = BCM_GPORT_INVALID;
   2524 #ifdef BCM_TRIDENT3_SUPPORT
   2525     } else if (BCM_GPORT_IS_FLOW_PORT(gport)) {
   2526         vp = BCM_GPORT_FLOW_PORT_ID_GET(gport);
   2527         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeFlow)) {
   2528             return BCM_E_PARAM;
   2529         }
   2530         port = BCM_GPORT_INVALID;
   2531 #endif
   2532 #endif
   2533 #ifdef BCM_HGPROXY_COE_SUPPORT
   2534     } else if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   2535         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) {
   2536 #endif
   2537     } else {
   2538         return BCM_E_PARAM;
   2539     }
   2540 
   2541     rv = BCM_E_UNAVAIL;
   2542 
   2543     switch (type) {
   2544         case bcmPortControlBridge:
   2545             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, DISABLE_VP_PRUNINGf)) {
   2546                 SOC_IF_ERROR_RETURN
   2547                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2548                 *value = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
   2549                         DISABLE_VP_PRUNINGf);
   2550                 rv = BCM_E_NONE;
   2551             } 
   2552             break;
   2553 
   2554         case bcmPortControlIP4:
   2555 #ifdef BCM_TRIDENT2_SUPPORT
   2556             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, IPV4L3_ENABLEf)) {
   2557                 SOC_IF_ERROR_RETURN
   2558                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2559                 *value = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
   2560                                                     IPV4L3_ENABLEf);
   2561                 rv = BCM_E_NONE;
   2562             }
   2563 #endif /* BCM_TRIDENT2_SUPPORT */
   2564             break;
   2565 
   2566         case bcmPortControlIP6:
   2567 #ifdef BCM_TRIDENT2_SUPPORT
   2568             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, IPV6L3_ENABLEf)) {
   2569                 SOC_IF_ERROR_RETURN
   2570                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2571                 *value = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
   2572                                                     IPV6L3_ENABLEf);
   2573                 rv = BCM_E_NONE;
   2574             }
   2575 #endif /* BCM_TRIDENT2_SUPPORT */
   2576             break;
   2577 
   2578         case bcmPortControlIP4Mcast:
   2579 #ifdef BCM_TRIDENT2_SUPPORT
   2580             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, IPMCV4_ENABLEf)) {
   2581                 SOC_IF_ERROR_RETURN
   2582                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2583                 *value = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
   2584                                                     IPMCV4_ENABLEf);
   2585                 rv = BCM_E_NONE;
   2586             }
   2587 #endif /* BCM_TRIDENT2_SUPPORT */
   2588             break;
   2589 
   2590         case bcmPortControlIP6Mcast:
   2591 #ifdef BCM_TRIDENT2_SUPPORT
   2592             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, IPMCV6_ENABLEf)) {
   2593                 SOC_IF_ERROR_RETURN
   2594                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2595                 *value = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
   2596                                                     IPMCV6_ENABLEf);
   2597                 rv = BCM_E_NONE;
   2598             }
   2599 #endif /* BCM_TRIDENT2_SUPPORT */
   2600             break;
   2601 
   2602         case bcmPortControlIP4McastL2:
   2603 #ifdef BCM_TRIDENT2_SUPPORT
   2604             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, IPMCV4_L2_ENABLEf)) {
   2605                 SOC_IF_ERROR_RETURN
   2606                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2607                 *value = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
   2608                                                     IPMCV4_L2_ENABLEf);
   2609                 rv = BCM_E_NONE;
   2610             }
   2611 #endif /* BCM_TRIDENT2_SUPPORT */
   2612             break;
   2613 
   2614         case bcmPortControlIP6McastL2:
   2615 #ifdef BCM_TRIDENT2_SUPPORT
   2616             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, IPMCV6_L2_ENABLEf)) {
   2617                 SOC_IF_ERROR_RETURN
   2618                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2619                 *value = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
   2620                                                     IPMCV6_L2_ENABLEf);
   2621                 rv = BCM_E_NONE;
   2622             }
   2623 #endif /* BCM_TRIDENT2_SUPPORT */
   2624             break;
   2625 
   2626         case bcmPortControlL3Ingress:
   2627 #ifdef BCM_TRIDENT2_SUPPORT
   2628             BCM_IF_ERROR_RETURN(
   2629                 _bcm_esw_port_gport_validate(unit, port, &port));
   2630             if (soc_mem_field_valid(unit, PORT_TABm, PORT_OPERATIONf)) {
   2631                 rv = _bcm_esw_port_tab_get(unit, port, PORT_OPERATIONf, value);
   2632                 BCM_IF_ERROR_RETURN(rv);
   2633                 if ((*value == 0x2) && 
   2634                     (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, L3_IIFf)) ) {
   2635                     rv = _bcm_trx_source_trunk_map_get(unit, port, L3_IIFf, (uint32 *)value);
   2636                 } 
   2637             } 
   2638 #endif /* BCM_TRIDENT2_SUPPORT */
   2639             break;
   2640 
   2641 #ifdef BCM_TRIDENT2_SUPPORT
   2642         case bcmPortControlFcoeRouteEnable:
   2643             if (soc_feature(unit, soc_feature_fcoe)) {
   2644                 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, FCOE_ROUTE_ENABLEf)) {
   2645                 SOC_IF_ERROR_RETURN
   2646                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2647                 *value = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
   2648                                                     FCOE_ROUTE_ENABLEf);
   2649                 rv = BCM_E_NONE;
   2650                 }     
   2651             }
   2652             break;
   2653 
   2654         case bcmPortControlFcoeVftEnable:
   2655             if (soc_feature(unit, soc_feature_fcoe)) {
   2656                 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, FCOE_VFT_ENABLEf)) {
   2657                 SOC_IF_ERROR_RETURN
   2658                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2659                 *value = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
   2660                                                     FCOE_VFT_ENABLEf);
   2661                 rv = BCM_E_NONE;
   2662                 }     
   2663             }
   2664             break;
   2665 
   2666         case bcmPortControlFcoeZoneCheckEnable:
   2667             if (soc_feature(unit, soc_feature_fcoe)) {
   2668                 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, 
   2669                                         FCOE_ZONE_CHECK_ENABLEf)) {
   2670                 SOC_IF_ERROR_RETURN
   2671                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2672                 *value = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
   2673                                                     FCOE_ZONE_CHECK_ENABLEf);
   2674                 rv = BCM_E_NONE;
   2675                 }     
   2676             }
   2677             break;
   2678 
   2679         case bcmPortControlFcoeSourceBindCheckEnable:
   2680             if (soc_feature(unit, soc_feature_fcoe)) {
   2681                 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, 
   2682                                         FCOE_SRC_BIND_CHECK_ENABLEf)) {
   2683                 SOC_IF_ERROR_RETURN
   2684                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2685                 *value = soc_SOURCE_VPm_field32_get(
   2686                                                 unit, &svp_entry,
   2687                                                 FCOE_SRC_BIND_CHECK_ENABLEf);
   2688                 rv = BCM_E_NONE;
   2689                 }     
   2690             }
   2691             break;
   2692 
   2693         case bcmPortControlFcoeFpmaPrefixCheckEnable:
   2694             if (soc_feature(unit, soc_feature_fcoe)) {
   2695                 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, 
   2696                                         FCOE_SRC_FPMA_PREFIX_CHECK_ENABLEf)) {
   2697                 SOC_IF_ERROR_RETURN
   2698                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2699                 *value = soc_SOURCE_VPm_field32_get(
   2700                                             unit, &svp_entry,
   2701                                             FCOE_SRC_FPMA_PREFIX_CHECK_ENABLEf);
   2702                 rv = BCM_E_NONE;
   2703                 }     
   2704             }
   2705             break;
   2706 
   2707         case bcmPortControlFcoeDoNotLearn:
   2708             if (soc_feature(unit, soc_feature_fcoe)) {
   2709                 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, FCOE_DO_NOT_LEARNf)) {
   2710                 SOC_IF_ERROR_RETURN
   2711                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2712                 *value = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
   2713                                                     FCOE_DO_NOT_LEARNf);
   2714                 rv = BCM_E_NONE;
   2715                 }     
   2716             }
   2717             break;
   2718 
   2719         case bcmPortControlFcoeNetworkPort:
   2720             if (soc_feature(unit, soc_feature_fcoe)) {
   2721                 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, FCOE_NETWORK_PORTf)) {
   2722                 SOC_IF_ERROR_RETURN
   2723                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2724                 *value = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
   2725                                                     FCOE_NETWORK_PORTf);
   2726                 rv = BCM_E_NONE;
   2727                 }     
   2728             }
   2729             break;
   2730 
   2731 #endif /* BCM_TRIDENT2_SUPPORT */
   2732 
   2733 
   2734         case bcmPortControlMcastGroupRemap:
   2735             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, NETWORK_PORTf)) {
   2736                 SOC_IF_ERROR_RETURN
   2737                     (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2738                 *value = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
   2739                                                     NETWORK_PORTf);
   2740                 rv = BCM_E_NONE;
   2741             }
   2742             break;
   2743 
   2744         case bcmPortControlVlanVpGroupIngress:
   2745             if (soc_feature(unit, soc_feature_vp_group_ingress_vlan_membership)) {
   2746                 int index = vp;
   2747                 soc_mem_t mem = SOURCE_VPm;
   2748                 soc_field_t field = VLAN_MEMBERSHIP_PROFILEf;
   2749                 uint32 buf[SOC_MAX_MEM_FIELD_WORDS];
   2750 
   2751 #ifdef BCM_HGPROXY_COE_SUPPORT
   2752                 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   2753                     _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) {
   2754                     int portid = -1;
   2755                     int modid = -1;
   2756                     int trunk = -1;
   2757                     int id = -1;
   2758                     mem = SOURCE_TRUNK_MAP_TABLEm;
   2759 
   2760                     BCM_IF_ERROR_RETURN(
   2761                         _bcm_esw_gport_resolve(unit, gport, &modid, &portid,
   2762                                                &trunk, &id));
   2763                     BCM_IF_ERROR_RETURN(
   2764                         _bcm_esw_src_mod_port_table_index_get(
   2765                             unit, modid, portid, &index));
   2766                 }
   2767 #endif
   2768                 SOC_IF_ERROR_RETURN(
   2769                     soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, buf));
   2770                 *value = soc_mem_field32_get(unit, mem, buf, field);
   2771 
   2772                 rv = BCM_E_NONE;
   2773             }
   2774             break;
   2775 
   2776         case bcmPortControlVlanVpGroupEgress:
   2777             if (soc_feature(unit,soc_feature_vp_group_egress_vlan_membership)) {
   2778                 int index = vp;
   2779                 soc_mem_t mem = EGR_DVP_ATTRIBUTEm;
   2780                 soc_field_t field = COMMON__VLAN_MEMBERSHIP_PROFILEf;
   2781                 uint32 buf[SOC_MAX_MEM_FIELD_WORDS];
   2782 
   2783 #ifdef BCM_HGPROXY_COE_SUPPORT
   2784                 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   2785                     _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) {
   2786                     int portid = -1;
   2787                     int modid = -1;
   2788                     int trunk = -1;
   2789                     int id = -1;
   2790                     mem = EGR_GPP_ATTRIBUTESm;
   2791                     field = VLAN_MEMBERSHIP_PROFILEf;
   2792 
   2793                     BCM_IF_ERROR_RETURN(
   2794                         _bcm_esw_gport_resolve(unit, gport, &modid, &portid,
   2795                                                &trunk, &id));
   2796                     BCM_IF_ERROR_RETURN(
   2797                         _bcm_esw_src_mod_port_table_index_get(
   2798                             unit, modid, portid, &index));
   2799                 }
   2800 #endif
   2801                 if (mem == EGR_DVP_ATTRIBUTEm) {
   2802                     SOC_IF_ERROR_RETURN(
   2803                         READ_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ANY,
   2804                                                 index, &dvp_entry));
   2805                     BCM_IF_ERROR_RETURN(
   2806                         _td_egr_dvp_attribute_field_name_get(
   2807                             unit, &dvp_entry,
   2808                             VLAN_MEMBERSHIP_PROFILEf, &field));
   2809                     *value = soc_EGR_DVP_ATTRIBUTEm_field32_get(
   2810                                  unit, &dvp_entry, field);
   2811                 } else {
   2812                     SOC_IF_ERROR_RETURN(
   2813                         soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, buf));
   2814                     *value = soc_mem_field32_get(unit, mem, buf, field);
   2815                 }
   2816                 rv = BCM_E_NONE;
   2817             }
   2818             break;
   2819 
   2820         case bcmPortControlL2Learn:
   2821             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, CML_FLAGS_NEWf)) {
   2822                 SOC_IF_ERROR_RETURN(
   2823                     READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2824                 val = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
   2825                                                  CML_FLAGS_NEWf);
   2826 
   2827                 if (!(val & (1 << 0))) {
   2828                    flags |= BCM_PORT_LEARN_FWD;
   2829                 }
   2830                 if (val & (1 << 1)) {
   2831                    flags |= BCM_PORT_LEARN_CPU;
   2832                 }
   2833                 if (val & (1 << 2)) {
   2834                    flags |= BCM_PORT_LEARN_PENDING;
   2835                 }
   2836                 if (val & (1 << 3)) {
   2837                    flags |= BCM_PORT_LEARN_ARL;
   2838                 }
   2839 
   2840                 *value = flags;
   2841                 rv = BCM_E_NONE;
   2842             }
   2843             break;
   2844 
   2845         case bcmPortControlL2Move:
   2846             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, CML_FLAGS_MOVEf)) {
   2847                 SOC_IF_ERROR_RETURN(
   2848                     READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2849                 val = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
   2850                                                  CML_FLAGS_MOVEf);
   2851                 if (!(val & (1 << 0))) {
   2852                    flags |= BCM_PORT_LEARN_FWD;
   2853                 }
   2854                 if (val & (1 << 1)) {
   2855                    flags |= BCM_PORT_LEARN_CPU;
   2856                 }
   2857                 if (val & (1 << 2)) {
   2858                    flags |= BCM_PORT_LEARN_PENDING;
   2859                 }
   2860                 if (val & (1 << 3)) {
   2861                    flags |= BCM_PORT_LEARN_ARL;
   2862                 }
   2863 
   2864                 *value = flags;
   2865                 rv = BCM_E_NONE;
   2866             }
   2867             break;
   2868         case bcmPortControlDoNotCheckVlan:
   2869 #ifdef BCM_TRIDENT2_SUPPORT
   2870             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, DISABLE_VLAN_CHECKSf)) {
   2871                 SOC_IF_ERROR_RETURN(
   2872                     READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2873                 *value = soc_SOURCE_VPm_field32_get(
   2874                     unit, &svp_entry, DISABLE_VLAN_CHECKSf);
   2875                 rv = BCM_E_NONE;
   2876             }
   2877 #endif /* BCM_TRIDENT2_SUPPORT */
   2878             break;
   2879         case bcmPortControlDoNotCheckVlanEgress:
   2880 #if defined(BCM_TRIDENT2_SUPPORT)
   2881             BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
   2882             field = COMMON__DISABLE_VLAN_CHECKf;
   2883             if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) {
   2884                 if (BCM_GPORT_IS_TRILL_PORT(gport)) {
   2885                     field = TRILL__DISABLE_VLAN_CHECKf;
   2886                 } else if (BCM_GPORT_IS_VXLAN_PORT(gport)) {
   2887                     field = VXLAN__DISABLE_VLAN_CHECKf;
   2888                 } else if (BCM_GPORT_IS_L2GRE_PORT(gport)) {
   2889                     field = L2GRE__DISABLE_VLAN_CHECKf;
   2890 #if defined(BCM_TRIDENT3_SUPPORT)
   2891                 } else if (BCM_GPORT_IS_FLOW_PORT(gport)) {
   2892                     uint32 data_type;
   2893 
   2894                     SOC_IF_ERROR_RETURN(READ_EGR_DVP_ATTRIBUTEm(unit,
   2895                           MEM_BLOCK_ANY, vp, &dvp_entry));
   2896                     data_type = soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTEm,
   2897                                  &dvp_entry, DATA_TYPEf);
   2898                     if (data_type == _BCM_FLOW_VXLAN_EGRESS_DEST_VP_TYPE) {
   2899                         field = VXLAN__DISABLE_VLAN_CHECKf;
   2900                     } else if (data_type ==
   2901                                     _BCM_FLOW_L2GRE_EGRESS_DEST_VP_TYPE) {
   2902                         field = L2GRE__DISABLE_VLAN_CHECKf;
   2903                     } else if (data_type >
   2904                                      _BCM_FLOW_L2GRE_EGRESS_DEST_VP_TYPE) {
   2905                         return BCM_E_UNAVAIL;
   2906                     }
   2907 #endif
   2908                 }
   2909             }
   2910 
   2911             if (SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm, field)) {
   2912                 SOC_IF_ERROR_RETURN(READ_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ANY,
   2913                                     vp, &dvp_entry));
   2914                 *value = soc_EGR_DVP_ATTRIBUTEm_field32_get(unit, &dvp_entry,
   2915                                                             field);
   2916                 rv = BCM_E_NONE;
   2917             }
   2918 #endif
   2919             break;
   2920         case bcmPortControlDvpGroupKnockoutEnable:
   2921 #if defined(BCM_KATANA2_SUPPORT)
   2922             if (soc_feature(unit, soc_feature_dvp_group_pruning)) {
   2923                 SOC_IF_ERROR_RETURN
   2924                     (READ_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ANY, vp, &dvp_entry));
   2925                 *value = soc_EGR_DVP_ATTRIBUTEm_field32_get(unit, &dvp_entry,
   2926                         ENABLE_VP_GROUP_PRUNINGf);
   2927                 
   2928                 rv = BCM_E_NONE;
   2929             }
   2930 #endif
   2931             break;
   2932         case bcmPortControlDvpGroupId:
   2933 #if defined(BCM_KATANA2_SUPPORT)
   2934             if (soc_feature(unit, soc_feature_dvp_group_pruning)) {
   2935                 /* coverity[negative_returns: FALSE] */
   2936                 rv = _bcm_td_dvp_group_get(unit, gport, vp, value);
   2937             }
   2938 #endif
   2939             break;
   2940 #if defined(BCM_KATANA2_SUPPORT)
   2941         case bcmPortControlOamLookupWithDvp:
   2942             if (SOC_IS_KATANA2(unit)) {
   2943                 rv = _bcm_kt2_port_control_oam_loopkup_with_dvp_get(unit, gport,
   2944                         value);
   2945             }
   2946             break;
   2947 #endif
   2948         case bcmPortControlTpidSrc:
   2949             if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, TPID_SOURCEf)) {
   2950                 SOC_IF_ERROR_RETURN(
   2951                     READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
   2952                 *value = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
   2953                                                     TPID_SOURCEf);
   2954                 switch(*value) {
   2955                     case 0:
   2956                         *value = bcmPortTpidSrcVp;
   2957                         break;
   2958                     case 1:
   2959                         *value = bcmPortTpidSrcVpn;
   2960                         break;
   2961                     case 2:
   2962                         *value = bcmPortTpidSrcPort;
   2963                         break;
   2964                     case 3:
   2965                         *value = bcmPortTpidSrcTrillPayload;
   2966                         break;
   2967                     default:
   2968                         return BCM_E_INTERNAL;
   2969                 }
   2970                 rv = BCM_E_NONE;
   2971             }
   2972             break;
   2973         default:
   2974             break;
   2975     }
   2976 
   2977     return rv;
   2978 }
   2979 
   2980 /*
   2981  * Function:
   2982  *      bcm_td_vp_force_vlan_set
   2983  * Purpose:
   2984  *      configure private vlan for virtual port.
   2985  * Parameters:
   2986  *      unit - (IN) BCM device number
   2987  *      port - (IN) VP gport number
   2988  *      value - (OUT) Current value
   2989  * Returns:
   2990  *      BCM_E_XXX
   2991  */
   2992 int
   2993 bcm_td_vp_force_vlan_set(int unit, bcm_gport_t gport,
   2994                        bcm_vlan_t vlan, uint32 flags)
   2995 {
   2996     int vp;
   2997     source_vp_entry_t svp_entry;
   2998     ing_dvp_table_entry_t dvp_entry;
   2999     soc_mem_t mem;
   3000     int rv;
   3001     int port_type = -1;
   3002 
   3003     if (BCM_GPORT_IS_VLAN_PORT(gport)) {
   3004         vp = BCM_GPORT_VLAN_PORT_ID_GET(gport);
   3005         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) {
   3006             return BCM_E_NOT_FOUND;
   3007         }
   3008     } else if (BCM_GPORT_IS_NIV_PORT(gport)) {
   3009         vp = BCM_GPORT_NIV_PORT_ID_GET(gport);
   3010         if(!_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv)) {
   3011             return BCM_E_NOT_FOUND;
   3012         }
   3013     } else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) {
   3014         vp = BCM_GPORT_EXTENDER_PORT_ID_GET(gport);
   3015         if(!_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender)) {
   3016             return BCM_E_NOT_FOUND;
   3017         }
   3018     } else {
   3019         return BCM_E_PARAM;
   3020     }
   3021 
   3022     if (flags & BCM_PORT_FORCE_VLAN_UNTAG) {
   3023         return BCM_E_PARAM;
   3024     }
   3025 
   3026     mem = SOURCE_VPm;
   3027     soc_mem_lock(unit, mem);
   3028     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, vp, &svp_entry);
   3029     if (SOC_FAILURE(rv)) {
   3030         soc_mem_unlock(unit, mem);
   3031         return (rv);
   3032     }
   3033 
   3034     soc_mem_field32_set(unit, mem, &svp_entry, EXP_PVLAN_VIDf,vlan);
   3035     soc_mem_field32_set(unit, mem, &svp_entry, PVLAN_ENABLEf,
   3036           flags & BCM_PORT_FORCE_VLAN_ENABLE? 1: 0);
   3037     rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, vp, &svp_entry);
   3038     soc_mem_unlock(unit, mem);
   3039     SOC_IF_ERROR_RETURN(rv);
   3040 
   3041     if ((flags & BCM_PORT_FORCE_VLAN_PORT_TYPE_MASK) == 
   3042                          BCM_PORT_FORCE_VLAN_PROMISCUOUS_PORT) {
   3043         port_type = 0;
   3044     } else if ((flags & BCM_PORT_FORCE_VLAN_PORT_TYPE_MASK) ==
   3045                          BCM_PORT_FORCE_VLAN_ISOLATED_PORT) {
   3046         port_type = 1;
   3047     } else if ((flags & BCM_PORT_FORCE_VLAN_PORT_TYPE_MASK) ==
   3048                          BCM_PORT_FORCE_VLAN_COMMUNITY_PORT) {
   3049         port_type = 2;
   3050     } 
   3051 
   3052     if (port_type != -1) { 
   3053         rv = soc_mem_field32_modify(unit, VLAN_TABm, vlan, 
   3054                     SRC_PVLAN_PORT_TYPEf,port_type);
   3055         SOC_IF_ERROR_RETURN(rv);
   3056     }
   3057 
   3058     mem = ING_DVP_TABLEm;
   3059     soc_mem_lock(unit, mem);
   3060     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, vp, &dvp_entry);
   3061     if (SOC_FAILURE(rv)) {
   3062         soc_mem_unlock(unit, mem);
   3063         return (rv);
   3064     }
   3065 
   3066     soc_mem_field32_set(unit, mem, &dvp_entry, PVLAN_VIDf,vlan);
   3067     if (port_type != -1) { 
   3068         soc_mem_field32_set(unit, mem, &dvp_entry, DST_PVLAN_PORT_TYPEf,
   3069                         port_type);
   3070     }
   3071     rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, vp, &dvp_entry);
   3072     soc_mem_unlock(unit, mem);
   3073     return rv;
   3074 }
   3075 
   3076 /*
   3077  * Function:
   3078  *      bcm_td_vp_force_vlan_get
   3079  * Purpose:
   3080  *      get private vlan information for a given virtual port.
   3081  * Parameters:
   3082  *      unit - (IN) BCM device number
   3083  *      port - (IN) VP gport number
   3084  *      value - (OUT) Current value
   3085  * Returns:
   3086  *      BCM_E_XXX
   3087  */
   3088 int
   3089 bcm_td_vp_force_vlan_get(int unit, bcm_gport_t gport,
   3090                        bcm_vlan_t *vlan, uint32 *flags)
   3091 {
   3092     int vp;
   3093     source_vp_entry_t svp_entry;
   3094     ing_dvp_table_entry_t dvp_entry;
   3095     int rv;
   3096     int port_type;
   3097 
   3098     if (BCM_GPORT_IS_VLAN_PORT(gport)) {
   3099         vp = BCM_GPORT_VLAN_PORT_ID_GET(gport);
   3100         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) {
   3101             return BCM_E_NOT_FOUND;
   3102         }
   3103     } else if (BCM_GPORT_IS_NIV_PORT(gport)) {
   3104         vp = BCM_GPORT_NIV_PORT_ID_GET(gport);
   3105         if(!_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv)) {
   3106             return BCM_E_NOT_FOUND;
   3107         }
   3108     } else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) {
   3109         vp = BCM_GPORT_EXTENDER_PORT_ID_GET(gport);
   3110         if(!_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender)) {
   3111             return BCM_E_NOT_FOUND;
   3112         }
   3113     } else {
   3114         return BCM_E_PARAM;
   3115     }
   3116 
   3117     *flags = 0;
   3118     rv = soc_mem_read(unit, SOURCE_VPm, MEM_BLOCK_ANY, vp, &svp_entry);
   3119     SOC_IF_ERROR_RETURN(rv);
   3120 
   3121     *vlan = soc_mem_field32_get(unit, SOURCE_VPm, &svp_entry, EXP_PVLAN_VIDf);
   3122     if (soc_mem_field32_get(unit, SOURCE_VPm, &svp_entry, PVLAN_ENABLEf)) {
   3123         *flags = BCM_PORT_FORCE_VLAN_ENABLE;
   3124     }
   3125 
   3126     rv = soc_mem_read(unit, ING_DVP_TABLEm, MEM_BLOCK_ANY, vp, &dvp_entry);
   3127     SOC_IF_ERROR_RETURN(rv);
   3128 
   3129     port_type = soc_mem_field32_get(unit, ING_DVP_TABLEm, &dvp_entry, 
   3130                          DST_PVLAN_PORT_TYPEf);
   3131     if (port_type == 0) {
   3132         *flags |= BCM_PORT_FORCE_VLAN_PROMISCUOUS_PORT;
   3133     } else if (port_type == 1) {
   3134         *flags |= BCM_PORT_FORCE_VLAN_ISOLATED_PORT;
   3135     } else if (port_type == 2) {
   3136         *flags |= BCM_PORT_FORCE_VLAN_COMMUNITY_PORT;
   3137     }
   3138     return rv;
   3139 }
   3140 #endif /* INCLUDE_L3 */
   3141 /*
   3142  * Function:
   3143  *     bcm_td_port_drain_cells
   3144  * Purpose:
   3145  *     To drain cells associated to the port.
   3146  * Parameters:
   3147  *     unit       - (IN) unit number
   3148  *     port       - (IN) Port
   3149  * Returns:
   3150  *     BCM_E_XXX
   3151  */
   3152 int bcm_td_port_drain_cells(int unit, int port)
   3153 {
   3154     mac_driver_t *macd;
   3155     int rv = BCM_E_NONE;
   3156 
   3157     PORT_LOCK(unit);
   3158     rv = soc_mac_probe(unit, port, &macd);
   3159 
   3160     if (BCM_SUCCESS(rv)) {
   3161         rv = MAC_CONTROL_SET(macd, unit, port, SOC_MAC_CONTROL_EGRESS_DRAIN, 1);
   3162     }
   3163     PORT_UNLOCK(unit);
   3164     return rv;
   3165 }
   3166 
   3167 #endif /* BCM_TRIDENT_SUPPORT */