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 (78946B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:        port.c
      8  * Purpose:     Port function implementations
      9  */
     10 
     11 
     12 #include <soc/defs.h>
     13 
     14 #include <assert.h>
     15 
     16 #include <sal/core/libc.h>
     17 #if defined(BCM_TRX_SUPPORT)
     18 
     19 #include <shared/util.h>
     20 #include <soc/mem.h>
     21 #include <soc/cm.h>
     22 #include <soc/drv.h>
     23 #include <soc/register.h>
     24 #include <soc/memory.h>
     25 #include <soc/lpm.h>
     26 #include <soc/tnl_term.h>
     27 
     28 #if  defined(BCM_TOMAHAWK3_SUPPORT)
     29 #include <soc/tomahawk3.h>
     30 #endif
     31 
     32 #include <bcm/port.h>
     33 #include <bcm/error.h>
     34 
     35 #include <bcm_int/esw/mbcm.h>
     36 #include <bcm_int/esw/firebolt.h>
     37 #include <bcm_int/esw/trx.h>
     38 #include <bcm_int/esw/triumph.h>
     39 #include <bcm_int/esw/port.h>
     40 #include <bcm_int/esw/xgs3.h>
     41 #include <bcm_int/esw/stack.h>
     42 #include <bcm_int/esw/trill.h>
     43 
     44 #include <bcm_int/esw_dispatch.h>
     45 #if defined(BCM_KATANA2_SUPPORT)
     46 #include <bcm_int/esw/katana2.h>
     47 #endif
     48 #if defined(BCM_HGPROXY_COE_SUPPORT)
     49 #include <bcm_int/esw/subport.h>
     50 #endif
     51 #if defined(BCM_TRIUMPH_SUPPORT)
     52 #include <bcm_int/esw/virtual.h>
     53 #endif /* BCM_TRIUMPH_SUPPORT */
     54 
     55 /*
     56  * Function:
     57  *      _bcm_trx_port_cml_hw2flags
     58  * Description:
     59  *      Converts a HW value to CML flags 
     60  * Parameters:
     61  *      unit         - (IN) Device number
     62  *      val          - (IN) TRX HW value 
     63  *      flags        - (OUT) CML flags BCM_PORT_LEARN_*
     64  * Return Value:
     65  *      BCM_E_XXX
     66  */
     67 int _bcm_trx_port_cml_hw2flags(int unit, uint32 val, uint32 *flags)
     68 {
     69     uint32  lflags = 0;
     70 
     71     if (NULL == flags) {
     72         return BCM_E_PARAM;
     73     }
     74 
     75     if (!(val & (1 << 0))) {
     76        lflags |= BCM_PORT_LEARN_FWD;
     77     }
     78     if (val & (1 << 1)) {
     79        lflags |= BCM_PORT_LEARN_CPU;
     80     }
     81     if (val & (1 << 2)) {
     82        lflags |= BCM_PORT_LEARN_PENDING;
     83     }
     84     if (val & (1 << 3)) {
     85        lflags |= BCM_PORT_LEARN_ARL;
     86     }
     87 
     88     *flags = lflags;
     89     return BCM_E_NONE;
     90 }
     91 
     92 
     93 /*
     94  * Function:
     95  *      _bcm_trx_port_cml_flags2hw
     96  * Description:
     97  *      Converts CML flags to a HW value.
     98  * Parameters:
     99  *      unit         - (IN) Device number
    100  *      flags        - (IN) CML flags BCM_PORT_LEARN_*
    101  *      val          - (OUT) TRX HW value
    102  * Return Value:
    103  *      BCM_E_XXX
    104  */
    105 int _bcm_trx_port_cml_flags2hw(int unit, uint32 flags, uint32 *val)
    106 {
    107     uint32 hw_val = 0;
    108 
    109     if (NULL == val) {
    110         return BCM_E_PARAM;
    111     }
    112     if (!(flags & BCM_PORT_LEARN_FWD)) {
    113        hw_val |= (1 << 0);
    114     }
    115     if (flags & BCM_PORT_LEARN_CPU) {
    116        hw_val |= (1 << 1);
    117     }
    118     if (flags & BCM_PORT_LEARN_PENDING) {
    119        hw_val |= (1 << 2);
    120     }
    121     if (flags & BCM_PORT_LEARN_ARL) {
    122        hw_val |= (1 << 3);
    123     }
    124 
    125     *val = hw_val;
    126     return (BCM_E_NONE);
    127 }
    128 
    129 /*
    130  * Function:
    131  *      _bcm_trx_vp_tpid_add
    132  * Description:
    133  *      Add allowed TPID for a virtual port.
    134  * Parameters:
    135  *      unit         - (IN) Device number
    136  *      vport        - (IN) Virtual Port identifier (MPLS ot MIM)
    137  *      tpid         - (IN) Tag Protocol ID
    138  *      color_select - (IN) Color mode for TPID
    139  * Return Value:
    140  *      BCM_E_XXX
    141  */
    142 int _bcm_trx_vp_tpid_add(int unit, bcm_gport_t vport, uint16 tpid, int color_select)
    143 {
    144     int                 vp, rv, tpid_idx=0, tpid_enable=0, islocal;
    145     source_vp_entry_t   svp;
    146     uint32              ena_f, cfi_cng, egr_vlan_ctrl;
    147     bcm_port_t          port;
    148     bcm_module_t        modid, mymodid;
    149     bcm_trunk_t         tgid;
    150 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    151     egr_vlan_control_1_entry_t entry;
    152 #endif
    153 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
    154     int vp_lag_vp;
    155 #endif
    156 #if defined(BCM_TRX_SUPPORT)
    157     /*
    158      * TRX devices only support OUTER_CFI to be mapped to CNG
    159      */
    160     if (color_select == BCM_COLOR_INNER_CFI && SOC_IS_TRX(unit)) {
    161         return BCM_E_UNAVAIL;
    162     }
    163 #endif
    164 
    165     BCM_IF_ERROR_RETURN(
    166         _bcm_esw_gport_resolve(unit, vport, &modid, &port, &tgid, &vp));
    167 
    168 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
    169     if (soc_feature(unit, soc_feature_vp_lag)) {
    170         if (tgid != -1) {
    171             rv = _bcm_esw_trunk_tid_to_vp_lag_vp(unit, tgid, &vp_lag_vp);
    172             if (BCM_SUCCESS(rv) &&
    173                 _bcm_vp_used_get(unit, vp_lag_vp, _bcmVpTypeVpLag)) {
    174                 vp = vp_lag_vp;
    175             }
    176         }
    177     }
    178 #endif
    179 
    180     if (-1 == vp) { 
    181         return BCM_E_PORT;
    182     }
    183     if (tgid == -1) {
    184         BCM_IF_ERROR_RETURN( _bcm_esw_modid_is_local(unit, modid, &islocal));
    185         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mymodid));
    186         if (!islocal)  {
    187             if (soc_feature(unit, soc_feature_subtag_coe) ||
    188                 soc_feature(unit, soc_feature_linkphy_coe)) {
    189             #ifdef BCM_KATANA2_SUPPORT
    190                 if (SOC_IS_KATANA2(unit) &&
    191                     (_bcm_kt2_mod_is_coe_mod_check(unit, modid) == BCM_E_NONE)) {
    192                         BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit,
    193                             modid, port, &port));
    194                 } else {
    195                     return BCM_E_PORT;
    196                 }
    197             #endif
    198             }
    199         } else {
    200             while (mymodid < modid) {
    201                 port += 32;
    202                 modid -= 1;
    203             }
    204         }
    205     }
    206 
    207     _bcm_fb2_outer_tpid_tab_lock(unit);
    208 
    209     rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp);
    210     if (BCM_FAILURE(rv)) {
    211         _bcm_fb2_outer_tpid_tab_unlock(unit);
    212         return rv;
    213     }
    214     
    215     /* See if the entry already exist */
    216     rv = _bcm_fb2_outer_tpid_lkup(unit, tpid, &tpid_idx);
    217 #if defined(BCM_TRIDENT3_SUPPORT)
    218     if (SOC_MEM_IS_VALID(unit, SVP_ATTRS_1m)) {
    219         uint32 svp_attrs_1[SOC_MAX_MEM_WORDS];
    220         uint32 tpid_enable = 0;
    221 
    222         BCM_IF_ERROR_RETURN(READ_SVP_ATTRS_1m(unit,
    223                     MEM_BLOCK_ANY, vp, svp_attrs_1));
    224         soc_SVP_ATTRS_1m_field_get(unit,
    225                 &svp_attrs_1, TPID_ENABLEf, (uint32 *)&tpid_enable);
    226 
    227         ena_f = tpid_enable;
    228     } else
    229 #endif
    230     {
    231         ena_f = soc_SOURCE_VPm_field32_get(unit, &svp, TPID_ENABLEf);
    232     }
    233 
    234     if ((BCM_E_NOT_FOUND == rv) || !(ena_f & (1 << tpid_idx)) ) {
    235         rv = _bcm_fb2_outer_tpid_entry_add(unit, tpid, &tpid_idx);
    236         if (BCM_FAILURE(rv)) {
    237             _bcm_fb2_outer_tpid_tab_unlock(unit);
    238             return rv;
    239         }
    240 
    241     }
    242 #if (defined(BCM_TRIDENT_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
    243     && defined(INCLUDE_L3)
    244     /* Add TPID for Trill Virtual Port */
    245     if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit))
    246          && (BCM_GPORT_IS_TRILL_PORT(vport)) 
    247          && (3 == soc_SOURCE_VPm_field32_get(unit, &svp, TPID_SOURCEf))) {
    248             rv = bcm_td_trill_tpid_add(unit, vport, tpid_idx);
    249             if (BCM_FAILURE(rv)) {
    250                 rv = _bcm_fb2_outer_tpid_entry_delete(unit,tpid_idx);
    251                 _bcm_fb2_outer_tpid_tab_unlock(unit);
    252                 return (rv);
    253             }
    254     } else
    255 #endif
    256     {
    257         tpid_enable = (1 << tpid_idx);
    258         soc_SOURCE_VPm_field32_set(unit, &svp, SD_TAG_MODEf, 1);
    259         ena_f |= tpid_enable;
    260 #if defined(BCM_TRIDENT3_SUPPORT)
    261         if (SOC_MEM_IS_VALID(unit, SVP_ATTRS_1m)) {
    262             rv = soc_mem_field32_modify(unit, SVP_ATTRS_1m,
    263                     vp, TPID_ENABLEf, ena_f);
    264         } else
    265 #endif
    266         {
    267             soc_SOURCE_VPm_field32_set(unit, &svp, TPID_ENABLEf, ena_f);
    268         }
    269 
    270         rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp);
    271 
    272         if (BCM_FAILURE(rv)) {
    273             rv = _bcm_fb2_outer_tpid_entry_delete(unit,tpid_idx);
    274             _bcm_fb2_outer_tpid_tab_unlock(unit);
    275             return rv;
    276         }
    277     }
    278 
    279     if ((tgid == -1) && islocal && SOC_PORT_VALID(unit, port)) {
    280 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    281         if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
    282             if (soc_feature(unit, soc_feature_egr_all_profile)) {
    283                 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_field_get(unit,
    284                     port, EGR_VLAN_CONTROL_1m, CFI_AS_CNGf, &cfi_cng));
    285             } else {
    286                 rv = READ_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, &entry);
    287                 cfi_cng = soc_EGR_VLAN_CONTROL_1m_field32_get(unit, &entry,
    288                                 CFI_AS_CNGf);
    289             }
    290         } else
    291 #endif
    292         {
    293             rv = READ_EGR_VLAN_CONTROL_1r(unit, port, &egr_vlan_ctrl);
    294             cfi_cng = soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r,
    295                             egr_vlan_ctrl, CFI_AS_CNGf);
    296         }
    297         if (BCM_FAILURE(rv)) {
    298             rv = _bcm_fb2_outer_tpid_entry_delete(unit,tpid_idx);
    299             _bcm_fb2_outer_tpid_tab_unlock(unit);
    300             return rv;
    301         }
    302 
    303         /* Update color selection per TPID per port */
    304         switch (color_select) {
    305           case BCM_COLOR_PRIORITY:
    306               cfi_cng &= ~tpid_enable;
    307               break;
    308           case BCM_COLOR_INNER_CFI:
    309               cfi_cng = 0x1;
    310               break;
    311           case BCM_COLOR_OUTER_CFI:
    312               cfi_cng |= tpid_enable;
    313               break;
    314           default:
    315               /* Already checked color_select param */
    316               /* Should never get here              */ 
    317               break;
    318         }
    319 
    320 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    321         if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
    322             if (soc_feature(unit, soc_feature_egr_all_profile)) {
    323                 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_field_set(unit,
    324                     port, EGR_VLAN_CONTROL_1m, CFI_AS_CNGf, cfi_cng));
    325             } else {
    326                 soc_EGR_VLAN_CONTROL_1m_field32_set(unit, &entry,
    327                         CFI_AS_CNGf, cfi_cng);
    328                 rv = WRITE_EGR_VLAN_CONTROL_1m(unit,
    329                         MEM_BLOCK_ANY, port, &entry);
    330             }
    331         } else
    332 #endif
    333         {
    334             soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &egr_vlan_ctrl,
    335                     CFI_AS_CNGf, cfi_cng);
    336             rv = WRITE_EGR_VLAN_CONTROL_1r(unit, port, egr_vlan_ctrl);
    337         }
    338         if (BCM_FAILURE(rv)) {
    339             rv = _bcm_fb2_outer_tpid_entry_delete(unit,tpid_idx);
    340             _bcm_fb2_outer_tpid_tab_unlock(unit);
    341             return rv;
    342         }
    343     }
    344     
    345     _bcm_fb2_outer_tpid_tab_unlock(unit);
    346     return BCM_E_NONE;
    347 }
    348 
    349 /*
    350  * Function:
    351  *      _bcm_trx_vp_tpid_get_all
    352  * Description:
    353  *      Retrieve a list of TPIDs available for the given vport.
    354  * Parameters:
    355  *      unit         - (IN) Device number
    356  *      vport        - (IN) Virtual Port identifier (MPLS ot MIM)
    357  *      size         - (IN) size of the buffer arrays
    358  *      tpid_array   - (OUT) tpid buffer array
    359  *      color_array  - (OUT) color buffer array
    360  *      count        - (OUT) actual number of tpids/colors retrieved
    361  * Return Value:
    362  *      BCM_E_XXX
    363  */
    364 int _bcm_trx_vp_tpid_get_all(int unit, bcm_gport_t vport, int size,
    365                 uint16 *tpid_array, int *color_array, int *count)
    366 {
    367     int                 vp, rv;
    368     source_vp_entry_t   svp;
    369     uint32              tpid_enable=0;
    370     bcm_port_t          port;
    371     bcm_module_t        modid;
    372     bcm_trunk_t         tgid;
    373     int cnt;
    374     uint32 tpid;
    375     int num_entries;
    376     int index;
    377 
    378     rv = BCM_E_NONE;
    379     cnt = 0;
    380 
    381     BCM_IF_ERROR_RETURN(
    382         _bcm_esw_gport_resolve(unit, vport, &modid, &port, &tgid, &vp));
    383 
    384     if (-1 == vp) {
    385         return BCM_E_PORT;
    386     }
    387 
    388     rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp);
    389     if (BCM_FAILURE(rv)) {
    390         return rv;
    391     }
    392 
    393 #if defined(BCM_TRIDENT3_SUPPORT)
    394     if (SOC_MEM_IS_VALID(unit, SVP_ATTRS_1m)) {
    395         uint32 svp_attrs_1[SOC_MAX_MEM_WORDS];
    396 
    397         BCM_IF_ERROR_RETURN(READ_SVP_ATTRS_1m(unit,
    398                     MEM_BLOCK_ANY, vp, svp_attrs_1));
    399         soc_SVP_ATTRS_1m_field_get(unit,
    400                 &svp_attrs_1, TPID_ENABLEf, (uint32 *)&tpid_enable);
    401 
    402         /* max tpid entries limited by width of this field */
    403         num_entries = soc_mem_field_length(unit,SVP_ATTRS_1m,TPID_ENABLEf);
    404     } else
    405 #endif
    406     {
    407         tpid_enable = soc_SOURCE_VPm_field32_get(unit, &svp, TPID_ENABLEf);
    408         /* max tpid entries limited by width of this field */
    409         num_entries = soc_mem_field_length(unit,SOURCE_VPm,TPID_ENABLEf);
    410     }
    411 
    412     if (size == 0) {
    413         for (index = 0; index < num_entries; index++) {
    414             if (tpid_enable & (1 << index)) {
    415                 cnt++;
    416             }
    417         }
    418         *count = cnt;
    419         return BCM_E_NONE;
    420     }
    421    
    422     for (index = 0; index < num_entries; index++) {
    423         if (cnt < size) {
    424             if (tpid_enable & (1 << index)) {
    425                 rv = READ_EGR_OUTER_TPIDr(unit, index, &tpid);
    426                 if (BCM_FAILURE(rv)) {
    427                     return (rv);
    428                 }
    429                 tpid_array[cnt] = (uint16)tpid;
    430                 cnt++;
    431             }
    432         }
    433     }
    434     *count = cnt;
    435 
    436     return rv;
    437 }
    438 
    439 /*
    440  * Function:
    441  *      _bcm_trx_vp_tpid_delete
    442  * Description:
    443  *      Delete allowed TPID for a virtual port.
    444  * Parameters:
    445  *      unit  - (IN) Device number
    446  *      vport - (IN) Virtual Port identifier (WLAN or MIM)
    447  *      tpid  - (IN) Tag Protocol ID
    448  * Return Value:
    449  *      BCM_E_XXX
    450  */
    451 int _bcm_trx_vp_tpid_delete(int unit, bcm_gport_t vport, uint16 tpid)
    452 {
    453     int                 vp, rv, tpid_idx;
    454     source_vp_entry_t   svp;
    455     uint32              ena_f;
    456     bcm_port_t          port;
    457     bcm_module_t        modid;
    458     bcm_trunk_t         tgid;
    459 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
    460     int vp_lag_vp;
    461 #endif
    462 
    463     BCM_IF_ERROR_RETURN(
    464         _bcm_esw_gport_resolve(unit, vport, &modid, &port, &tgid, &vp));
    465     
    466 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
    467     if (soc_feature(unit, soc_feature_vp_lag)) {
    468         if (tgid != -1) {
    469             rv = _bcm_esw_trunk_tid_to_vp_lag_vp(unit, tgid, &vp_lag_vp);
    470             if (BCM_SUCCESS(rv) &&
    471                 _bcm_vp_used_get(unit, vp_lag_vp, _bcmVpTypeVpLag)) {
    472                 vp = vp_lag_vp;
    473             }
    474         }
    475     }
    476 #endif
    477 
    478     if (-1 == vp) {
    479         return BCM_E_PORT;
    480     }
    481 
    482     BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp));
    483 #if defined(BCM_TRIDENT3_SUPPORT)
    484     if (SOC_MEM_IS_VALID(unit, SVP_ATTRS_1m)) {
    485         uint32 svp_attrs_1[SOC_MAX_MEM_WORDS];
    486         uint32 tpid_enable = 0;
    487         BCM_IF_ERROR_RETURN(READ_SVP_ATTRS_1m(unit,
    488                             MEM_BLOCK_ANY, vp, svp_attrs_1));
    489         tpid_enable = soc_mem_field32_get(unit, SVP_ATTRS_1m, &svp_attrs_1, TPID_ENABLEf);
    490         ena_f = tpid_enable;
    491     } else
    492 #endif
    493     {
    494         ena_f = soc_SOURCE_VPm_field32_get(unit, &svp, TPID_ENABLEf);
    495     }
    496     _bcm_fb2_outer_tpid_tab_lock(unit);
    497 
    498     rv = _bcm_fb2_outer_tpid_lkup(unit, tpid, &tpid_idx);
    499     if (BCM_FAILURE(rv)) {
    500         _bcm_fb2_outer_tpid_tab_unlock(unit);
    501         return (rv);
    502     }
    503 
    504 #if (defined(BCM_TRIDENT_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
    505     && defined(INCLUDE_L3)
    506     /* Add TPID for Trill Virtual Port */
    507     if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit))
    508          && (BCM_GPORT_IS_TRILL_PORT(vport))
    509          && (3 == soc_SOURCE_VPm_field32_get(unit, &svp, TPID_SOURCEf))) {
    510             rv = bcm_td_trill_tpid_delete(unit, vport, tpid_idx);
    511             if (BCM_FAILURE(rv)) {
    512                 rv = _bcm_fb2_outer_tpid_entry_delete(unit,tpid_idx);
    513                 _bcm_fb2_outer_tpid_tab_unlock(unit);
    514                 return (rv);
    515             }
    516     } else
    517 #endif
    518     {
    519         if (ena_f & (1 << tpid_idx)) {
    520             ena_f &= ~(1 << tpid_idx);
    521 #if defined(BCM_TRIDENT3_SUPPORT)
    522             if (SOC_MEM_IS_VALID(unit, SVP_ATTRS_1m)) {
    523                 rv = soc_mem_field32_modify(unit, SVP_ATTRS_1m,
    524                         vp, TPID_ENABLEf, ena_f);
    525             } else
    526 #endif
    527             {
    528                 soc_SOURCE_VPm_field32_set(unit, &svp, TPID_ENABLEf, ena_f);
    529             }
    530             if (!ena_f) {
    531                 soc_SOURCE_VPm_field32_set(unit, &svp, SD_TAG_MODEf, 0);
    532             }
    533             rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp);
    534 
    535             if (BCM_FAILURE(rv)) {
    536                 rv = _bcm_fb2_outer_tpid_entry_delete(unit,tpid_idx);
    537                 _bcm_fb2_outer_tpid_tab_unlock(unit);
    538                 return rv;
    539             }
    540         } else {
    541             _bcm_fb2_outer_tpid_tab_unlock(unit);
    542             return BCM_E_NOT_FOUND;
    543         }
    544     }
    545 
    546     rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_idx);
    547     _bcm_fb2_outer_tpid_tab_unlock(unit);
    548     return rv;
    549 }
    550 
    551 /*
    552  * Function:
    553  *      _bcm_trx_vp_tpid_delete_all
    554  * Description:
    555  *      Delete all allowed TPID for a virtual port.
    556  * Parameters:
    557  *      unit  - (IN) Device number
    558  *      vport - (IN) Virtual Port identifier
    559  * Return Value:
    560  *      BCM_E_XXX
    561  */
    562 int _bcm_trx_vp_tpid_delete_all(int unit, bcm_gport_t vport)
    563 {
    564     int                 vp, rv = BCM_E_NONE, tpid_idx;
    565     source_vp_entry_t   svp;
    566     uint32              ena_f;
    567     bcm_port_t          port;
    568     bcm_module_t        modid;
    569     bcm_trunk_t         tgid;
    570 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
    571     int vp_lag_vp;
    572 #endif
    573 
    574     BCM_IF_ERROR_RETURN(
    575         _bcm_esw_gport_resolve(unit, vport, &modid, &port, &tgid, &vp));
    576     
    577 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
    578     if (soc_feature(unit, soc_feature_vp_lag)) {
    579         if (tgid != -1) {
    580             rv = _bcm_esw_trunk_tid_to_vp_lag_vp(unit, tgid, &vp_lag_vp);
    581             if (BCM_SUCCESS(rv) &&
    582                 _bcm_vp_used_get(unit, vp_lag_vp, _bcmVpTypeVpLag)) {
    583                 vp = vp_lag_vp;
    584             }
    585         }
    586     }
    587 #endif
    588 
    589     if (-1 == vp) {
    590         return BCM_E_PORT;
    591     }
    592 
    593     BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp));
    594 #if defined(BCM_TRIDENT3_SUPPORT)
    595     if (SOC_MEM_IS_VALID(unit, SVP_ATTRS_1m)) {
    596         uint32 svp_attrs_1[SOC_MAX_MEM_WORDS];
    597         uint32 tpid_enable = 0;
    598         BCM_IF_ERROR_RETURN(READ_SVP_ATTRS_1m(unit,
    599                             MEM_BLOCK_ANY, vp, svp_attrs_1));
    600         tpid_enable = soc_mem_field32_get(unit, SVP_ATTRS_1m, &svp_attrs_1, TPID_ENABLEf);
    601         ena_f = tpid_enable;
    602     } else
    603 #endif
    604     {
    605         ena_f = soc_SOURCE_VPm_field32_get(unit, &svp, TPID_ENABLEf);
    606     }
    607     /* If was not set - do nothing */
    608     if (!ena_f) {
    609         return BCM_E_NONE;
    610     }
    611     soc_SOURCE_VPm_field32_set(unit, &svp, SD_TAG_MODEf, 0);
    612 #if defined(BCM_TRIDENT3_SUPPORT)
    613     if (SOC_MEM_IS_VALID(unit, SVP_ATTRS_1m)) {
    614         rv = soc_mem_field32_modify(unit, SVP_ATTRS_1m,
    615                                     vp, TPID_ENABLEf, ena_f);
    616     } else
    617 #endif
    618     {
    619         soc_SOURCE_VPm_field32_set(unit, &svp, TPID_ENABLEf, 0);
    620     }
    621     BCM_IF_ERROR_RETURN(WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp));
    622 
    623     /* Perform SW delition only after HW was updated */
    624     _bcm_fb2_outer_tpid_tab_lock(unit);
    625     tpid_idx = 0;
    626     while (ena_f) {
    627         if (ena_f & 1) {
    628             rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_idx);
    629             if (BCM_FAILURE(rv)) {
    630                 _bcm_fb2_outer_tpid_tab_unlock(unit);
    631                 return (rv);
    632             }
    633         }
    634         ena_f = (ena_f >> 1);
    635         tpid_idx++;
    636     }
    637     _bcm_fb2_outer_tpid_tab_unlock(unit);
    638     return rv;
    639 }
    640 
    641 /*
    642  * Function:
    643  *      _bcm_trx_vp_tpid_set
    644  * Description:
    645  *      Set the default Tag Protocol ID for a virtual gport.
    646  * Parameters:
    647  *      unit  - Device number
    648  *      vport - Virtual Port identifier
    649  *      tpid  - Tag Protocol ID
    650  * Return Value:
    651  *      BCM_E_XXX
    652  */
    653 int _bcm_trx_vp_tpid_set(int unit, bcm_gport_t vport, uint16 tpid)
    654 {
    655     int                 vp, rv, tpid_idx, old_idx, islocal;
    656     source_vp_entry_t   svp;
    657     uint32              ena_f, evc;
    658     bcm_port_t          port;
    659     bcm_module_t        modid, mymodid;
    660     bcm_trunk_t         tgid;
    661 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    662     egr_vlan_control_1_entry_t vlan_control;
    663 #endif
    664     int pp_port_flag = 0;
    665 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
    666     int vp_lag_vp;
    667 #endif
    668     BCM_IF_ERROR_RETURN(
    669         _bcm_esw_gport_resolve(unit, vport, &modid, &port, &tgid, &vp));
    670 
    671 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
    672     if (soc_feature(unit, soc_feature_vp_lag)) {
    673         if (tgid != -1) {
    674             rv = _bcm_esw_trunk_tid_to_vp_lag_vp(unit, tgid, &vp_lag_vp);
    675             if (BCM_SUCCESS(rv) &&
    676                 _bcm_vp_used_get(unit, vp_lag_vp, _bcmVpTypeVpLag)) {
    677                 vp = vp_lag_vp;
    678             }
    679         }
    680     }
    681 #endif
    682 
    683     if (-1 == vp) {
    684         return BCM_E_PORT;
    685     }
    686 
    687     BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp));
    688 #if defined(BCM_TRIDENT3_SUPPORT)
    689     if (SOC_MEM_IS_VALID(unit, SVP_ATTRS_1m)) {
    690         uint32 svp_attrs_1[SOC_MAX_MEM_WORDS];
    691         uint32 tpid_enable = 0;
    692 
    693         BCM_IF_ERROR_RETURN(READ_SVP_ATTRS_1m(unit,
    694                             MEM_BLOCK_ANY, vp, svp_attrs_1));
    695         tpid_enable = soc_mem_field32_get(unit, SVP_ATTRS_1m, &svp_attrs_1, TPID_ENABLEf);
    696         ena_f = tpid_enable;
    697     } else
    698 #endif
    699     {
    700         ena_f = soc_SOURCE_VPm_field32_get(unit, &svp, TPID_ENABLEf);
    701     }
    702 
    703     old_idx = 0;
    704     if (tgid == -1) {
    705         BCM_IF_ERROR_RETURN( _bcm_esw_modid_is_local(unit, modid, &islocal));
    706         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mymodid));
    707 
    708         if (!islocal)  {
    709             if (soc_feature(unit, soc_feature_subtag_coe) ||
    710                 soc_feature(unit, soc_feature_linkphy_coe)) {
    711             #ifdef BCM_KATANA2_SUPPORT
    712                 if (SOC_IS_KATANA2(unit) &&
    713                     (_bcm_kt2_mod_is_coe_mod_check(unit, modid) == BCM_E_NONE)) {
    714                     BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit,
    715                         modid, port, &port));
    716                     pp_port_flag = 1;
    717                 } else {
    718                     return BCM_E_PORT;
    719                 }
    720             #endif
    721             }
    722         } else {
    723             while (mymodid < modid) {
    724                 port += 32;
    725                 modid -= 1;
    726             }
    727         }
    728         
    729         if (islocal || (!islocal && pp_port_flag)) {
    730 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    731             if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
    732                 if (soc_feature(unit, soc_feature_egr_all_profile)) {
    733                     BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_field_get(unit,
    734                         port, EGR_VLAN_CONTROL_1m, OUTER_TPID_INDEXf,
    735                         (void *)&old_idx));
    736                 } else {
    737                     BCM_IF_ERROR_RETURN(READ_EGR_VLAN_CONTROL_1m(unit,
    738                                 MEM_BLOCK_ANY, port, &vlan_control));
    739                     old_idx = soc_EGR_VLAN_CONTROL_1m_field32_get(unit,
    740                                 &vlan_control, OUTER_TPID_INDEXf);
    741                 }
    742             } else
    743 #endif
    744             {
    745                 BCM_IF_ERROR_RETURN(READ_EGR_VLAN_CONTROL_1r(unit, port, &evc));
    746                 old_idx =  soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r,
    747                                              evc, OUTER_TPID_INDEXf);
    748             }
    749         }
    750     }
    751 
    752     _bcm_fb2_outer_tpid_tab_lock(unit);
    753     if (tgid == -1 && islocal) {
    754         /* Delete the TPID referenced by EGR_VLAN_CONTROL_1r */
    755         rv = _bcm_fb2_outer_tpid_entry_delete(unit, old_idx);
    756         if (BCM_FAILURE(rv)) {
    757             _bcm_fb2_outer_tpid_tab_unlock(unit);
    758             return (rv);
    759         }
    760     }
    761 
    762     /* Delete the TPID referenced by SOURCE_VP table */
    763     tpid_idx = 0;
    764     while (ena_f) {
    765         if (ena_f & 1) {
    766             rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_idx);
    767             if (BCM_FAILURE(rv)) {
    768                 _bcm_fb2_outer_tpid_tab_unlock(unit);
    769                 return (rv);
    770             }
    771         }
    772         ena_f = ena_f >> 1;
    773         tpid_idx++;
    774     }
    775 
    776     /* Add TPID */
    777     rv = _bcm_fb2_outer_tpid_entry_add(unit, tpid, &tpid_idx);
    778     if (BCM_FAILURE(rv)) {
    779         _bcm_fb2_outer_tpid_tab_unlock(unit);
    780         return (rv);
    781     }
    782 
    783     if (tgid == -1 && islocal) {
    784         /* Add TPID reference for EGR_VLAN_CONTROL_1. 
    785          * The first insertion and second insertion will return
    786          * the same status because we are adding the same TPID value.
    787          */
    788         rv = _bcm_fb2_outer_tpid_entry_add(unit, tpid, &tpid_idx);
    789         if (BCM_FAILURE(rv)) {
    790             _bcm_fb2_outer_tpid_entry_delete(unit, tpid_idx);
    791             _bcm_fb2_outer_tpid_tab_unlock(unit);
    792             return (rv);
    793         }
    794 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    795         if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
    796             if (soc_feature(unit, soc_feature_egr_all_profile)) {
    797                 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_field_set(unit,
    798                     port, EGR_VLAN_CONTROL_1m, OUTER_TPID_INDEXf, tpid_idx));
    799             } else {
    800                 soc_EGR_VLAN_CONTROL_1m_field32_set(unit, &vlan_control,
    801                         OUTER_TPID_INDEXf, tpid_idx);
    802                 rv = WRITE_EGR_VLAN_CONTROL_1m(unit,
    803                             MEM_BLOCK_ANY, port, &vlan_control);
    804             }
    805         } else
    806 #endif
    807         {
    808             soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &evc,
    809                               OUTER_TPID_INDEXf, tpid_idx);
    810             rv = WRITE_EGR_VLAN_CONTROL_1r(unit, port, evc);
    811         }
    812         if (BCM_FAILURE(rv)) {
    813             _bcm_fb2_outer_tpid_entry_delete(unit, tpid_idx);
    814             _bcm_fb2_outer_tpid_entry_delete(unit, tpid_idx);
    815             _bcm_fb2_outer_tpid_tab_unlock(unit);
    816             return (rv);
    817         }
    818     }
    819 #if (defined(BCM_TRIDENT_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
    820     && defined(INCLUDE_L3)
    821     /* Set TPID for Trill Virtual Port */
    822     if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit))
    823          && (BCM_GPORT_IS_TRILL_PORT(vport))
    824          && (3 == soc_SOURCE_VPm_field32_get(unit, &svp, TPID_SOURCEf))) {
    825             rv = bcm_td_trill_tpid_set(unit, vport, tpid_idx);
    826             if (BCM_FAILURE(rv)) {
    827                 _bcm_fb2_outer_tpid_entry_delete(unit, tpid_idx);
    828                 _bcm_fb2_outer_tpid_tab_unlock(unit);
    829                 return (rv);
    830             }
    831     } else
    832 #endif
    833     {
    834         ena_f = 1 << tpid_idx;
    835 #if defined(BCM_TRIDENT3_SUPPORT)
    836         if (SOC_MEM_IS_VALID(unit, SVP_ATTRS_1m)) {
    837             rv = soc_mem_field32_modify(unit, SVP_ATTRS_1m,
    838                     vp, TPID_ENABLEf, ena_f);
    839         } else
    840 #endif
    841         {
    842             soc_SOURCE_VPm_field32_set(unit, &svp, TPID_ENABLEf, ena_f);
    843         }
    844         soc_SOURCE_VPm_field32_set(unit, &svp, SD_TAG_MODEf, 1);
    845  
    846         rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 
    847         if (BCM_FAILURE(rv)) {
    848             _bcm_fb2_outer_tpid_entry_delete(unit, tpid_idx);
    849             _bcm_fb2_outer_tpid_tab_unlock(unit);
    850             return (rv);
    851         }
    852     }
    853 
    854     _bcm_fb2_outer_tpid_tab_unlock(unit);
    855     return BCM_E_NONE;
    856 }
    857 
    858 /*
    859  * Function:
    860  *      _bcm_trx_vp_tpid_get
    861  * Description:
    862  *      Get the default Tag Protocol ID for a virtual port.
    863  * Parameters:
    864  *      unit  - Device number
    865  *      vport - Virtual Port identifier
    866  *      tpid  - Tag Protocol ID
    867  * Return Value:
    868  *      BCM_E_XXX
    869  */
    870 int _bcm_trx_vp_tpid_get(int unit, bcm_gport_t vport, uint16 *tpid)
    871 {
    872     int                 tpid_idx, vp, islocal;
    873     uint32              evc;
    874     bcm_port_t          port;
    875     bcm_module_t        modid, mymodid;
    876     bcm_trunk_t         tgid;
    877     source_vp_entry_t   svp;
    878     uint32              ena_f; 
    879 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
    880     int rv;
    881     int vp_lag_vp;
    882 #endif
    883 
    884     BCM_IF_ERROR_RETURN(
    885         _bcm_esw_gport_resolve(unit, vport, &modid, &port, &tgid, &vp));
    886 
    887 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
    888     if (soc_feature(unit, soc_feature_vp_lag)) {
    889         if (tgid != -1) {
    890             rv = _bcm_esw_trunk_tid_to_vp_lag_vp(unit, tgid, &vp_lag_vp);
    891             if (BCM_SUCCESS(rv) &&
    892                 _bcm_vp_used_get(unit, vp_lag_vp, _bcmVpTypeVpLag)) {
    893                 vp = vp_lag_vp;
    894             }
    895         }
    896     }
    897 #endif
    898 
    899     if (-1 == vp) { 
    900         return BCM_E_PORT;
    901     }
    902     if (tgid == -1) {
    903         BCM_IF_ERROR_RETURN( _bcm_esw_modid_is_local(unit, modid, &islocal));
    904         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mymodid));
    905         if (!islocal)  {
    906             if (soc_feature(unit, soc_feature_subtag_coe) ||
    907                 soc_feature(unit, soc_feature_linkphy_coe)) {
    908             #ifdef BCM_KATANA2_SUPPORT
    909                 if (SOC_IS_KATANA2(unit) &&
    910                     (_bcm_kt2_mod_is_coe_mod_check(unit, modid) == BCM_E_NONE)) {
    911                     BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit,
    912                         modid, port, &port));
    913                 } else {
    914                     return BCM_E_PORT;
    915                 }
    916             #endif
    917             }
    918         } else {
    919             while (mymodid < modid) {
    920                 port += 32;
    921                 modid -= 1;
    922             }
    923         }
    924     }
    925 
    926 #if (defined(BCM_TRIDENT_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
    927     && defined(INCLUDE_L3)
    928     if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit))
    929          && (BCM_GPORT_IS_TRILL_PORT(vport))) {
    930         int rv;
    931         rv = bcm_td_trill_tpid_get(unit, vport, &tpid_idx);
    932         if (BCM_FAILURE(rv)) {
    933             return (rv);
    934         }   
    935     } else
    936 #endif
    937     {
    938         if (tgid == -1 && islocal) {
    939             if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
    940                 if (soc_feature(unit, soc_feature_egr_all_profile)) {
    941                     BCM_IF_ERROR_RETURN(
    942                         bcm_esw_port_egr_lport_field_get(
    943                         unit, port, EGR_VLAN_CONTROL_1m,
    944                         OUTER_TPID_INDEXf, (uint32 *)&tpid_idx));
    945                 } else {
    946                     egr_vlan_control_1_entry_t vlan_control;
    947                     SOC_IF_ERROR_RETURN(soc_mem_read(unit, EGR_VLAN_CONTROL_1m,
    948                                          MEM_BLOCK_ANY, port, &vlan_control));
    949                     soc_mem_field_get(unit, EGR_VLAN_CONTROL_1m,
    950                                       (uint32*) &vlan_control, OUTER_TPID_INDEXf,
    951                                       (uint32 *) &tpid_idx);
    952                 }
    953             } else {
    954                 SOC_IF_ERROR_RETURN(READ_EGR_VLAN_CONTROL_1r(unit, port, &evc));
    955                 tpid_idx = soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r,
    956                                       evc, OUTER_TPID_INDEXf);
    957             }
    958         } else {
    959             BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp));
    960 #if defined(BCM_TRIDENT3_SUPPORT)
    961             if (SOC_MEM_IS_VALID(unit, SVP_ATTRS_1m)) {
    962                 uint32 svp_attrs_1[SOC_MAX_MEM_WORDS];
    963                 uint32 tpid_enable = 0;
    964 
    965                 BCM_IF_ERROR_RETURN(READ_SVP_ATTRS_1m(unit,
    966                             MEM_BLOCK_ANY, vp, svp_attrs_1));
    967                 soc_SVP_ATTRS_1m_field_get(unit,
    968                         &svp_attrs_1, TPID_ENABLEf, (uint32 *)&tpid_enable);
    969 
    970                 ena_f = tpid_enable;
    971             } else
    972 #endif
    973             {
    974                 ena_f = soc_SOURCE_VPm_field32_get(unit, &svp, TPID_ENABLEf);
    975             }
    976             tpid_idx = -1;
    977             while (ena_f) {
    978                 tpid_idx++;
    979                 if (ena_f & 1) {
    980                     break;
    981                 }
    982                 ena_f = ena_f >> 1;
    983             }
    984             if (tpid_idx == -1) {
    985                 return BCM_E_NOT_FOUND;
    986             }
    987         }
    988     }
    989     _bcm_fb2_outer_tpid_entry_get(unit, tpid, tpid_idx);
    990 
    991     return (BCM_E_NONE);
    992 }
    993 
    994 
    995 
    996 /*
    997  * Function:
    998  *      _bcm_trx_egr_src_port_outer_tpid_set
    999  * Description:
   1000  *      Enable/Disable  outer tpid on all egress ports 
   1001  * Parameters:
   1002  *      unit - Device number
   1003  *      tpid_index - Tag Protocol ID
   1004  * Return Value:
   1005  *      BCM_E_XXX
   1006  */
   1007 int
   1008 _bcm_trx_egr_src_port_outer_tpid_set(int unit, int tpid_index, int enable)
   1009 {
   1010     uint32      egr_src_port;
   1011     uint32      tpid_enable;
   1012     uint32      new_tpid_enable;
   1013     bcm_port_t  port;
   1014     soc_reg_t   reg;
   1015     soc_pbmp_t  temp_pbmp;
   1016 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   1017     egr_port_1_entry_t  pe;
   1018 #endif
   1019 
   1020     if (SOC_IS_TD_TT(unit) || SOC_IS_HURRICANE(unit) || SOC_IS_TRIUMPH3(unit) 
   1021         || SOC_IS_KATANAX(unit) || SOC_IS_HURRICANE2(unit)) {
   1022         reg = EGR_PORT_1r;
   1023     } else {
   1024         reg = EGR_SRC_PORTr;
   1025     }
   1026 
   1027     BCM_PBMP_CLEAR(temp_pbmp);
   1028     BCM_PBMP_ASSIGN(temp_pbmp, PBMP_E_ALL(unit));
   1029 #ifdef BCM_KATANA2_SUPPORT
   1030     if (soc_feature(unit, soc_feature_linkphy_coe) ||
   1031         soc_feature(unit, soc_feature_subtag_coe)) {
   1032         _bcm_kt2_subport_pbmp_update (unit, &temp_pbmp);
   1033     }
   1034 #endif
   1035 
   1036     PBMP_ITER(temp_pbmp, port) {
   1037 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   1038         if (soc_feature(unit, soc_feature_td2p_style_egr_outer_tpid)) {
   1039             BCM_IF_ERROR_RETURN(READ_EGR_PORT_1m(unit, MEM_BLOCK_ANY,
   1040                         port, &pe));
   1041             tpid_enable = soc_mem_field32_get(unit, EGR_PORT_1m, &pe,
   1042                     OUTER_TPID_ENABLEf);
   1043         } else 
   1044 #endif
   1045         {
   1046             BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &egr_src_port));
   1047             tpid_enable = soc_reg_field_get(unit, reg,
   1048                     egr_src_port, OUTER_TPID_ENABLEf);
   1049         }
   1050 
   1051         if (enable) {
   1052             new_tpid_enable = (tpid_enable | (1 << tpid_index));
   1053         } else {
   1054             new_tpid_enable = (tpid_enable & ~(1 << tpid_index));
   1055         } 
   1056 
   1057         if (new_tpid_enable != tpid_enable) {
   1058 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   1059             if (soc_feature(unit, soc_feature_td2p_style_egr_outer_tpid)) {
   1060                 soc_mem_field32_set(unit, EGR_PORT_1m, &pe, 
   1061                         OUTER_TPID_ENABLEf, new_tpid_enable);
   1062                 BCM_IF_ERROR_RETURN(WRITE_EGR_PORT_1m(unit, 
   1063                             MEM_BLOCK_ANY, port, &pe));
   1064             } else 
   1065 #endif
   1066             {
   1067                 soc_reg_field_set(unit, reg, &egr_src_port,
   1068                         OUTER_TPID_ENABLEf, new_tpid_enable);
   1069                 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, egr_src_port));
   1070             }
   1071         }
   1072     } 
   1073     return (BCM_E_NONE);
   1074 }
   1075 
   1076 /*
   1077  * Function:
   1078  *      _bcm_esw_source_trunk_map_set
   1079  * Description:
   1080  *      Helper funtion to modify fields in SOURCE_TRUNK_MAP memory.
   1081  * Parameters:
   1082  *      unit  - Device number
   1083  *      port  - Port number
   1084  *      field - Field name within SOURCE_TRUNK_MAP table entry
   1085  *      value - new field value
   1086  * Return Value:
   1087  *      BCM_E_XXX 
   1088  */
   1089 int
   1090 _bcm_trx_source_trunk_map_set(int unit, bcm_port_t port, 
   1091                               soc_field_t field, uint32 value)
   1092 {
   1093     bcm_module_t    mod_out;
   1094     bcm_port_t      port_out;
   1095     int index, trunk_id = -1, id = -1;
   1096 
   1097 #if defined BCM_HGPROXY_COE_SUPPORT
   1098     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   1099         BCM_GPORT_IS_SET(port) &&
   1100         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   1101         /* Resolve the port */
   1102         SOC_IF_ERROR_RETURN(
   1103             _bcm_esw_gport_resolve(unit, port, &mod_out, 
   1104                                    &port_out, &trunk_id, &id));
   1105     } else
   1106 #endif
   1107     {
   1108         if (soc_feature(unit, soc_feature_shg_support_remote_port) &&
   1109             BCM_GPORT_IS_SET(port) && (field == CLASS_IDf)) {
   1110             SOC_IF_ERROR_RETURN(
   1111                 _bcm_esw_gport_resolve(unit, port, &mod_out,
   1112                                        &port_out, &trunk_id, &id));
   1113         } else {
   1114             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
   1115             /* Port sanity check. */
   1116             if (SOC_PORT_ADDRESSABLE(unit, port)) {
   1117                 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mod_out));
   1118                 port_out = port;
   1119             } else {
   1120                 return (BCM_E_PORT);
   1121             }
   1122         }
   1123     }
   1124     /* Calculate table index. */
   1125     BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, 
   1126         mod_out, port_out, &index));
   1127 
   1128     return soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm,
   1129                                   index, field, value);
   1130 }
   1131 
   1132 /*
   1133  * Function:
   1134  *      _bcm_esw_source_trunk_map_get
   1135  * Description:
   1136  *      Helper funtion to get fields in SOURCE_TRUNK_MAP memory.
   1137  * Parameters:
   1138  *      unit  - Device number
   1139  *      port  - Port number
   1140  *      field - Field name within SOURCE_TRUNK_MAP table entry
   1141  *      value - New field value
   1142  * Return Value:
   1143  *      BCM_E_XXX 
   1144  */
   1145 int
   1146 _bcm_trx_source_trunk_map_get(int unit, bcm_port_t port, 
   1147                               soc_field_t field, uint32 *value)
   1148 {
   1149     uint32 buf[SOC_MAX_MEM_FIELD_WORDS];
   1150     bcm_module_t    mod_out;
   1151     bcm_port_t      port_out;
   1152     int index, trunk_id = -1, id = -1;
   1153 
   1154     /* Input parameters check */
   1155     if (NULL == value) {
   1156         return (BCM_E_PARAM);
   1157     }
   1158 
   1159     /* Memory field is valid check. */ 
   1160     if (!SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, field)) {
   1161         return (BCM_E_UNAVAIL);
   1162     }
   1163 
   1164 #if defined BCM_HGPROXY_COE_SUPPORT
   1165     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   1166         BCM_GPORT_IS_SET(port) &&
   1167         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   1168         /* Resolve the port */
   1169         SOC_IF_ERROR_RETURN(
   1170             _bcm_esw_gport_resolve(unit, port, &mod_out, 
   1171                                    &port_out, &trunk_id, &id));
   1172     } else
   1173 #endif
   1174     {
   1175         if (soc_feature(unit, soc_feature_shg_support_remote_port) &&
   1176             BCM_GPORT_IS_SET(port) && (field == CLASS_IDf)) {
   1177             SOC_IF_ERROR_RETURN(
   1178                 _bcm_esw_gport_resolve(unit, port, &mod_out,
   1179                                        &port_out, &trunk_id, &id));
   1180         } else {
   1181             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
   1182             /* Port sanity check. */
   1183             if (SOC_PORT_ADDRESSABLE(unit, port)) {
   1184                 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mod_out));
   1185                 port_out = port;
   1186             } else {
   1187                 return (BCM_E_PORT);
   1188             }
   1189         }
   1190     }
   1191 
   1192     
   1193 
   1194     /* Get table index. */
   1195     BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit,
   1196         mod_out, port_out, &index));
   1197 
   1198     if ((index > soc_mem_index_max(unit, SOURCE_TRUNK_MAP_TABLEm)) ||
   1199         (index < soc_mem_index_min(unit, SOURCE_TRUNK_MAP_TABLEm))) {
   1200         return (BCM_E_INTERNAL);
   1201     }
   1202 
   1203     /* Read table entry. */
   1204     BCM_IF_ERROR_RETURN
   1205         (soc_mem_read(unit, SOURCE_TRUNK_MAP_TABLEm, MEM_BLOCK_ANY, index, buf));
   1206 
   1207     /* Read requested field value. */
   1208     *value = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, buf, field);
   1209 
   1210     return (BCM_E_NONE);
   1211 }
   1212 
   1213 /*
   1214  * Function:
   1215  *     _bcm_trx_port_force_vlan_set
   1216  * Description:
   1217  *     To set the force vlan attribute of a port
   1218  * Parameters:
   1219  *     unit        device number
   1220  *     port        port number
   1221  *     vlan        vlan identifier
   1222  *                 (0 - 4095) - use this VLAN id if egress packet is tagged
   1223  *     pkt_prio    egress packet priority (-1, 0..7)
   1224  *                 any negative priority value disable the priority
   1225  *                 override if the egress packet is tagged
   1226  *     flags       bit fields
   1227  *                 BCM_PORT_FORCE_VLAN_ENABLE - enable force vlan on this
   1228  *                                              port
   1229  *                 BCM_PORT_FORCE_VLAN_UNTAG - egress untagged when force
   1230  *                                             vlan is enabled on this port
   1231  *
   1232  * Return:
   1233  *     BCM_E_XXX
   1234  */
   1235 int
   1236 _bcm_trx_port_force_vlan_set(int unit, bcm_port_t port, bcm_vlan_t vlan,
   1237                             int pkt_prio, uint32 flags)
   1238 {
   1239     bcm_port_cfg_t pcfg;
   1240     uint32 reg_val;
   1241 
   1242     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
   1243 
   1244     BCM_IF_ERROR_RETURN(mbcm_driver[unit]->mbcm_port_cfg_get(unit, port,
   1245                                                              &pcfg));
   1246     reg_val = 0;
   1247 
   1248     if (flags & BCM_PORT_FORCE_VLAN_ENABLE) {
   1249         if (!BCM_VLAN_VALID(vlan)) {
   1250             return BCM_E_PARAM;
   1251         }
   1252 
   1253         if (pkt_prio > 7) {
   1254             return BCM_E_PARAM;
   1255         }
   1256 
   1257         pcfg.pc_pvlan_enable = 1;
   1258         soc_reg_field_set(unit, EGR_PVLAN_EPORT_CONTROLr, &reg_val,
   1259                           PVLAN_ENABLEf, 1);
   1260         if (!(flags & BCM_PORT_FORCE_VLAN_UNTAG)) {
   1261             soc_reg_field_set(unit, EGR_PVLAN_EPORT_CONTROLr, &reg_val,
   1262                               PVLAN_PVIDf, vlan);
   1263             if (pkt_prio >= 0) {
   1264                 soc_reg_field_set(unit, EGR_PVLAN_EPORT_CONTROLr, &reg_val,
   1265                                   PVLAN_PRIf, pkt_prio);
   1266                 soc_reg_field_set(unit, EGR_PVLAN_EPORT_CONTROLr, &reg_val,
   1267                                   PVLAN_RPEf, 1);
   1268             }
   1269         } else {
   1270             soc_reg_field_set(unit, EGR_PVLAN_EPORT_CONTROLr, &reg_val,
   1271                               PVLAN_UNTAGf, 1);
   1272         }
   1273     } else {
   1274         pcfg.pc_pvlan_enable = 0;
   1275     }
   1276 
   1277     BCM_IF_ERROR_RETURN(mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg));
   1278     SOC_IF_ERROR_RETURN(WRITE_EGR_PVLAN_EPORT_CONTROLr(unit, port, reg_val));
   1279 
   1280     return BCM_E_NONE;
   1281 }
   1282 
   1283 /*
   1284  * Function:
   1285  *     _bcm_trx_port_force_vlan_get
   1286  * Description:
   1287  *     To get the force vlan attribute of a port
   1288  * Parameters:
   1289  *     unit        device number
   1290  *     port        port number
   1291  *     vlan        pointer to vlan identifier
   1292  *                 (0 - 4095) - use this VLAN id if egress packet is tagged
   1293  *                 valid only when BCM_PORT_FORCE_VLAN_ENABLE is set and
   1294  *                 BCM_PORT_FORCE_VLAN_UNTAG is clear
   1295  *     pkt_prio    egress packet priority (-1, 0 - 7)
   1296  *                 valid only when BCM_PORT_FORCE_VLAN_ENABLE is set and
   1297  *                 BCM_PORT_FORCE_VLAN_UNTAG is clear
   1298  *     flags       bit fields
   1299  *                 BCM_PORT_FORCE_VLAN_ENABLE - enable force vlan on this
   1300  *                                              port
   1301  *                 BCM_PORT_FORCE_VLAN_UNTAG - egress untagged when force
   1302  *                                             vlan is enabled on this port
   1303  *
   1304  * Return:
   1305  *     BCM_E_XXX
   1306  */
   1307 int
   1308 _bcm_trx_port_force_vlan_get(int unit, bcm_port_t port, bcm_vlan_t *vlan,
   1309                             int *pkt_prio, uint32 *flags)
   1310 {
   1311     bcm_port_cfg_t pcfg;
   1312     uint32 reg_val;
   1313 
   1314     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
   1315 
   1316     if (!vlan || !pkt_prio || !flags) {
   1317         return BCM_E_PARAM;
   1318     }
   1319 
   1320     BCM_IF_ERROR_RETURN(mbcm_driver[unit]->mbcm_port_cfg_get(unit, port,
   1321                                                              &pcfg));
   1322     SOC_IF_ERROR_RETURN(READ_EGR_PVLAN_EPORT_CONTROLr(unit, port,
   1323                                                       &reg_val));
   1324 
   1325     *flags = 0;
   1326     if (pcfg.pc_pvlan_enable) {
   1327         *flags |= BCM_PORT_FORCE_VLAN_ENABLE;
   1328         if (!soc_reg_field_get(unit, EGR_PVLAN_EPORT_CONTROLr, reg_val,
   1329                                PVLAN_UNTAGf)) {
   1330             *vlan = soc_reg_field_get(unit, EGR_PVLAN_EPORT_CONTROLr,
   1331                                       reg_val, PVLAN_PVIDf);
   1332             if (soc_reg_field_get(unit, EGR_PVLAN_EPORT_CONTROLr, reg_val,
   1333                                   PVLAN_RPEf)) {
   1334                 *pkt_prio = soc_reg_field_get(unit,
   1335                                               EGR_PVLAN_EPORT_CONTROLr,
   1336                                               reg_val, PVLAN_PRIf);
   1337             } else {
   1338                 *pkt_prio = -1;
   1339             }
   1340         } else {
   1341             *flags |= BCM_PORT_FORCE_VLAN_UNTAG;
   1342         }
   1343     }
   1344 
   1345     return BCM_E_NONE;
   1346 }
   1347 
   1348 /*
   1349  * Function:
   1350  *      _bcm_trx_port_dtag_mode_set
   1351  * Description:
   1352  *      Set the double-tagging mode of a port.
   1353  * Parameters:
   1354  *      unit - Device number
   1355  *      port - Port number
   1356  *      mode - Double-tagging mode, one of:
   1357  *              BCM_PORT_DTAG_MODE_NONE            No double tagging
   1358  *              BCM_PORT_DTAG_MODE_INTERNAL        Service Provider port
   1359  *              BCM_PORT_DTAG_MODE_EXTERNAL        Customer port
   1360  *              BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG  Remove customer tag
   1361  *              BCM_PORT_DTAG_ADD_EXTERNAL_TAG     Add customer tag
   1362  * Return Value:
   1363  *      BCM_E_XXX
   1364  * Notes:
   1365  *      BCM_PORT_DTAG_MODE_INTERNAL is for service provider ports.
   1366  *              A tag will be added if the packet does not already
   1367  *              have the internal TPID (see bcm_port_tpid_set below).
   1368  *              Internally this sets DT_MODE and clears IGNORE_TAG.
   1369  *      BCM_PORT_DTAG_MODE_EXTERNAL is for customer ports.
   1370  *              The service provider TPID will always be added
   1371  *              (see bcm_port_tpid_set below).
   1372  *              Internally this sets DT_MODE and sets IGNORE_TAG.
   1373  */
   1374 
   1375 int
   1376 _bcm_trx_port_dtag_mode_set(int unit, bcm_port_t port, int mode)
   1377 {
   1378     bcm_vlan_action_set_t action;
   1379     _bcm_port_info_t      *pinfo;
   1380     int                   color_mode;
   1381 #if defined(BCM_TRX_SUPPORT)
   1382     int                   prev_mode;
   1383     int                   index;
   1384 #endif    
   1385     int                   rv;
   1386 
   1387     if (!IS_HG_PORT(unit, port)) {
   1388         /* Modify default ingress actions */
   1389         BCM_IF_ERROR_RETURN
   1390             (_bcm_trx_vlan_port_default_action_get(unit, port, &action));
   1391         action.dt_outer      = bcmVlanActionNone;
   1392         action.dt_outer_prio = bcmVlanActionReplace;
   1393         action.dt_inner      = bcmVlanActionNone;
   1394         action.dt_inner_prio = bcmVlanActionNone;
   1395         action.ot_outer      = bcmVlanActionNone;
   1396         action.ot_outer_prio = bcmVlanActionReplace;
   1397         action.ot_inner      = bcmVlanActionNone;
   1398         action.it_outer      = bcmVlanActionAdd;
   1399         action.it_inner      = bcmVlanActionNone;
   1400         action.it_inner_prio = bcmVlanActionNone;
   1401         action.ut_outer      = bcmVlanActionAdd;
   1402         if (mode & BCM_PORT_DTAG_ADD_EXTERNAL_TAG) {
   1403             action.ut_inner = bcmVlanActionAdd;
   1404         } else {
   1405             action.ut_inner = bcmVlanActionNone;
   1406         }
   1407 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
   1408         if (SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
   1409             rv = _bcm_trx_vlan_port_default_action_profile_set(unit, port, &action);
   1410         } else
   1411 #endif
   1412         {
   1413             rv = _bcm_trx_vlan_port_default_action_set(unit, port, &action);
   1414         }
   1415         BCM_IF_ERROR_RETURN(rv);
   1416 
   1417         /* Modify default egress actions */
   1418         rv = _bcm_trx_vlan_port_egress_default_action_get(unit, port, &action);
   1419         BCM_IF_ERROR_RETURN(rv);
   1420 
   1421         action.ot_inner      = bcmVlanActionNone;
   1422         if (mode & BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG) {
   1423             action.dt_inner = bcmVlanActionDelete;
   1424             action.dt_inner_prio = bcmVlanActionDelete;
   1425         } else {
   1426             action.dt_inner = bcmVlanActionNone;
   1427             action.dt_inner_prio = bcmVlanActionNone;
   1428         }
   1429         action.dt_outer      = bcmVlanActionNone;
   1430         action.dt_outer_prio = bcmVlanActionNone;
   1431         action.ot_outer      = bcmVlanActionNone;
   1432         action.ot_outer_prio = bcmVlanActionNone;
   1433         rv = _bcm_trx_vlan_port_egress_default_action_set(unit, port, &action);
   1434         BCM_IF_ERROR_RETURN(rv);
   1435     }
   1436 
   1437     rv = _bcm_port_info_get(unit, port, &pinfo);
   1438     BCM_IF_ERROR_RETURN(rv);
   1439 
   1440 #if defined(BCM_TRX_SUPPORT)
   1441     prev_mode = pinfo->dtag_mode;
   1442 #endif    
   1443     pinfo->dtag_mode = mode;
   1444     mode &= BCM_PORT_DTAG_MODE_INTERNAL | BCM_PORT_DTAG_MODE_EXTERNAL;
   1445 
   1446 #if defined(BCM_TRX_SUPPORT)
   1447     /* return if previous mode and current mode are same */
   1448     if(prev_mode & mode) {
   1449         return  BCM_E_NONE;
   1450     }
   1451 #endif
   1452     if (mode == BCM_PORT_DTAG_MODE_NONE) {
   1453         /* Set the default outer TPID. */
   1454         rv = bcm_esw_port_tpid_set(unit, port, 
   1455                                    _bcm_fb2_outer_tpid_default_get(unit));
   1456         BCM_IF_ERROR_RETURN(rv);
   1457     } else if (mode == BCM_PORT_DTAG_MODE_INTERNAL) {
   1458         /* Add the default outer TPID. */
   1459         rv = bcm_esw_switch_control_port_get(unit, port, 
   1460                                              bcmSwitchColorSelect, &color_mode);
   1461         BCM_IF_ERROR_RETURN(rv);
   1462 
   1463         rv = bcm_esw_port_tpid_add(unit, port, _bcm_fb2_outer_tpid_default_get(unit),
   1464                                    color_mode);
   1465         BCM_IF_ERROR_RETURN(rv);
   1466 
   1467     } else if (mode == BCM_PORT_DTAG_MODE_EXTERNAL) {
   1468         /* Disable all outer TPIDs. */
   1469         BCM_IF_ERROR_RETURN (bcm_esw_port_tpid_delete_all(unit, port));
   1470     }
   1471 #if defined(BCM_TRX_SUPPORT)
   1472     /*  Increase the ref count of the default tpid if the mode
   1473      *  is changing to internal/none from external */
   1474     if (prev_mode & BCM_PORT_DTAG_MODE_EXTERNAL) { 
   1475           rv = _bcm_fb2_outer_tpid_lkup(unit, _bcm_fb2_outer_tpid_default_get(unit),
   1476                                         &index);
   1477           BCM_IF_ERROR_RETURN(rv);
   1478         
   1479           rv = _bcm_fb2_outer_tpid_tab_ref_count_add(unit, index, 1);
   1480           BCM_IF_ERROR_RETURN(rv);
   1481     }
   1482 #endif    
   1483     return BCM_E_NONE;
   1484 }
   1485 
   1486 /*
   1487  * Function:
   1488  *      _bcm_trx_port_control_egress_class_select_set
   1489  * Description:
   1490  *      Helper funtion to modify fields in FP_I2E_CLASSID_SELECT/IFP_I2E_CLASSID_SELECTm memory.
   1491  * Parameters:
   1492  *      unit  - (IN) Device number
   1493  *      port  - (IN) Port number
   1494  *      value - (IN) new field value
   1495  * Return Value:
   1496  *      BCM_E_XXX 
   1497  */
   1498 int
   1499 _bcm_trx_port_control_egress_class_select_set(int unit, bcm_port_t port, 
   1500                                               uint32 value)
   1501 {
   1502     int rv = BCM_E_NONE;
   1503     soc_mem_t mem;
   1504 
   1505     if (SOC_MEM_IS_VALID(unit, FP_I2E_CLASSID_SELECTm)) {
   1506         mem = FP_I2E_CLASSID_SELECTm;
   1507     }
   1508     else if (SOC_MEM_IS_VALID(unit, IFP_I2E_CLASSID_SELECTm)) {
   1509         /* For TOMAHAWK IFP_I2E_CLASSID_SELECTm is used */
   1510         mem = IFP_I2E_CLASSID_SELECTm;
   1511     }
   1512     else {
   1513         return SOC_E_UNAVAIL;
   1514     }
   1515 
   1516     /* Check for valid input for I2E_CLASSID_SELECT*/
   1517     /* coverity[unsigned_compare] : FALSE */
   1518     if ((value < bcmPortEgressClassSelectNone) ||
   1519         (value >= bcmPortEgressClassSelectCount)) {
   1520         return (BCM_E_PARAM);
   1521     }
   1522 
   1523     switch (value) {
   1524        case bcmPortEgressClassSelectFieldIngress:
   1525 #if defined(BCM_TRIDENT2_SUPPORT)
   1526             if (SOC_IS_TRIDENT2(unit)) {
   1527                value = 0xf;  /* IFD_CLASS_ID bit */
   1528             } else  
   1529 #endif /* BCM_TRIDENT2_SUPPORT */
   1530                return BCM_E_UNAVAIL;
   1531             break;
   1532        default:
   1533             break;
   1534     } 
   1535 
   1536     /* Port sanity check. */
   1537     if (!SOC_PORT_ADDRESSABLE(unit, port)) {
   1538         return (BCM_E_PORT);
   1539     }
   1540 
   1541 #ifdef BCM_TRIDENT3_SUPPORT
   1542     /* In TD3, IFP_I2E_CLASSID_SELECT is indexed by    *
   1543      * LPORT_PROFILE_TABLE.MISC_PORT_PROFILE_INDEX.    *
   1544      *                                                 *
   1545      * The LPORT_PROFILE_TABLE is indexed from the     *
   1546      * SOURCE_TRUNK_MAP_TABLE Lport_profile_idx field. */
   1547      
   1548     if (SOC_IS_TRIDENT3X(unit) && (mem == IFP_I2E_CLASSID_SELECTm)) {
   1549         int src_index;
   1550         uint32 src_ent[SOC_MAX_MEM_FIELD_WORDS];
   1551         int src_tbl_is_stm = 1;
   1552         soc_mem_t src_mem = SOURCE_TRUNK_MAP_TABLEm;
   1553 
   1554         lport_tab_entry_t lport_entry;
   1555         uint32 lport_index = 0;
   1556 
   1557         BCM_IF_ERROR_RETURN
   1558             (bcm_esw_port_lport_prof_src_check(unit, _BCM_ESW_PT_PORT,
   1559             &src_tbl_is_stm));
   1560 
   1561         if (src_tbl_is_stm) {
   1562             int modid = 0;
   1563             BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &modid));
   1564             BCM_IF_ERROR_RETURN
   1565                 (_bcm_esw_src_mod_port_table_index_get(unit, modid, port,
   1566                                                        &src_index));
   1567         } else {
   1568             src_mem = ING_DEVICE_PORTm;
   1569             src_index = port;
   1570         }
   1571 
   1572         BCM_IF_ERROR_RETURN
   1573             (soc_mem_read(unit, src_mem, MEM_BLOCK_ANY, src_index, src_ent));
   1574         lport_index = soc_mem_field32_get(unit, src_mem,
   1575                                           src_ent, LPORT_PROFILE_IDXf);
   1576 
   1577         BCM_IF_ERROR_RETURN(READ_LPORT_TABm(unit, MEM_BLOCK_ANY, 
   1578                                        lport_index, &lport_entry));
   1579 
   1580         soc_LPORT_TABm_field32_set(unit, &lport_entry, 
   1581                        MISC_PORT_PROFILE_INDEXf, port);
   1582 
   1583         BCM_IF_ERROR_RETURN(WRITE_LPORT_TABm(unit, MEM_BLOCK_ANY, 
   1584                                      lport_index, &lport_entry));
   1585     }
   1586 #endif /* BCM_TRIDENT3_SUPPORT */
   1587 
   1588     /* Memory field is valid check. */
   1589     if (!SOC_MEM_FIELD_VALID(unit, mem, PORT_SELf)) {
   1590         return (BCM_E_UNAVAIL);
   1591     }
   1592 
   1593     rv = soc_mem_field32_modify(unit, mem, port, PORT_SELf, value);
   1594 
   1595     return rv;
   1596 }
   1597 
   1598 /*
   1599  * Function:
   1600  *      _bcm_trx_port_control_egress_class_select_get
   1601  * Description:
   1602  *      Helper funtion to get fields in FP_I2E_CLASSID_SELECT/IFP_I2E_CLASSID_SELECTm memory.
   1603  * Parameters:
   1604  *      unit  - (IN) Device number
   1605  *      port  - (IN) Port number
   1606  *      value - (OUT) New field value
   1607  * Return Value:
   1608  *      BCM_E_XXX 
   1609  */
   1610 int
   1611 _bcm_trx_port_control_egress_class_select_get(int unit, bcm_port_t port, 
   1612                                               uint32 *value)
   1613 {
   1614     fp_i2e_classid_select_entry_t fp_ent;
   1615     ifp_i2e_classid_select_entry_t ifp_ent;
   1616     soc_mem_t mem;
   1617     void *ptr_ent;
   1618 
   1619     if (SOC_MEM_IS_VALID(unit, FP_I2E_CLASSID_SELECTm)) {
   1620         mem = FP_I2E_CLASSID_SELECTm;
   1621         ptr_ent = (void*) &fp_ent;
   1622     }
   1623     else if (SOC_MEM_IS_VALID(unit, IFP_I2E_CLASSID_SELECTm)) {
   1624         /* For TOMAHAWK IFP_I2E_CLASSID_SELECTm is used */
   1625         mem = IFP_I2E_CLASSID_SELECTm;
   1626         ptr_ent = (void*) &ifp_ent;
   1627     }
   1628     else {
   1629         return SOC_E_UNAVAIL;
   1630     }
   1631 
   1632     /* Memory field is valid check. */
   1633     if (!SOC_MEM_FIELD_VALID(unit, mem, PORT_SELf)) {
   1634         return (BCM_E_UNAVAIL);
   1635     }
   1636 
   1637     /* Port sanity check. */
   1638     if (!SOC_PORT_ADDRESSABLE(unit, port)) {
   1639         return (BCM_E_PORT);
   1640     }
   1641 
   1642     /* Read table entry. */
   1643     BCM_IF_ERROR_RETURN
   1644         (soc_mem_read(unit, mem, MEM_BLOCK_ANY, port, ptr_ent));
   1645 
   1646     /* Read requested field value. */
   1647     *value = soc_mem_field32_get(unit, mem, ptr_ent, PORT_SELf);
   1648     return BCM_E_NONE;
   1649 
   1650 }
   1651 
   1652 /*
   1653  * Function:
   1654  *      _bcm_trx_port_control_higig_class_select_set
   1655  * Description:
   1656  *      Helper funtion to modify fields in FP_HG_CLASSID_SELECT memory.
   1657  * Parameters:
   1658  *      unit  - (IN) Device number
   1659  *      port  - (IN) Port number
   1660  *      value - (IN) new field value
   1661  * Return Value:
   1662  *      BCM_E_XXX
   1663  */
   1664 int
   1665 _bcm_trx_port_control_higig_class_select_set(int unit, bcm_port_t port,
   1666                                               uint32 value)
   1667 {
   1668     int rv = BCM_E_NONE;
   1669     soc_mem_t mem;
   1670 
   1671     /* Check for valid input for I2E_CLASSID_SELECT*/
   1672     /* coverity[unsigned_compare] : FALSE */
   1673     if ((value < bcmPortFieldHiGigClassSelectNone) ||
   1674         (value >= bcmPortFieldHiGigClassSelectCount)) {
   1675         return (BCM_E_PARAM);
   1676     }
   1677 
   1678     /* Value 2 and 3 are reserved for TD2/TD2+/TH/APACHE chips*/
   1679 #if defined(BCM_TRIDENT2_SUPPORT)
   1680     if (SOC_IS_TD2_TT2(unit)) {
   1681         if ((value == bcmPortFieldHiGigClassSelectL3Egress) ||
   1682             (value == bcmPortFieldHiGigClassSelectL3EgressIntf)) {
   1683             return (BCM_E_PARAM);
   1684         }
   1685     }
   1686 #endif
   1687 
   1688     if (SOC_IS_TOMAHAWKX(unit)) {
   1689         mem = IFP_HG_CLASSID_SELECTm;
   1690     } else {
   1691         mem = FP_HG_CLASSID_SELECTm;
   1692     }
   1693 
   1694     /* Memory field is valid check. */
   1695     if (!SOC_MEM_FIELD_VALID(unit, mem, PORT_SELf)) {
   1696         return (BCM_E_UNAVAIL);
   1697     }
   1698 
   1699     /* Port sanity check. */
   1700     if (!SOC_PORT_ADDRESSABLE(unit, port)) {
   1701         return (BCM_E_PORT);
   1702     }
   1703 
   1704     rv = soc_mem_field32_modify(unit, mem, port, PORT_SELf, value);
   1705 
   1706     return rv;
   1707 }
   1708 
   1709 /*
   1710  * Function:
   1711  *      _bcm_trx_port_control_higig_class_select_get
   1712  * Description:
   1713  *      Helper funtion to get fields in FP_HG_CLASSID_SELECT memory.
   1714  * Parameters:
   1715  *      unit  - (IN) Device number
   1716  *      port  - (IN) Port number
   1717  *      value - (OUT) New field value
   1718  * Return Value:
   1719  *      BCM_E_XXX
   1720  */
   1721 int
   1722 _bcm_trx_port_control_higig_class_select_get(int unit, bcm_port_t port, 
   1723                                               uint32 *value)
   1724 {
   1725     soc_mem_t mem;
   1726 
   1727 #if defined(BCM_TOMAHAWK_SUPPORT)
   1728     if (SOC_IS_TOMAHAWKX(unit)) {
   1729         ifp_hg_classid_select_entry_t ent;
   1730         mem = IFP_HG_CLASSID_SELECTm;
   1731 
   1732         /* Memory field is valid check. */
   1733         if (!SOC_MEM_FIELD_VALID(unit, mem, PORT_SELf)) {
   1734             return (BCM_E_UNAVAIL);
   1735         }
   1736 
   1737         /* Port sanity check. */
   1738         if (!SOC_PORT_ADDRESSABLE(unit, port)) {
   1739             return (BCM_E_PORT);
   1740         }
   1741 
   1742         /* Read table entry. */
   1743         BCM_IF_ERROR_RETURN
   1744             (soc_mem_read(unit, mem, MEM_BLOCK_ANY, port, &ent));
   1745 
   1746         /* Read requested field value. */
   1747         *value = soc_mem_field32_get(unit, mem, &ent, PORT_SELf);
   1748     } else 
   1749 #endif
   1750     {
   1751         fp_hg_classid_select_entry_t ent;
   1752         mem = FP_HG_CLASSID_SELECTm;
   1753 
   1754         /* Memory field is valid check. */
   1755         if (!SOC_MEM_FIELD_VALID(unit, mem, PORT_SELf)) {
   1756             return (BCM_E_UNAVAIL);
   1757         }
   1758 
   1759         /* Port sanity check. */
   1760         if (!SOC_PORT_ADDRESSABLE(unit, port)) {
   1761             return (BCM_E_PORT);
   1762         }
   1763 
   1764         /* Read table entry. */
   1765         BCM_IF_ERROR_RETURN
   1766             (soc_mem_read(unit, mem, MEM_BLOCK_ANY, port, &ent));
   1767 
   1768         /* Read requested field value. */
   1769         *value = soc_mem_field32_get(unit, mem, &ent, PORT_SELf);
   1770     }
   1771 
   1772     return BCM_E_NONE;
   1773 }
   1774 
   1775 /*
   1776  * Function:
   1777  *      bcm_trx_source_trunk_map_lport_all_set
   1778  * Purpose:
   1779  *      Set the LPORT profile index reference for all entries
   1780  *      in the Source Trunk Map Table.
   1781  *      Helper routine.
   1782  * Parameters:
   1783  *      unit             - (IN) Device number
   1784  *      lport_index      - (IN) LPORT Index
   1785  *      stm_num_entries  - (OUT) Returns number of entries in table
   1786  * Returns:
   1787  *      BCM_E_XXX
   1788  */
   1789 STATIC int
   1790 bcm_trx_source_table_lport_all_set(int unit, uint32 lport_index,
   1791                                    int *src_num_entries)
   1792 {
   1793     int rv = BCM_E_NONE;
   1794     int i, m;
   1795 #if defined(BCM_TOMAHAWK3_SUPPORT)
   1796     int pipe;
   1797     soc_info_t *si;
   1798     source_trunk_map_table_entry_t stm_ent;
   1799     int stm_entry_per_pipe;
   1800 #endif 
   1801     soc_mem_t src_mem[2] = {SOURCE_TRUNK_MAP_TABLEm, INVALIDm};
   1802     uint32 *src_entry;
   1803     int index_min, index_max;
   1804     uint32 *stm_buf;
   1805 
   1806 #ifdef BCM_TOMAHAWK3_SUPPORT
   1807     /* This code is added to support the non-contiguous pipes (0, 1, 6,7 half chip or
   1808        bond option 0, 1, 4, 5) in TH3. Since this memory is addr_split in TH3, we cannot
   1809        use mem_read/write_range as only certain blocks of entries are valid. With this
   1810        check of checking if the pipe is active we make sure that only the entries which
   1811        are valid are accessed
   1812     */
   1813     if (SOC_IS_TOMAHAWK3(unit)) {
   1814         
   1815         si = &SOC_INFO(unit);
   1816         index_min = soc_mem_index_min(unit, src_mem[0]);
   1817         index_max = soc_mem_index_max(unit, src_mem[0]);
   1818         *src_num_entries = index_max - index_min + 1;
   1819         stm_entry_per_pipe = *src_num_entries / _TH3_PIPES_PER_DEV;
   1820         for (i = 0; i < *src_num_entries; i++) {
   1821             pipe = i / stm_entry_per_pipe;
   1822             if (SOC_PBMP_IS_NULL(si->pipe_pbm[pipe])) {
   1823                 continue;
   1824             }
   1825             SOC_IF_ERROR_RETURN(
   1826                 READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY,
   1827                                        i, &stm_ent));
   1828 
   1829             soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_ent,
   1830                                                LPORT_PROFILE_IDXf,
   1831                                                lport_index);
   1832 
   1833             SOC_IF_ERROR_RETURN(WRITE_SOURCE_TRUNK_MAP_TABLEm(unit,MEM_BLOCK_ALL,
   1834                                                i, &stm_ent));
   1835         }
   1836         return BCM_E_NONE;
   1837     }
   1838     else
   1839 #endif
   1840     {
   1841         if (soc_mem_is_valid(unit, ING_DEVICE_PORTm)) {
   1842             src_mem[1] = ING_DEVICE_PORTm;
   1843         }
   1844 
   1845         for (m = 0; m < 2; m++) {
   1846             if (src_mem[m] == INVALIDm) {
   1847                 continue;
   1848             }
   1849 
   1850             index_min = soc_mem_index_min(unit, src_mem[m]);
   1851             index_max = soc_mem_index_max(unit, src_mem[m]);
   1852             *src_num_entries = index_max - index_min + 1;
   1853             stm_buf = soc_cm_salloc(unit,
   1854                                     (*src_num_entries) *
   1855                                     (WORDS2BYTES(soc_mem_entry_words(unit, src_mem[m]))),
   1856                                     "Source Trunk Map table buffer");
   1857             if (stm_buf == NULL) {
   1858                 return BCM_E_MEMORY;
   1859             }
   1860 
   1861             soc_mem_lock(unit, src_mem[m]);
   1862             rv = soc_mem_read_range(unit, src_mem[m], MEM_BLOCK_ANY,
   1863                                     index_min, index_max,
   1864                                     stm_buf);
   1865             if (SOC_SUCCESS(rv)) {
   1866                 for (i = 0; i < *src_num_entries; i++) {
   1867                     src_entry =
   1868                         soc_mem_table_idx_to_pointer(unit, src_mem[m], void *, stm_buf, i);
   1869                     soc_mem_field32_set(unit, src_mem[m], src_entry, LPORT_PROFILE_IDXf,
   1870                                         lport_index);
   1871                 }
   1872                 rv = soc_mem_write_range(unit, src_mem[m], MEM_BLOCK_ANY,
   1873                                         index_min, index_max,
   1874                                          stm_buf);
   1875             }
   1876 
   1877             soc_mem_unlock(unit, src_mem[m]);
   1878             soc_cm_sfree(unit, stm_buf);
   1879 
   1880             if (BCM_FAILURE(rv)) {
   1881                 break;
   1882             }
   1883         }
   1884 
   1885     }
   1886     return rv;
   1887 }
   1888 
   1889 /*
   1890  * Function:
   1891  *      _bcm_trx_lport_tab_default_entry_index_get
   1892  * Purpose:
   1893  *      Return the default LPORT profile entry index.
   1894  * Parameters:
   1895  *      unit  - (IN) Device number
   1896  * Returns:
   1897  *      Default LPORT profile entry index.
   1898  */
   1899 int
   1900 _bcm_trx_lport_tab_default_entry_index_get(int unit)
   1901 {
   1902     return soc_mem_index_min(unit, LPORT_TABm);
   1903 }
   1904 
   1905 /*
   1906  * Function:
   1907  *      _bcm_trx_egr_lport_tab_default_entry_index_get
   1908  * Purpose:
   1909  *      Return the default LPORT profile entry index.
   1910  * Parameters:
   1911  *      unit  - (IN) Device number
   1912  * Returns:
   1913  *      Default LPORT profile entry index.
   1914  */
   1915 int
   1916 _bcm_trx_egr_lport_tab_default_entry_index_get(int unit)
   1917 {
   1918     return soc_mem_index_min(unit, EGR_LPORT_PROFILEm);
   1919 }
   1920 
   1921 /*
   1922  * Function:
   1923  *      _bcm_trx_rtag7_tab_default_entry_index_get
   1924  * Purpose:
   1925  *      Return the default RTAG7 profile entry index.
   1926  * Parameters:
   1927  *      unit  - (IN) Device number
   1928  * Returns:
   1929  *      Default LPORT profile entry index.
   1930  */
   1931 int
   1932 _bcm_trx_rtag7_tab_default_entry_index_get(int unit)
   1933 {
   1934     return soc_mem_index_min(unit, RTAG7_PORT_BASED_HASHm);
   1935 }
   1936 
   1937 /*
   1938  * Function:
   1939  *      _bcm_trx_lport_tab_default_entry_add
   1940  * Purpose:
   1941  *      Internal function for initializing common resource management
   1942  *      Shared by Virtual-port based  modules
   1943  * Parameters:
   1944  *      unit    -  (IN) Device number.
   1945  *      prof    -  (IN) LPORT memory profile. 
   1946  * Returns:
   1947  *      BCM_X_XXX
   1948  */
   1949 int 
   1950 _bcm_trx_lport_tab_default_entry_add(int unit, soc_profile_mem_t *prof) 
   1951 {
   1952     int rv = BCM_E_NONE;
   1953     soc_info_t *si;
   1954     lport_tab_entry_t lport_entry;
   1955     rtag7_port_based_hash_entry_t rtag7_entry;
   1956     uint32 lport_index;
   1957     void *entries[2];
   1958     bcm_module_t my_modid=0;
   1959     int stab_num_entries = 0;
   1960     int i;
   1961 #ifdef BCM_TOMAHAWK3_SUPPORT
   1962     int entries_per_pipe;
   1963 #endif
   1964 
   1965     /* Input parameters check. */
   1966     if (NULL == prof) {
   1967         return (BCM_E_PARAM);
   1968     }
   1969 
   1970     si = &SOC_INFO(unit);
   1971 
   1972     sal_memcpy(&lport_entry, soc_mem_entry_null(unit, LPORT_TABm),
   1973                soc_mem_entry_words(unit, LPORT_TABm) * sizeof(uint32)); 
   1974 
   1975     if (SOC_MEM_IS_VALID(unit, RTAG7_PORT_BASED_HASHm)) {
   1976         sal_memcpy(&rtag7_entry,
   1977                    soc_mem_entry_null(unit, RTAG7_PORT_BASED_HASHm),
   1978                    soc_mem_entry_words(unit, RTAG7_PORT_BASED_HASHm) *
   1979                    sizeof(uint32));
   1980     }
   1981 
   1982     /* Create a default LPORT profile entry */
   1983     rv = bcm_esw_stk_my_modid_get(unit, &my_modid);
   1984     if (rv < 0) {
   1985         return rv;
   1986     }
   1987 
   1988     /* Enable IFP. */
   1989     soc_LPORT_TABm_field32_set(unit, &lport_entry, FILTER_ENABLEf, 1);
   1990 
   1991     /* Enable VFP. */
   1992     if (!(SOC_IS_HURRICANE(unit) || SOC_IS_HURRICANE2(unit))) {
   1993         soc_LPORT_TABm_field32_set(unit, &lport_entry, VFP_ENABLEf, 1);
   1994     }
   1995 
   1996     /* Set port filed select index to PFS index max - 1. */
   1997     if(SOC_MEM_FIELD_VALID(unit, LPORT_TABm, FP_PORT_FIELD_SEL_INDEXf)) {
   1998         soc_LPORT_TABm_field32_set(unit, &lport_entry, FP_PORT_FIELD_SEL_INDEXf,
   1999                                    (soc_mem_index_max(unit, FP_PORT_FIELD_SELm)
   2000                                     - 1));
   2001     }
   2002 
   2003     /* Enable MPLS */
   2004     if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, MPLS_ENABLEf)) {
   2005          soc_LPORT_TABm_field32_set(unit, &lport_entry, MPLS_ENABLEf, 1);
   2006     }
   2007 
   2008     /* Enable TRILL */
   2009     if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, TRILL_ENABLEf)) {
   2010          soc_LPORT_TABm_field32_set(unit, &lport_entry, TRILL_ENABLEf, 1);
   2011     }
   2012     if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, ALLOW_TRILL_FRAMESf)) {
   2013          soc_LPORT_TABm_field32_set(unit, &lport_entry, ALLOW_TRILL_FRAMESf, 1);
   2014     }
   2015     if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, ALLOW_NON_TRILL_FRAMESf)) {
   2016          soc_LPORT_TABm_field32_set(unit, &lport_entry,
   2017                                     ALLOW_NON_TRILL_FRAMESf, 1);
   2018     }
   2019     if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, COPY_CORE_IS_IS_TO_CPUf)) {
   2020          soc_LPORT_TABm_field32_set(unit, &lport_entry,
   2021                                     COPY_CORE_IS_IS_TO_CPUf, 1);
   2022     }
   2023     if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, RTAG7_HASH_CFG_SEL_TRILL_ECMPf)) {
   2024          soc_LPORT_TABm_field32_set(unit, &lport_entry,
   2025                                     RTAG7_HASH_CFG_SEL_TRILL_ECMPf, 1);
   2026     }
   2027 
   2028     /* Enable OAM */
   2029     if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, OAM_ENABLEf)) {
   2030          soc_LPORT_TABm_field32_set(unit, &lport_entry, OAM_ENABLEf, 1);
   2031     }
   2032 
   2033     /* Enable MIM */
   2034     if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, MIM_TERM_ENABLEf)) {
   2035          soc_LPORT_TABm_field32_set(unit, &lport_entry, MIM_TERM_ENABLEf, 1);
   2036     }
   2037     if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, MIM_MC_TERM_ENABLEf)) {
   2038         soc_LPORT_TABm_field32_set(unit, &lport_entry, MIM_MC_TERM_ENABLEf, 1);
   2039     } 
   2040     if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, SRC_SYS_PORT_IDf)) {
   2041         soc_LPORT_TABm_field32_set(unit, &lport_entry, SRC_SYS_PORT_IDf,
   2042                                    si->lb_port);
   2043     }
   2044 
   2045     if(SOC_MEM_FIELD_VALID(unit, LPORT_TABm, MY_MODIDf)) {
   2046         soc_LPORT_TABm_field32_set(unit, &lport_entry, MY_MODIDf, my_modid);
   2047     }
   2048 
   2049 #ifdef BCM_MONTEREY_SUPPORT
   2050     if (SOC_IS_MONTEREY(unit) && soc_feature(unit, soc_feature_xflow_macsec)) {
   2051         if(SOC_MEM_FIELD_VALID(unit, LPORT_TABm, PORT_VIDf)) {
   2052             soc_LPORT_TABm_field32_set(unit, &lport_entry, PORT_VIDf,
   2053                                        BCM_VLAN_DEFAULT);
   2054             if(SOC_MEM_FIELD_VALID(unit, LPORT_TABm, OUTER_TPID_ENABLEf)) {
   2055                 soc_LPORT_TABm_field32_set(unit, &lport_entry,
   2056                                            OUTER_TPID_ENABLEf, 1);
   2057             }
   2058         }
   2059     }
   2060 #endif
   2061 
   2062     /* Add LPORT default entry */
   2063     entries[0] = &lport_entry; 
   2064     entries[1] = &rtag7_entry;
   2065 
   2066     /* Note that when 'soc_feature_separate_ing_lport_rtag7_profile' is TRUE
   2067        we only set the LPORT index and not RTAG7, but this one call will suffice
   2068        since the entries[0] will point to 'lport' entry, the entries[1] which
   2069        points to RTAG7 will only be used in the case when the mentioned
   2070        feature is FALSE, wherein the 'prof' passed in would be acting on an
   2071        older profiling scheme */
   2072 
   2073     /* Tomahawk 3 made this memory on a per pipe unique, so we're going to add
   2074      * a default entry into index 0 of each pipe
   2075      */
   2076 #ifdef BCM_TOMAHAWK3_SUPPORT
   2077     if (SOC_IS_TOMAHAWK3(unit) && SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) {
   2078         for (i = 0; i < _TH3_PIPES_PER_DEV; i++) {
   2079             rv = soc_profile_mem_add_unique(unit, prof, entries, 1, i, &lport_index);
   2080         }
   2081     } else
   2082 #endif
   2083     {
   2084         rv = soc_profile_mem_add(unit, prof, entries, 1, &lport_index);
   2085     }
   2086 
   2087     if (lport_index != _bcm_trx_lport_tab_default_entry_index_get(unit)) {
   2088         /* Something went horribly wrong. */
   2089         return (BCM_E_INTERNAL);
   2090     }
   2091 
   2092     /* Update all entries in SOURCE_TRUNK_MAP to use LPORT default entry */
   2093     BCM_IF_ERROR_RETURN
   2094         (bcm_trx_source_table_lport_all_set(unit, lport_index,
   2095                                             &stab_num_entries));
   2096 
   2097     /* Update reference count (keep 1 extra count) */
   2098     for (i = 0; i < stab_num_entries; i++) {
   2099         if (soc_feature(unit, soc_feature_separate_ing_lport_rtag7_profile)) {
   2100             BCM_IF_ERROR_RETURN
   2101                 (_bcm_lport_ind_profile_mem_reference(unit, lport_index, 1));
   2102         } else {
   2103 #ifdef BCM_TOMAHAWK3_SUPPORT
   2104             /* This adds a reference count to the first index of the per pipe
   2105              * memory:
   2106              * example:
   2107              * LPORT_TAB_PIPE0 index 0's ref_count == 21
   2108              * LPORT_TAB_PIPE1 index 0's ref_count == 21
   2109              */
   2110             if (SOC_IS_TOMAHAWK3(unit) && SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) {
   2111                 /* Fetches the # of entries per pipe.  This is so that
   2112                  * the function call below will increase the ref_count on a per
   2113                  * pipe basis
   2114                  */
   2115                 entries_per_pipe = SOC_MEM_SIZE(unit, LPORT_TABm);
   2116                 BCM_IF_ERROR_RETURN
   2117                     (_bcm_lport_profile_mem_reference_unique(
   2118                                     unit, lport_index, 1, i/entries_per_pipe));
   2119             } else
   2120 #endif
   2121             {
   2122                 BCM_IF_ERROR_RETURN
   2123                     (_bcm_lport_profile_mem_reference(unit, lport_index, 1));
   2124             }
   2125         }
   2126     }
   2127 
   2128     return rv;
   2129 }
   2130 
   2131 /*
   2132  * Function:
   2133  *      _bcm_trx_egr_lport_tab_default_entry_add
   2134  * Purpose:
   2135  *      Internal function for initializing common resource management
   2136  *      Shared by Virtual-port based  modules
   2137  * Parameters:
   2138  *      unit    -  (IN) Device number.
   2139  *      prof    -  (IN) LPORT memory profile. 
   2140  * Returns:
   2141  *      BCM_X_XXX
   2142  */
   2143 int 
   2144 _bcm_trx_egr_lport_tab_default_entry_add(int unit, soc_profile_mem_t *prof) 
   2145 {
   2146     int rv = BCM_E_NONE;
   2147     int index = 0;
   2148     uint32 egr_lport_index;
   2149     void *entries[9];
   2150     egr_lport_profile_entry_t    egr_lport_profile_entry;
   2151     egr_vlan_control_1_entry_t   egr_vlan_control_1_entry;
   2152     egr_vlan_control_2_entry_t   egr_vlan_control_2_entry;
   2153     egr_vlan_control_3_entry_t   egr_vlan_control_3_entry;
   2154     egr_ipmc_cfg2_entry_t        egr_ipmc_cfg2_entry;
   2155     egr_mtu_entry_t                egr_mtu_entry;
   2156     egr_port_1_entry_t            egr_port_1_entry;
   2157     egr_counter_control_entry_t  egr_counter_control_entry;
   2158     egr_shaping_control_entry_t  egr_shaping_control_entry;
   2159 
   2160     /* Input parameters check. */
   2161     if (NULL == prof) {
   2162         return (BCM_E_PARAM);
   2163     }
   2164 
   2165     if (SOC_MEM_IS_VALID(unit, EGR_LPORT_PROFILEm)) {
   2166         sal_memcpy(&egr_lport_profile_entry,
   2167                    soc_mem_entry_null(unit, EGR_LPORT_PROFILEm),
   2168                    soc_mem_entry_words(unit, EGR_LPORT_PROFILEm) *
   2169                    sizeof(uint32));
   2170         entries[index++] = &egr_lport_profile_entry;
   2171     }
   2172 
   2173     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_1m)) {
   2174         sal_memcpy(&egr_vlan_control_1_entry,
   2175                    soc_mem_entry_null(unit, EGR_VLAN_CONTROL_1m),
   2176                    soc_mem_entry_words(unit, EGR_VLAN_CONTROL_1m) *
   2177                    sizeof(uint32));
   2178         entries[index++] = &egr_vlan_control_1_entry;
   2179     }
   2180 
   2181     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_2m)) {
   2182         sal_memcpy(&egr_vlan_control_2_entry,
   2183                    soc_mem_entry_null(unit, EGR_VLAN_CONTROL_2m),
   2184                    soc_mem_entry_words(unit, EGR_VLAN_CONTROL_2m) *
   2185                    sizeof(uint32));
   2186         entries[index++] = &egr_vlan_control_2_entry;
   2187     }
   2188 
   2189     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_3m)) {
   2190         sal_memcpy(&egr_vlan_control_3_entry,
   2191                    soc_mem_entry_null(unit, EGR_VLAN_CONTROL_3m),
   2192                    soc_mem_entry_words(unit, EGR_VLAN_CONTROL_3m) *
   2193                    sizeof(uint32));
   2194         entries[index++] = &egr_vlan_control_3_entry;
   2195     }
   2196 
   2197     if (SOC_MEM_IS_VALID(unit, EGR_IPMC_CFG2m)) {
   2198         sal_memcpy(&egr_ipmc_cfg2_entry,
   2199                    soc_mem_entry_null(unit, EGR_IPMC_CFG2m),
   2200                    soc_mem_entry_words(unit, EGR_IPMC_CFG2m) *
   2201                    sizeof(uint32));
   2202         entries[index++] = &egr_ipmc_cfg2_entry;
   2203     }
   2204 
   2205     if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) {
   2206         sal_memcpy(&egr_mtu_entry,
   2207                    soc_mem_entry_null(unit, EGR_MTUm),
   2208                    soc_mem_entry_words(unit, EGR_MTUm) *
   2209                    sizeof(uint32));
   2210         entries[index++] = &egr_mtu_entry;
   2211     }
   2212 
   2213     if (SOC_MEM_IS_VALID(unit, EGR_PORT_1m)) {
   2214         sal_memcpy(&egr_port_1_entry,
   2215                    soc_mem_entry_null(unit, EGR_PORT_1m),
   2216                    soc_mem_entry_words(unit, EGR_PORT_1m) *
   2217                    sizeof(uint32));
   2218         entries[index++] = &egr_port_1_entry;
   2219     }
   2220 
   2221     if (soc_feature(unit, soc_feature_egr_all_profile) == 0) {
   2222         if (SOC_MEM_IS_VALID(unit, EGR_COUNTER_CONTROLm)) {
   2223             sal_memcpy(&egr_counter_control_entry,
   2224                        soc_mem_entry_null(unit, EGR_COUNTER_CONTROLm),
   2225                        soc_mem_entry_words(unit, EGR_COUNTER_CONTROLm) *
   2226                        sizeof(uint32));
   2227             entries[index++] = &egr_counter_control_entry;
   2228         }
   2229 
   2230         if (SOC_MEM_IS_VALID(unit, EGR_SHAPING_CONTROLm)) {
   2231             sal_memcpy(&egr_shaping_control_entry,
   2232                        soc_mem_entry_null(unit, EGR_SHAPING_CONTROLm),
   2233                        soc_mem_entry_words(unit, EGR_SHAPING_CONTROLm) *
   2234                        sizeof(uint32));
   2235             entries[index++] = &egr_shaping_control_entry;
   2236         }
   2237     }
   2238 
   2239     if (index > 0) {
   2240         BCM_IF_ERROR_RETURN(
   2241             soc_profile_mem_add(unit, prof, entries, 1, &egr_lport_index));
   2242         if (egr_lport_index !=
   2243             _bcm_trx_egr_lport_tab_default_entry_index_get(unit)) {
   2244             /* Something went horribly wrong. */
   2245             rv = BCM_E_INTERNAL;
   2246         }
   2247     }
   2248 
   2249     return rv;
   2250 }
   2251 
   2252 /*
   2253  * Function:
   2254  *      _bcm_trx_rtag7_tab_default_entry_add
   2255  * Purpose:
   2256  *      Internal function for initializing RTAG7 default
   2257  *      entry
   2258  * Parameters:
   2259  *      unit    -  (IN) Device number.
   2260  *      prof    -  (IN) LPORT memory profile. 
   2261  * Returns:
   2262  *      BCM_X_XXX
   2263  */
   2264 int 
   2265 _bcm_trx_rtag7_tab_default_entry_add(int unit, soc_profile_mem_t *prof) 
   2266 {
   2267     rtag7_port_based_hash_entry_t rtag7_entry;
   2268     void *entries[1];
   2269     uint32 rtag7_index;
   2270     int stm_num_entries = 0, i;
   2271 
   2272     /* Input parameters check. */
   2273     if (NULL == prof) {
   2274         return (BCM_E_PARAM);
   2275     }
   2276 
   2277     if (SOC_MEM_IS_VALID(unit, RTAG7_PORT_BASED_HASHm)) {
   2278         sal_memcpy(&rtag7_entry,
   2279                    soc_mem_entry_null(unit, RTAG7_PORT_BASED_HASHm),
   2280                    soc_mem_entry_words(unit, RTAG7_PORT_BASED_HASHm) *
   2281                    sizeof(uint32));
   2282     }
   2283 
   2284     entries[0] = &rtag7_entry;
   2285 
   2286     BCM_IF_ERROR_RETURN(
   2287         soc_profile_mem_add(unit, prof, entries, 1, &rtag7_index));
   2288 
   2289     if (rtag7_index != _bcm_trx_rtag7_tab_default_entry_index_get(unit)) {
   2290         /* Something went horribly wrong. */
   2291         return (BCM_E_INTERNAL);
   2292     }
   2293     if (SOC_IS_TRIDENT3X(unit)) {
   2294         /* Update reference count (keep 1 extra count) */
   2295         stm_num_entries = soc_mem_index_max(unit,
   2296                               SOURCE_TRUNK_MAP_TABLEm) - soc_mem_index_min(unit,
   2297                               SOURCE_TRUNK_MAP_TABLEm) + 1;
   2298         for (i = 0; i < stm_num_entries; i++) {
   2299             BCM_IF_ERROR_RETURN
   2300                    (_bcm_rtag7_ind_profile_mem_reference(unit, rtag7_index, 1));
   2301         }
   2302     }
   2303     return BCM_E_NONE;
   2304 }
   2305 
   2306 /*
   2307  * Function:
   2308  *           _bcm_trx_gport_to_nhi_set
   2309  * Purpose:
   2310 *            set EGR_PORT_TO_NHI_MAPPINGr or EGR_DGPP_TO_NHIm 
   2311  * Parameters:
   2312  *           unit -  (IN) Device number.
   2313  *           gport -  (IN) modport gport.
   2314  *           nh_index -  (IN) nexthop index.
   2315  * Returns:
   2316  *           BCM_E_XXX
   2317  */
   2318 int
   2319 _bcm_trx_gport_to_nhi_set(int unit, int gport, int nh_index)
   2320 {
   2321     int rv = 0;
   2322     int port;
   2323 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   2324     int                              modid;
   2325     uint32                           dgpp = 0;
   2326     uint32                           modbase = 0;
   2327     egr_dgpp_to_nhi_modbase_entry_t  mem_val;
   2328 #endif
   2329     if (nh_index < 0) {
   2330         return BCM_E_PARAM;
   2331     }
   2332     if (!BCM_GPORT_IS_MODPORT(gport)) {
   2333         return BCM_E_PARAM;
   2334     }
   2335 
   2336     port = BCM_GPORT_MODPORT_PORT_GET(gport);
   2337 
   2338     if (!soc_feature(unit, soc_feature_egr_modport_to_nhi)) {
   2339         rv = soc_reg_field32_modify(unit, EGR_PORT_TO_NHI_MAPPINGr,
   2340                                     port, NEXT_HOP_INDEXf, nh_index);
   2341     } 
   2342 #ifdef BCM_TRIDENT2PLUS_SUPPORT    
   2343     else {
   2344         modid = BCM_GPORT_MODPORT_MODID_GET(gport);
   2345         BCM_IF_ERROR_RETURN(
   2346             READ_EGR_DGPP_TO_NHI_MODBASEm(unit, MEM_BLOCK_ANY, modid, &mem_val));
   2347         modbase = soc_mem_field32_get(unit, EGR_DGPP_TO_NHI_MODBASEm,
   2348                                       &mem_val, BASEf);
   2349         dgpp = modbase + port;
   2350         rv = soc_mem_field32_modify(unit, EGR_DGPP_TO_NHIm,
   2351                                     dgpp, NEXT_HOP_INDEXf, nh_index);
   2352     }
   2353 #endif    
   2354     return rv;
   2355 }
   2356 
   2357 /*
   2358  * Function:
   2359  *           _bcm_trx_gport_to_nhi_get
   2360  * Purpose:
   2361 *            get EGR_PORT_TO_NHI_MAPPINGr or EGR_DGPP_TO_NHIm 
   2362  * Parameters:
   2363  *           unit -  (IN) Device number.
   2364  *           gport -  (IN) modport gport.
   2365  *           nh_index -  (OUT) nexthop index ptr.
   2366  * Returns:
   2367  *           BCM_E_XXX
   2368  */
   2369 
   2370 int
   2371 _bcm_trx_gport_to_nhi_get(int unit, int gport, int* nh_index)
   2372 {
   2373     uint32 reg_val=0;
   2374     int port;
   2375 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   2376     int                                modid;
   2377     uint32                             modbase = 0;
   2378     uint32                             dgpp = 0;
   2379     egr_dgpp_to_nhi_modbase_entry_t    mem_val1;
   2380     egr_dgpp_to_nhi_entry_t            mem_val2;
   2381 #endif
   2382     if (!BCM_GPORT_IS_MODPORT(gport)) {
   2383         return BCM_E_PARAM;
   2384     }
   2385 
   2386     port = BCM_GPORT_MODPORT_PORT_GET(gport);
   2387     
   2388     if (!soc_feature(unit, soc_feature_egr_modport_to_nhi)) {
   2389        BCM_IF_ERROR_RETURN(
   2390            READ_EGR_PORT_TO_NHI_MAPPINGr(unit, port, &reg_val));
   2391        *nh_index = soc_reg_field_get(unit, EGR_PORT_TO_NHI_MAPPINGr, reg_val, 
   2392                                      NEXT_HOP_INDEXf);
   2393     } 
   2394 #ifdef BCM_TRIDENT2PLUS_SUPPORT    
   2395     else {
   2396         /* TD2+ */
   2397         modid = BCM_GPORT_MODPORT_MODID_GET(gport);
   2398         BCM_IF_ERROR_RETURN(
   2399             READ_EGR_DGPP_TO_NHI_MODBASEm(unit, MEM_BLOCK_ANY, modid, &mem_val1));
   2400         modbase = soc_mem_field32_get(unit, EGR_DGPP_TO_NHI_MODBASEm,
   2401                                       &mem_val1, BASEf);
   2402         dgpp = modbase + port;
   2403         BCM_IF_ERROR_RETURN(
   2404             READ_EGR_DGPP_TO_NHIm(unit, MEM_BLOCK_ANY, dgpp, &mem_val2));
   2405         *nh_index = soc_mem_field32_get(unit, EGR_DGPP_TO_NHIm, &mem_val2, 
   2406                                         NEXT_HOP_INDEXf);
   2407     }
   2408 #endif    
   2409     return BCM_E_NONE;
   2410 }
   2411 #else /* BCM_TRX_SUPPORT */
   2412 int bcm_esw_trx_port_not_empty;
   2413 #endif  /* BCM_TRX_SUPPORT */
   2414