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


      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:     Tracks and manages ports.
      9  *              P-VLAN table is managed directly.
     10  *              MAC/PHY interfaces are managed through respective drivers.
     11  */
     12 
     13 #include <shared/bsl.h>
     14 
     15 #include <assert.h>
     16 
     17 #include <sal/core/libc.h>
     18 #include <sal/core/boot.h>
     19 #include <shared/bsl.h>
     20 
     21 #include <soc/cm.h>
     22 #include <soc/drv.h>
     23 #include <soc/scache.h>
     24 #include <soc/phy.h>
     25 #include <soc/ll.h>
     26 #include <soc/ptable.h>
     27 #include <soc/firebolt.h>
     28 #include <soc/xaui.h>
     29 #include <soc/phyctrl.h>
     30 #include <soc/phyreg.h>
     31 #include <soc/higig.h>
     32 #include <soc/hash.h>
     33 #include <soc/macutil.h>
     34 
     35 #include <bcm/port.h>
     36 #include <bcm/error.h>
     37 #include <bcm/mirror.h>
     38 
     39 #ifdef SW_AUTONEG_SUPPORT 
     40 #include <bcm_int/common/sw_an.h>
     41 #endif 
     42  
     43 #include <bcm_int/api_xlate_port.h>
     44 #include <bcm_int/common/lock.h>
     45 #include <bcm_int/common/tx.h>
     46 #include <bcm_int/common/sat.h>
     47 #include <bcm_int/esw/mbcm.h>
     48 #include <bcm_int/esw/port.h>
     49 #include <bcm_int/esw/link.h>
     50 #include <bcm_int/esw/mirror.h>
     51 #include <bcm_int/esw/stack.h>
     52 #include <bcm_int/esw/stat.h>
     53 #include <bcm_int/esw/timesync.h>
     54 #include <bcm_int/esw/firebolt.h>
     55 #include <bcm_int/esw/portctrl.h>
     56 #include <bcm_int/esw/vxlan.h>
     57 #if defined(BCM_TRIUMPH_SUPPORT)
     58 #include <bcm_int/esw/triumph.h>
     59 #include <bcm_int/esw/virtual.h>
     60 #endif /* BCM_TRIUMPH_SUPPORT */
     61 #if defined(BCM_SCORPION_SUPPORT)
     62 #include <bcm_int/esw/scorpion.h>
     63 #include <bcm_int/esw/triumph.h>
     64 #endif /* BCM_SCORPION_SUPPORT */
     65 #if defined(BCM_TRX_SUPPORT)
     66 #include <bcm_int/esw/trx.h>
     67 #endif /* BCM_TRX_SUPPORT */
     68 #if defined(BCM_TRIUMPH2_SUPPORT)
     69 #include <bcm_int/esw/triumph2.h>
     70 #include <soc/triumph2.h>
     71 #endif /* BCM_TRIUMPH2_SUPPORT */
     72 #if defined(BCM_TRIDENT_SUPPORT)
     73 #include <bcm_int/esw/trident.h>
     74 #endif /* BCM_TRIUMPH2_SUPPORT */
     75 #if defined(BCM_KATANA_SUPPORT)
     76 #include <bcm_int/esw/katana.h>
     77 #endif /* BCM_KATANA_SUPPORT */
     78 #if defined(BCM_APACHE_SUPPORT)
     79 #include <bcm_int/esw/monterey.h>
     80 #include <soc/monterey.h>
     81 #endif /* BCM_MONTEREY_SUPPORT */
     82 #if defined(BCM_APACHE_SUPPORT)
     83 #include <bcm_int/esw/apache.h>
     84 #include <soc/apache.h>
     85 #endif /* BCM_APACHE_SUPPORT */
     86 #if defined(BCM_ENDURO_SUPPORT)
     87 #include <bcm_int/esw/enduro.h>
     88 #endif /* BCM_ENDURO_SUPPORT */
     89 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT)
     90 #include <bcm_int/esw/hurricane.h>
     91 #endif /* BCM_HURRICANE_SUPPORT */
     92 #if defined(BCM_HURRICANE2_SUPPORT)
     93 #include <soc/hurricane2.h>
     94 #endif /* BCM_HURRICANE_SUPPORT */
     95 #if defined(BCM_SHADOW_SUPPORT)
     96 #include <soc/shadow.h>
     97 #endif /* BCM_SHADOW_SUPPORT */
     98 #if defined(BCM_TRIUMPH3_SUPPORT)
     99 #include <bcm_int/esw/triumph3.h>
    100 #include <soc/triumph3.h>
    101 #include <bcm_int/esw/extender.h>
    102 #endif /* BCM_TRIUMPH3_SUPPORT */
    103 #if defined(BCM_TRIDENT2_SUPPORT)
    104 #include <bcm_int/esw/trident2.h>
    105 #include <soc/trident2.h>
    106 #include <bcm_int/esw/trunk.h>
    107 #endif /* BCM_TRIDENT2_SUPPORT */
    108 #if defined(BCM_TOMAHAWK_SUPPORT)
    109 #include <bcm_int/esw/tomahawk.h>
    110 #include <soc/tomahawk.h>
    111 #endif /* BCM_TOMAHAWK_SUPPORT */
    112 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    113 #include <bcm_int/esw/trident2plus.h>
    114 #include  <soc/td2_td2p.h>
    115 #include <bcm_int/esw/subport.h>
    116 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
    117 #if defined(BCM_TRIDENT3_SUPPORT)
    118 #include <soc/esw/cancun.h>
    119 #include <bcm_int/esw/trident3.h>
    120 #include <soc/trident3.h>
    121 #endif /* BCM_TRIDENT3_SUPPORT */
    122 #if defined(BCM_HELIX5_SUPPORT)
    123 #include <soc/esw/cancun.h>
    124 #include <bcm_int/esw/helix5.h>
    125 #include <soc/helix5.h>
    126 #endif /* BCM_HELIX5_SUPPORT */
    127 #if defined(BCM_MAVERICK2_SUPPORT)
    128 #include <soc/esw/cancun.h>
    129 #include <bcm_int/esw/maverick2.h>
    130 #include <soc/maverick2.h>
    131 #endif /* BCM_MAVERICK2_SUPPORT */
    132 #if defined(BCM_TOMAHAWK3_SUPPORT)
    133 #include <bcm_int/esw/tomahawk3.h>
    134 #include <bcm_int/esw/pfc.h>
    135 #include <bcm_int/esw/xgs5.h>
    136 #include <soc/tomahawk3.h>
    137 #endif /* BCM_TOMAHAWK3_SUPPORT */
    138 
    139 #if defined (BCM_HGPROXY_COE_SUPPORT)
    140 #include <bcm_int/esw/xgs5.h>
    141 #include <bcm_int/esw/subport.h>
    142 #endif /* BCM_HGPROXY_COE_SUPPORT */
    143 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
    144 #include <bcm_int/esw/tomahawk2.h>
    145 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT */
    146 #if defined(BCM_TOMAHAWK2_SUPPORT)
    147 #include <bcm_int/esw/xgs5.h>
    148 #include <soc/tomahawk2.h>
    149 #endif /* BCM_TOMAHAWK2_SUPPORT */
    150 #include <bcm_int/esw/xgs3.h>
    151 
    152 #include <bcm_int/esw/flex_ctr.h>
    153 #include <bcm_int/esw/policer.h>
    154 #if defined(BCM_KATANA2_SUPPORT)
    155 #include <bcm_int/esw/subport.h>
    156 #include <bcm_int/esw/katana2.h>
    157 #include <soc/katana2.h>
    158 #include <bcm/subport.h>
    159 #endif /* BCM_KATANA2_SUPPORT */
    160 #if defined(BCM_SABER2_SUPPORT)
    161 #include <bcm_int/esw/saber2.h>
    162 #include <soc/saber2.h>
    163 #endif /* BCM_SABER2_SUPPORT */
    164 #if defined(BCM_METROLITE_SUPPORT)
    165 #include <bcm_int/esw/metrolite.h>
    166 #include <soc/metrolite.h>
    167 #endif /* BCM_METROLITE_SUPPORT */
    168 #if defined(BCM_GREYHOUND_SUPPORT)
    169 #include <bcm_int/esw/greyhound.h>
    170 #endif /* BCM_GREYHOUND_SUPPORT */
    171 #if defined(BCM_HURRICANE3_SUPPORT)
    172 #include <bcm_int/esw/hurricane3.h>
    173 #include <soc/hurricane3.h>
    174 #endif /* BCM_HURRICANE3_SUPPORT */
    175 #if defined(BCM_GREYHOUND2_SUPPORT)
    176 #include <bcm_int/esw/greyhound2.h>
    177 #endif /* BCM_GREYHOUND2_SUPPORT */
    178 #if defined (BCM_EP_REDIRECT_VERSION_2)
    179 #include <bcm_int/esw/xgs5.h>
    180 #endif
    181 #if defined(BCM_HGPROXY_COE_SUPPORT)
    182 #include <bcm_int/esw/subport.h>
    183 #include <bcm_int/esw/xgs5.h>
    184 #endif /* BCM_HGPROXY_COE_SUPPORT */
    185 #if defined(BCM_PREEMPTION_SUPPORT)
    186 #include <bcm_int/esw/preemption.h>
    187 #include <bcm_int/esw/preemption_cnt.h>
    188 #endif /* BCM_PREEMPTION_SUPPORT */
    189 #include <bcm_int/esw_dispatch.h>
    190 
    191 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_WARM_BOOT_SUPPORT)
    192 #include <bcm_int/esw/switch.h>
    193 #endif /* BCM_WARM_BOOT_SUPPORT */
    194 
    195 #if defined(BCM_TRIUMPH2_SUPPORT)
    196 #include <bcm_int/esw/qos.h>
    197 #endif /* BCM_TRIUMPH2_SUPPORT */
    198 
    199 #ifdef PORTMOD_SUPPORT
    200 #include <soc/portmod/portmod.h>
    201 #endif /* PORTMOD_SUPPORT */
    202 
    203 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT
    204 #include <bcm_int/esw/xgs5.h>
    205 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT */
    206 
    207 #ifdef INCLUDE_FCMAP
    208 #include <../../phyident.h>
    209 #endif
    210 
    211 #define BCMI_GPORT_TYPE_VALID(port)         \
    212         (BCM_GPORT_IS_VLAN_PORT(port) ||     \
    213          BCM_GPORT_IS_NIV_PORT(port) ||      \
    214          BCM_GPORT_IS_EXTENDER_PORT(port) || \
    215          BCM_GPORT_IS_SUBPORT_PORT(port) ||  \
    216          BCM_GPORT_IS_VXLAN_PORT(port) ||  \
    217          BCM_GPORT_IS_L2GRE_PORT(port) ||  \
    218          BCM_GPORT_IS_MIM_PORT(port) || \
    219          BCM_GPORT_IS_MPLS_PORT(port) || \
    220          BCM_GPORT_IS_FLOW_PORT(port) || \
    221          BCM_GPORT_IS_TRUNK(port))
    222 
    223 
    224 #if defined (BCM_EP_REDIRECT_VERSION_2)
    225 #define BCMI_EP_REDIRECT_PORT (74)
    226 #endif
    227 
    228 #define _BCM_QOS_MAP_CHUNK_EGR_DSCP 64
    229 #define _BCM_I2E_CLASS_ID_MAX   0x1ff
    230 
    231 /*
    232  * Define the macro for measuring the benchmark of speed change.
    233  */
    234 #define BCM_PORT_SPEED_CHANGE_BENCHMARK
    235 
    236 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    237 #define MODULE_ID_LOWER_6_BITS(a) ((a) = ((a) & 0x3f))
    238 #endif
    239 
    240 /*
    241  * Port Function Vector Driver
    242  */
    243 bcm_esw_port_drv_t    *bcm_esw_port_drv[BCM_MAX_NUM_UNITS] = {0};
    244 
    245 /*
    246  * Variable:
    247  *      bcm_port_info
    248  * Purpose:
    249  *      One entry for each SOC device containing port information
    250  *      for that device.  Use the PORT macro to access it.
    251  */
    252 static _bcm_port_info_t     *bcm_port_info[BCM_MAX_NUM_UNITS];
    253 
    254 STATIC _bcm_port_force_forward_linkstate_t p_linkstate[BCM_MAX_NUM_UNITS];
    255 
    256 #define PORT(unit, port)        bcm_port_info[unit][port]
    257 
    258 extern int inside_bcm_shutdown[BCM_MAX_NUM_UNITS];
    259 
    260 #if defined(BCM_XMAC_SUPPORT)
    261 extern int _mac_x_reinit(int unit, soc_port_t port);
    262 #endif
    263 
    264 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    265 extern src_modid_base_index_bookkeeping_t *src_modid_base_index_bk[BCM_MAX_NUM_UNITS];
    266 #endif
    267 
    268 /* Accessor to bcm_port_info used by other modules */
    269 void _bcm_port_info_access(int unit, bcm_port_t port, _bcm_port_info_t **info)
    270 {
    271     (bcm_port_info[unit] != NULL) ? (*info = &PORT(unit, port)):(*info = NULL);
    272     return;
    273 }
    274 
    275 /* Return On error with port mutex unlocked */
    276 #define _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(op)  \
    277     do {                                        \
    278         int __rv__;                             \
    279         if (((__rv__ = (op)) < 0)) {            \
    280             PORT_UNLOCK(unit);                  \
    281             _SHR_ERROR_TRACE(__rv__);           \
    282             return(__rv__);                     \
    283         }                                       \
    284     } while(0)
    285 
    286 int
    287 _bcm_esw_port_gport_phyn_validate(int unit, bcm_port_t port,
    288                                   bcm_port_t *local_port, int *phyn,
    289                                   int *phy_lane, int *sys_side);
    290 
    291 #if defined(BCM_KATANA2_SUPPORT)
    292    int _bcm_kt2_update_port_mode(int unit, uint8 port, int speed);
    293    int _bcm_kt2_cosq_dynamic_port_encap_change(int unit, bcm_port_t port);
    294 #endif
    295 
    296 #if defined(BCM_METROLITE_SUPPORT)
    297 int _bcm_ml_update_port_mode(int unit, uint8 port, int speed);
    298 #endif
    299 #if defined(BCM_SABER2_SUPPORT)
    300 int _bcm_sb2_update_port_mode(int unit, uint8 port, int speed);
    301 #ifdef BCM_WARM_BOOT_SUPPORT
    302 int bcm_sb2_wb_v2_flexio_update = 0;
    303 #endif
    304 #endif
    305 #if defined(BCM_TRIUMPH3_SUPPORT)
    306 STATIC int
    307 _bcm_port_force_forward_add(int unit, bcm_port_t local_port, 
    308                                     bcm_port_t egr_port);
    309                                     
    310 STATIC int 
    311 _bcm_port_force_forward_init(int unit);
    312 
    313 STATIC int 
    314 _bcm_port_force_forward_deinit(int unit);
    315 
    316 #ifdef BCM_WARM_BOOT_SUPPORT            
    317 STATIC int
    318 _bcm_port_force_forward_sync(int unit, uint8 **scache_ptr);
    319 
    320 STATIC int
    321 _bcm_port_force_forward_reinit(int unit, uint8 **scache_ptr);
    322 
    323 STATIC int
    324 _bcm_port_force_forward_scache_size(int unit, int *size);
    325 #endif /* BCM_WARM_BOOT_SUPPORT */
    326 #endif /* defined(BCM_TRIUMPH3_SUPPORT) */
    327 
    328 /*
    329  * Define:
    330  *      PORT_INIT
    331  * Purpose:
    332  *      Causes a routine to return BCM_E_INIT if port is not yet initialized.
    333  */
    334 
    335 #define PORT_INIT(unit) \
    336         if (bcm_port_info[unit] == NULL) { return BCM_E_INIT; }
    337 
    338 /*
    339  * Define:
    340  *      PORT_PARAM_CHECK
    341  * Purpose:
    342  *      Check unit and port parameters for most bcm_port api calls
    343  */
    344 #define PORT_PARAM_CHECK(unit, port) do { \
    345         PORT_INIT(unit); \
    346         if (!SOC_PORT_VALID(unit, port)) { return BCM_E_PORT; } \
    347         } while (0);
    348 
    349 /*
    350  * Define:
    351  *      PORT_SWITCHED_CHECK
    352  * Purpose:
    353  *      Check unit and port for switching feature support
    354  */
    355 #define PORT_SWITCHED_CHECK(unit, port) do { \
    356         if (IS_ST_PORT(unit, port)) { \
    357             return BCM_E_PORT; \
    358         } else { \
    359             if (IS_CPU_PORT(unit, port)) { \
    360                 if (!soc_feature(unit, soc_feature_cpuport_switched)) { \
    361                     return BCM_E_PORT; \
    362                 } \
    363             } \
    364         } \
    365         } while (0);
    366 
    367 
    368 /*
    369  * Define:
    370  *      PORT_INFO_RX_LOS_SET
    371  * Purpose:
    372  *      Records the SW RX LOS configuration used for warmboot recovery
    373  */
    374 #define PORT_INFO_RX_LOS_SET(_u, _p, _type, _val) do {                  \
    375         if (_type == BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS) {            \
    376             PORT(_u, _p).rx_los = _val;                                 \
    377         }                                                               \
    378     } while (0);
    379 
    380 
    381 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT) \
    382     || defined(BCM_TRIUMPH3_SUPPORT)
    383  #define BCM_MAX_PORTS_SUPPORT_FOR_DMVOQ 64
    384 #endif
    385 #ifdef BCM_TRIUMPH2_SUPPORT
    386 typedef int _port_src_mod_egr_prof_ptr_t;
    387 STATIC _port_src_mod_egr_prof_ptr_t
    388     port_src_mod_egr_prof_ptr[BCM_MAX_NUM_UNITS][SOC_MAX_NUM_PORTS];
    389 #define PORT_SRC_MOD_EGR_PROF_PTR(_u, _p) port_src_mod_egr_prof_ptr[_u][_p]
    390 
    391 STATIC soc_profile_mem_t *_bcm_src_mod_egr_profile[BCM_MAX_NUM_UNITS];
    392 #define PORT_SRC_MOD_EGR_PROFILE(_u) _bcm_src_mod_egr_profile[_u]
    393 
    394 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
    395 STATIC
    396 bcm_error_t _bcm_esw_port_stat_get_table_info(
    397                    int                        unit,
    398                    bcm_gport_t                port,
    399                    uint32                     *num_of_tables,
    400                    bcm_stat_flex_table_info_t *table_info);
    401 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT */
    402 #endif /* BCM_TRIUMPH2_SUPPORT */
    403 
    404 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) ||\
    405 defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_SHADOW_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT)
    406 /* EEE standard compliance Work Around:
    407  * To Maintain software state of native eee in MAC*/
    408 STATIC int eee_cfg[BCM_MAX_NUM_UNITS][SOC_MAX_NUM_PORTS];
    409 #endif
    410 
    411 #ifdef BCM_TRIUMPH3_SUPPORT
    412 STATIC int _bcm_tr3_port_lanes_set(int unit, bcm_port_t port, int value);
    413 STATIC int _bcm_tr3_port_lanes_get(int unit, bcm_port_t port, int *value);
    414 #endif /* BCM_TRIUMPH3_SUPPORT */
    415 
    416 /*
    417  * The Port Monitor Thread is intended for handling work-arounds
    418  * that are unneeded in most cases. In order to avoid unnecessary
    419  * processing overhead the thread is not started by default, but
    420  * only if so requested through configuration parameters.
    421  */
    422 
    423 typedef struct _port_mon_ctrl_s
    424 {
    425     char taskname[16];
    426     sal_sem_t sema;
    427     int interval;
    428     int running;
    429     int stop;
    430     int unit;
    431     uint32 gtuc;
    432     uint32 gtmca;
    433     uint32 gtbca;
    434     uint32 gtlcl;
    435     uint32 gtpok;
    436 } _port_mon_ctrl_t;
    437 
    438 STATIC _port_mon_ctrl_t _bcm_esw_port_mon_ctrl[BCM_MAX_NUM_UNITS];
    439 
    440 #define PORT_MON_CTRL(_u) (&_bcm_esw_port_mon_ctrl[_u])
    441 
    442 #define PORT_MON_INTERVAL_MIN   100000
    443 
    444 int
    445 _bcm_port_mac_init(int unit, bcm_port_t port, int *okay);
    446 
    447 #if defined(BCM_TRIDENT3_SUPPORT)
    448 STATIC int
    449 _bcm_esw_td3_asf_init(int unit, soc_td3_asf_mode_e asf_mode);
    450 STATIC int
    451 _bcm_esw_td3_port_asf_mode_set(int unit, bcm_port_t port, int mode);
    452 #endif
    453 
    454 #if defined(BCM_MAVERICK2_SUPPORT)
    455 STATIC int
    456 _bcm_esw_mv2_asf_init(int unit, soc_mv2_asf_mode_e asf_mode);
    457 STATIC int
    458 _bcm_esw_mv2_port_asf_mode_set(int unit, bcm_port_t port, int mode);
    459 #endif
    460 
    461 #if defined(BCM_TOMAHAWK_SUPPORT)
    462 STATIC int
    463 _bcm_esw_asf_init(int unit, soc_th_asf_mode_e asf_mode);
    464 
    465 STATIC int
    466 _bcm_esw_asf_deinit(int unit);
    467 
    468 #ifdef BCM_WARM_BOOT_SUPPORT
    469 STATIC int
    470 _bcm_esw_asf_wb_memsz_get(int unit, uint32* const mem_sz, uint16 scache_ver);
    471 
    472 STATIC int
    473 _bcm_esw_asf_wb_sync(int unit, uint8* wb_data);
    474 
    475 STATIC int
    476 _bcm_esw_asf_wb_recover(int unit, uint8* const wb_data, uint16 scache_ver);
    477 
    478 STATIC int
    479 _bcm_esw_sflow_wb_recover(int unit);
    480 
    481 STATIC int
    482 _bcm_esw_sflow_counter_wb_recover(int unit, soc_mem_t mem);
    483 #endif /* BCM_WARM_BOOT_SUPPORT */
    484 #endif /* BCM_TOMAHAWK_SUPPORT */
    485 
    486 #ifdef BCM_WARM_BOOT_SUPPORT
    487 STATIC int
    488 _bcm_esw_port_ifg_wb_sync(int unit, uint8 **scache_ptr);
    489 
    490 STATIC int
    491 _bcm_esw_port_ifg_wb_reinit(int unit, uint8 **scache_ptr);
    492 #endif
    493 
    494 STATIC int
    495 bcmi_esw_port_encap_validate(int unit, bcm_port_t port, int mode, int speed);
    496 STATIC int
    497 _bcm_esw_port_encap_set(int unit, bcm_port_t port, int mode);
    498 
    499 
    500 #if defined(BCM_GREYHOUND_SUPPORT)
    501 /* Treat Packet Priority as dot1p ref_cnt structure */
    502 typedef struct bcmi_esw_treat_pktpri_as_dot1p_s {
    503     sal_mutex_t ref_cnt_mutex;
    504     int ref_cnt;
    505 } bcmi_esw_treat_pktpri_as_dot1p_t;
    506 
    507 STATIC bcmi_esw_treat_pktpri_as_dot1p_t
    508     bcmi_treat_pktpri_as_dot1p[BCM_MAX_NUM_UNITS];
    509 
    510 /* Treat Packet Priority as dot1p ref_cnt lock/unlock */
    511 #define TREAT_PKTPRI_AS_DOT1P_LOCK(_unit_)                           \
    512     sal_mutex_take(bcmi_treat_pktpri_as_dot1p[_unit_].ref_cnt_mutex, \
    513                    sal_mutex_FOREVER)
    514 #define TREAT_PKTPRI_AS_DOT1P_UNLOCK(_unit_)                         \
    515     sal_mutex_give(bcmi_treat_pktpri_as_dot1p[_unit_].ref_cnt_mutex)
    516 
    517 /*
    518  * Function:
    519  *    bcmi_esw_port_treat_pktpri_as_dot1p_cleanup
    520  * Purpose:
    521  *    cleanup resource after detach
    522  * Parameters:
    523  *    unit - (IN) Device Number
    524  * Return Value:
    525  *    BCM_E_XXX
    526  * Notes:
    527  */
    528 STATIC int
    529 bcmi_esw_port_treat_pktpri_as_dot1p_cleanup(int unit)
    530 {
    531     if (bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex != NULL) {
    532         sal_mutex_destroy(bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex);
    533         bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex = NULL;
    534     }
    535 
    536     return BCM_E_NONE;
    537 }
    538 
    539 /*
    540  * Function:
    541  *    bcmi_esw_port_treat_pktpri_as_dot1p_init
    542  * Purpose:
    543  *    Initialize the ref_cnt of enabling treat packet priority
    544  *    as dot1p priority for different packet types or port controls.
    545  * Parameters:
    546  *    unit - (IN) Device Number
    547  * Return Value:
    548  *    BCM_E_XXX
    549  * Notes:
    550  *    The ref_cnt of treat packet priority as dot1p priority is system-wise.
    551  */
    552 STATIC int
    553 bcmi_esw_port_treat_pktpri_as_dot1p_init(int unit)
    554 {
    555     if (!soc_feature(unit, soc_feature_pktpri_as_dot1p)) {
    556         return BCM_E_UNAVAIL;
    557     }
    558 
    559     /* Create protection mutex. */
    560     if (NULL == bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex) {
    561         bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex =
    562             sal_mutex_create("treat_pktpri_as_dot1p.lock");
    563         if (NULL == bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex) {
    564             return BCM_E_RESOURCE;
    565         }
    566     }
    567 
    568     bcmi_treat_pktpri_as_dot1p[unit].ref_cnt = 0;
    569 
    570     return BCM_E_NONE;
    571 }
    572 
    573 /*
    574  * Function:
    575  *    bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update
    576  * Purpose:
    577  *    Update the ref_cnt of enabling treat packet priority
    578  *    as dot1p priority for various packet types or port controls.
    579  * Parameters:
    580  *    unit - (IN) Device Number
    581  *    incr_decr_flag - (IN) If TRUE, increment ref_cnt, else decrease ref_cnt
    582  * Return Value:
    583  *    BCM_E_XXX
    584  * Notes:
    585  *    The ref_cnt of treat packet priority as dot1p priority is system-wise.
    586  */
    587 STATIC int
    588 bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update(
    589     int unit, int incr_decr_flag)
    590 {
    591     int rv = BCM_E_NONE;
    592     uint64 regval64;
    593 
    594     if (!soc_feature(unit, soc_feature_pktpri_as_dot1p)) {
    595         return BCM_E_UNAVAIL;
    596     }
    597 
    598     /* Input parameter check */
    599     if ((incr_decr_flag != 1) && (incr_decr_flag != -1)) {
    600         return BCM_E_PARAM;
    601     }
    602 
    603     TREAT_PKTPRI_AS_DOT1P_LOCK(unit);
    604     if (incr_decr_flag == 1) {
    605         /* Increment */
    606         /* Need to set TREAT_PKTPRI_AS_DOT1Pf for the first ref_cnt */
    607         if (bcmi_treat_pktpri_as_dot1p[unit].ref_cnt == 0) {
    608             COMPILER_64_ZERO(regval64);
    609             rv = READ_ING_CONFIG_64r(unit, &regval64);
    610             if (BCM_FAILURE(rv)) {
    611                 TREAT_PKTPRI_AS_DOT1P_UNLOCK(unit);
    612                 return rv;
    613             }
    614             soc_reg64_field32_set(unit, ING_CONFIG_64r, &regval64,
    615                                   TREAT_PKTPRI_AS_DOT1Pf, 1);
    616             rv = WRITE_ING_CONFIG_64r(unit, regval64);
    617             if (BCM_FAILURE(rv)) {
    618                 TREAT_PKTPRI_AS_DOT1P_UNLOCK(unit);
    619                 return rv;
    620             }
    621         }
    622         bcmi_treat_pktpri_as_dot1p[unit].ref_cnt++;
    623     } else {
    624         /* Decrement */
    625         if (bcmi_treat_pktpri_as_dot1p[unit].ref_cnt >= 1) {
    626             bcmi_treat_pktpri_as_dot1p[unit].ref_cnt--;
    627             /* Need to unset TREAT_PKTPRI_AS_DOT1Pf when ref_cnt = 0 */
    628             if (bcmi_treat_pktpri_as_dot1p[unit].ref_cnt == 0) {
    629                 COMPILER_64_ZERO(regval64);
    630                 rv = READ_ING_CONFIG_64r(unit, &regval64);
    631                 if (BCM_FAILURE(rv)) {
    632                     TREAT_PKTPRI_AS_DOT1P_UNLOCK(unit);
    633                     return rv;
    634                 }
    635                 soc_reg64_field32_set(unit, ING_CONFIG_64r, &regval64,
    636                                       TREAT_PKTPRI_AS_DOT1Pf, 0);
    637                 rv = WRITE_ING_CONFIG_64r(unit, regval64);
    638                 if (BCM_FAILURE(rv)) {
    639                     TREAT_PKTPRI_AS_DOT1P_UNLOCK(unit);
    640                     return rv;
    641                 }
    642             }
    643         }
    644     }
    645     TREAT_PKTPRI_AS_DOT1P_UNLOCK(unit);
    646 
    647     return rv;
    648 }
    649 
    650 #ifdef BCM_WARM_BOOT_SUPPORT
    651 /*
    652  * Function:
    653  *    bcmi_esw_port_treat_pktpri_as_dot1p_reinit
    654  * Purpose:
    655  *    Recovery the ref_cnt of enabling treat packet priority
    656  *    as dot1p priority for different packet types or port contols.
    657  * Parameters:
    658  *    unit - (IN) Device Number
    659  * Return Value:
    660  *    BCM_E_XXX
    661  */
    662 STATIC int
    663 bcmi_esw_port_treat_pktpri_as_dot1p_reinit(int unit)
    664 {
    665     int rv = BCM_E_NONE;
    666     bcm_port_t port_idx;
    667     int pri_en = 0;
    668     uint64 regval64;
    669 
    670     if (!soc_feature(unit, soc_feature_pktpri_as_dot1p)) {
    671         return BCM_E_UNAVAIL;
    672     }
    673 
    674     bcmi_treat_pktpri_as_dot1p[unit].ref_cnt = 0;
    675 
    676     COMPILER_64_ZERO(regval64);
    677     BCM_IF_ERROR_RETURN(
    678         READ_ING_CONFIG_64r(unit, &regval64));
    679     if (soc_reg64_field32_get(unit, ING_CONFIG_64r, regval64,
    680                               TREAT_PKTPRI_AS_DOT1Pf) == 0x1) {
    681         BCM_PBMP_ITER(PBMP_PORT_ALL(unit), port_idx) {
    682             /* Recover ref_cnt for Egress VLAN internal priority mapping */
    683             rv = bcm_esw_port_control_get
    684                      (unit, port_idx,
    685                       bcmPortControlEgressVlanPriUsesPktPri, &pri_en);
    686             if (BCM_FAILURE(rv)) {
    687                 return rv;
    688             }
    689             if (pri_en) {
    690                 BCM_IF_ERROR_RETURN(
    691                     bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update
    692                         (unit, 1));
    693             }
    694 
    695             /* Recover ref_cnt for ETAG internal priority mapping */
    696             if (soc_feature(unit, soc_feature_port_extension)) {
    697                 rv = bcm_esw_port_control_get(unit, port_idx,
    698                                               bcmPortControlUseEtagPri, &pri_en);
    699                 if (BCM_FAILURE(rv)) {
    700                     return rv;
    701                 }
    702                 if (pri_en) {
    703                     BCM_IF_ERROR_RETURN(
    704                         bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update
    705                             (unit, 1));
    706                 }
    707             }
    708 #ifdef BCM_HURRICANE3_SUPPORT
    709             /* Recover ref_cnt for MiML internal priority mapping */
    710             if (soc_feature(unit, soc_feature_miml)) {
    711                 rv = bcm_esw_port_control_get(unit, port_idx,
    712                                               bcmPortControlTrustMimlPri, &pri_en);
    713                 if (BCM_FAILURE(rv)) {
    714                     return rv;
    715                 }
    716                 if (pri_en) {
    717                     BCM_IF_ERROR_RETURN(
    718                         bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update
    719                             (unit, 1));
    720                 }
    721             }
    722 #endif /* BCM_HURRICANE3_SUPPORT */
    723         }
    724     }
    725 
    726     return rv;
    727 }
    728 #endif /* BCM_WARM_BOOT_SUPPORT */
    729 #endif /* BCM_GREYHOUND_SUPPORT */
    730 
    731 /*
    732  * Function:
    733  *      _bcm_esw_port_mon_unimac_lock_up
    734  * Description:
    735  *      Check for UniMAC half duplex collision lock-up issue
    736  * Parameters:
    737  *      pmc  - (IN) port monitor control data
    738  * Return Value:
    739  *      None
    740  * Notes:
    741  *      See errata 56020-ES105-R for additional details.
    742  */
    743 STATIC void
    744 _bcm_esw_port_mon_unimac_lock_up(_port_mon_ctrl_t *pmc)
    745 {
    746     int unit = pmc->unit;
    747     int port, rv, link_up, fulld, lock_up;
    748     uint32 gtuc, gtmca, gtbca, gtlcl, gtpok;
    749     uint32 ccnt, rcnt, txfifo;
    750 
    751     if (!soc_feature(unit, soc_feature_unimac)) {
    752         return;
    753     }
    754 
    755     PBMP_E_ITER(unit, port) {
    756         /* Check only half duplex ports */
    757         rv = _bcm_esw_link_get(unit, port, &link_up);
    758         if (BCM_FAILURE(rv) || !link_up) {
    759             continue;
    760         }
    761         rv = MAC_DUPLEX_GET(PORT(unit, port).p_mac, unit, port, &fulld);
    762         if (BCM_FAILURE(rv) || fulld) {
    763             continue;
    764         }
    765 
    766         lock_up = 0;
    767         rv = 0;
    768 
    769         /* Collect test counters */
    770         rv += soc_counter_get32(unit, port, GTUCr, 0, &gtuc);
    771         rv += soc_counter_get32(unit, port, GTMCAr, 0, &gtmca);
    772         rv += soc_counter_get32(unit, port, GTBCAr, 0, &gtbca);
    773         rv += soc_counter_get32(unit, port, GTLCLr, 0, &gtlcl);
    774         rv += soc_counter_get32(unit, port, GTPOKr, 0, &gtpok);
    775 
    776         /* Test lock-up conditions */
    777         if (gtuc == pmc->gtuc &&
    778             gtmca == pmc->gtmca &&
    779             gtbca == pmc->gtbca) {
    780             if (gtlcl != pmc->gtlcl &&
    781                 gtpok != pmc->gtpok) {
    782                 lock_up = 2;
    783             } else {
    784                 rcnt = ccnt = 0;
    785                 if (SOC_REG_IS_VALID(unit, GE0_GBODE_CELL_CNTr)) {
    786                     uint32 reg, addr, idx;
    787                     idx = (port < 6) ? (port - 1) : ((port - 6) % 12);
    788                     reg = GE0_GBODE_CELL_CNTr;
    789                     addr = soc_reg_addr(unit, reg, port, 0);
    790                     addr += idx;
    791                     rv += soc_reg32_read(unit, addr, &ccnt);
    792                     reg = GE0_GBODE_CELL_REQ_CNTr;
    793                     addr = soc_reg_addr(unit, reg, port, 0);
    794                     addr += idx;
    795                     rv += soc_reg32_read(unit, addr, &rcnt);
    796                 } else if (SOC_REG_IS_VALID(unit, GE_GBODE_CELL_CNTr)) {
    797                     rv += READ_GE_GBODE_CELL_CNTr(unit, port, &ccnt);
    798                     rv += READ_GE_GBODE_CELL_REQ_CNTr(unit, port, &rcnt);
    799                 }
    800                 if (gtlcl && rcnt == 0 && ccnt == 4) {
    801                     lock_up = 1;
    802                 }
    803             }
    804         }
    805         if (lock_up == 0) {
    806             rv += READ_TXFIFO_STATr(unit, port, &txfifo);
    807             if (soc_reg_field_get(unit, TXFIFO_STATr,
    808                                   txfifo, TXFIFO_UNDERRUNf)) {
    809                 lock_up = 2;
    810             }
    811         }
    812 
    813         /* Reset MAC if lock-up is detected */
    814         if (rv == 0 && lock_up) {
    815             LOG_VERBOSE(BSL_LS_BCM_PORT,
    816                         (BSL_META_U(unit,
    817                                     "Port %s: UniMAC lock up (%d) detected\n"),
    818                          SOC_PORT_NAME(unit, port), lock_up));
    819             PORT_LOCK(unit);
    820             MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
    821                             SOC_MAC_CONTROL_SW_RESET, TRUE);
    822             MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
    823                             SOC_MAC_CONTROL_SW_RESET, FALSE);
    824             PORT_UNLOCK(unit);
    825         }
    826 
    827         /* Sync test counters */
    828         pmc->gtuc = gtuc;
    829         pmc->gtmca = gtmca;
    830         pmc->gtbca = gtbca;
    831         pmc->gtlcl = gtlcl;
    832         pmc->gtpok = gtpok;
    833     }
    834 }
    835 
    836 /*
    837  * Function:
    838  *      _bcm_esw_port_mon_ctrl_thread
    839  * Description:
    840  *      Port monitor thread
    841  * Parameters:
    842  *      context  - (IN) Port monitor control data
    843  * Return Value:
    844  *      None
    845  */
    846 STATIC void
    847 _bcm_esw_port_mon_ctrl_thread(void *context)
    848 {
    849     _port_mon_ctrl_t *pmc = (_port_mon_ctrl_t *)context;
    850 
    851     LOG_VERBOSE(BSL_LS_BCM_PORT,
    852                 (BSL_META("Port monitor started on unit %d\n"), pmc->unit));
    853 
    854     pmc->running = 1;
    855     while (!pmc->stop) {
    856         _bcm_esw_port_mon_unimac_lock_up(pmc);
    857         (void)sal_sem_take(pmc->sema, pmc->interval);
    858     }
    859     pmc->running = 0;
    860 }
    861 
    862 /*
    863  * Function:
    864  *      _bcm_esw_port_mon_start
    865  * Description:
    866  *      Start port monitor thread
    867  * Parameters:
    868  *      unit  - (IN) BCM device number
    869  * Return Value:
    870  *      BCM_E_NONE if thread started successfully
    871  */
    872 int
    873 _bcm_esw_port_mon_start(int unit)
    874 {
    875     _port_mon_ctrl_t *pmc = PORT_MON_CTRL(unit);
    876     int cnt;
    877 
    878     pmc->interval = soc_property_get(unit, spn_PORTMON_INTERVAL, 0);
    879     if (pmc->interval == 0) {
    880         return BCM_E_NONE;
    881     }
    882 
    883     if (pmc->interval < PORT_MON_INTERVAL_MIN) {
    884         pmc->interval = PORT_MON_INTERVAL_MIN;
    885     }
    886 
    887     pmc->unit = unit;
    888     if (pmc->running) {
    889         LOG_VERBOSE(BSL_LS_BCM_PORT,
    890                     (BSL_META_U(unit,
    891                                 "Port monitor already running on unit %d\n"),
    892                      pmc->unit));
    893     } else {
    894         if (pmc->sema == NULL) {
    895             pmc->sema = sal_sem_create("port_mon_SLEEP", sal_sem_BINARY, 0);
    896             if (pmc->sema == NULL) {
    897                 return BCM_E_MEMORY;
    898             }
    899         }
    900         sal_snprintf(pmc->taskname, sizeof (pmc->taskname),
    901                      "bcmPortMon.%d", unit);
    902         pmc->stop = 0;
    903         if (sal_thread_create(pmc->taskname, SAL_THREAD_STKSZ,
    904                               soc_property_get(unit,
    905                                                spn_PORTMON_THREAD_PRI,
    906                                                50),
    907                               _bcm_esw_port_mon_ctrl_thread,
    908                               pmc) == SAL_THREAD_ERROR) {
    909             return BCM_E_MEMORY;
    910         }
    911         cnt = 10;
    912         while (!pmc->running && cnt--) {
    913             sal_usleep(100000);
    914         }
    915         if (!pmc->running) {
    916             LOG_ERROR(BSL_LS_BCM_PORT,
    917                       (BSL_META_U(unit,
    918                                   "%s: Thread did not start\n"), pmc->taskname));
    919             return BCM_E_TIMEOUT;
    920         }
    921     }
    922     return BCM_E_NONE;
    923 }
    924 
    925 /*
    926  * Function:
    927  *      _bcm_esw_port_mon_stop
    928  * Description:
    929  *      Stop port monitor thread
    930  * Parameters:
    931  *      unit  - (IN) BCM device number
    932  * Return Value:
    933  *      BCM_E_NONE if thread stopped successfully
    934  */
    935 int
    936 _bcm_esw_port_mon_stop(int unit)
    937 {
    938     int cnt;
    939     _port_mon_ctrl_t *pmc = PORT_MON_CTRL(unit);
    940 
    941     if (pmc->sema == NULL) {
    942         return BCM_E_NONE;
    943     }
    944 
    945     pmc->stop = 1;
    946     sal_sem_give(pmc->sema);
    947     cnt = 10;
    948     while (pmc->running && cnt--) {
    949         sal_usleep(100000);
    950     }
    951     if (pmc->running) {
    952         LOG_ERROR(BSL_LS_BCM_PORT,
    953                   (BSL_META_U(unit,
    954                               "%s: Thread did not start\n"), pmc->taskname));
    955         return BCM_E_TIMEOUT;
    956     }
    957     sal_sem_destroy(pmc->sema);
    958     pmc->sema = NULL;
    959 
    960     return BCM_E_NONE;
    961 }
    962 
    963 #ifdef BCM_TRIUMPH3_SUPPORT
    964 static _port_ibod_ctrl_t *_port_ibod_ctrl[BCM_MAX_NUM_UNITS];
    965 static int txerr_trigger_flag[SOC_MAX_NUM_PORTS];
    966 
    967 #define IBOD_RECOVERY_GROUP_MAX  ((SOC_MAX_NUM_PORTS + 3) /4)
    968 #define IBOD_RECOVERY_GROUP_VALID(grp) ((grp) >= 0 && (grp) < IBOD_RECOVERY_GROUP_MAX)
    969 #define IBOD_RECOVERY_GROUP(phy_port) ((phy_port - 1)/4)
    970 static sal_mutex_t ibod_port_group_recovery_lock[BCM_MAX_NUM_UNITS][IBOD_RECOVERY_GROUP_MAX];
    971         
    972 #define TR3_IARB_TDM_TABLE_LENGTH      512
    973 
    974 #define IBOD_IF_ERROR_RETURN_UNLOCK(unit,port,rv) \
    975         if (SOC_FAILURE(rv)) {   \
    976             soc_ibod_recovery_in_progress_set(unit, 0); \
    977             _bcm_esw_ibod_recovery_port_unlock(unit, port); \
    978             PORT_UNLOCK(unit);       \
    979             return rv;               \
    980         }
    981 
    982 #define TXERR_IF_ERROR_RETURN_UNLOCK(unit,port,rv) \
    983         if (SOC_FAILURE(rv)) {   \
    984             _bcm_esw_ibod_recovery_port_unlock(unit, port); \
    985             PORT_UNLOCK(unit);       \
    986             _bcm_esw_lc_unlock(unit);\
    987             return rv;               \
    988         }
    989 
    990 /*#define IBOD_DEBUG
    991 #define TXERR_DEBUG */
    992 
    993 int _ibod_debug_flag = 0;
    994 
    995 void _bcm_esw_ibod_debug_flag_set(int unit, int flag)
    996 {
    997     _ibod_debug_flag = flag;
    998     cli_out("IBOD debug flag:0X%x\n", _ibod_debug_flag);
    999 }
   1000 
   1001 static int _bcm_esw_ibod_recovery_lock_init(int unit)
   1002 {
   1003     int rv = BCM_E_NONE;
   1004     int group, rollback_group;
   1005 
   1006     for (group = 0; group < IBOD_RECOVERY_GROUP_MAX; group++) {
   1007         ibod_port_group_recovery_lock[unit][group] = sal_mutex_create("IBOD_GROUP_LOCK");
   1008         if (ibod_port_group_recovery_lock[unit][group] == NULL) {
   1009             rv = BCM_E_MEMORY;
   1010             break;
   1011         }
   1012     }
   1013     /* Recycle the memory */
   1014     if (SOC_FAILURE(rv)) {
   1015         for (rollback_group = group - 1; rollback_group >= 0; rollback_group--) {
   1016             sal_mutex_destroy(ibod_port_group_recovery_lock[unit][rollback_group]);
   1017         }
   1018     }
   1019     return BCM_E_NONE;
   1020 }
   1021 
   1022 static void _bcm_esw_ibod_recovery_lock_deinit(int unit)
   1023 {
   1024     int group;
   1025     
   1026     for (group = 0; group < IBOD_RECOVERY_GROUP_MAX; group++) {
   1027         if (ibod_port_group_recovery_lock[unit][group] != NULL) {
   1028             sal_mutex_destroy(ibod_port_group_recovery_lock[unit][group]);
   1029         }
   1030     }
   1031 }
   1032 
   1033 void _bcm_esw_ibod_recovery_port_lock(int unit, bcm_port_t port)
   1034 {
   1035     int phy_port;
   1036     int group;
   1037     /* coverity[overrun-local : FALSE] */
   1038     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   1039     group = IBOD_RECOVERY_GROUP(phy_port);
   1040     if (IBOD_RECOVERY_GROUP_VALID(group) &&
   1041         ibod_port_group_recovery_lock[unit][group] != NULL) {
   1042         sal_mutex_take(ibod_port_group_recovery_lock[unit][group], sal_mutex_FOREVER);
   1043     }
   1044 }
   1045 
   1046 void _bcm_esw_ibod_recovery_port_unlock(int unit, bcm_port_t port)
   1047 {
   1048     int phy_port;
   1049     int group;
   1050     
   1051     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   1052     group = IBOD_RECOVERY_GROUP(phy_port);
   1053     if (IBOD_RECOVERY_GROUP_VALID(group) &&
   1054         ibod_port_group_recovery_lock[unit][group] != NULL) {
   1055         sal_mutex_give(ibod_port_group_recovery_lock[unit][group]);
   1056     }
   1057 }
   1058 
   1059 STATIC int _bcm_tr3_port_is_control_port(int unit, soc_port_t port)
   1060 {
   1061     int phy_port, phy_port_base;
   1062     soc_info_t *si = &SOC_INFO(unit);
   1063 
   1064     phy_port = si->port_l2p_mapping[port];
   1065     if (phy_port == -1) {
   1066         return FALSE;
   1067     }
   1068 
   1069     phy_port_base = ((phy_port - 1) & ~0x3) + 1;
   1070     if (phy_port == phy_port_base) {
   1071         return TRUE;
   1072     }
   1073 
   1074     return FALSE;
   1075 }
   1076 
   1077 STATIC int
   1078 _bcm_tr3_ibod_mac_x_enable_set(int unit, soc_port_t port, int enable)
   1079 {
   1080     uint64 ctrl, octrl;
   1081     pbmp_t mask;
   1082 
   1083     SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &ctrl));
   1084     octrl = ctrl;
   1085     /* Don't disable TX since it stops egress and hangs if CPU sends */
   1086     soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, TX_ENf, 1);
   1087     if (enable) {
   1088         soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, RX_ENf, 1);
   1089     } else {
   1090         soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, RX_ENf, 0);
   1091     }
   1092     if (COMPILER_64_NE(ctrl, octrl)) {
   1093         SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl));
   1094         sal_udelay(10);
   1095     }
   1096 
   1097     /* Put the XMAC in a soft reset state when disabled to allow packets to
   1098      * drain from the TX FIFO */
   1099     soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, SOFT_RESETf,
   1100                           enable ? 0 : 1);
   1101     if (COMPILER_64_NE(ctrl, octrl)) {
   1102         SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl));
   1103     }
   1104 
   1105     if (enable) {
   1106         SOC_IF_ERROR_RETURN(soc_phyctrl_notify(unit, port, phyEventResume,
   1107                                                PHY_STOP_MAC_DIS));
   1108     } else {
   1109         soc_link_mask2_get(unit, &mask);
   1110         SOC_PBMP_PORT_REMOVE(mask, port);
   1111         SOC_IF_ERROR_RETURN(soc_link_mask2_set(unit, mask));
   1112         SOC_IF_ERROR_RETURN(_mac_x_drain_cells(unit, port, 0));
   1113         SOC_IF_ERROR_RETURN(soc_phyctrl_notify(unit, port, phyEventStop,
   1114                                                PHY_STOP_MAC_DIS));
   1115     }
   1116 
   1117     return SOC_E_NONE;
   1118 }
   1119 
   1120 STATIC int
   1121 _bcm_tr3_ibod_port_isolate(int unit, int port_enable, bcm_port_t port,
   1122                                   int *port_dis_untag, int *port_dis_tag)
   1123 {
   1124     port_tab_entry_t ptab_entry;
   1125 
   1126     /* Isolate, drain and remove port from epc link */
   1127     BCM_IF_ERROR_RETURN
   1128         (_bcm_tr3_ibod_mac_x_enable_set(unit, port, FALSE));
   1129 
   1130     if (port_enable) {
   1131         LOG_VERBOSE(BSL_LS_BCM_PORT,
   1132                     (BSL_META_U(unit,
   1133                                "Port %d enable case..\n"), port));
   1134         /* Enable phy so that packets can loopback */
   1135         SOC_IF_ERROR_RETURN
   1136             (soc_phyctrl_enable_set(unit, port, TRUE));
   1137     } else {
   1138         LOG_VERBOSE(BSL_LS_BCM_PORT,
   1139                     (BSL_META_U(unit,
   1140                                 "Port %d Runt received case..\n"), port));
   1141     }
   1142 
   1143     SOC_IF_ERROR_RETURN(MAC_LOOPBACK_SET(PORT(unit, port).p_mac, unit, port, TRUE));
   1144 
   1145     /* Enable MAC so that packets can loopback from phy */
   1146     BCM_IF_ERROR_RETURN
   1147         (_bcm_tr3_ibod_mac_x_enable_set(unit, port, TRUE));
   1148 
   1149     /* Discard tag and untag packet at IP before send packets */
   1150     BCM_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, port, &ptab_entry));
   1151     *port_dis_untag = soc_mem_field32_get(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf);
   1152     *port_dis_tag = soc_mem_field32_get(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf);
   1153     soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf, 1);
   1154     soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf, 1);
   1155     BCM_IF_ERROR_RETURN(soc_mem_write(unit, PORT_TABm, MEM_BLOCK_ALL, port, &ptab_entry));
   1156 
   1157     return SOC_E_NONE;
   1158 }
   1159 
   1160 STATIC int
   1161 _bcm_tr3_ibod_port_resume(int unit, bcm_port_t port, int port_dis_untag, int port_dis_tag)
   1162 {
   1163     pbmp_t epc_pbm;
   1164     port_tab_entry_t ptab_entry;
   1165 
   1166     /* Remove MAC loopback */
   1167     SOC_IF_ERROR_RETURN(MAC_LOOPBACK_SET(PORT(unit, port).p_mac, unit, port, FALSE));
   1168 
   1169     /* Restore port discard tag and untag at IP  */
   1170     BCM_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, port, &ptab_entry));
   1171     soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf, port_dis_untag);
   1172     soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf, port_dis_tag);
   1173     BCM_IF_ERROR_RETURN(soc_mem_write(unit, PORT_TABm, MEM_BLOCK_ALL, port, &ptab_entry));
   1174 
   1175     /* Restore port in epc link bmap */
   1176     soc_link_mask2_get(unit, &epc_pbm);
   1177     SOC_PBMP_PORT_ADD(epc_pbm, port);
   1178     SOC_IF_ERROR_RETURN(soc_link_mask2_set(unit, epc_pbm));
   1179 
   1180     return SOC_E_NONE;
   1181 }
   1182 
   1183 STATIC int
   1184 _bcm_hx4_ibod_sync_recovery_port(_port_ibod_ctrl_t *ibod_ctrl, int port_group_iter,
   1185                                  bcm_port_t port)
   1186 {
   1187     bcm_pbmp_t pbmp;
   1188     bcm_port_t port_iter;
   1189     uint32 port_mode;
   1190     uint32 rval, rval_1, port_dis_tag=0, port_dis_untag=0, xmac_mode=0;
   1191     uint64 rval64,tmp64;
   1192     uint64 egress_meter[4];
   1193     int unit=ibod_ctrl->unit;
   1194     int rv = BCM_E_NONE;
   1195     bcm_pkt_t *pkt = &ibod_ctrl->pkt;
   1196     pbmp_t mask, mask1, mask1_restore, mask_restore;
   1197     uint64 rrpkt, rrbyt, count64, count64_1;
   1198     int count, count_1, i;
   1199     soc_timeout_t timeout;
   1200     egr_enable_entry_t egr_en;
   1201     soc_info_t *si = &SOC_INFO(unit);
   1202     port_tab_entry_t ptab_entry;
   1203     egr_mmu_requests_entry_t mmu_entry;
   1204     int rx_llfc_en[4], rx_pfc_en[4], pause_rx[4], rx_lss[4], rx_lss_1[4], rx_en[4];
   1205     uint32 max_used_entry, ep_level, overflow0, overflow1, total_cell;
   1206     static const soc_reg_t lls_port_credit_reg[] = {
   1207         LLS_PORT_0_CREDITr, LLS_PORT_1_CREDITr, LLS_PORT_2_CREDITr,
   1208         LLS_PORT_3_CREDITr, LLS_PORT_4_CREDITr, LLS_PORT_5_CREDITr,
   1209         LLS_PORT_6_CREDITr, LLS_PORT_7_CREDITr, LLS_PORT_8_CREDITr,
   1210         LLS_PORT_9_CREDITr, LLS_PORT_10_CREDITr, LLS_PORT_11_CREDITr,
   1211         LLS_PORT_12_CREDITr, LLS_PORT_13_CREDITr, LLS_PORT_14_CREDITr,
   1212         LLS_PORT_15_CREDITr, LLS_PORT_16_CREDITr, LLS_PORT_17_CREDITr,
   1213         LLS_PORT_18_CREDITr, LLS_PORT_19_CREDITr, LLS_PORT_20_CREDITr,
   1214         LLS_PORT_21_CREDITr, LLS_PORT_22_CREDITr, LLS_PORT_23_CREDITr,
   1215         LLS_PORT_24_CREDITr, LLS_PORT_25_CREDITr, LLS_PORT_26_CREDITr,
   1216         LLS_PORT_27_CREDITr, LLS_PORT_28_CREDITr, LLS_PORT_29_CREDITr,
   1217         LLS_PORT_30_CREDITr, LLS_PORT_31_CREDITr, LLS_PORT_32_CREDITr,
   1218         LLS_PORT_33_CREDITr, LLS_PORT_34_CREDITr, LLS_PORT_35_CREDITr,
   1219         LLS_PORT_36_CREDITr, LLS_PORT_37_CREDITr, LLS_PORT_38_CREDITr,
   1220         LLS_PORT_39_CREDITr, LLS_PORT_40_CREDITr, LLS_PORT_41_CREDITr,
   1221         LLS_PORT_42_CREDITr, LLS_PORT_43_CREDITr, LLS_PORT_44_CREDITr,
   1222         LLS_PORT_45_CREDITr, LLS_PORT_46_CREDITr, LLS_PORT_47_CREDITr,
   1223         LLS_PORT_48_CREDITr, LLS_PORT_49_CREDITr, LLS_PORT_50_CREDITr,
   1224         LLS_PORT_51_CREDITr, LLS_PORT_52_CREDITr, LLS_PORT_53_CREDITr,
   1225         LLS_PORT_54_CREDITr, LLS_PORT_55_CREDITr, LLS_PORT_56_CREDITr,
   1226         LLS_PORT_57_CREDITr, LLS_PORT_58_CREDITr, LLS_PORT_59_CREDITr,
   1227         LLS_PORT_60_CREDITr, LLS_PORT_61_CREDITr, LLS_PORT_62_CREDITr
   1228     }; 
   1229     sal_usecs_t time1, time2;
   1230 
   1231     time1 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time);
   1232 
   1233     rv = bcm_esw_port_subsidiary_ports_get(unit, port, &pbmp);
   1234     if (BCM_FAILURE(rv)) {
   1235         LOG_ERROR(BSL_LS_BCM_PORT,
   1236                   (BSL_META_U(unit, "\n Error in retreiving the subsidiary ports"
   1237                   "for port %s"), SOC_PORT_NAME(unit,port)));
   1238         return BCM_E_NONE;
   1239     }
   1240 
   1241     count=0;
   1242     BCM_PBMP_ITER(pbmp, port_iter) {
   1243         rv = READ_XMAC_MODEr(unit, port_iter, &rval64);
   1244         if (BCM_FAILURE(rv)) {
   1245             return BCM_E_NONE;
   1246         }
   1247         xmac_mode = soc_reg64_field32_get(unit, XMAC_MODEr,rval64, HDR_MODEf);
   1248         if ((xmac_mode == 1) || (xmac_mode == 2)) {
   1249             count++;
   1250         }
   1251     }
   1252 
   1253     if (!count) {
   1254          return BCM_E_NONE;
   1255     }
   1256 
   1257     BCM_PBMP_ITER(pbmp, port_iter) {
   1258         SOC_IF_ERROR_RETURN(READ_PORT_CDC_TXFIFO_OVRFLWr(unit, port_iter, &rval));
   1259         if (rval) {
   1260             LOG_ERROR(BSL_LS_BCM_PORT,
   1261                       (BSL_META_U(unit, "ENTER VALIDATE PORT_CDC_TXFIFO_OVRFLW ERR"
   1262                       " failed on port:%d\n\r"), port_iter ));
   1263         }
   1264     }
   1265 
   1266     _bcm_esw_lc_lock(unit);
   1267 
   1268     soc_link_fwd_get(unit, &mask1);
   1269     SOC_PBMP_ASSIGN(mask1_restore,mask1);
   1270      BCM_PBMP_ITER(pbmp, port_iter) {
   1271         BCM_PBMP_PORT_REMOVE(mask1,port_iter);
   1272      }
   1273     rv = soc_link_fwd_set(unit, mask1);
   1274     if (BCM_FAILURE(rv)) {
   1275         _bcm_esw_lc_unlock(unit);
   1276         LOG_ERROR(BSL_LS_BCM_PORT,
   1277                   (BSL_META_U(unit, "\n Error in setting the mask FWD"
   1278                   " for WAR on port %s"), SOC_PORT_NAME(unit,port)));
   1279         return BCM_E_NONE;
   1280     }
   1281     
   1282     /* Hold the ibod recovery port group lock */
   1283     _bcm_esw_ibod_recovery_port_lock(unit, port);
   1284     PORT_LOCK(unit);
   1285 
   1286     soc_link_mask2_get(unit, &mask);
   1287     SOC_PBMP_ASSIGN(mask_restore, mask);
   1288     BCM_PBMP_ITER(pbmp, port_iter) {
   1289         BCM_PBMP_PORT_REMOVE(mask,port_iter);
   1290     }
   1291     rv = soc_link_mask2_set(unit, mask);
   1292     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1293 
   1294     
   1295     BCM_PBMP_ITER(pbmp, port_iter) {
   1296         rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, port_iter,
   1297                           &ptab_entry);
   1298         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1299         port_dis_untag = soc_mem_field32_get(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf);
   1300         port_dis_tag = soc_mem_field32_get(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf);
   1301         soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf, 1);
   1302         soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf, 1);
   1303         rv = soc_mem_write(unit, PORT_TABm, MEM_BLOCK_ALL, port_iter,
   1304                            &ptab_entry);
   1305         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1306     }
   1307 
   1308     count=0;
   1309     BCM_PBMP_ITER(pbmp, port_iter) {
   1310         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1311         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1312         rx_en[count] = soc_reg64_field32_get(unit, XMAC_CTRLr, rval64, RX_ENf);
   1313         count++; 
   1314         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf, 0);
   1315         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1316         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1317     }
   1318 
   1319     BCM_PBMP_ITER(pbmp, port_iter) {
   1320         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1321         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1322         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, TX_ENf, 0);
   1323         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1324         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1325     }
   1326 
   1327     BCM_PBMP_ITER(pbmp, port_iter) {
   1328         rv = READ_XMAC_TX_CTRLr(unit, port_iter, &rval64);
   1329         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1330         soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval64, DISCARDf, 1);
   1331         rv = WRITE_XMAC_TX_CTRLr(unit, port_iter, rval64);
   1332         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1333     }
   1334     
   1335     BCM_PBMP_ITER(pbmp, port_iter) {
   1336         rv = READ_XPORT_TO_MMU_BKPr(unit, port_iter, &rval);
   1337         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1338         soc_reg_field_set(unit, XPORT_TO_MMU_BKPr, &rval, PRI15_0_BKPf, 0);
   1339         rv = WRITE_XPORT_TO_MMU_BKPr(unit, port_iter, 0);
   1340         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1341     }
   1342     
   1343     count=0;
   1344     BCM_PBMP_ITER(pbmp, port_iter) {
   1345         rv = READ_XMAC_PAUSE_CTRLr(unit, port_iter, &rval64);
   1346         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1347         pause_rx[count] = soc_reg64_field32_get(unit, XMAC_PAUSE_CTRLr, rval64, RX_PAUSE_ENf);
   1348         soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, &rval64, RX_PAUSE_ENf, 0);
   1349         rv = WRITE_XMAC_PAUSE_CTRLr(unit, port_iter, rval64);
   1350         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1351 
   1352         rv = READ_XMAC_PFC_CTRLr(unit, port_iter, &rval64);
   1353         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1354         rx_pfc_en[count] = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval64, RX_PFC_ENf);
   1355         soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, &rval64, RX_PFC_ENf, 0);
   1356         rv = WRITE_XMAC_PFC_CTRLr(unit, port_iter, rval64);
   1357         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1358 
   1359         rv = READ_XMAC_LLFC_CTRLr(unit, port_iter, &rval64);
   1360         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1361         rx_llfc_en[count] = soc_reg64_field32_get(unit, XMAC_LLFC_CTRLr, rval64, RX_LLFC_ENf);
   1362         soc_reg64_field32_set(unit, XMAC_LLFC_CTRLr, &rval64, RX_LLFC_ENf, 0);
   1363         rv = WRITE_XMAC_LLFC_CTRLr(unit, port_iter, rval64);
   1364         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1365         count++;
   1366     }
   1367 
   1368     count=0;
   1369     BCM_PBMP_ITER(pbmp, port_iter) {
   1370         rv = READ_EGRMETERINGCONFIG_64r(unit, port_iter, &rval64);
   1371         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1372         egress_meter[count]=rval64;
   1373         COMPILER_64_ZERO(tmp64);
   1374         rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, tmp64);
   1375         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1376         count++;
   1377     }
   1378 
   1379     count=0;
   1380     BCM_PBMP_ITER(pbmp, port_iter) {
   1381         rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64);
   1382         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1383         rx_lss[count] = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64,
   1384                                        DROP_TX_DATA_ON_LOCAL_FAULTf);
   1385         rx_lss_1[count] = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64,
   1386                                        DROP_TX_DATA_ON_REMOTE_FAULTf);
   1387         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 1);
   1388         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, 1);
   1389         rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64);
   1390         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1391         count++;
   1392     }
   1393 
   1394     COMPILER_64_SET(tmp64, pbmp.pbits[1], pbmp.pbits[0]);
   1395     rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64);
   1396     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1397     soc_reg64_field_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, tmp64);
   1398     rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64);
   1399     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1400 
   1401     BCM_PBMP_ITER(pbmp, port_iter) {
   1402         rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, &rval);
   1403         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1404         soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 1);
   1405         rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, rval);
   1406         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1407     }
   1408 
   1409     count_1=0;
   1410     soc_timeout_init(&timeout, 30000, 0);
   1411     do {
   1412         if (soc_timeout_check(&timeout)) {
   1413             rv = READ_EGR_EDB_MISC_CTRLr(unit, &rval);
   1414             TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1415             soc_reg_field_set(unit, EGR_EDB_MISC_CTRLr, &rval, SELECT_CURRENT_USED_ENTRIESf, 1);
   1416             rv = WRITE_EGR_EDB_MISC_CTRLr(unit, rval);
   1417             TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1418             /* coverity[overrun-local : FALSE] */
   1419             rv = READ_EGR_MAX_USED_ENTRIESm(unit, MEM_BLOCK_ALL,
   1420                                             si->port_l2p_mapping[port],
   1421                                             &max_used_entry);
   1422             TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1423             ep_level = soc_mem_field32_get(unit, EGR_MAX_USED_ENTRIESm, &max_used_entry, LEVELf);
   1424             if(ep_level == 0) {
   1425                 ibod_ctrl->drain_timeout_flag = 1;
   1426             }
   1427             else {
   1428                 rv = READ_PQEFIFOOVERFLOW0r(unit, &overflow0);
   1429                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1430                 rv = READ_PQEFIFOOVERFLOW1r(unit, &overflow1);
   1431                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1432                 rv = READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port, &total_cell);
   1433                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1434                 LOG_ERROR(BSL_LS_BCM_PORT,
   1435                     (BSL_META_U(unit, "\n IBOD recovery Timeout Drain packets %d PORT: %s, "
   1436                     "ep_level:%d, overflow0:%d, overflow1:%d,total_cell:%d\n"),
   1437                     ibod_ctrl->unit, SOC_PORT_NAME(unit,port), ep_level, overflow0, overflow1,total_cell));
   1438             }
   1439             break;
   1440         } else {
   1441             BCM_PBMP_ITER(pbmp, port_iter) {
   1442                rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]],
   1443                              REG_PORT_ANY, 0, &rval);
   1444                TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1445                if (!rval) {
   1446                    count_1++;
   1447                    rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY,
   1448                                      si->port_l2p_mapping[port_iter],
   1449                                      &mmu_entry);
   1450                    TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1451                    rval = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf);
   1452                    rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]],
   1453                                  REG_PORT_ANY, 0, rval);
   1454                    TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1455                }
   1456             }
   1457             count=0;
   1458             BCM_PBMP_ITER(pbmp, port_iter) {
   1459                 rv = READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port_iter, &rval);
   1460                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1461                 count += soc_reg_field_get(unit, OP_PORT_TOTAL_COUNT_CELLr,rval, TOTAL_COUNTf);
   1462                 rv = READ_PORT_TXFIFO_CELL_CNTr(unit, port_iter, &rval);
   1463                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1464                 count += soc_reg_field_get(unit, PORT_TXFIFO_CELL_CNTr, rval, CELL_CNTf);
   1465             }
   1466        }
   1467     } while (count);
   1468 
   1469     BCM_PBMP_ITER(pbmp, port_iter) {
   1470         /* coverity[overrun-local : FALSE] */
   1471         rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY,
   1472                           si->port_l2p_mapping[port_iter], &mmu_entry);
   1473         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1474         rval = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf);
   1475         /* coverity[overrun-local : FALSE] */
   1476         rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]],
   1477                       REG_PORT_ANY, 0, &rval_1);
   1478         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1479         if (rval != rval_1) {
   1480             /* coverity[overrun-local : FALSE] */
   1481             rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]],
   1482                           REG_PORT_ANY, 0, rval);
   1483             TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1484         } 
   1485     }
   1486 
   1487     count = 0;
   1488     BCM_PBMP_ITER(pbmp, port_iter) {
   1489         rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, egress_meter[count]);
   1490         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1491         count++;
   1492     }
   1493 
   1494     rv = READ_PORT_MODE_REGr(unit, port, &rval);
   1495     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1496     port_mode = soc_reg_field_get(unit, PORT_MODE_REGr,
   1497                                 rval, XPORT0_CORE_PORT_MODEf);
   1498 
   1499     BCM_PBMP_ITER(pbmp, port_iter) {
   1500         rv = READ_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, &rval64);
   1501         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1502         soc_reg64_field32_set(unit, XMAC_CLEAR_FIFO_STATUSr, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 1);
   1503         rv = WRITE_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, rval64);
   1504         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1505     }
   1506 
   1507     BCM_PBMP_ITER(pbmp, port_iter) {
   1508         rv = READ_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, &rval64);
   1509         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1510         soc_reg64_field32_set(unit, XMAC_CLEAR_FIFO_STATUSr, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 0);
   1511         rv = WRITE_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, rval64);
   1512         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1513     }
   1514 
   1515     rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64);
   1516     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1517     soc_reg64_field32_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, 0);
   1518     rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64);
   1519     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1520 
   1521     BCM_PBMP_ITER(pbmp, port_iter) {
   1522         rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, &rval);
   1523         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1524         soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 0);
   1525         rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, rval);
   1526         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1527     }
   1528 
   1529     BCM_PBMP_ITER(pbmp, port_iter) {
   1530         rv = READ_RRPKTr(unit, port_iter, &rrpkt);
   1531         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1532         rv = READ_RRBYTr(unit, port_iter, &rrbyt);
   1533         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1534         /* coverity[overrun-local : FALSE] */
   1535         ibod_ctrl->rrpkt[port_iter] = rrpkt;
   1536         ibod_ctrl->rrbyt[port_iter] = rrbyt;
   1537     }
   1538 
   1539     BCM_PBMP_ITER(pbmp, port_iter) {
   1540         /* coverity[overrun-local : FALSE] */
   1541         rv = READ_EGR_ENABLEm(
   1542                 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en);
   1543         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1544         soc_EGR_ENABLEm_field32_set(unit, &egr_en, PRT_ENABLEf, 0);
   1545         rv = WRITE_EGR_ENABLEm(
   1546                 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en);
   1547         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1548     }
   1549 
   1550     BCM_PBMP_ITER(pbmp, port_iter) {
   1551         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1552         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1553         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 1);
   1554         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1555         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1556     }
   1557 
   1558     rv = READ_PORT_ENABLE_REGr(unit, port, &rval);
   1559     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1560     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT0f , 0);
   1561     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT1f , 0);
   1562     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT2f , 0);
   1563     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT3f , 0);
   1564     rv = WRITE_PORT_ENABLE_REGr(unit, port, rval);
   1565     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1566 
   1567     rv = READ_PORT_MODE_REGr(unit, port, &rval);
   1568     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1569     port_mode=soc_reg_field_get(unit, PORT_MODE_REGr,
   1570                                 rval, XPORT0_CORE_PORT_MODEf);
   1571     if(port_mode) {
   1572         soc_reg_field_set(unit, PORT_MODE_REGr,
   1573                            &rval, XPORT0_CORE_PORT_MODEf,0);
   1574     }
   1575     else {
   1576         soc_reg_field_set(unit, PORT_MODE_REGr,
   1577                            &rval, XPORT0_CORE_PORT_MODEf,1);
   1578     }
   1579     rv = WRITE_PORT_MODE_REGr(unit, port, rval);
   1580     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1581     rv = READ_PORT_MODE_REGr(unit, port, &rval);
   1582     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1583     soc_reg_field_set(unit, PORT_MODE_REGr,
   1584                       &rval, XPORT0_CORE_PORT_MODEf,port_mode);
   1585     rv = WRITE_PORT_MODE_REGr(unit, port, rval);
   1586     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1587 
   1588     rv = READ_PORT_ENABLE_REGr(unit, port, &rval);
   1589     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1590     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT0f , 1);
   1591     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT2f , 1);
   1592     if (port_mode == 2) {
   1593         soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT1f , 1);
   1594         soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT3f , 1);
   1595     }
   1596     rv = WRITE_PORT_ENABLE_REGr(unit, port, rval);
   1597     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1598 
   1599     BCM_PBMP_ITER(pbmp, port_iter) {
   1600         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1601         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1602         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 0);
   1603         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1604         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1605     }
   1606 
   1607     BCM_PBMP_ITER(pbmp, port_iter) {
   1608         rv = READ_EGR_ENABLEm(
   1609                 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en);
   1610         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1611         soc_EGR_ENABLEm_field32_set(unit, &egr_en, PRT_ENABLEf, 1);
   1612         rv = WRITE_EGR_ENABLEm(
   1613                 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en);
   1614         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1615     }
   1616 
   1617     BCM_PBMP_ITER(pbmp, port_iter) {
   1618         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1619         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1620         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, LINE_LOCAL_LPBKf, 1);
   1621         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1622         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1623     }
   1624 
   1625     BCM_PBMP_ITER(pbmp, port_iter) {
   1626         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1627         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1628         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, TX_ENf, 1);
   1629         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf, 1);
   1630         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1631         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1632     }
   1633     BCM_PBMP_ITER(pbmp, port_iter) {
   1634         rv = READ_XMAC_TX_CTRLr(unit, port_iter, &rval64);
   1635         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1636         soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval64, DISCARDf, 0);
   1637         rv = WRITE_XMAC_TX_CTRLr(unit, port_iter, rval64);
   1638         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1639     }
   1640     sal_udelay(200); 
   1641     /* Send 80-byte packets to fill IBOD FIFO */
   1642     BCM_PBMP_ITER(pbmp, port_iter) {
   1643         rv = READ_RPKTr(unit, port_iter, &rval64);
   1644         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1645         count64 = soc_reg64_field_get(unit, RPKTr, rval64, COUNTf);
   1646         for (i=0;i<2;i++)
   1647         {
   1648             BCM_PKT_TX_LEN_SET(pkt, 68);
   1649             BCM_PKT_HDR_VTAG_CONTROL_SET(pkt, VLAN_CTRL(0, 0, 1));
   1650             BCM_PKT_PORT_SET(pkt, port_iter, FALSE, FALSE);
   1651             rv = bcm_common_tx(unit, pkt, NULL);
   1652             if (BCM_FAILURE(rv)) {
   1653                 LOG_ERROR(BSL_LS_BCM_PORT,(BSL_META_U(unit,"IBOD 80-byte packet transmit"
   1654                           "failed[%d] on port:%d\n\r"), rv, port_iter));
   1655                 ibod_ctrl->port_recovery_failed_flag = 1;
   1656                 break;
   1657             }
   1658             sal_udelay(200);
   1659 
   1660         }
   1661         if (ibod_ctrl->port_recovery_failed_flag) {
   1662             break;
   1663         }
   1664 
   1665         rv = READ_RPKTr(unit, port_iter, &rval64);
   1666         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1667         count64_1 =  soc_reg64_field_get(unit, RPKTr, rval64, COUNTf);
   1668         COMPILER_64_SET(tmp64, 0, 2);
   1669         COMPILER_64_SUB_64(count64_1, count64);  
   1670         if (COMPILER_64_LT(count64_1, tmp64)) {
   1671             sal_udelay(1000);
   1672             rv = READ_RPKTr(unit, port_iter, &rval64);
   1673             TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1674             count64_1 =  soc_reg64_field_get(unit, RPKTr, rval64, COUNTf);
   1675             COMPILER_64_SUB_64(count64_1, count64);  
   1676             if (COMPILER_64_LT(count64_1, tmp64)) {
   1677                 LOG_WARN(BSL_LS_BCM_PORT,
   1678                      (BSL_META_U(unit,"\n HELIX4 IBOD loopback packet"
   1679                                  " not received in port %s"),SOC_PORT_NAME(unit,port_iter)));
   1680             }
   1681         }
   1682     }
   1683 
   1684     BCM_PBMP_ITER(pbmp, port_iter) {
   1685         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1686         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1687         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf, 0);
   1688         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1689         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1690     }
   1691 
   1692     BCM_PBMP_ITER(pbmp, port_iter) {
   1693         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1694         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1695         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, TX_ENf, 0);
   1696         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1697         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1698     }
   1699 
   1700     BCM_PBMP_ITER(pbmp, port_iter) {
   1701         rv = READ_XMAC_TX_CTRLr(unit, port_iter, &rval64);
   1702         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1703         soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval64, DISCARDf, 1);
   1704         rv = WRITE_XMAC_TX_CTRLr(unit, port_iter, rval64);
   1705         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1706     }
   1707 
   1708     BCM_PBMP_ITER(pbmp, port_iter) {
   1709         rv = READ_EGR_ENABLEm(
   1710                 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en);
   1711         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1712         soc_EGR_ENABLEm_field32_set(unit, &egr_en, PRT_ENABLEf, 0);
   1713         rv = WRITE_EGR_ENABLEm(
   1714                 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en);
   1715         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1716     }
   1717 
   1718     BCM_PBMP_ITER(pbmp, port_iter) {
   1719         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1720         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1721         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 1);
   1722         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1723         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1724     }
   1725 
   1726     rv = READ_PORT_ENABLE_REGr(unit, port, &rval);
   1727     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1728     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT0f , 0);
   1729     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT1f , 0);
   1730     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT2f , 0);
   1731     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT3f , 0);
   1732     rv = WRITE_PORT_ENABLE_REGr(unit, port, rval);
   1733     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1734 
   1735     rv = READ_PORT_MODE_REGr(unit, port, &rval);
   1736     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1737     port_mode=soc_reg_field_get(unit, PORT_MODE_REGr,
   1738                                 rval, XPORT0_CORE_PORT_MODEf);
   1739     if(port_mode) {
   1740         soc_reg_field_set(unit, PORT_MODE_REGr,
   1741                            &rval, XPORT0_CORE_PORT_MODEf,0);
   1742     }
   1743     else {
   1744         soc_reg_field_set(unit, PORT_MODE_REGr,
   1745                            &rval, XPORT0_CORE_PORT_MODEf,1);
   1746     }
   1747     rv = WRITE_PORT_MODE_REGr(unit, port, rval);
   1748     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1749     rv = READ_PORT_MODE_REGr(unit, port, &rval);
   1750     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1751     soc_reg_field_set(unit, PORT_MODE_REGr,
   1752                       &rval, XPORT0_CORE_PORT_MODEf,port_mode);
   1753     rv = WRITE_PORT_MODE_REGr(unit, port, rval);
   1754     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1755 
   1756     rv = READ_PORT_ENABLE_REGr(unit, port, &rval);
   1757     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1758     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT0f , 1);
   1759     soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT2f , 1);
   1760     if (port_mode == 2) {
   1761         soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT1f , 1);
   1762         soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT3f , 1);
   1763     }
   1764     rv = WRITE_PORT_ENABLE_REGr(unit, port, rval);
   1765     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1766 
   1767     BCM_PBMP_ITER(pbmp, port_iter) {
   1768         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1769         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1770         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 0);
   1771         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1772         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1773     }
   1774 
   1775     BCM_PBMP_ITER(pbmp, port_iter) {
   1776         rv = READ_EGR_ENABLEm(
   1777                 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en);
   1778         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1779         soc_EGR_ENABLEm_field32_set(unit, &egr_en, PRT_ENABLEf, 1);
   1780         rv = WRITE_EGR_ENABLEm(
   1781                 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en);
   1782         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1783     }
   1784 
   1785     switch(port_group_iter) {
   1786         case 0:
   1787           rv = READ_IBOD_INTR_STATUSr(unit, &rval);
   1788           TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1789           soc_reg_field_set(unit, IBOD_INTR_STATUSr,
   1790                  &rval, CL0_DATA_FIFO_FULL_ERR_INTR_STATUSf, 1);
   1791           soc_reg_field_set(unit, IBOD_INTR_STATUSr,
   1792                  &rval, CL0_CTRL_FIFO_FULL_ERR_INTR_STATUSf, 1);
   1793           rv = WRITE_IBOD_INTR_STATUSr(unit, rval);
   1794           TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1795           break;
   1796         case 1:
   1797           rv = READ_IBOD_INTR_STATUSr(unit, &rval);
   1798           TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1799           soc_reg_field_set(unit, IBOD_INTR_STATUSr,
   1800                  &rval, CL1_DATA_FIFO_FULL_ERR_INTR_STATUSf, 1);
   1801           soc_reg_field_set(unit, IBOD_INTR_STATUSr,
   1802                  &rval, CL1_CTRL_FIFO_FULL_ERR_INTR_STATUSf, 1);
   1803           rv = WRITE_IBOD_INTR_STATUSr(unit, rval);
   1804           TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1805           break;
   1806         case 2:
   1807           rv = READ_IBOD_INTR_STATUSr(unit, &rval);
   1808           TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1809           soc_reg_field_set(unit, IBOD_INTR_STATUSr,
   1810                  &rval, CL2_DATA_FIFO_FULL_ERR_INTR_STATUSf, 1);
   1811           soc_reg_field_set(unit, IBOD_INTR_STATUSr,
   1812                  &rval, CL2_CTRL_FIFO_FULL_ERR_INTR_STATUSf, 1);
   1813           rv = WRITE_IBOD_INTR_STATUSr(unit, rval);
   1814           TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1815           break;
   1816         default:
   1817           break;
   1818     }
   1819 
   1820     rv = READ_MEM_FAIL_INT_STAT_64r(unit, &rval64);
   1821     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1822     soc_reg64_field32_set(unit, MEM_FAIL_INT_STAT_64r,
   1823                           &rval64, START_BY_START_ERRf, 0);
   1824     rv = WRITE_MEM_FAIL_INT_STAT_64r(unit, rval64);
   1825     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1826 
   1827     rv = READ_MEM_FAIL_INT_CTRr(unit, &rval);
   1828     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1829     soc_reg_field_set(unit, MEM_FAIL_INT_CTRr, &rval, INT_CTRf, 0);
   1830     rv = WRITE_MEM_FAIL_INT_CTRr(unit, rval);
   1831     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1832 
   1833     BCM_PBMP_ITER(pbmp, port_iter) {
   1834         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1835         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1836         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, LINE_LOCAL_LPBKf, 0);
   1837         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1838         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1839     }
   1840 
   1841     BCM_PBMP_ITER(pbmp, port_iter) {
   1842         rv = soc_mem_read(
   1843                 unit, PORT_TABm, MEM_BLOCK_ANY, port_iter, &ptab_entry);
   1844         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1845         soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf, port_dis_untag);
   1846         soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf, port_dis_tag);
   1847         rv = soc_mem_write(
   1848                 unit, PORT_TABm, MEM_BLOCK_ALL, port_iter, &ptab_entry);
   1849         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1850     }
   1851 
   1852     count=0;
   1853     BCM_PBMP_ITER(pbmp, port_iter) {
   1854         rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64);
   1855         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1856         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, rx_lss[count]);
   1857         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, rx_lss_1[count]);
   1858         rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64);
   1859         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1860         count++;
   1861     }
   1862 
   1863     count=0;
   1864     BCM_PBMP_ITER(pbmp, port_iter) {
   1865         rv = READ_XMAC_PAUSE_CTRLr(unit, port_iter, &rval64);
   1866         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1867         soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, &rval64, RX_PAUSE_ENf, pause_rx[count]);
   1868         rv = WRITE_XMAC_PAUSE_CTRLr(unit, port_iter, rval64);
   1869         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1870 
   1871         rv = READ_XMAC_PFC_CTRLr(unit, port_iter, &rval64);
   1872         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1873         soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, &rval64, RX_PFC_ENf, rx_pfc_en[count]);
   1874         rv = WRITE_XMAC_PFC_CTRLr(unit, port_iter, rval64);
   1875         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1876 
   1877         rv = READ_XMAC_LLFC_CTRLr(unit, port_iter, &rval64);
   1878         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1879         soc_reg64_field32_set(unit, XMAC_LLFC_CTRLr, &rval64, RX_LLFC_ENf, rx_llfc_en[count]);
   1880         rv = WRITE_XMAC_LLFC_CTRLr(unit, port_iter, rval64);
   1881         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1882         count++;
   1883     }
   1884 
   1885     BCM_PBMP_ITER(pbmp, port_iter) {
   1886         rv = READ_XMAC_TX_CTRLr(unit, port_iter, &rval64);
   1887         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1888         soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval64, DISCARDf, 0);
   1889         rv = WRITE_XMAC_TX_CTRLr(unit, port_iter, rval64);
   1890         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1891     }
   1892 
   1893     count=0;
   1894     BCM_PBMP_ITER(pbmp, port_iter) {
   1895         rv = READ_XMAC_CTRLr(unit, port_iter, &rval64);
   1896         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1897         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, TX_ENf, 1);
   1898         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf, rx_en[count]);
   1899         count++;
   1900         rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   1901         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1902     }
   1903     sal_udelay(200);
   1904     rv = soc_link_mask2_set(unit, mask_restore);
   1905     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   1906 
   1907     PORT_UNLOCK(unit);
   1908     /* Release the ibod recovery port group lock */
   1909     _bcm_esw_ibod_recovery_port_unlock(unit, port);
   1910     
   1911     rv = soc_link_fwd_set(unit, mask1_restore);
   1912     if (BCM_FAILURE(rv)) {
   1913         _bcm_esw_lc_unlock(unit);
   1914         LOG_ERROR(BSL_LS_BCM_PORT,
   1915                       (BSL_META_U(unit,"\n Error in re-setting the mask FWD"
   1916                                  " for WAR on port %s"), SOC_PORT_NAME(unit,port)));
   1917         return BCM_E_NONE;
   1918     }
   1919     _bcm_esw_lc_unlock(unit);
   1920 
   1921     BCM_PBMP_ITER(pbmp, port_iter) {
   1922         SOC_IF_ERROR_RETURN(
   1923             READ_PORT_CDC_TXFIFO_OVRFLWr(unit, port_iter, &rval));
   1924         if (rval) {
   1925             LOG_ERROR(BSL_LS_BCM_PORT,
   1926                       (BSL_META_U(unit," EXIT VALIDATE PORT_CDC_TXFIFO_OVRFLW ERR"
   1927                              " failed on port:%d\n\r"), port_iter));
   1928         }
   1929     }
   1930     time2 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time);
   1931     ibod_ctrl->event_count++;
   1932     ibod_ctrl->port_avg_time = (ibod_ctrl->port_avg_time*(ibod_ctrl->event_count - 1) +
   1933             time2 - time1) /ibod_ctrl->event_count;
   1934 
   1935     return SOC_E_NONE;
   1936 
   1937 }
   1938 
   1939 STATIC int
   1940 _bcm_hx4_txerr_recovery_port(_port_ibod_ctrl_t *ibod_ctrl,
   1941                                  bcm_port_t port)
   1942 {
   1943     bcm_pbmp_t pbmp;
   1944     bcm_port_t port_iter;
   1945     uint32 port_mode;
   1946     uint32 rval, rval_1;
   1947     uint64 rval64, txerr, flush_enable_pbm, tmp64;
   1948     uint64 egress_meter[4];
   1949     int unit=ibod_ctrl->unit, okay=0, rv = BCM_E_NONE;
   1950     pbmp_t      mask, mask1, mask1_restore, mask_restore;
   1951     soc_timeout_t timeout;
   1952     int count,count_1;
   1953     soc_info_t *si = &SOC_INFO(unit);
   1954     egr_mmu_requests_entry_t mmu_entry;
   1955     int rx_llfc_en[4],rx_pfc_en[4],pause_rx[4], rx_lss[4], rx_lss_1[4];
   1956     uint32 max_used_entry, ep_level, overflow0, overflow1;
   1957     static const soc_reg_t lls_port_credit_reg[] = {
   1958         LLS_PORT_0_CREDITr, LLS_PORT_1_CREDITr, LLS_PORT_2_CREDITr,
   1959         LLS_PORT_3_CREDITr, LLS_PORT_4_CREDITr, LLS_PORT_5_CREDITr,
   1960         LLS_PORT_6_CREDITr, LLS_PORT_7_CREDITr, LLS_PORT_8_CREDITr,
   1961         LLS_PORT_9_CREDITr, LLS_PORT_10_CREDITr, LLS_PORT_11_CREDITr,
   1962         LLS_PORT_12_CREDITr, LLS_PORT_13_CREDITr, LLS_PORT_14_CREDITr,
   1963         LLS_PORT_15_CREDITr, LLS_PORT_16_CREDITr, LLS_PORT_17_CREDITr,
   1964         LLS_PORT_18_CREDITr, LLS_PORT_19_CREDITr, LLS_PORT_20_CREDITr,
   1965         LLS_PORT_21_CREDITr, LLS_PORT_22_CREDITr, LLS_PORT_23_CREDITr,
   1966         LLS_PORT_24_CREDITr, LLS_PORT_25_CREDITr, LLS_PORT_26_CREDITr,
   1967         LLS_PORT_27_CREDITr, LLS_PORT_28_CREDITr, LLS_PORT_29_CREDITr,
   1968         LLS_PORT_30_CREDITr, LLS_PORT_31_CREDITr, LLS_PORT_32_CREDITr,
   1969         LLS_PORT_33_CREDITr, LLS_PORT_34_CREDITr, LLS_PORT_35_CREDITr,
   1970         LLS_PORT_36_CREDITr, LLS_PORT_37_CREDITr, LLS_PORT_38_CREDITr,
   1971         LLS_PORT_39_CREDITr, LLS_PORT_40_CREDITr, LLS_PORT_41_CREDITr,
   1972         LLS_PORT_42_CREDITr, LLS_PORT_43_CREDITr, LLS_PORT_44_CREDITr,
   1973         LLS_PORT_45_CREDITr, LLS_PORT_46_CREDITr, LLS_PORT_47_CREDITr,
   1974         LLS_PORT_48_CREDITr, LLS_PORT_49_CREDITr, LLS_PORT_50_CREDITr,
   1975         LLS_PORT_51_CREDITr, LLS_PORT_52_CREDITr, LLS_PORT_53_CREDITr,
   1976         LLS_PORT_54_CREDITr, LLS_PORT_55_CREDITr, LLS_PORT_56_CREDITr,
   1977         LLS_PORT_57_CREDITr, LLS_PORT_58_CREDITr, LLS_PORT_59_CREDITr,
   1978         LLS_PORT_60_CREDITr, LLS_PORT_61_CREDITr, LLS_PORT_62_CREDITr
   1979     }; 
   1980     sal_usecs_t time1, time2;
   1981 
   1982     time1 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time);
   1983 
   1984     SOC_IF_ERROR_RETURN(READ_PORT_MODE_REGr(unit, port, &rval));
   1985     port_mode=soc_reg_field_get(unit, PORT_MODE_REGr,
   1986                                 rval, XPORT0_CORE_PORT_MODEf);
   1987     sal_memset(&pbmp, 0, sizeof(bcm_pbmp_t));
   1988     if (port_mode) {
   1989         rv = bcm_esw_port_subsidiary_ports_get(unit, port, &pbmp);
   1990         if (BCM_FAILURE(rv)) {
   1991             LOG_ERROR(BSL_LS_BCM_PORT,
   1992                       (BSL_META_U(unit,"\n Error in retreiving the subsidiary ports"
   1993                                      " for port %s"), SOC_PORT_NAME(unit,port)));
   1994             return BCM_E_NONE;
   1995         }
   1996     } else {
   1997         SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &okay));
   1998         if (okay) {
   1999             SOC_PBMP_PORT_ADD(pbmp, port);
   2000         } else {
   2001             return SOC_E_NONE;
   2002         }
   2003     }
   2004 
   2005     BCM_PBMP_ITER(pbmp, port_iter) {
   2006         SOC_IF_ERROR_RETURN(READ_PORT_CDC_TXFIFO_OVRFLWr(unit, port_iter, &rval));
   2007         if (rval) {
   2008             LOG_ERROR(BSL_LS_BCM_PORT,
   2009                       (BSL_META_U(unit,"IBOD PORT_CDC_TXFIFO_OVRFLW ERR"
   2010                          " failed on port:%d\n\r"), port_iter));
   2011         }
   2012     }
   2013 
   2014     count=0;
   2015     BCM_PBMP_ITER(pbmp, port_iter) {
   2016        SOC_IF_ERROR_RETURN(READ_TERRr(unit, port_iter, &txerr));
   2017        /* coverity[overrun-local : FALSE] */
   2018        if (COMPILER_64_NE(ibod_ctrl->txerrpkt[port_iter], txerr)) {
   2019            ibod_ctrl->txerrpkt[port_iter] = txerr;
   2020            count++;
   2021        }
   2022     }
   2023     BCM_PBMP_ITER(pbmp, port_iter) {
   2024         SOC_IF_ERROR_RETURN(READ_XMAC_FIFO_STATUSr(unit, port_iter, &rval64));
   2025         if (!count) {
   2026             count = soc_reg64_field32_get(unit, XMAC_FIFO_STATUSr, rval64, TX_PKT_UNDERFLOWf);
   2027         } 
   2028     }
   2029 
   2030     if (!count) {
   2031         return SOC_E_NONE;
   2032     }
   2033     
   2034     LOG_VERBOSE(BSL_LS_BCM_PORT,
   2035              (BSL_META_U(unit,"\n WAR Trigerred by TXERR in subports %s"),SOC_PORT_NAME(unit,port)));
   2036 
   2037     _bcm_esw_lc_lock(unit);
   2038     soc_link_fwd_get(unit, &mask1);
   2039     SOC_PBMP_ASSIGN(mask1_restore,mask1);
   2040     BCM_PBMP_ITER(pbmp, port_iter) {
   2041         BCM_PBMP_PORT_REMOVE(mask1,port_iter);
   2042     }
   2043     rv = soc_link_fwd_set(unit, mask1);
   2044     if (BCM_FAILURE(rv)) {
   2045         _bcm_esw_lc_unlock(unit);
   2046         LOG_ERROR(BSL_LS_BCM_PORT,
   2047                       (BSL_META_U(unit,"\n Error in setting the mask FWD"
   2048                                  " for WAR on port %s"), SOC_PORT_NAME(unit,port)));
   2049         return BCM_E_NONE;
   2050     }
   2051     
   2052     /* Hold the ibod recovery port group lock */
   2053     _bcm_esw_ibod_recovery_port_lock(unit, port);
   2054     PORT_LOCK(unit);
   2055 
   2056     soc_link_mask2_get(unit, &mask);
   2057     SOC_PBMP_ASSIGN(mask_restore,mask);
   2058     BCM_PBMP_ITER(pbmp, port_iter) {
   2059         BCM_PBMP_PORT_REMOVE(mask,port_iter);
   2060     }
   2061     rv = soc_link_mask2_set(unit, mask);
   2062     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2063 
   2064 
   2065     count=0;
   2066     BCM_PBMP_ITER(pbmp, port_iter) {
   2067         rv = READ_XMAC_PAUSE_CTRLr(unit, port_iter, &rval64);
   2068         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2069         pause_rx[count] = soc_reg64_field32_get(unit, XMAC_PAUSE_CTRLr, rval64, RX_PAUSE_ENf);
   2070         soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, &rval64, RX_PAUSE_ENf, 0);
   2071         rv = WRITE_XMAC_PAUSE_CTRLr(unit, port_iter, rval64);
   2072         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2073 
   2074         rv = READ_XMAC_PFC_CTRLr(unit, port_iter, &rval64);
   2075         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2076         rx_pfc_en[count] = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval64, RX_PFC_ENf);
   2077         soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, &rval64, RX_PFC_ENf, 0);
   2078         rv = WRITE_XMAC_PFC_CTRLr(unit, port_iter, rval64);
   2079         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2080 
   2081         rv = READ_XMAC_LLFC_CTRLr(unit, port_iter, &rval64);
   2082         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2083         rx_llfc_en[count] = soc_reg64_field32_get(unit, XMAC_LLFC_CTRLr, rval64, RX_LLFC_ENf);
   2084         soc_reg64_field32_set(unit, XMAC_LLFC_CTRLr, &rval64, RX_LLFC_ENf, 0);
   2085         rv = WRITE_XMAC_LLFC_CTRLr(unit, port_iter, rval64);
   2086         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2087         count++;
   2088     }
   2089 
   2090     count=0;
   2091     BCM_PBMP_ITER(pbmp, port_iter) {
   2092         rv = READ_EGRMETERINGCONFIG_64r(unit, port_iter, &rval64);
   2093         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2094         egress_meter[count] = rval64;
   2095         COMPILER_64_ZERO(tmp64);
   2096         rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, tmp64);
   2097         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2098         count++;
   2099     }
   2100 
   2101     count=0;
   2102     BCM_PBMP_ITER(pbmp, port_iter) {
   2103         rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64);
   2104         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2105         rx_lss[count] = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64,
   2106                                        DROP_TX_DATA_ON_LOCAL_FAULTf);
   2107         rx_lss_1[count] = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64,
   2108                                        DROP_TX_DATA_ON_REMOTE_FAULTf);
   2109         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 1);
   2110         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, 1);
   2111         rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64);
   2112         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2113         count++;
   2114     }
   2115 
   2116     rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64);
   2117     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2118     COMPILER_64_SET(flush_enable_pbm, pbmp.pbits[1], pbmp.pbits[0]);
   2119     soc_reg64_field_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, flush_enable_pbm);
   2120     rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64);
   2121     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2122 
   2123     BCM_PBMP_ITER(pbmp, port_iter) {
   2124         rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, &rval);
   2125         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2126         soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 1);
   2127         rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, rval);
   2128         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2129     }
   2130     rv = READ_PORT_MODE_REGr(unit, port, &rval);
   2131     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2132     port_mode = soc_reg_field_get(unit, PORT_MODE_REGr,
   2133                                   rval, XPORT0_CORE_PORT_MODEf);
   2134 
   2135     soc_timeout_init(&timeout, 30000, 0);
   2136     count_1=0;
   2137     do {
   2138         if (soc_timeout_check(&timeout)) {
   2139             ep_level = 0;
   2140             BCM_PBMP_ITER(pbmp, port_iter) {
   2141                 rv = READ_EGR_EDB_MISC_CTRLr(unit, &rval);
   2142                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2143                 soc_reg_field_set(unit, EGR_EDB_MISC_CTRLr, &rval, SELECT_CURRENT_USED_ENTRIESf, 1);
   2144                 rv = WRITE_EGR_EDB_MISC_CTRLr(unit, rval);
   2145                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2146                 /* coverity[overrun-local : FALSE] */
   2147                 rv = READ_EGR_MAX_USED_ENTRIESm(
   2148                         unit, MEM_BLOCK_ALL, si->port_l2p_mapping[port_iter],
   2149                         &max_used_entry);
   2150                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2151                 ep_level += soc_mem_field32_get(unit, EGR_MAX_USED_ENTRIESm, &max_used_entry, LEVELf);
   2152             }
   2153             if(ep_level == 0) {
   2154                 ibod_ctrl->drain_timeout_flag = 1;
   2155             }
   2156             else {
   2157                 rv = READ_PQEFIFOOVERFLOW0r(unit, &overflow0);
   2158                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2159                 rv = READ_PQEFIFOOVERFLOW1r(unit, &overflow1);
   2160                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2161                 LOG_ERROR(BSL_LS_BCM_PORT,
   2162                     (BSL_META_U(unit, "\n IBOD recovery Timeout Drain packets %d PORT: %s, "
   2163                         "total ep_level:%d, overflow0:%d, overflow1:%d\n"),
   2164                         ibod_ctrl->unit, SOC_PORT_NAME(unit,port), ep_level, overflow0, overflow1));
   2165             }
   2166             break;
   2167         } else {
   2168             BCM_PBMP_ITER(pbmp, port_iter) {
   2169                 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]],
   2170                                      REG_PORT_ANY, 0, &rval);
   2171                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2172                 if (!rval) {
   2173                     count_1++;
   2174                     rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY,
   2175                                       si->port_l2p_mapping[port_iter],
   2176                                       &mmu_entry);
   2177                     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2178                     rval = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf);
   2179                     rv = soc_reg32_set(unit,
   2180                         lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]],
   2181                         REG_PORT_ANY, 0, rval);
   2182                     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2183                 }
   2184             }
   2185             count=0;
   2186             BCM_PBMP_ITER(pbmp, port_iter) {
   2187                 rv = READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port_iter, &rval);
   2188                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2189                 count += soc_reg_field_get(unit, OP_PORT_TOTAL_COUNT_CELLr,rval, TOTAL_COUNTf);
   2190                 rv = READ_PORT_TXFIFO_CELL_CNTr(unit, port_iter, &rval);
   2191                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2192                 count += soc_reg_field_get(unit, PORT_TXFIFO_CELL_CNTr, rval, CELL_CNTf);
   2193 
   2194             }
   2195        }
   2196     } while (count);
   2197 
   2198     BCM_PBMP_ITER(pbmp, port_iter) {
   2199         rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY,
   2200                           si->port_l2p_mapping[port_iter], &mmu_entry);
   2201         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2202         rval = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf);
   2203         rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]],
   2204                                             REG_PORT_ANY, 0, &rval_1);
   2205         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2206         if (rval != rval_1) {
   2207             rv = soc_reg32_set(unit,
   2208                 lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]],
   2209                 REG_PORT_ANY, 0, rval);
   2210             TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2211         }
   2212     }
   2213 
   2214     BCM_PBMP_ITER(pbmp, port_iter) {
   2215         rv = READ_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, &rval64);
   2216         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2217         soc_reg64_field32_set(unit, XMAC_CLEAR_FIFO_STATUSr, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 1);
   2218         rv = WRITE_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, rval64);
   2219         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2220     }
   2221 
   2222     BCM_PBMP_ITER(pbmp, port_iter) {
   2223         rv = READ_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, &rval64);
   2224         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2225         soc_reg64_field32_set(unit, XMAC_CLEAR_FIFO_STATUSr, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 0);
   2226         rv = WRITE_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, rval64);
   2227         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2228     }
   2229 
   2230     count=0;
   2231     BCM_PBMP_ITER(pbmp, port_iter) {
   2232         rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, egress_meter[count]);
   2233         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2234         count++;
   2235     }
   2236 
   2237     BCM_PBMP_ITER(pbmp, port_iter) {
   2238         rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, &rval);
   2239         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2240         soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 0);
   2241         rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, rval);
   2242         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2243     }
   2244 
   2245     rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64);
   2246     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2247     soc_reg64_field32_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, 0); 
   2248     rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64);
   2249     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2250 
   2251     count=0;
   2252     BCM_PBMP_ITER(pbmp, port_iter) {
   2253         rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64);
   2254         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2255         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, rx_lss[count]);
   2256         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, rx_lss_1[count]);
   2257         rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64);
   2258         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2259         count++;
   2260     }
   2261 
   2262     count=0;
   2263     BCM_PBMP_ITER(pbmp, port_iter) {
   2264         rv = READ_XMAC_PAUSE_CTRLr(unit, port_iter, &rval64);
   2265         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2266         soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, &rval64, RX_PAUSE_ENf, pause_rx[count]);
   2267         rv = WRITE_XMAC_PAUSE_CTRLr(unit, port_iter, rval64);
   2268         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2269 
   2270         rv = READ_XMAC_PFC_CTRLr(unit, port_iter, &rval64);
   2271         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2272         soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, &rval64, RX_PFC_ENf, rx_pfc_en[count]);
   2273         rv = WRITE_XMAC_PFC_CTRLr(unit, port_iter, rval64);
   2274         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2275 
   2276         rv = READ_XMAC_LLFC_CTRLr(unit, port_iter, &rval64);
   2277         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2278         soc_reg64_field32_set(unit, XMAC_LLFC_CTRLr, &rval64, RX_LLFC_ENf, rx_llfc_en[count]);
   2279         rv = WRITE_XMAC_LLFC_CTRLr(unit, port_iter, rval64);
   2280         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2281         count++;
   2282     }
   2283 
   2284     rv = soc_link_mask2_set(unit, mask_restore);
   2285     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   2286     PORT_UNLOCK(unit);
   2287     /* Release the ibod recovery port group lock */
   2288     _bcm_esw_ibod_recovery_port_unlock(unit, port);
   2289 
   2290     rv = soc_link_fwd_set(unit, mask1_restore);
   2291     if (BCM_FAILURE(rv)) {
   2292         _bcm_esw_lc_unlock(unit);
   2293         LOG_ERROR(BSL_LS_BCM_PORT,
   2294                       (BSL_META_U(unit,"\n Error in re-setting the mask FWD"
   2295                                  " for WAR on port %s"), SOC_PORT_NAME(unit,port)));
   2296         return BCM_E_NONE;
   2297     }
   2298 
   2299     _bcm_esw_lc_unlock(unit);
   2300     time2 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time);
   2301     ibod_ctrl->txerr_count++;
   2302     ibod_ctrl->txerr_avg_time = (ibod_ctrl->txerr_avg_time*(ibod_ctrl->txerr_count-1) +
   2303             time2 - time1) /ibod_ctrl->txerr_count;
   2304 
   2305     return SOC_E_NONE;
   2306 }
   2307 
   2308 
   2309 STATIC int
   2310 _bcm_tr3_mmu_recovery(_port_ibod_ctrl_t *ibod_ctrl)
   2311 {
   2312     mac_driver_t *macd;
   2313     bcm_port_t port_iter;
   2314     uint32 rval, rval_1, count;
   2315     uint64 rval64,txerr, val64;
   2316     int unit=ibod_ctrl->unit, rv = BCM_E_NONE;
   2317     soc_info_t *si = &SOC_INFO(unit);
   2318     egr_mmu_requests_entry_t mmu_entry;
   2319     int linkscan_interval, counter_interval;
   2320     uint32 counter_flags;
   2321     uint32    l2x_flags;
   2322     int scan_rate, l2x_running = 0, mem_scan_running = 0;
   2323     sal_usecs_t l2x_interval, scan_interval;
   2324     bcm_pbmp_t rx_en_pbmp, rx_llfc_en_pbmp, tx_llfc_en_pbmp;
   2325     bcm_pbmp_t rx_pfc_en_pbmp, tx_pfc_en_pbmp;
   2326     bcm_pbmp_t pause_rx_pbmp, pause_tx_pbmp;
   2327     bcm_pbmp_t rx_lss_local_pbmp,rx_lss_remote_pbmp, counter_pbmp;
   2328     uint64 egrmeteringconfig[_SOC_TR3_MAX_NUM_LPORTS];
   2329     soc_timeout_t timeout;
   2330     int num_mmu_port, mmu_port, phy_port, port;
   2331     pbmp_t  pbm;
   2332     epc_link_bmap_entry_t entry, epc_lin_bmap_entry;
   2333     static const soc_reg_t lls_port_credit_reg[] = {
   2334         LLS_PORT_0_CREDITr, LLS_PORT_1_CREDITr, LLS_PORT_2_CREDITr,
   2335         LLS_PORT_3_CREDITr, LLS_PORT_4_CREDITr, LLS_PORT_5_CREDITr,
   2336         LLS_PORT_6_CREDITr, LLS_PORT_7_CREDITr, LLS_PORT_8_CREDITr,
   2337         LLS_PORT_9_CREDITr, LLS_PORT_10_CREDITr, LLS_PORT_11_CREDITr,
   2338         LLS_PORT_12_CREDITr, LLS_PORT_13_CREDITr, LLS_PORT_14_CREDITr,
   2339         LLS_PORT_15_CREDITr, LLS_PORT_16_CREDITr, LLS_PORT_17_CREDITr,
   2340         LLS_PORT_18_CREDITr, LLS_PORT_19_CREDITr, LLS_PORT_20_CREDITr,
   2341         LLS_PORT_21_CREDITr, LLS_PORT_22_CREDITr, LLS_PORT_23_CREDITr,
   2342         LLS_PORT_24_CREDITr, LLS_PORT_25_CREDITr, LLS_PORT_26_CREDITr,
   2343         LLS_PORT_27_CREDITr, LLS_PORT_28_CREDITr, LLS_PORT_29_CREDITr,
   2344         LLS_PORT_30_CREDITr, LLS_PORT_31_CREDITr, LLS_PORT_32_CREDITr,
   2345         LLS_PORT_33_CREDITr, LLS_PORT_34_CREDITr, LLS_PORT_35_CREDITr,
   2346         LLS_PORT_36_CREDITr, LLS_PORT_37_CREDITr, LLS_PORT_38_CREDITr,
   2347         LLS_PORT_39_CREDITr, LLS_PORT_40_CREDITr, LLS_PORT_41_CREDITr,
   2348         LLS_PORT_42_CREDITr, LLS_PORT_43_CREDITr, LLS_PORT_44_CREDITr,
   2349         LLS_PORT_45_CREDITr, LLS_PORT_46_CREDITr, LLS_PORT_47_CREDITr,
   2350         LLS_PORT_48_CREDITr, LLS_PORT_49_CREDITr, LLS_PORT_50_CREDITr,
   2351         LLS_PORT_51_CREDITr, LLS_PORT_52_CREDITr, LLS_PORT_53_CREDITr,
   2352         LLS_PORT_54_CREDITr, LLS_PORT_55_CREDITr, LLS_PORT_56_CREDITr,
   2353         LLS_PORT_57_CREDITr, LLS_PORT_58_CREDITr, LLS_PORT_59_CREDITr,
   2354         LLS_PORT_60_CREDITr, LLS_PORT_61_CREDITr, LLS_PORT_62_CREDITr
   2355     }; 
   2356     sal_usecs_t time1, time2;
   2357 
   2358     time1 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time);
   2359 
   2360     /*****"Preparation and Stop ingress traffic Start*****/
   2361     /*1.  Disable all back ground threads to prevent any SBUS acitivities (software handling)*/
   2362     BCM_IF_ERROR_RETURN(bcm_esw_linkscan_enable_get(unit, &linkscan_interval));
   2363     BCM_IF_ERROR_RETURN(bcm_esw_linkscan_enable_set(unit, 0));
   2364     BCM_IF_ERROR_RETURN(soc_counter_status(unit, &counter_flags,
   2365                     &counter_interval, &counter_pbmp));
   2366     BCM_IF_ERROR_RETURN(soc_counter_stop(unit));
   2367     if (soc_l2x_running(unit, &l2x_flags, &l2x_interval)) {
   2368         l2x_running = 1;
   2369         BCM_IF_ERROR_RETURN(soc_l2x_stop(unit));
   2370     }
   2371 #ifdef INCLUDE_MEM_SCAN
   2372     if (soc_mem_scan_running(unit, &scan_rate, &scan_interval)) {
   2373         mem_scan_running = 1;
   2374         BCM_IF_ERROR_RETURN(soc_mem_scan_stop(unit));
   2375     }
   2376 #endif
   2377 
   2378     /*2.  Disable "TX" API to prevent CPU packet from going into MMU (software handling)*/
   2379     PBMP_PORT_ITER(unit, port_iter){
   2380         _bcm_esw_ibod_recovery_port_lock(unit, port_iter);
   2381     }
   2382 
   2383     /*3. Stop all ingress ports traffic to prevent any packet from going into MMU */
   2384     sal_memset(&rx_en_pbmp, 0, sizeof(bcm_pbmp_t));
   2385     PBMP_PORT_ITER(unit, port_iter){
   2386         macd = PORT(unit, port_iter).p_mac;
   2387         rv = MAC_CONTROL_GET(macd,unit, port_iter, SOC_MAC_CONTROL_RX_SET, (int *)&rval);
   2388         if (BCM_FAILURE(rv)) {
   2389             goto end;
   2390         }
   2391         if (rval) {
   2392             BCM_PBMP_PORT_ADD(rx_en_pbmp, port_iter);
   2393         }
   2394         rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_RX_SET, 0);
   2395         if (BCM_FAILURE(rv)) {
   2396             goto end;
   2397         }
   2398     }
   2399 
   2400     /*4. Stop all AXP traffic to prevent any packet from going into MMU */
   2401     sal_memset(&pbm, 0, sizeof(pbmp_t));
   2402     /*    coverity[check_return]    */
   2403     rv = READ_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&entry);
   2404     if (BCM_FAILURE(rv)) {
   2405         goto end;
   2406     }
   2407     sal_memcpy(&epc_lin_bmap_entry, &entry, sizeof(epc_link_bmap_entry_t));
   2408     soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, &entry, PORT_BITMAPf, &pbm);
   2409     rv = WRITE_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&entry);
   2410     if (BCM_FAILURE(rv)) {
   2411         goto end;
   2412     }
   2413     /*****"Preparation and Stop ingress traffic End*****/
   2414 
   2415     /*****Packet Drain Start*****/
   2416     /* 1.Stop all pauses to speed up draining*/
   2417     sal_memset(&pause_rx_pbmp, 0, sizeof(bcm_pbmp_t));
   2418     sal_memset(&pause_tx_pbmp, 0, sizeof(bcm_pbmp_t));
   2419 
   2420     PBMP_PORT_ITER(unit, port_iter){
   2421         macd = PORT(unit, port_iter).p_mac;
   2422         rv = MAC_PAUSE_GET(macd, unit, port_iter, (int *)&rval, (int *)&rval_1);
   2423         if (BCM_FAILURE(rv)) {
   2424             goto end;
   2425         }
   2426         if (rval) {
   2427             BCM_PBMP_PORT_ADD(pause_tx_pbmp, port_iter);
   2428         }
   2429         if (rval_1) {
   2430             BCM_PBMP_PORT_ADD(pause_rx_pbmp, port_iter);
   2431         }
   2432         rv = MAC_PAUSE_SET(macd, unit, port_iter, 0, 0);
   2433         if (BCM_FAILURE(rv)) {
   2434             goto end;
   2435         }
   2436     }
   2437 
   2438     sal_memset(&rx_llfc_en_pbmp, 0, sizeof(bcm_pbmp_t));
   2439     sal_memset(&tx_llfc_en_pbmp, 0, sizeof(bcm_pbmp_t));
   2440     PBMP_PORT_ITER(unit, port_iter){
   2441         macd = PORT(unit, port_iter).p_mac;
   2442         rv = MAC_CONTROL_GET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_TX_ENABLE, (int *)&rval);
   2443         if (BCM_FAILURE(rv)) {
   2444             goto end;
   2445         }
   2446         if (rval) {
   2447             BCM_PBMP_PORT_ADD(tx_llfc_en_pbmp, port_iter);
   2448         }
   2449         rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_TX_ENABLE, 0);
   2450         if (BCM_FAILURE(rv)) {
   2451             goto end;
   2452         }
   2453         rv = MAC_CONTROL_GET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_RX_ENABLE, (int *)&rval);
   2454         if (BCM_FAILURE(rv)) {
   2455             goto end;
   2456         }
   2457         if (rval) {
   2458             BCM_PBMP_PORT_ADD(rx_llfc_en_pbmp, port_iter);
   2459         }
   2460         rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_RX_ENABLE, 0);
   2461         if (BCM_FAILURE(rv)) {
   2462             goto end;
   2463         }
   2464     }
   2465 
   2466     sal_memset(&tx_pfc_en_pbmp, 0, sizeof(bcm_pbmp_t));
   2467     sal_memset(&rx_pfc_en_pbmp, 0, sizeof(bcm_pbmp_t));
   2468     PBMP_PORT_ITER(unit, port_iter){
   2469         macd = PORT(unit, port_iter).p_mac;
   2470         rv = MAC_CONTROL_GET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_TX_ENABLE, (int *)&rval);
   2471         if (BCM_FAILURE(rv)) {
   2472             goto end;
   2473         }
   2474         if (rval) {
   2475             BCM_PBMP_PORT_ADD(tx_pfc_en_pbmp, port_iter);
   2476         }
   2477         rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_TX_ENABLE, 0);
   2478         if (BCM_FAILURE(rv)) {
   2479             goto end;
   2480         }
   2481         rv = MAC_CONTROL_GET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_RX_ENABLE, (int *)&rval);
   2482         if (BCM_FAILURE(rv)) {
   2483             goto end;
   2484         }
   2485         if (rval) {
   2486             BCM_PBMP_PORT_ADD(rx_pfc_en_pbmp, port_iter);
   2487         }
   2488         rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_RX_ENABLE, 0);
   2489         if (BCM_FAILURE(rv)) {
   2490             goto end;
   2491         }
   2492     }
   2493 
   2494     /*2. Set XMAC LLS CTRL to ignore Serdes fault signal which may prevent packets from draining at cable unplug case*/
   2495     sal_memset(&rx_lss_local_pbmp, 0, sizeof(bcm_pbmp_t));
   2496     sal_memset(&rx_lss_remote_pbmp, 0, sizeof(bcm_pbmp_t));
   2497     PBMP_PORT_ITER(unit, port_iter){
   2498         rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64);
   2499         if (BCM_FAILURE(rv)) {
   2500             goto end;
   2501         }
   2502         rval = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64,
   2503                                         DROP_TX_DATA_ON_LOCAL_FAULTf);
   2504         if (0 == rval) {
   2505             BCM_PBMP_PORT_ADD(rx_lss_local_pbmp, port_iter);
   2506             soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 1);
   2507         }
   2508 
   2509         rval = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64,
   2510                                         DROP_TX_DATA_ON_REMOTE_FAULTf);
   2511         if (0 == rval) {
   2512             BCM_PBMP_PORT_ADD(rx_lss_remote_pbmp, port_iter);
   2513             soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, 1);
   2514         }
   2515         rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64);
   2516         if (BCM_FAILURE(rv)) {
   2517             goto end;
   2518         }
   2519     }
   2520 
   2521     /*3. Enable IPMC fast flush */
   2522     rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64);
   2523     if (BCM_FAILURE(rv)) {
   2524         goto end;
   2525     }
   2526 
   2527     COMPILER_64_SET(val64, 0x3fffffff, 0xffffffff);
   2528     soc_reg64_field_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, val64);
   2529     rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64);
   2530     if (BCM_FAILURE(rv)) {
   2531         goto end;
   2532     }
   2533 
   2534     /*4. Set PORT fast flush */
   2535     PBMP_PORT_ITER(unit, port_iter){
   2536         rv = soc_reg_field32_modify(unit, PORT_TXFIFO_PKT_DROP_CTLr, port_iter,
   2537                 DROP_ENf, 1);
   2538         if (BCM_FAILURE(rv)) {
   2539             goto end;
   2540         }
   2541     }
   2542 
   2543     /*5.Stop MMU egress */
   2544     PBMP_PORT_ITER(unit, port_iter){
   2545         rv = READ_EGRMETERINGCONFIG_64r(unit, port_iter, &rval64);
   2546         if (BCM_FAILURE(rv)) {
   2547             goto end;
   2548         }
   2549 
   2550         COMPILER_64_SET(egrmeteringconfig[port_iter], COMPILER_64_HI(rval64), COMPILER_64_LO(rval64));
   2551         COMPILER_64_SET(val64, 0, 0);
   2552         soc_reg64_field_set(unit, EGRMETERINGCONFIG_64r, &rval64, REFRESHf, val64);
   2553         COMPILER_64_SET(val64, 0, 1);
   2554         soc_reg64_field_set(unit, EGRMETERINGCONFIG_64r, &rval64, THD_SELf, val64);
   2555         COMPILER_64_SET(val64, 0, 0);
   2556         soc_reg64_field_set(unit, EGRMETERINGCONFIG_64r, &rval64, METER_GRANf, val64);
   2557         rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, rval64);
   2558         if (BCM_FAILURE(rv)) {
   2559             goto end;
   2560         }
   2561     }
   2562 
   2563     /*6.Wait until all PORT TXFIFO count == 0*/
   2564     soc_timeout_init(&timeout, 30000, 0);
   2565     do {
   2566         if (soc_timeout_check(&timeout)) {
   2567             LOG_ERROR(BSL_LS_BCM_PORT,
   2568                       (BSL_META_U(unit, "\n MMU Recovery Timeout Ports Drain packets unit:%d"), ibod_ctrl->unit));
   2569             break;
   2570         }
   2571         count=0;
   2572         PBMP_PORT_ITER(unit, port_iter){
   2573             rv = READ_PORT_CDC_TXFIFO_CELL_CNTr(unit, port_iter, &rval);
   2574             if (BCM_FAILURE(rv)) {
   2575                 goto end;
   2576             }
   2577             count += soc_reg_field_get(unit, PORT_CDC_TXFIFO_CELL_CNTr,rval, CELL_CNTf);
   2578             rv = READ_PORT_TXFIFO_CELL_CNTr(unit, port_iter, &rval);
   2579             if (BCM_FAILURE(rv)) {
   2580                 goto end;
   2581             }
   2582             count += soc_reg_field_get(unit, PORT_TXFIFO_CELL_CNTr, rval, CELL_CNTf);
   2583         }
   2584     } while (count);
   2585 
   2586     /*****Packet Drain End*****/
   2587 
   2588     /*****MMU reset Start*****/
   2589     /*1. Backup all necessary MMU configurations */
   2590     rv = soc_tr3_mmu_register_store(unit);
   2591     if (BCM_FAILURE(rv)) {
   2592         goto end;
   2593     }
   2594     rv = soc_tr3_mmu_memory_store(unit);
   2595     if (BCM_FAILURE(rv)) {
   2596         goto end;
   2597     }
   2598 
   2599     /*2. Do TOP level MMU reset*/
   2600     rv = READ_TOP_SOFT_RESET_REGr(unit, &rval);
   2601     if (BCM_FAILURE(rv)) {
   2602         goto end;
   2603     }
   2604     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 0);
   2605     rv = WRITE_TOP_SOFT_RESET_REGr(unit, rval);
   2606     if (BCM_FAILURE(rv)) {
   2607         goto end;
   2608     }
   2609     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 1);
   2610     rv = WRITE_TOP_SOFT_RESET_REGr(unit, rval);
   2611     if (BCM_FAILURE(rv)) {
   2612         goto end;
   2613     }
   2614      /* 3. REFRESH_ENF*/
   2615     rv = soc_reg32_get(unit, MISCCONFIGr, REG_PORT_ANY, 0, &rval);
   2616     if (BCM_FAILURE(rv)) {
   2617         goto end;
   2618     }
   2619     soc_reg_field_set(unit, MISCCONFIGr, &rval, METERING_CLK_ENf, 1);
   2620     rv = soc_reg32_set(unit, MISCCONFIGr, REG_PORT_ANY, 0, rval);
   2621     if(BCM_FAILURE(rv)) {
   2622         goto end;
   2623     }
   2624     
   2625     /*4. Call soc_mmu_init to init MMU*/
   2626     rv = soc_mmu_init(unit);
   2627     if (BCM_FAILURE(rv)) {
   2628         goto end;
   2629     }
   2630 
   2631      /*5.Restore Registers/Memories which are called in MMU init (following MMU init sequence)*/
   2632     rv = soc_tr3_mmu_init_restore(unit);
   2633     if (BCM_FAILURE(rv)) {
   2634     goto end;
   2635     }
   2636 
   2637     /*6.Restore other MMU registers without sequence*/
   2638     rv = soc_tr3_mmu_register_restore(unit);
   2639     if (BCM_FAILURE(rv)) {
   2640         goto end;
   2641     }
   2642 
   2643     /*7.Restore other MMU memories without sequence*/
   2644     rv = soc_tr3_mmu_memory_restore(unit);
   2645     if (BCM_FAILURE(rv)) {
   2646         goto end;
   2647     }
   2648 
   2649     /*8.Restore MMU2PHY port mapping and MMU2LOGIC port mapping*/
   2650     num_mmu_port = SOC_REG_NUMELS(unit, MMU_TO_PHY_PORT_MAPPINGr);
   2651     for (mmu_port = 0; mmu_port < num_mmu_port; mmu_port++) {
   2652         phy_port = si->port_m2p_mapping[mmu_port];
   2653         port = phy_port == -1 ? -1 : si->port_p2l_mapping[phy_port];
   2654 
   2655         rval = 0;
   2656         soc_reg_field_set(unit, MMU_TO_PHY_PORT_MAPPINGr, &rval, PHY_PORTf,
   2657                           phy_port == -1 ? 0x7f : phy_port);
   2658         rv = WRITE_MMU_TO_PHY_PORT_MAPPINGr(unit, mmu_port, rval);
   2659         if (BCM_FAILURE(rv)) {
   2660             goto end;
   2661         }
   2662         rval = 0;
   2663         soc_reg_field_set(unit, MMU_TO_LOGIC_PORT_MAPPINGr, &rval, LOGIC_PORTf,
   2664                           port == -1 ? 0x3f : port);
   2665         rv = WRITE_MMU_TO_LOGIC_PORT_MAPPINGr(unit, mmu_port, rval);
   2666         if (BCM_FAILURE(rv)) {
   2667             goto end;
   2668         }
   2669     }
   2670 
   2671     /* 9. Restore MMU to EP credicts after EP restore because EP port enable will update EGR_MMU_REQUESTSm*/
   2672     PBMP_ALL_ITER(unit, port_iter){
   2673         if (!IS_CPU_PORT(unit, port_iter) && !IS_PORT(unit, port_iter)) {
   2674             continue;
   2675         }
   2676         rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, si->port_l2p_mapping[port_iter], &mmu_entry);
   2677         if (BCM_FAILURE(rv)) {
   2678             goto end;
   2679         }
   2680         rval = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf);
   2681         rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]],
   2682                           REG_PORT_ANY, 0, &rval_1);
   2683         if (BCM_FAILURE(rv)) {
   2684             goto end;
   2685         }
   2686         if (rval != rval_1) {
   2687             rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]],
   2688                               REG_PORT_ANY, 0, rval);
   2689             if(BCM_FAILURE(rv)) {
   2690                 goto end;
   2691             }
   2692         }
   2693     }
   2694     /*restore axp credit*/
   2695     rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[58]]],
   2696                       REG_PORT_ANY, 0, 0x14);
   2697     if (BCM_FAILURE(rv)) {
   2698         goto end;
   2699     }
   2700     rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[59]]],
   2701                       REG_PORT_ANY, 0, 0x14);
   2702     if (BCM_FAILURE(rv)) {
   2703         goto end;
   2704     }
   2705     rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[60]]],
   2706                       REG_PORT_ANY, 0, 4);
   2707     if (BCM_FAILURE(rv)) {
   2708         goto end;
   2709     }
   2710     rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[61]]],
   2711                       REG_PORT_ANY, 0, 0x14);
   2712     if (BCM_FAILURE(rv)) {
   2713         goto end;
   2714     }
   2715     /*****MMU reset End*****/
   2716 
   2717     /***** Resume ingress traffic Start*****/
   2718     /*1.Restore XMAC_RX_LSS_CTRL setting*/
   2719     BCM_PBMP_ITER(rx_lss_local_pbmp, port_iter){
   2720         rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64);
   2721         if (BCM_FAILURE(rv)) {
   2722             goto end;
   2723         }
   2724         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 0);
   2725         rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64);
   2726         if (BCM_FAILURE(rv)) {
   2727             goto end;
   2728         }
   2729     }
   2730     BCM_PBMP_ITER(rx_lss_remote_pbmp, port_iter){
   2731         rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64);
   2732         if (BCM_FAILURE(rv)) {
   2733             goto end;
   2734         }
   2735         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 0);
   2736         soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, 0);
   2737         rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64);
   2738         if (BCM_FAILURE(rv)) {
   2739             goto end;
   2740         }
   2741     }
   2742 
   2743     /*2.Restore MMU egress */
   2744     PBMP_PORT_ITER(unit, port_iter){
   2745         rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, egrmeteringconfig[port_iter]);
   2746         if (BCM_FAILURE(rv)) {
   2747             goto end;
   2748         }
   2749     }
   2750 
   2751     /*3.Disable PORT fast flush*/
   2752     PBMP_PORT_ITER(unit, port_iter){
   2753         rv = soc_reg_field32_modify(unit, PORT_TXFIFO_PKT_DROP_CTLr, port_iter,
   2754                 DROP_ENf, 0);
   2755         if (BCM_FAILURE(rv)) {
   2756             goto end;
   2757         }
   2758     }
   2759     /*4.Disable IPMC fast flush  */
   2760     rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64);
   2761     if (BCM_FAILURE(rv)) {
   2762         goto end;
   2763     }
   2764     soc_reg64_field32_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, 0);
   2765     rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64);
   2766     if (BCM_FAILURE(rv)) {
   2767         goto end;
   2768     }
   2769     /* 5.Restore pause settings*/
   2770     BCM_PBMP_ITER(pause_tx_pbmp, port_iter){
   2771         macd = PORT(unit, port_iter).p_mac;
   2772         rv = MAC_PAUSE_GET(macd, unit, port_iter, (int *)&rval, (int *)&rval_1);
   2773         if (BCM_FAILURE(rv)) {
   2774             goto end;
   2775         }
   2776         rv = MAC_PAUSE_SET(macd, unit, port_iter, 1, rval_1);
   2777         if (BCM_FAILURE(rv)) {
   2778             goto end;
   2779         }
   2780     }
   2781     BCM_PBMP_ITER(pause_rx_pbmp, port_iter){
   2782         macd = PORT(unit, port_iter).p_mac;
   2783         rv = MAC_PAUSE_GET(macd, unit, port_iter, (int *)&rval, (int *)&rval_1);
   2784         if (BCM_FAILURE(rv)) {
   2785             goto end;
   2786         }
   2787         rv = MAC_PAUSE_SET(macd, unit, port_iter, rval, 1);
   2788         if (BCM_FAILURE(rv)) {
   2789             goto end;
   2790         }
   2791     }
   2792     BCM_PBMP_ITER(tx_llfc_en_pbmp, port_iter){
   2793         macd = PORT(unit, port_iter).p_mac;
   2794         rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_TX_ENABLE, 1);
   2795         if (BCM_FAILURE(rv)) {
   2796             goto end;
   2797         }
   2798     }
   2799     BCM_PBMP_ITER(rx_llfc_en_pbmp, port_iter){
   2800         macd = PORT(unit, port_iter).p_mac;
   2801         rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_RX_ENABLE, 1);
   2802         if (BCM_FAILURE(rv)) {
   2803             goto end;
   2804         }
   2805     }
   2806     BCM_PBMP_ITER(tx_pfc_en_pbmp, port_iter){
   2807         macd = PORT(unit, port_iter).p_mac;
   2808         rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_TX_ENABLE, 1);
   2809         if (BCM_FAILURE(rv)) {
   2810             goto end;
   2811         }
   2812     }
   2813     BCM_PBMP_ITER(rx_pfc_en_pbmp, port_iter){
   2814         macd = PORT(unit, port_iter).p_mac;
   2815         rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_RX_ENABLE, 1);
   2816         if (BCM_FAILURE(rv)) {
   2817             goto end;
   2818         }
   2819     }
   2820     /* 6. Refresh FLOW CONTROL XOFF state*/
   2821     PBMP_PORT_ITER(unit, port_iter){
   2822         rv = WRITE_FLOW_CONTROL_XOFF_STATEr(unit, port_iter, 0xff);
   2823         if (BCM_FAILURE(rv)) {
   2824             goto end;
   2825         }
   2826         rv = WRITE_FLOW_CONTROL_XOFF_STATEr(unit, port_iter, 0);
   2827         if (BCM_FAILURE(rv)) {
   2828             goto end;
   2829         }
   2830     }
   2831     /*Wait until all EDATABUF FIFO count == 0 (Optional ?)*/
   2832     /*7.Do IBOD reset for all ports*/
   2833     rv = READ_IBOD_BOD_FIFO_CONTROLr(unit, &rval);
   2834     if (BCM_FAILURE(rv)) {
   2835         goto end;
   2836     }
   2837     soc_reg_field_set(unit, IBOD_BOD_FIFO_CONTROLr, &rval, BOD_SW_RST_Lf, 0);
   2838     rv = WRITE_IBOD_BOD_FIFO_CONTROLr(unit, rval);
   2839     if (BCM_FAILURE(rv)) {
   2840         goto end;
   2841     }
   2842     soc_reg_field_set(unit, IBOD_BOD_FIFO_CONTROLr, &rval, BOD_SW_RST_Lf, 1);
   2843     rv = WRITE_IBOD_BOD_FIFO_CONTROLr(unit, rval);
   2844     if (BCM_FAILURE(rv)) {
   2845         goto end;
   2846     }
   2847 
   2848     /*8. Restore EPC  link*/
   2849     rv = WRITE_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&epc_lin_bmap_entry);
   2850     if (BCM_FAILURE(rv)) {
   2851         goto end;
   2852     }
   2853 
   2854     if (SOC_IS_HELIX4(unit)) {
   2855     /*9. Update txerrpkt after modules reset*/
   2856         PBMP_ITER(PBMP_XW_ALL(unit), port) {
   2857             rv = READ_TERRr(unit, port, &txerr);
   2858             if (SOC_FAILURE(rv)) {
   2859                 continue;
   2860             }
   2861             /* coverity[overrun-local : FALSE] */
   2862             ibod_ctrl->txerrpkt[port] = txerr;
   2863         }
   2864     }
   2865     else {
   2866         /*9. Update txerrpkt and tuflpkt after modules reset*/
   2867         PBMP_CL_ITER(unit, port_iter){
   2868             rv = READ_TERRr(unit, port_iter, &rval64);
   2869             if(BCM_FAILURE(rv)) {
   2870                 goto end;
   2871             }
   2872             COMPILER_64_SET(ibod_ctrl->txerrpkt[port_iter],
   2873                              COMPILER_64_HI(rval64), COMPILER_64_LO(rval64));
   2874             rv = READ_TUFLr(unit, port_iter, &rval64);
   2875             if(BCM_FAILURE(rv)) {
   2876                 goto end;
   2877             }
   2878             COMPILER_64_SET(ibod_ctrl->tuflpkt[port_iter],
   2879                              COMPILER_64_HI(rval64), COMPILER_64_LO(rval64));
   2880         }
   2881 
   2882         /* MAC RESET*/
   2883         PBMP_PORT_ITER(unit, port_iter){
   2884             SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port_iter, &rval64));
   2885             soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 1);
   2886             rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   2887             if (BCM_FAILURE(rv)) {
   2888                 goto end;
   2889             }
   2890             soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 0);
   2891             rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64);
   2892             if (BCM_FAILURE(rv)) {
   2893                 goto end;
   2894             }
   2895         }
   2896     }
   2897 
   2898     /*10.Resume ingress traffic*/
   2899     BCM_PBMP_ITER(rx_en_pbmp, port_iter){
   2900         macd = PORT(unit, port_iter).p_mac;
   2901         rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_RX_SET, 1);
   2902         if (BCM_FAILURE(rv)) {
   2903             goto end;
   2904         }
   2905     }
   2906     /***** Resume ingress traffic End*****/
   2907 
   2908     /***** Enable software handling Start*****/
   2909     /*1.  Enable all back ground threads to prevent any SBUS acitivities (software handling)*/
   2910     rv = bcm_esw_linkscan_enable_set(unit, linkscan_interval);
   2911     if (BCM_FAILURE(rv)) {
   2912         goto end;
   2913     }
   2914     rv = soc_counter_start(unit, counter_flags, counter_interval, counter_pbmp);
   2915     if (BCM_FAILURE(rv)) {
   2916         goto end;
   2917     }
   2918     if (l2x_running) {
   2919         rv = soc_l2x_start(unit, l2x_flags, l2x_interval);
   2920         if (BCM_FAILURE(rv)) {
   2921             goto end;
   2922         }
   2923     }
   2924 #ifdef INCLUDE_MEM_SCAN
   2925     if (mem_scan_running) {
   2926         rv = soc_mem_scan_start(unit, scan_rate, scan_interval);
   2927         if (BCM_FAILURE(rv)) {
   2928             goto end;
   2929         }
   2930     }
   2931 #endif
   2932 
   2933 end:
   2934     /*2.  Enable "TX" API to prevent CPU packet from going into MMU (software handling)*/
   2935     PBMP_PORT_ITER(unit, port_iter){
   2936         _bcm_esw_ibod_recovery_port_unlock(unit, port_iter);
   2937     }
   2938 
   2939     /***** Enable software handling End*****/
   2940     time2 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time);
   2941     ibod_ctrl->mmu_war_count++;
   2942     ibod_ctrl->mmu_avg_time= (ibod_ctrl->mmu_avg_time*(ibod_ctrl->mmu_war_count-1)
   2943                                 + time2 - time1) /ibod_ctrl->mmu_war_count;
   2944 
   2945     return rv;
   2946 }
   2947 
   2948 STATIC int
   2949 _bcm_tr3_mmu_check_and_recovery(_port_ibod_ctrl_t *ibod_ctrl)
   2950 {
   2951     int rv = BCM_E_NONE;
   2952     uint32 overflow0,overflow1;
   2953     int ibod_timeout_flag = 0;
   2954     int txerr_timeout_flag = 0;
   2955     int port_recovery_failed_flag = 0;
   2956     int unit = ibod_ctrl->unit;
   2957 
   2958     overflow0 = 0;
   2959     overflow1 = 0;
   2960 
   2961     rv = READ_PQEFIFOOVERFLOW0r(unit, &overflow0);
   2962     if (SOC_FAILURE(rv)) {
   2963         LOG_ERROR(BSL_LS_BCM_PORT,
   2964                    (BSL_META_U(unit, "\n Error in ibod recovery thread when reading register PQEFIFOOVERFLOW0")));
   2965         return rv;
   2966     }
   2967     rv = READ_PQEFIFOOVERFLOW1r(unit, &overflow1);
   2968     if (SOC_FAILURE(rv)) {
   2969         LOG_ERROR(BSL_LS_BCM_PORT,
   2970                    (BSL_META_U(unit, "\n Error in ibod recovery thread when reading register PQEFIFOOVERFLOW1")));
   2971         return rv;
   2972     }
   2973 
   2974     _soc_egress_drain_timeout_flag_get(unit, &ibod_timeout_flag);
   2975     txerr_timeout_flag = ibod_ctrl->drain_timeout_flag;
   2976     port_recovery_failed_flag = ibod_ctrl->port_recovery_failed_flag;
   2977 
   2978     if ((overflow0 != 0) || (overflow1 != 0) || ibod_timeout_flag || txerr_timeout_flag
   2979         || port_recovery_failed_flag || (_ibod_debug_flag & _PORT_IBOD_FLAG_MMU_TRIGGER)) {
   2980         rv = _bcm_tr3_mmu_recovery(ibod_ctrl);
   2981         if (txerr_timeout_flag) {
   2982             ibod_ctrl->drain_timeout_flag = 0;
   2983             ibod_ctrl->drain_timeout_count++;
   2984         }
   2985         if  (port_recovery_failed_flag) {
   2986             ibod_ctrl->port_recovery_failed_flag = 0;
   2987             ibod_ctrl->port_recovery_failed_count++;
   2988         }
   2989         if (ibod_timeout_flag) {
   2990             _soc_egress_drain_timeout_flag_set(unit, 0);
   2991             ibod_ctrl->egress_drain_timeout_count++;
   2992         }
   2993         if (_ibod_debug_flag & _PORT_IBOD_FLAG_MMU_TRIGGER) {
   2994             _ibod_debug_flag &= (~_PORT_IBOD_FLAG_MMU_TRIGGER);
   2995         }
   2996         if (SOC_FAILURE(rv)) {
   2997             LOG_ERROR(BSL_LS_BCM_PORT,
   2998                         (BSL_META_U(unit, "\n Error in MMU recovery ")));
   2999         }
   3000     }
   3001 
   3002     return rv;
   3003 }
   3004 
   3005 STATIC int
   3006 _bcm_tr3_txerr_recovery_port(_port_ibod_ctrl_t *ibod_ctrl,
   3007                                  bcm_port_t port)
   3008 {
   3009     bcm_pbmp_t pbmp;
   3010     uint32 rval;
   3011     uint64 rval64, txerr, tufl, flush_enable_pbm, tmp64;
   3012     uint64 egress_meter;
   3013     int unit=ibod_ctrl->unit, okay=0, rv = BCM_E_NONE;
   3014     pbmp_t      mask, mask1, mask1_restore, mask_restore;
   3015     soc_timeout_t timeout;
   3016     int txerr_status,tufl_status, underflow_status, lanes;
   3017     uint32 cur_cells, new_cells, mmu_cells,credit_set;
   3018     uint32 cdc_fifo_cells, tx_fifo_cells;
   3019     uint32 overflow0, overflow1, total_cell;
   3020     soc_info_t *si = &SOC_INFO(unit);
   3021     egr_mmu_requests_entry_t mmu_entry;
   3022     uint32 max_used_entry;
   3023 #ifdef TXERR_DEBUG
   3024     uint64 tpkt, tfcs;
   3025     uint32 ep_max_level = 0;
   3026 #endif
   3027     uint32 credit, mmu_req, ep_level;
   3028     int rx_llfc_en,rx_pfc_en,pause_rx, rx_lss, rx_lss_1;
   3029     soc_reg_t temp_reg_id;
   3030     static const soc_reg_t lls_port_credit_reg[] = {
   3031         LLS_PORT_0_CREDITr, LLS_PORT_1_CREDITr, LLS_PORT_2_CREDITr,
   3032         LLS_PORT_3_CREDITr, LLS_PORT_4_CREDITr, LLS_PORT_5_CREDITr,
   3033         LLS_PORT_6_CREDITr, LLS_PORT_7_CREDITr, LLS_PORT_8_CREDITr,
   3034         LLS_PORT_9_CREDITr, LLS_PORT_10_CREDITr, LLS_PORT_11_CREDITr,
   3035         LLS_PORT_12_CREDITr, LLS_PORT_13_CREDITr, LLS_PORT_14_CREDITr,
   3036         LLS_PORT_15_CREDITr, LLS_PORT_16_CREDITr, LLS_PORT_17_CREDITr,
   3037         LLS_PORT_18_CREDITr, LLS_PORT_19_CREDITr, LLS_PORT_20_CREDITr,
   3038         LLS_PORT_21_CREDITr, LLS_PORT_22_CREDITr, LLS_PORT_23_CREDITr,
   3039         LLS_PORT_24_CREDITr, LLS_PORT_25_CREDITr, LLS_PORT_26_CREDITr,
   3040         LLS_PORT_27_CREDITr, LLS_PORT_28_CREDITr, LLS_PORT_29_CREDITr,
   3041         LLS_PORT_30_CREDITr, LLS_PORT_31_CREDITr, LLS_PORT_32_CREDITr,
   3042         LLS_PORT_33_CREDITr, LLS_PORT_34_CREDITr, LLS_PORT_35_CREDITr,
   3043         LLS_PORT_36_CREDITr, LLS_PORT_37_CREDITr, LLS_PORT_38_CREDITr,
   3044         LLS_PORT_39_CREDITr, LLS_PORT_40_CREDITr, LLS_PORT_41_CREDITr,
   3045         LLS_PORT_42_CREDITr, LLS_PORT_43_CREDITr, LLS_PORT_44_CREDITr,
   3046         LLS_PORT_45_CREDITr, LLS_PORT_46_CREDITr, LLS_PORT_47_CREDITr,
   3047         LLS_PORT_48_CREDITr, LLS_PORT_49_CREDITr, LLS_PORT_50_CREDITr,
   3048         LLS_PORT_51_CREDITr, LLS_PORT_52_CREDITr, LLS_PORT_53_CREDITr,
   3049         LLS_PORT_54_CREDITr, LLS_PORT_55_CREDITr, LLS_PORT_56_CREDITr,
   3050         LLS_PORT_57_CREDITr, LLS_PORT_58_CREDITr, LLS_PORT_59_CREDITr,
   3051         LLS_PORT_60_CREDITr, LLS_PORT_61_CREDITr, LLS_PORT_62_CREDITr
   3052     }; 
   3053     sal_usecs_t time1, time2;
   3054 
   3055     sal_memset(&pbmp, 0, sizeof(bcm_pbmp_t));
   3056     SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &okay));
   3057     if (okay) {
   3058         SOC_PBMP_PORT_ADD(pbmp, port);
   3059     } else {
   3060         return SOC_E_NONE;
   3061     }
   3062 
   3063     txerr_status = 0;
   3064     /* check and update tx err counter */
   3065     SOC_IF_ERROR_RETURN(READ_TERRr(unit, port, &txerr));
   3066     if (COMPILER_64_NE(ibod_ctrl->txerrpkt[port], txerr)) {
   3067        ibod_ctrl->txerrpkt[port] = txerr;
   3068        txerr_status = 1;
   3069     }
   3070 
   3071     tufl_status = 0;
   3072     /* check and update tx underflow counter */
   3073     SOC_IF_ERROR_RETURN(READ_TUFLr(unit, port, &tufl));
   3074     if (COMPILER_64_NE(ibod_ctrl->tuflpkt[port], tufl)) {
   3075        ibod_ctrl->tuflpkt[port] = tufl;
   3076        tufl_status = 1;
   3077     }
   3078     temp_reg_id = IS_C_PORT(unit, port) ? CMAC_FIFO_STATUSr : XMAC_FIFO_STATUSr;
   3079     BCM_IF_ERROR_RETURN(soc_reg64_get(unit, temp_reg_id, port, 0, &rval64));
   3080     underflow_status = soc_reg64_field32_get(unit, temp_reg_id, rval64, TX_PKT_UNDERFLOWf);
   3081 
   3082     /* check tx error and tx underflow */
   3083     if ((txerr_status == 0) && (tufl_status == 0) &&(underflow_status == 0) &&
   3084         (txerr_trigger_flag[port] == 0)) {
   3085         return SOC_E_NONE;
   3086     }
   3087 
   3088     if ((txerr_status != 0) || (tufl_status != 0) || (underflow_status != 0)) {
   3089         txerr_trigger_flag[port] = 1;
   3090     }
   3091     else if (txerr_trigger_flag[port] == 1) {
   3092         txerr_trigger_flag[port] = 0;
   3093     }
   3094 
   3095 #ifdef TXERR_DEBUG
   3096     cli_out("WAR TER Trigerred  [port %d]:txerr_status:%d, tufl_status:%d, underflow_status:%d\r\n",
   3097             port, txerr_status,  tufl_status, underflow_status);
   3098 #endif
   3099     rv = (soc_tr3_port_lanes_get(unit, port, &lanes));
   3100     if (BCM_FAILURE(rv)) {
   3101        return rv;
   3102     }
   3103 
   3104     switch (lanes) {
   3105     case 10: /* 100G */
   3106         si->port_credit[port] = 108;
   3107         break;
   3108     case 4: /* SINGLE  */
   3109         si->port_credit[port] = 36;
   3110         break;
   3111     case 2: /* DUAL */
   3112         si->port_credit[port] = 18;
   3113         break;
   3114     case 1: /* QUAD */
   3115         si->port_credit[port] = 9;
   3116         break;
   3117     default:
   3118         si->port_credit[port] = 36;
   3119         break;
   3120     }
   3121 
   3122     time1 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time);
   3123 
   3124     _bcm_esw_lc_lock(unit);
   3125     soc_link_fwd_get(unit, &mask1);
   3126     SOC_PBMP_ASSIGN(mask1_restore,mask1);
   3127     BCM_PBMP_PORT_REMOVE(mask1,port);
   3128     rv = soc_link_fwd_set(unit, mask1);
   3129     if (BCM_FAILURE(rv)) {
   3130         _bcm_esw_lc_unlock(unit);
   3131         LOG_ERROR(BSL_LS_BCM_PORT,
   3132                       (BSL_META_U(unit,"\n Error in setting the mask FWD"
   3133                                  " for WAR on port %s"), SOC_PORT_NAME(unit,port)));
   3134         return BCM_E_NONE;
   3135     }
   3136 
   3137     PORT_LOCK(unit);
   3138     _bcm_esw_ibod_recovery_port_lock(unit, port);
   3139 
   3140     /* move port from EPC_LINK_BMAP */
   3141     soc_link_mask2_get(unit, &mask);
   3142     SOC_PBMP_ASSIGN(mask_restore,mask);
   3143     BCM_PBMP_PORT_REMOVE(mask,port);
   3144     rv = soc_link_mask2_set(unit, mask);
   3145     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3146 
   3147     temp_reg_id = IS_C_PORT(unit, port) ? CMAC_PAUSE_CTRLr : XMAC_PAUSE_CTRLr;
   3148     rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64);
   3149     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3150     pause_rx = soc_reg64_field32_get(unit, temp_reg_id, rval64, RX_PAUSE_ENf);
   3151     soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_PAUSE_ENf, 0);
   3152     rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64);
   3153     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3154 
   3155     temp_reg_id = IS_C_PORT(unit, port) ? CMAC_PFC_CTRLr : XMAC_PFC_CTRLr;
   3156     rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64);
   3157     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3158     rx_pfc_en = soc_reg64_field32_get(unit, temp_reg_id, rval64, RX_PFC_ENf);
   3159     soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_PFC_ENf, 0);
   3160     rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64);
   3161     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3162 
   3163     temp_reg_id = IS_C_PORT(unit, port) ? CMAC_LLFC_CTRLr : XMAC_LLFC_CTRLr;
   3164     rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64);
   3165     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3166     rx_llfc_en = soc_reg64_field32_get(unit, temp_reg_id, rval64, RX_LLFC_ENf);
   3167     soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_LLFC_ENf, 0);
   3168     rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64);
   3169     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3170 
   3171     rv = READ_EGRMETERINGCONFIG_64r(unit, port, &rval64);
   3172     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3173     egress_meter = rval64;
   3174     COMPILER_64_ZERO(tmp64);
   3175     rv = WRITE_EGRMETERINGCONFIG_64r(unit, port, tmp64);
   3176     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3177 
   3178     temp_reg_id = IS_C_PORT(unit, port) ? CMAC_RX_LSS_CTRLr : XMAC_RX_LSS_CTRLr;
   3179     rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64);
   3180     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3181     rx_lss = soc_reg64_field32_get(unit, temp_reg_id, rval64,
   3182                                    DROP_TX_DATA_ON_LOCAL_FAULTf);
   3183     rx_lss_1 = soc_reg64_field32_get(unit, temp_reg_id, rval64,
   3184                                    DROP_TX_DATA_ON_REMOTE_FAULTf);
   3185     soc_reg64_field32_set(unit, temp_reg_id, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 1);
   3186     soc_reg64_field32_set(unit, temp_reg_id, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, 1);
   3187     rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64);
   3188     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3189 
   3190     rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64);
   3191     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3192     COMPILER_64_SET(flush_enable_pbm, pbmp.pbits[1], pbmp.pbits[0]);
   3193     soc_reg64_field_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, flush_enable_pbm);
   3194     rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64);
   3195     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3196 
   3197     /* drop packets */
   3198     rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port, &rval);
   3199     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3200     soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 1);
   3201     rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port, rval);
   3202     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3203 
   3204     cur_cells = 0xffffffff;
   3205     soc_timeout_init(&timeout, 30000, 0);
   3206 
   3207     while(1) {
   3208 #ifdef TXERR_DEBUG
   3209         /* check epc_link_bmap for debug */
   3210         pbmp_t  pbm;
   3211         epc_link_bmap_entry_t entry;
   3212         READ_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&entry);
   3213         soc_mem_pbmp_field_get(unit, EPC_LINK_BMAPm, &entry, PORT_BITMAPf, &pbm);
   3214         if (SOC_PBMP_MEMBER(pbm, port)) {
   3215             LOG_WARN(BSL_LS_BCM_PORT,
   3216                      (BSL_META_U(unit, "TXERR recovery:uint %d port %d still in epc link bitmap 0x%x\r\n"),
   3217                       unit, port, pbm.pbits[0]));
   3218         }
   3219 #endif
   3220         new_cells=0;
   3221 
   3222         /*1. check MMU cell */
   3223         rv = READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port, &rval);
   3224         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3225         mmu_cells = soc_reg_field_get(unit, OP_PORT_TOTAL_COUNT_CELLr,rval, TOTAL_COUNTf);
   3226         new_cells += mmu_cells;
   3227 
   3228         /*2. check port CDC fifo */
   3229         rv = READ_PORT_CDC_TXFIFO_CELL_CNTr(unit, port, &rval);
   3230         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3231         cdc_fifo_cells = soc_reg_field_get(unit, PORT_CDC_TXFIFO_CELL_CNTr, rval, CELL_CNTf);
   3232         new_cells += cdc_fifo_cells;
   3233 
   3234         /*3. check port tx fifo */
   3235         rv = READ_PORT_TXFIFO_CELL_CNTr(unit, port, &rval);
   3236         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3237         tx_fifo_cells = soc_reg_field_get(unit, PORT_TXFIFO_CELL_CNTr, rval, CELL_CNTf);
   3238         new_cells += tx_fifo_cells;
   3239 
   3240         /* read MMU credit */
   3241         rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, &credit);
   3242         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3243 
   3244         rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, si->port_l2p_mapping[port], &mmu_entry);
   3245         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3246         mmu_req = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf);
   3247 
   3248         /* read EP level */
   3249         rv = READ_EGR_EDB_MISC_CTRLr(unit, &rval);
   3250         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3251         soc_reg_field_set(unit, EGR_EDB_MISC_CTRLr, &rval, SELECT_CURRENT_USED_ENTRIESf, 1);
   3252         rv = WRITE_EGR_EDB_MISC_CTRLr(unit, rval);
   3253         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3254         rv = READ_EGR_MAX_USED_ENTRIESm(unit, MEM_BLOCK_ALL, si->port_l2p_mapping[port], &max_used_entry);
   3255         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3256         ep_level = soc_mem_field32_get(unit, EGR_MAX_USED_ENTRIESm, &max_used_entry, LEVELf);
   3257 
   3258         /* Update cur_cells and give more time to drain packets.  */
   3259         if (new_cells < cur_cells) {
   3260             soc_timeout_init(&timeout, 30000, 0);
   3261             cur_cells = new_cells;
   3262         }
   3263         else {
   3264 #ifdef TXERR_DEBUG
   3265             cli_out("TXERR reovery: mmu cells not draining 1: %d cells remain,cur_cells %d, mmu_cells %d, level %d, credit %d mmu_req %d \r\n",
   3266                      new_cells, cur_cells, mmu_cells, ep_level, credit, mmu_req);
   3267 #endif
   3268             rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, si->port_credit[port]);
   3269             TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3270         }
   3271 
   3272         if (soc_timeout_check(&timeout)) {
   3273             if(ep_level == 0) {
   3274                 ibod_ctrl->drain_timeout_flag = 1;
   3275             }
   3276             else {
   3277                 rv = READ_PQEFIFOOVERFLOW0r(unit, &overflow0);
   3278                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3279                 rv = READ_PQEFIFOOVERFLOW1r(unit, &overflow1);
   3280                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3281                 rv = READ_OP_PORT_TOTAL_COUNT_CELLr(unit,port, &total_cell);
   3282                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3283                 LOG_ERROR(BSL_LS_BCM_PORT,
   3284                           (BSL_META_U(unit, "\n TXERR recovery Timeout Drain packets %d PORT: %s, "
   3285                             "ep_level:%d, overflow0:%d, overflow1:%d total_cell %d "
   3286                             "credit %d mmu_req %d \n"),
   3287                             ibod_ctrl->unit, SOC_PORT_NAME(unit,port), ep_level, overflow0,
   3288                             overflow1, total_cell, credit, mmu_req));
   3289             }
   3290             break;
   3291         }
   3292 #ifdef TXERR_DEBUG
   3293         /* for debug */
   3294         uint32 mmu_req_1;
   3295 
   3296         rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, si->port_l2p_mapping[port], &mmu_entry);
   3297         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3298         mmu_req_1 = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf);
   3299         if(mmu_req_1 != mmu_req){
   3300             cli_out("TXERR recovery: credit %d mmu_req %d is not equal mmu_req_1 %d  !!!!!\r\n",credit, mmu_req, mmu_req_1);
   3301 
   3302         }
   3303 #endif
   3304         /* All packets were drained */
   3305         if (new_cells == 0) {
   3306             if (_soc_egress_drain_credit_calc(credit, si->port_credit[port], mmu_req, ep_level, &credit_set)) {
   3307                 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, credit_set);
   3308                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3309             }
   3310 #ifdef TXERR_DEBUG
   3311             rv = _soc_egress_drain_ep_max_level_get(unit, port, &ep_max_level);
   3312             if(rv == BCM_E_NONE)
   3313             {
   3314                  cli_out("TXERR recovery: MacDrainOK max_level %d  !!!!!\r\n", ep_max_level);
   3315             }
   3316 
   3317             rv = READ_TPKTr(unit, port, &tpkt);
   3318             TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3319             rv = READ_TFCSr(unit, port, &tfcs);
   3320             TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3321 
   3322             cli_out("TXERR recovery: MacDrainOK credit = %d, Port:%d, tpkt:%lld, tfcs=%lld\r\n",  credit, port, tpkt, tfcs);
   3323 #endif
   3324             rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, &credit);
   3325             TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3326             if(credit == 0) {
   3327                 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]],
   3328                     REG_PORT_ANY, 0, si->port_credit[port]);
   3329                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3330             }
   3331             break;
   3332         }
   3333         else if (mmu_cells){  /* some packets still stay in MMU */
   3334             if((credit == 0)) {
   3335                 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, &credit);
   3336                 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3337                 if(credit == 0) {
   3338                     rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, si->port_l2p_mapping[port], &mmu_entry);
   3339                     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3340                     mmu_req = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf);
   3341 
   3342                     if (_soc_egress_drain_credit_calc(credit, si->port_credit[port], mmu_req, ep_level, &credit_set)) {
   3343                         rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, credit_set);
   3344                         TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3345                     }
   3346                 }
   3347                 else {
   3348 #ifdef TXERR_DEBUG
   3349                     _soc_egress_drain_debug(unit, port, lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]]);
   3350 #endif
   3351                 }
   3352             }
   3353             else {
   3354 #ifdef TXERR_DEBUG
   3355                 _soc_egress_drain_debug(unit, port, lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]]);
   3356 #endif
   3357             }
   3358         }
   3359     }
   3360 
   3361     temp_reg_id = IS_C_PORT(unit, port) ? CMAC_CLEAR_FIFO_STATUSr : XMAC_CLEAR_FIFO_STATUSr;
   3362     rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64);
   3363     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3364     soc_reg64_field32_set(unit, temp_reg_id, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 1);
   3365     rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64);
   3366     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3367 
   3368     rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64);
   3369     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3370     soc_reg64_field32_set(unit, temp_reg_id, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 0);
   3371     rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64);
   3372     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3373 
   3374     rv = WRITE_EGRMETERINGCONFIG_64r(unit, port, egress_meter);
   3375     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3376 
   3377     rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port, &rval);
   3378     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3379     soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 0);
   3380     rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port, rval);
   3381     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3382 
   3383     rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64);
   3384     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3385     soc_reg64_field32_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, 0);
   3386     rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64);
   3387     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3388 
   3389     temp_reg_id = IS_C_PORT(unit, port) ? CMAC_RX_LSS_CTRLr : XMAC_RX_LSS_CTRLr;
   3390     rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64);
   3391     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3392     soc_reg64_field32_set(unit, temp_reg_id, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, rx_lss);
   3393     soc_reg64_field32_set(unit, temp_reg_id, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, rx_lss_1);
   3394     rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64);
   3395     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3396 
   3397     temp_reg_id = IS_C_PORT(unit, port) ? CMAC_PAUSE_CTRLr : XMAC_PAUSE_CTRLr;
   3398     rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64);
   3399     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3400     soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_PAUSE_ENf, pause_rx);
   3401     rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64);
   3402     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3403 
   3404     temp_reg_id = IS_C_PORT(unit, port) ? CMAC_PFC_CTRLr : XMAC_PFC_CTRLr;
   3405     rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64);
   3406     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3407     soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_PFC_ENf, rx_pfc_en);
   3408     rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64);
   3409     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3410 
   3411     temp_reg_id = IS_C_PORT(unit, port) ? CMAC_LLFC_CTRLr : XMAC_LLFC_CTRLr;
   3412     rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64);
   3413     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3414     soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_LLFC_ENf, rx_llfc_en);
   3415     rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64);
   3416     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3417 
   3418     /* restore port from EPC_LINK_BMAP */
   3419     rv = soc_link_mask2_set(unit, mask_restore);
   3420     TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3421 
   3422     _bcm_esw_ibod_recovery_port_unlock(unit, port);
   3423     PORT_UNLOCK(unit);
   3424     rv = soc_link_fwd_set(unit, mask1_restore);
   3425     if (BCM_FAILURE(rv)) {
   3426         _bcm_esw_lc_unlock(unit);
   3427         LOG_ERROR(BSL_LS_BCM_PORT,
   3428                       (BSL_META_U(unit,"\n Error in re-setting the mask FWD"
   3429                                  " for WAR on port %s"), SOC_PORT_NAME(unit,port)));
   3430         return BCM_E_NONE;
   3431     }
   3432 
   3433     _bcm_esw_lc_unlock(unit);
   3434 
   3435     time2 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time);
   3436     ibod_ctrl->txerr_count++;
   3437     ibod_ctrl->txerr_avg_time = (ibod_ctrl->txerr_avg_time*(ibod_ctrl->txerr_count-1) +
   3438             time2 - time1) /ibod_ctrl->txerr_count;
   3439 
   3440     return SOC_E_NONE;
   3441 }
   3442 
   3443 STATIC int
   3444 _bcm_tr3_ibod_port_check(
   3445 _port_ibod_ctrl_t *ibod_ctrl, bcm_port_t port, int *need_recovery)
   3446 {
   3447     int rv, unit = ibod_ctrl->unit;
   3448     uint64 rrpkt, rrbyt;
   3449     uint64 rrpkt_diff, rrbyt_diff;
   3450     uint64 rval64;
   3451     int runt_threshold;
   3452 
   3453     /* Only check HG port */
   3454     if (!IS_HG_PORT(unit, port)) {
   3455         return BCM_E_NONE;
   3456     }
   3457 
   3458     /* Check if any new runt packet logged in RRPKT */
   3459     rv = READ_RRPKTr(unit, port, &rrpkt);
   3460     if (SOC_FAILURE(rv)) {
   3461         return BCM_E_FAIL;
   3462     }
   3463     if (COMPILER_64_EQ(rrpkt, ibod_ctrl->rrpkt[port])) {
   3464         return BCM_E_NONE;
   3465     }
   3466 
   3467     /* Check total runt byte count */
   3468     rv = READ_RRBYTr(unit, port, &rrbyt);
   3469     if (SOC_FAILURE(rv)) {
   3470         return BCM_E_FAIL;
   3471     }
   3472 
   3473     /* It's very unlikely both packet and byte counters wrap around
   3474                * and stop at 0, the code assume this is from clear counter */
   3475     if (COMPILER_64_IS_ZERO(rrpkt) && COMPILER_64_IS_ZERO(rrbyt)) {
   3476         ibod_ctrl->rrpkt_old[port] = ibod_ctrl->rrpkt[port];
   3477         ibod_ctrl->rrbyt_old[port] = ibod_ctrl->rrbyt[port];
   3478         ibod_ctrl->rrpkt[port] = rrpkt;
   3479         ibod_ctrl->rrbyt[port] = rrbyt;
   3480         return BCM_E_NONE;
   3481     }
   3482 
   3483     rrpkt_diff = rrpkt;
   3484     rrbyt_diff = rrbyt;
   3485     COMPILER_64_SUB_64(rrpkt_diff, ibod_ctrl->rrpkt[port]);
   3486     COMPILER_64_SUB_64(rrbyt_diff, ibod_ctrl->rrbyt[port]);
   3487     ibod_ctrl->rrpkt_old[port] = ibod_ctrl->rrpkt[port];
   3488     ibod_ctrl->rrbyt_old[port] = ibod_ctrl->rrbyt[port];
   3489     ibod_ctrl->rrpkt[port] = rrpkt;
   3490     ibod_ctrl->rrbyt[port] = rrbyt;
   3491 #ifdef IBOD_DEBUG
   3492     cli_out("WAR IBOD Check [port %d] rrbyt %lld rrpkt %lld, rrpkt_diff %lld rrbyt_diff %lld\r\n",
   3493             port, ibod_ctrl->rrbyt[port], ibod_ctrl->rrpkt[port], rrpkt_diff, rrbyt_diff);
   3494 #endif
   3495     rv = READ_XMAC_RX_CTRLr(unit,port, &rval64);
   3496     if (SOC_FAILURE(rv)) {
   3497         return BCM_E_FAIL;
   3498     }
   3499 
   3500     runt_threshold = soc_reg64_field32_get(unit, XMAC_RX_CTRLr, rval64, RUNT_THRESHOLDf);
   3501 
   3502     /* Recovery is needed only for packet size between 33 and threshold */
   3503     if (COMPILER_64_HI(rrpkt_diff) == 0 &&
   3504         COMPILER_64_LO(rrpkt_diff) == 1) {
   3505         if (COMPILER_64_LO(rrbyt_diff) >= runt_threshold) {
   3506             return BCM_E_NONE;
   3507         }
   3508     }
   3509     if (COMPILER_64_HI(rrbyt_diff) == 0 &&
   3510         COMPILER_64_LO(rrbyt_diff) <= 32) {
   3511         return BCM_E_NONE;
   3512     }
   3513 
   3514     *need_recovery = TRUE;
   3515 
   3516     return BCM_E_NONE;
   3517 }
   3518 
   3519 STATIC int
   3520 _bcm_tr3_ibod_sync_recovery_port(_port_ibod_ctrl_t *ibod_ctrl, int port_set,
   3521                                  bcm_port_t port)
   3522 {
   3523     int idx, fifo_len, send_time;
   3524     int rv = BCM_E_NONE;
   3525     int rv1 = BCM_E_NONE;
   3526     int enable, tdm_length;
   3527     uint64 rrpkt, rrbyt;
   3528     uint64 rpkt, tpkt;
   3529     pbmp_t  pbm;
   3530     epc_link_bmap_entry_t entry;
   3531     int lanes, unit = ibod_ctrl->unit;
   3532     soc_info_t *si = &SOC_INFO(unit);
   3533     int phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   3534     uint32 *tdm_array;
   3535     int port_dis_tag=0, port_dis_untag=0;
   3536     bcm_pkt_t *pkt = &ibod_ctrl->pkt;
   3537     SHR_BITDCLNAME(used_bmp, TR3_IARB_TDM_TABLE_LENGTH);
   3538     uint32 _tdm_array_hw[380] = {-1};
   3539     int pause_tx, pause_rx, pfc_rx, llfc_rx;
   3540     iarb_tdm_table_entry_t new_entry;
   3541     uint32 rval;
   3542     pbmp_t mask, mask1, mask1_restore;
   3543     int ibod_data_fifo_full_intr_status = 0;
   3544     soc_field_t cl_data_fifo_full_err_intr_status = 0;
   3545     soc_field_t cl_ctrl_fifo_full_err_intr_status = 0;
   3546 #ifdef IBOD_DEBUG
   3547     uint64 rpkt, tpkt;
   3548     uint64 rpkt_fin, tpkt_fin, rrpkt_fin, rrbyt_fin;
   3549 #endif
   3550 
   3551     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   3552     rv = (soc_tr3_port_lanes_get(unit, port, &lanes));
   3553     if (BCM_FAILURE(rv)) {
   3554        return rv;
   3555     }
   3556 
   3557     switch (lanes) {
   3558     case 10: /* 100G */
   3559         fifo_len = 34;
   3560         si->port_credit[port] = 108;
   3561         break;
   3562     case 4: /* SINGLE  */
   3563         fifo_len = 34;
   3564         si->port_credit[port] = 36;
   3565         break;
   3566     case 2: /* DUAL */
   3567         fifo_len = 34;
   3568         si->port_credit[port] = 18;
   3569         break;
   3570     case 1: /* QUAD */
   3571         fifo_len = 34;
   3572         si->port_credit[port] = 9;
   3573         break;
   3574     default:
   3575         fifo_len = 34;
   3576         si->port_credit[port] = 36;
   3577         break;
   3578     }
   3579 
   3580     
   3581     if ((phy_port >= 53)  && (phy_port <= 64 )){
   3582         cl_data_fifo_full_err_intr_status = CL0_DATA_FIFO_FULL_ERR_INTR_STATUSf;
   3583         cl_ctrl_fifo_full_err_intr_status = CL0_CTRL_FIFO_FULL_ERR_INTR_STATUSf;
   3584     }
   3585     else if ((phy_port >= 69) && (phy_port <= 80)) {
   3586         cl_data_fifo_full_err_intr_status = CL1_DATA_FIFO_FULL_ERR_INTR_STATUSf;
   3587         cl_ctrl_fifo_full_err_intr_status = CL1_CTRL_FIFO_FULL_ERR_INTR_STATUSf;
   3588     }
   3589     else {
   3590         LOG_ERROR(BSL_LS_BCM_PORT,
   3591                  (BSL_META_U(unit, "IBOD port:%d is not CL port\n\r"), port));
   3592         return BCM_E_PORT;
   3593     }
   3594     fifo_len = soc_property_get(unit, "ibod_fifo_len", fifo_len);
   3595 
   3596     soc_link_fwd_get(unit, &mask1);
   3597     SOC_PBMP_ASSIGN(mask1_restore,mask1);
   3598     BCM_PBMP_PORT_REMOVE(mask1,port);
   3599     rv = soc_link_fwd_set(unit, mask1);
   3600     if (BCM_FAILURE(rv)) {
   3601        LOG_ERROR(BSL_LS_BCM_PORT,
   3602                  (BSL_META_U(unit,
   3603                   "IBOD Link fwd set failed[%d] on port:%d\n\r"),
   3604                   rv, port));
   3605        return rv;
   3606     }
   3607 
   3608     PORT_LOCK(unit); /* Begin port atomic */
   3609     _bcm_esw_ibod_recovery_port_lock(unit, port);
   3610     soc_ibod_recovery_in_progress_set(unit, 1);
   3611 
   3612     if (port_set == 0) {
   3613         soc_link_mask2_get(unit, &mask);
   3614         rv = bcm_esw_port_enable_get(unit, port, &enable);
   3615         IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3616         /* port is disabled */
   3617         if ((enable == 0) || !SOC_PBMP_MEMBER(mask, port)) {
   3618             soc_ibod_recovery_in_progress_set(unit, 0);
   3619             _bcm_esw_ibod_recovery_port_unlock(unit, port);
   3620             PORT_UNLOCK(unit);
   3621             rv = soc_link_fwd_set(unit, mask1_restore);
   3622             /*  
   3623              *  Since the recovery is not run when the port is down the
   3624              *  rrpkt is updated back to the original value, as the 
   3625              *  recovery will happen when the port is up 
   3626              */   
   3627             ibod_ctrl->rrpkt[port] = ibod_ctrl->rrpkt_old[port];
   3628             ibod_ctrl->rrbyt[port] = ibod_ctrl->rrbyt_old[port];
   3629             LOG_INFO(BSL_LS_BCM_PORT,
   3630                       (BSL_META_U(unit,
   3631                                   "Skip ibod sync war if port %d is disabled %d.\n"),
   3632                                   port, enable));
   3633             return rv;
   3634         }
   3635     }
   3636 
   3637     /* Isolate port */
   3638     rv = _bcm_tr3_ibod_port_isolate(unit, port_set, port, &port_dis_untag, &port_dis_tag);
   3639     if (BCM_FAILURE(rv)) {
   3640         soc_ibod_recovery_in_progress_set(unit, 0);
   3641         _bcm_esw_ibod_recovery_port_unlock(unit, port);
   3642         PORT_UNLOCK(unit);
   3643         rv1 = soc_link_fwd_set(unit, mask1_restore);
   3644         LOG_ERROR(BSL_LS_BCM_PORT,
   3645                   (BSL_META_U(unit, "IBOD port(%d) isolate Failed[%d %d]\n\r"),
   3646                    port, rv, rv1));
   3647         return rv;
   3648     }
   3649 
   3650     sal_memset(&used_bmp, 0, sizeof(used_bmp));
   3651 
   3652     /* Remove the port from IARB_TDM_TABLE */
   3653     tdm_length = _soc_tr3_tdm_size;
   3654     for (idx = 0; idx < _soc_tr3_tdm_size; idx++) {
   3655         /*    coverity[unchecked_value]    */
   3656         (void)soc_mem_read(unit, IARB_TDM_TABLEm, MEM_BLOCK_ALL, idx,&new_entry);
   3657         _tdm_array_hw[idx] = 
   3658               soc_mem_field32_get(unit, IARB_TDM_TABLEm, &new_entry, PORT_NUMf);
   3659     }
   3660     tdm_array = _tdm_array_hw;
   3661 
   3662     sal_memset(&new_entry, 0, sizeof(iarb_tdm_table_entry_t));
   3663     soc_mem_field32_set(unit, IARB_TDM_TABLEm, &new_entry, PORT_NUMf, 127);
   3664     for (idx = 0; idx < _soc_tr3_tdm_size; idx++) {
   3665         if (tdm_array[idx] != phy_port) {
   3666             continue;
   3667         }
   3668         (void)soc_mem_write(unit, IARB_TDM_TABLEm, MEM_BLOCK_ALL, idx,
   3669                             &new_entry);
   3670         SHR_BITSET(used_bmp, idx);
   3671     }
   3672     sal_udelay(10000);
   3673 
   3674     /* Disable pause/pfc/llfc function */
   3675     rv = soc_mac_x.md_pause_get(unit, port, &pause_tx, &pause_rx);
   3676     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3677 
   3678     rv = soc_mac_x.md_pause_set(unit, port, 0, 0);
   3679     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3680 
   3681     rv = soc_mac_x.md_control_get(unit, port, SOC_MAC_CONTROL_PFC_RX_ENABLE, &pfc_rx);
   3682     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3683 
   3684     rv = soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_PFC_RX_ENABLE, 0);
   3685     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3686 
   3687     rv = soc_mac_x.md_control_get(unit, port, SOC_MAC_CONTROL_LLFC_RX_ENABLE,&llfc_rx);
   3688     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3689 
   3690     rv = soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_LLFC_RX_ENABLE,0);
   3691     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3692 
   3693     /* check epc_link_bmap */
   3694     /* coverity[check_return] */
   3695     READ_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&entry);
   3696     soc_mem_pbmp_field_get(unit, EPC_LINK_BMAPm, &entry, PORT_BITMAPf, &pbm);
   3697     if (SOC_PBMP_MEMBER(pbm, port)) {
   3698         LOG_WARN(BSL_LS_BCM_PORT,
   3699                   (BSL_META_U(unit, "uint %d port %d still in epc link bitmap 0x%x\r\n"),
   3700                    unit, port, pbm.pbits[0]));
   3701     }
   3702 
   3703     rv = READ_RRBYTr(unit, port, &rrbyt);
   3704     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3705 
   3706     rv = READ_RRPKTr(unit, port, &rrpkt);
   3707     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3708 
   3709     rv = READ_RPKTr(unit, port, &rpkt);
   3710     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3711     rv = READ_TPKTr(unit, port, &tpkt);
   3712     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3713 #ifdef IBOD_DEBUG
   3714     cli_out("WAR Trigerred IBOD recovery [port %d] enable %d orign rrbyt %lld rrpkt %lld rpkt %lld tpkt %lld\r\n",
   3715         port, port_set, rrbyt, rrpkt, rpkt, tpkt );
   3716 #endif
   3717     send_time = 0;
   3718 
   3719     /* send loopback packets untill fifo full error occurred. */
   3720     do {
   3721         /* Send 80-byte packets to fill IBOD FIFO */
   3722         for (idx = 0; idx < fifo_len; idx++) {
   3723             BCM_PKT_TX_LEN_SET(pkt, 68);
   3724             BCM_PKT_PORT_SET(pkt, port, TRUE, FALSE);
   3725             BCM_PKT_HGHDR_REQUIRE(pkt);
   3726             rv = bcm_common_tx(unit, pkt, NULL);
   3727             if (BCM_FAILURE(rv)) {
   3728                 LOG_ERROR(BSL_LS_BCM_PORT,
   3729                           (BSL_META_U(unit, "IBOD 80-byte packet transmit"
   3730                            " failed[%d] on port:%d, send_time:%d\n\r"), rv, port, send_time));
   3731                 ibod_ctrl->port_recovery_failed_flag = 1;
   3732                 break;
   3733             }
   3734         }
   3735         if (ibod_ctrl->port_recovery_failed_flag) {
   3736             break;
   3737         }
   3738 
   3739         send_time ++;
   3740         rv = READ_IBOD_INTR_STATUSr(unit, &rval);
   3741         IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3742         ibod_data_fifo_full_intr_status = soc_reg_field_get(unit, IBOD_INTR_STATUSr,
   3743              rval, cl_data_fifo_full_err_intr_status);
   3744 #ifdef IBOD_DEBUG
   3745         if (!ibod_data_fifo_full_intr_status){
   3746             cli_out("%s IBOD intr data fifo full err status is 0 !!!!!!!%d\r\n",
   3747             (cl_data_fifo_full_err_intr_status == CL0_DATA_FIFO_FULL_ERR_INTR_STATUSf)?"CL0":"CL1", ibod_data_fifo_full_intr_status);
   3748         }
   3749 #endif
   3750 
   3751         if (send_time >= 5) {
   3752 #ifdef IBOD_DEBUG
   3753             int lb = 0;
   3754             MAC_LOOPBACK_GET(PORT(unit, port).p_mac, unit, port, &lb);
   3755 
   3756             rv = READ_RPKTr(unit, port, &rpkt_fin);
   3757             IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3758             rv = READ_TPKTr(unit, port, &tpkt_fin);
   3759             IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3760 
   3761             LOG_ERROR(BSL_LS_BCM_PORT, (BSL_META_U(unit,"\n IBOD recovery (unit %d PORT: %s) fill IBOD FIFO full failed: rpkt_fin %lld tpkt_fin %lld loopback %d\r\n"),
   3762                       ibod_ctrl->unit, SOC_PORT_NAME(unit,port),rpkt_fin,tpkt_fin, lb));
   3763 #else
   3764             LOG_ERROR(BSL_LS_BCM_PORT,
   3765                   (BSL_META_U(unit,"\n IBOD recovery (unit %d PORT: %s) fill IBOD FIFO full failed\r\n"),
   3766                   unit, SOC_PORT_NAME(unit,port)));
   3767 #endif
   3768            ibod_ctrl->port_recovery_failed_flag = 1;
   3769            break;
   3770         }
   3771     }while (ibod_data_fifo_full_intr_status == 0);
   3772 
   3773 #ifdef IBOD_DEBUG
   3774     rv = READ_RRBYTr(unit, port, &rrbyt);
   3775     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3776 
   3777     rv = READ_RRPKTr(unit, port, &rrpkt);
   3778     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3779 
   3780     rv = READ_RPKTr(unit, port, &rpkt_fin);
   3781     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3782 
   3783     rv = READ_TPKTr(unit, port, &tpkt_fin);
   3784     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3785     cli_out("WAR Trigerred IBOD recovery [port %d] normal rrbyt %lld rrpkt %lld rpkt_fin %lld tpkt_fin %lld send_time %d\r\n",
   3786         port, rrbyt, rrpkt, rpkt_fin,tpkt_fin, send_time);
   3787     if((rpkt_fin - rpkt) != fifo_len * send_time ) {
   3788         cli_out("IBOD recovery loopback regular counter is not right!!!!!!! \r\n");
   3789         if((rpkt_fin - rpkt) < fifo_len * send_time ) {
   3790             cli_out("IBOD recovery loopback regular counter is less than tx!!!!!!!! \r\n");
   3791         }
   3792     }
   3793 #endif
   3794     /* Restore IARB_TDM_TABLE */
   3795     soc_mem_field32_set(unit, IARB_TDM_TABLEm, &new_entry, PORT_NUMf,
   3796                         phy_port);
   3797     for (idx = 0; idx < tdm_length; idx++) {
   3798         if (!SHR_BITGET(used_bmp, idx)) {
   3799             continue;
   3800         }
   3801         (void)soc_mem_write(unit, IARB_TDM_TABLEm, MEM_BLOCK_ALL, idx,
   3802                             &new_entry);
   3803     }
   3804 
   3805     for (idx = 0; idx < tdm_length; idx++) {
   3806         if (tdm_array[idx] != phy_port) {
   3807             continue;
   3808         }
   3809 #ifdef IBOD_DEBUG
   3810         (void)soc_mem_read(unit, IARB_TDM_TABLEm, MEM_BLOCK_ALL, idx,&new_entry);
   3811         _tdm_array_hw[idx] = soc_mem_field32_get(unit, IARB_TDM_TABLEm, &new_entry, PORT_NUMf);
   3812         if(_tdm_array_hw[idx] != phy_port){
   3813             cli_out("IBOD IARB TDM port number idx %d _tdm_array_hw[idx] %d !!!!!!\r\n",idx, _tdm_array_hw[idx]);
   3814         }
   3815 #endif
   3816     }
   3817     /* waiting for IARB_TDM_TABLE ready */
   3818     sal_udelay(30000);
   3819     /* Send 72-byte RUNT packet */
   3820     if (BCM_SUCCESS(rv)) {
   3821         BCM_PKT_TX_LEN_SET(pkt, 60);
   3822         BCM_PKT_PORT_SET(pkt, port, TRUE, FALSE);
   3823         rv = bcm_common_tx(unit, pkt, NULL);
   3824         if (BCM_FAILURE(rv)) {
   3825             LOG_ERROR(BSL_LS_BCM_PORT,
   3826                       (BSL_META_U(unit,
   3827                        "IBOD Runt Pkt transmit failed[%d] on port:%d\n\r"),
   3828                        rv, port));
   3829             ibod_ctrl->port_recovery_failed_flag = 1;
   3830         }
   3831     }
   3832 
   3833 #ifdef IBOD_DEBUG
   3834     rv = READ_RRPKTr(unit, port, &rrpkt_fin);
   3835     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3836     rv = READ_RRBYTr(unit, port, &rrbyt_fin);
   3837     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3838     rv = READ_RPKTr(unit, port, &rpkt_fin);
   3839     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3840     rv = READ_TPKTr(unit, port, &tpkt_fin);
   3841     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3842 
   3843     cli_out("recovery runt rrbyt_fin %lld rrpkt_fin %lld rpkt_fin %lld tpkt_fin %lld\r\n",rrbyt_fin, rrpkt_fin,
   3844     rpkt_fin, tpkt_fin);
   3845 
   3846     if((rrpkt_fin - rrpkt) != 1 ) {
   3847         cli_out("IBOD recovery loopback runt counter is not right!!!! \r\n");
   3848     }
   3849 #endif
   3850     /* Update ibod_ctrl rrbyt and rrpkt */
   3851     rv = READ_RRPKTr(unit, port, &rrpkt);
   3852     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3853     rv = READ_RRBYTr(unit, port, &rrbyt);
   3854     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3855 
   3856     ibod_ctrl->rrpkt[port] = rrpkt;
   3857     ibod_ctrl->rrbyt[port] = rrbyt;
   3858 
   3859     /* Restore original pause/pfc/llfc configuration */
   3860     rv = soc_mac_x.md_pause_set(unit, port, pause_tx, pause_rx);
   3861     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3862 
   3863     rv = soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_PFC_RX_ENABLE, pfc_rx);
   3864     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3865     rv = soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_LLFC_RX_ENABLE,llfc_rx);
   3866     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3867 
   3868     /* clear and check IBOD FIFO full interrupt */
   3869     rv = READ_IBOD_INTR_STATUSr(unit, &rval);
   3870     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3871     ibod_data_fifo_full_intr_status = soc_reg_field_get(unit, IBOD_INTR_STATUSr,
   3872          rval, cl_data_fifo_full_err_intr_status);
   3873     soc_reg_field_set(unit, IBOD_INTR_STATUSr,
   3874          &rval, cl_data_fifo_full_err_intr_status, 1);
   3875     soc_reg_field_set(unit, IBOD_INTR_STATUSr,
   3876          &rval, cl_ctrl_fifo_full_err_intr_status, 1);
   3877     rv = WRITE_IBOD_INTR_STATUSr(unit, rval);
   3878     IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv);
   3879 #ifdef IBOD_DEBUG
   3880     READ_IBOD_INTR_STATUSr(unit, &rval);
   3881     ibod_data_fifo_full_intr_status = soc_reg_field_get(unit, IBOD_INTR_STATUSr,
   3882          rval, cl_data_fifo_full_err_intr_status);
   3883     cli_out("after set. %s IBOD intr data fifo full err status %d\r\n",
   3884         (cl_data_fifo_full_err_intr_status == CL0_DATA_FIFO_FULL_ERR_INTR_STATUSf)?"CL0":"CL1", ibod_data_fifo_full_intr_status);
   3885 #endif
   3886     /* Restore port operation */
   3887     rv = _bcm_tr3_ibod_port_resume(unit, port, port_dis_untag, port_dis_tag);
   3888     if (BCM_FAILURE(rv)) {
   3889         soc_ibod_recovery_in_progress_set(unit, 0);
   3890         _bcm_esw_ibod_recovery_port_unlock(unit, port);
   3891         PORT_UNLOCK(unit);
   3892         rv1 = soc_link_fwd_set(unit, mask1_restore);
   3893         LOG_ERROR(BSL_LS_BCM_PORT,
   3894                   (BSL_META_U(unit,
   3895                   "IBOD Port[%d] Resume failed[%d %d]\n\r"), port, rv, rv1));
   3896         return rv;
   3897     }
   3898 
   3899     soc_ibod_recovery_in_progress_set(unit, 0);
   3900     _bcm_esw_ibod_recovery_port_unlock(unit, port);
   3901     PORT_UNLOCK(unit); /* End port atomic */
   3902 
   3903     rv = soc_link_fwd_set(unit, mask1_restore);
   3904     if (BCM_FAILURE(rv)) {
   3905        LOG_ERROR(BSL_LS_BCM_PORT,
   3906                  (BSL_META_U(unit,
   3907                  "IBOD link fwd set failed[%d] on port:%d\n\r"), rv, port));
   3908        return rv;
   3909     }
   3910 
   3911     return rv;
   3912 }
   3913 
   3914 STATIC int
   3915 _bcm_tr3_ibod_recovery_port(_port_ibod_ctrl_t *ibod_ctrl, bcm_port_t port)
   3916 {
   3917     int rv = BCM_E_NONE;
   3918     int need_recovery = FALSE;
   3919     sal_usecs_t time1, time2;
   3920 
   3921     /* Check and update runt counter */
   3922     rv = _bcm_tr3_ibod_port_check(ibod_ctrl, port, &need_recovery);
   3923     if (BCM_FAILURE(rv)) {
   3924         LOG_ERROR(BSL_LS_BCM_PORT,
   3925                       (BSL_META_U(ibod_ctrl->unit,
   3926                                   "Ibod recovery port %d check error\n"), port));
   3927        return rv;
   3928     }
   3929     else if(need_recovery == FALSE){
   3930         return BCM_E_NONE;
   3931     }
   3932 
   3933     time1 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time);
   3934 
   3935     rv = _bcm_tr3_ibod_sync_recovery_port(ibod_ctrl, 0, port);
   3936 
   3937     time2 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time);
   3938     ibod_ctrl->event_count++;
   3939     ibod_ctrl->port_avg_time = (ibod_ctrl->port_avg_time*(ibod_ctrl->event_count-1) +
   3940             time2 - time1) /ibod_ctrl->event_count;
   3941 
   3942     return rv;
   3943 }
   3944 
   3945 STATIC void
   3946 _bcm_tr3_ibod_sync_recovery_thread(void *context)
   3947 {
   3948     _port_ibod_ctrl_t *ibod_ctrl = context;
   3949     int port, rv, unit = ibod_ctrl->unit;
   3950 
   3951     LOG_VERBOSE(BSL_LS_BCM_PORT,
   3952                 (BSL_META_U(unit,
   3953                             "IBOD recovery started on unit %d\n"), ibod_ctrl->unit));
   3954 
   3955     ibod_ctrl->running = 1;
   3956     while (!ibod_ctrl->stop) {
   3957         if (!SOC_IS_DONE_INIT(unit)) {
   3958             (void)sal_sem_take(ibod_ctrl->sema, ibod_ctrl->interval);
   3959             continue;
   3960         }
   3961         /* Need to wait until warmboot recovery of ibod related stats is done */
   3962         if (!SOC_WARM_BOOT(unit)) {
   3963             PBMP_CL_ITER(unit, port) {
   3964                 if (SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port)) {
   3965                     continue;
   3966                 }
   3967                 ibod_ctrl->start_time = sal_time_usecs();
   3968                 if(!IS_C_PORT(unit, port)) {
   3969                     (void)_bcm_tr3_ibod_recovery_port(ibod_ctrl, port);
   3970                 }
   3971 
   3972                 rv = _bcm_tr3_txerr_recovery_port(ibod_ctrl, port);
   3973                 if (SOC_FAILURE(rv)) {
   3974                     LOG_ERROR(BSL_LS_BCM_PORT,
   3975                                  (BSL_META_U(unit, "\n Error in TXERR WAR %s"),SOC_PORT_NAME(unit,port)));
   3976                 }
   3977             }
   3978 
   3979             rv = _bcm_tr3_mmu_check_and_recovery(ibod_ctrl);
   3980             if (SOC_FAILURE(rv)) {
   3981                 LOG_ERROR(BSL_LS_BCM_PORT,
   3982                     (BSL_META_U(unit, "\n Error in MMU recovery ")));
   3983             }
   3984 
   3985         }
   3986         (void)sal_sem_take(ibod_ctrl->sema, ibod_ctrl->interval);
   3987     }
   3988     ibod_ctrl->running = 0;
   3989 }
   3990 
   3991 STATIC void
   3992 _bcm_hx4_ibod_sync_recovery_thread(void *context)
   3993 {
   3994     _port_ibod_ctrl_t *ibod_ctrl = context;
   3995     int port, flex_port=0, rv, unit = ibod_ctrl->unit;
   3996     uint64 rrpkt, rrbyt;
   3997     uint64 rrpkt_diff, rrbyt_diff;
   3998     uint32 rval,rval_1,port_mode=0,encap_mode=0,next_flex_port=0;
   3999     int port_group_iter;
   4000     int flex_port_arr[3]={-1,-1,-1},cou,i;
   4001     uint64 rval64;
   4002     int runt_threshold;
   4003     uint64 txerr;
   4004     int egress_drain_timeout, port_drain_timeout, port_recovery_failed_flag;
   4005 
   4006     LOG_VERBOSE(BSL_LS_BCM_PORT,
   4007                 (BSL_META_U(unit, "IBOD recovery started on unit %d\n"),ibod_ctrl->unit));
   4008 
   4009     cou=0;
   4010     PBMP_ITER(PBMP_XW_ALL(unit), port) {
   4011         (void) READ_PORT_MODE_REGr(unit, port, &rval);
   4012         port_mode=soc_reg_field_get(unit, PORT_MODE_REGr,
   4013                                     rval, XPORT0_CORE_PORT_MODEf);
   4014 
   4015         if (port_mode != 3) {
   4016             /* coverity[overrun-call : FALSE] */
   4017             if (_bcm_tr3_port_is_control_port(unit, port)) {
   4018                 flex_port_arr[cou] = port;
   4019                 cou++;
   4020             }
   4021         }
   4022         rv = READ_RRPKTr(unit, port, &rrpkt);
   4023         if (SOC_FAILURE(rv)) {
   4024            LOG_ERROR(BSL_LS_BCM_PORT,
   4025                          (BSL_META_U(unit, "Error in reading RRPKTr %d\n"),ibod_ctrl->unit));
   4026 
   4027         }
   4028 
   4029         rv = READ_RRBYTr(unit, port, &rrbyt);
   4030         if (SOC_FAILURE(rv)) {
   4031            LOG_ERROR(BSL_LS_BCM_PORT,
   4032                          (BSL_META_U(unit, "Error in reading RRBYTr %d\n"),ibod_ctrl->unit));
   4033         }
   4034         /* coverity[overrun-local : FALSE] */
   4035         ibod_ctrl->rrpkt[port] = rrpkt;
   4036         /* coverity[overrun-local : FALSE] */
   4037         ibod_ctrl->rrbyt[port] = rrbyt;
   4038     }
   4039 
   4040     ibod_ctrl->running = 1;
   4041     while (!ibod_ctrl->stop) {
   4042         if (!SOC_IS_DONE_INIT(unit)) {
   4043             (void)sal_sem_take(ibod_ctrl->sema, ibod_ctrl->interval);
   4044             continue;
   4045         }
   4046         /* Need to wait until warmboot recovery of ibod related stats is done */
   4047         if (!SOC_WARM_BOOT(unit)) {
   4048             next_flex_port=0;
   4049             port_group_iter=-1;
   4050             PBMP_ITER(PBMP_XW_ALL(unit), port) {
   4051                 if (!((IS_HG_PORT(unit,port)) || (IS_XE_PORT(unit,port)))) {
   4052                     continue;
   4053                 }
   4054                 /* coverity[overrun-local : FALSE] */
   4055                 if (SOC_INFO(unit).port_speed_max[port] >= 100000) {
   4056                     continue;
   4057                 }
   4058                 ibod_ctrl->start_time = sal_time_usecs();
   4059                 /* coverity[overrun-call : FALSE] */
   4060                 if (_bcm_tr3_port_is_control_port(unit, port)) {
   4061                     flex_port=port;
   4062                     next_flex_port=0;
   4063                     port_group_iter++;
   4064                 }
   4065                 if (next_flex_port) {
   4066                     continue;
   4067                 }
   4068                 (void) READ_PORT_EHG_RX_CONTROLr(unit, port, &rval);
   4069                 encap_mode = soc_reg_field_get(unit, PORT_EHG_RX_CONTROLr,
   4070                                             rval, MODEf);
   4071                 if (encap_mode) {
   4072                     (void) READ_PORT_EHG_RX_PKT_DROPr(unit, port, &rval);
   4073                     if (rval) {
   4074                         LOG_VERBOSE(BSL_LS_BCM_PORT,
   4075                                      (BSL_META_U(unit, "\n WAR Trigerred by Embedded HG RX control")));
   4076                         rv = BCM_E_NONE;
   4077                         /* coverity[overrun-call : FALSE] */
   4078                         rv = _bcm_hx4_ibod_sync_recovery_port(ibod_ctrl, port_group_iter, flex_port);
   4079                         if (SOC_FAILURE(rv)) {
   4080                             PORT_UNLOCK(unit);
   4081                             /* Release the ibod recovery port group lock */
   4082                             /* coverity[overrun-call : FALSE] */
   4083                             _bcm_esw_ibod_recovery_port_unlock(unit, flex_port);
   4084                             _bcm_esw_lc_unlock(unit);
   4085                             LOG_ERROR(BSL_LS_BCM_PORT,
   4086                                      (BSL_META_U(unit, "\n Error in RRPKT WAR %s"),SOC_PORT_NAME(unit,flex_port)));
   4087                         }
   4088                         soc_event_generate(unit, SOC_SWITCH_EVENT_RUNT_DETECT, port, 0, 0);
   4089                         for (i=0; i<3; i++) {
   4090                         if ((flex_port_arr[i] != flex_port) && (flex_port_arr[i] != -1)) {
   4091                              rv = BCM_E_NONE;
   4092                              rv = _bcm_hx4_txerr_recovery_port(ibod_ctrl, flex_port_arr[i]);
   4093                              if (SOC_FAILURE(rv)) {
   4094                                  PORT_UNLOCK(unit);
   4095                                  /* Release the ibod recovery port group lock */
   4096                                 _bcm_esw_ibod_recovery_port_unlock(unit, flex_port_arr[i]);
   4097                                  _bcm_esw_lc_unlock(unit);
   4098                                  LOG_ERROR(BSL_LS_BCM_PORT,
   4099                                      (BSL_META_U(unit, "\n Error in TXERR WAR %s"),SOC_PORT_NAME(unit,flex_port_arr[i])));
   4100                              }
   4101                             }
   4102                         }
   4103                         next_flex_port=1;
   4104                         continue;
   4105                     }
   4106                 }
   4107 
   4108                 rv = READ_TERRr(unit, port, &txerr);
   4109                 if (SOC_FAILURE(rv)) {
   4110                     continue;
   4111                 }
   4112                 /* coverity[overrun-local : FALSE] */
   4113                 if (COMPILER_64_NE(txerr, ibod_ctrl->txerrpkt[port])) {
   4114                     /* coverity[overrun-call : FALSE] */
   4115                     rv = _bcm_hx4_txerr_recovery_port(ibod_ctrl, flex_port);
   4116                     if (SOC_FAILURE(rv)) {
   4117                         PORT_UNLOCK(unit);
   4118                         /* Release the ibod recovery port group lock */
   4119                         /* coverity[overrun-call : FALSE] */
   4120                         _bcm_esw_ibod_recovery_port_unlock(unit, flex_port);
   4121                         _bcm_esw_lc_unlock(unit);
   4122                         LOG_ERROR(BSL_LS_BCM_PORT,
   4123                                      (BSL_META_U(unit, "\n Error in TXERR WAR %s"),SOC_PORT_NAME(unit,flex_port)));
   4124                     }
   4125                 }
   4126                 /* Check if any new runt packet logged in RRPKT */
   4127                 rv = READ_RRPKTr(unit, port, &rrpkt); 
   4128                 if (SOC_FAILURE(rv)) {
   4129                     continue;
   4130                 }
   4131                 if (COMPILER_64_EQ(rrpkt, ibod_ctrl->rrpkt[port])) {
   4132                     continue; 
   4133                 }
   4134                 /* Check total runt byte count */
   4135                 rv = READ_RRBYTr(unit, port, &rrbyt);
   4136                 if (SOC_FAILURE(rv)) {
   4137                     continue;
   4138                 }
   4139 
   4140                 /* It's very unlikely both packet and byte counters wrap around
   4141                  * and stop at 0, the code assume this is from clear counter */
   4142                 if (COMPILER_64_IS_ZERO(rrpkt) && COMPILER_64_IS_ZERO(rrbyt)) {
   4143                     ibod_ctrl->rrpkt[port] = rrpkt;
   4144                     ibod_ctrl->rrbyt[port] = rrbyt;
   4145                     continue;
   4146                 }
   4147 
   4148                 rrpkt_diff = rrpkt;
   4149                 rrbyt_diff = rrbyt;
   4150                 COMPILER_64_SUB_64(rrpkt_diff, ibod_ctrl->rrpkt[port]);
   4151                 COMPILER_64_SUB_64(rrbyt_diff, ibod_ctrl->rrbyt[port]);
   4152                 ibod_ctrl->rrpkt[port] = rrpkt;
   4153                 ibod_ctrl->rrbyt[port] = rrbyt;
   4154 
   4155                 rv = READ_XMAC_RX_CTRLr(unit,port, &rval64);
   4156                 if (SOC_FAILURE(rv)) {
   4157                     continue;
   4158                 }
   4159                 runt_threshold = soc_reg64_field32_get(unit, XMAC_RX_CTRLr, rval64, RUNT_THRESHOLDf);
   4160 
   4161                 /* Recovery is needed only for packet size between 33 and 76 */
   4162                 if (COMPILER_64_HI(rrpkt_diff) == 0 &&
   4163                     COMPILER_64_LO(rrpkt_diff) == 1) {
   4164                     if (COMPILER_64_LO(rrbyt_diff) >= runt_threshold) {
   4165                         continue;
   4166                     }
   4167                 }
   4168                 if (COMPILER_64_HI(rrbyt_diff) == 0 &&
   4169                     COMPILER_64_LO(rrbyt_diff) <= 32) {
   4170                     continue;
   4171                 }
   4172                 LOG_VERBOSE(BSL_LS_BCM_PORT,
   4173                       (BSL_META_U(unit,"\n WAR Trigerred by RRPKT/RRBYT")));
   4174                 /* coverity[overrun-call : FALSE] */
   4175                 rv = _bcm_hx4_ibod_sync_recovery_port(ibod_ctrl, port_group_iter, flex_port);
   4176                 if (SOC_FAILURE(rv)) {
   4177                     PORT_UNLOCK(unit);
   4178                     /* Release the ibod recovery port group lock */
   4179                     /* coverity[overrun-call : FALSE] */
   4180                     _bcm_esw_ibod_recovery_port_unlock(unit, flex_port);
   4181                     _bcm_esw_lc_unlock(unit);
   4182                     LOG_ERROR(BSL_LS_BCM_PORT,
   4183                                      (BSL_META_U(unit, "\n Error in RRPKT WAR %s"),SOC_PORT_NAME(unit,flex_port)));
   4184                 }
   4185                 soc_event_generate(unit, SOC_SWITCH_EVENT_RUNT_DETECT, port, 0, 0);
   4186                 for (i=0; i<3; i++) {
   4187                     if ((flex_port_arr[i] != flex_port) && (flex_port_arr[i] != -1)) {
   4188                         rv = BCM_E_NONE;
   4189                         rv = _bcm_hx4_txerr_recovery_port(ibod_ctrl, flex_port_arr[i]);
   4190                         if (SOC_FAILURE(rv)) {
   4191                             PORT_UNLOCK(unit);
   4192                             /* Release the ibod recovery port group lock */
   4193                             /* coverity[overrun-call : FALSE] */
   4194                             _bcm_esw_ibod_recovery_port_unlock(unit, flex_port_arr[i]);
   4195                             _bcm_esw_lc_unlock(unit);
   4196                             LOG_ERROR(BSL_LS_BCM_PORT,
   4197                                      (BSL_META_U(unit, "\n Error in TXERR WAR %s"),SOC_PORT_NAME(unit,flex_port_arr[i])));
   4198                         }
   4199                     }
   4200                 }
   4201                 next_flex_port=1;
   4202             }
   4203 
   4204              _soc_egress_drain_timeout_flag_get(unit, &egress_drain_timeout);
   4205              port_drain_timeout = ibod_ctrl->drain_timeout_flag;
   4206              port_recovery_failed_flag = ibod_ctrl->port_recovery_failed_flag;
   4207 
   4208             rv = READ_PQEFIFOOVERFLOW0r(unit, &rval);
   4209             if (SOC_FAILURE(rv)) {
   4210                 LOG_ERROR(BSL_LS_BCM_PORT,
   4211                          (BSL_META_U(unit, "\n Error in ibod recovery thread when reading register PQEFIFOOVERFLOW0")));
   4212             }
   4213             rv = READ_PQEFIFOOVERFLOW1r(unit, &rval_1);
   4214             if (SOC_FAILURE(rv)) {
   4215                 LOG_ERROR(BSL_LS_BCM_PORT,
   4216                          (BSL_META_U(unit, "\n Error in ibod recovery thread when reading register PQEFIFOOVERFLOW1")));
   4217             }
   4218 
   4219             if ((rval != 0) || (rval_1 != 0) || (egress_drain_timeout != 0) || (port_drain_timeout != 0)
   4220                     || port_recovery_failed_flag || (_ibod_debug_flag & _PORT_IBOD_FLAG_MMU_TRIGGER)) {
   4221                 rv = _bcm_tr3_mmu_recovery(ibod_ctrl);
   4222                 ibod_ctrl->drain_timeout_flag = 0;
   4223                 _soc_egress_drain_timeout_flag_set(unit, 0);
   4224                 if (port_drain_timeout) {
   4225                     ibod_ctrl->drain_timeout_flag = 0;
   4226                     ibod_ctrl->drain_timeout_count++;
   4227                 }
   4228                 if (egress_drain_timeout) {
   4229                     _soc_egress_drain_timeout_flag_set(unit, 0);
   4230                     ibod_ctrl->egress_drain_timeout_count++;
   4231                 }
   4232                 if (port_recovery_failed_flag) {
   4233                     ibod_ctrl->port_recovery_failed_flag = 0;
   4234                     ibod_ctrl->port_recovery_failed_count++;
   4235                 }
   4236                 if (_ibod_debug_flag & _PORT_IBOD_FLAG_MMU_TRIGGER) {
   4237                     _ibod_debug_flag &= (~_PORT_IBOD_FLAG_MMU_TRIGGER);
   4238                 }
   4239                 if (SOC_FAILURE(rv)) {
   4240                     LOG_ERROR(BSL_LS_BCM_PORT,
   4241                             (BSL_META_U(unit, "\n Error in MMU recovery ")));
   4242                 }
   4243             }
   4244         }
   4245         (void)sal_sem_take(ibod_ctrl->sema, ibod_ctrl->interval);
   4246     }
   4247     ibod_ctrl->running = 0;
   4248 }
   4249 
   4250 int _bcm_esw_ibod_syn_port_down (int unit, int port)
   4251 {
   4252     _port_ibod_ctrl_t *ibod_ctrl = _port_ibod_ctrl[unit];
   4253     int rv;
   4254     uint64 rrpkt, rrbyt,rval64;
   4255     uint64 rrpkt_diff, rrbyt_diff;
   4256     int runt_threshold;
   4257     uint32 port_mode, rval;
   4258 
   4259     if (!SOC_IS_TRIUMPH3(unit) || !ibod_ctrl) {
   4260         return BCM_E_NONE;
   4261     }
   4262 
   4263     if (SOC_IS_HELIX4(unit)) {
   4264         if (!IS_XE_PORT(unit, port) && !IS_HG_PORT(unit, port)) {
   4265             return SOC_E_NONE;
   4266         }
   4267     } else {
   4268         if (!IS_HG_PORT(unit, port)) {
   4269             return SOC_E_NONE;
   4270         }
   4271     }
   4272 
   4273      if (SOC_INFO(unit).port_speed_max[port] >= 100000 ||
   4274         !(SOC_CONTROL(unit)->soc_flags & SOC_F_INITED)) {
   4275          return SOC_E_NONE;
   4276      }
   4277 
   4278      BCM_IF_ERROR_RETURN(READ_PORT_MODE_REGr(unit, port, &rval));
   4279      port_mode=soc_reg_field_get(unit, PORT_MODE_REGr,
   4280                                  rval, XPORT0_CORE_PORT_MODEf);
   4281 
   4282      /* Port mode must be Dual or Qual */
   4283      if ((port_mode != 1) && (port_mode != 2)) {
   4284          return SOC_E_NONE;
   4285      }
   4286 
   4287      /* Check if any new runt packet logged in RRPKT */
   4288      rv = READ_RRPKTr(unit, port, &rrpkt);
   4289      if (SOC_FAILURE(rv)) {
   4290          return SOC_E_NONE;
   4291      }
   4292      if (COMPILER_64_EQ(rrpkt, ibod_ctrl->rrpkt[port])) {
   4293          return SOC_E_NONE;
   4294      }
   4295      /* Check total runt byte count */
   4296      rv = READ_RRBYTr(unit, port, &rrbyt);
   4297      if (SOC_FAILURE(rv)) {
   4298          return SOC_E_NONE;
   4299      }
   4300 
   4301      /* It's very unlikely both packet and byte counters wrap around
   4302      * and stop at 0, the code assume this is from clear counter */
   4303      if (COMPILER_64_IS_ZERO(rrpkt) && COMPILER_64_IS_ZERO(rrbyt)) {
   4304          ibod_ctrl->rrpkt[port] = rrpkt;
   4305          ibod_ctrl->rrbyt[port] = rrbyt;
   4306          return SOC_E_NONE;
   4307      }
   4308 
   4309      rrpkt_diff = rrpkt;
   4310      rrbyt_diff = rrbyt;
   4311      COMPILER_64_SUB_64(rrpkt_diff, ibod_ctrl->rrpkt[port]);
   4312      COMPILER_64_SUB_64(rrbyt_diff, ibod_ctrl->rrbyt[port]);
   4313      ibod_ctrl->rrpkt[port] = rrpkt;
   4314      ibod_ctrl->rrbyt[port] = rrbyt;
   4315 
   4316      rv = READ_XMAC_RX_CTRLr(unit,port, &rval64);
   4317      if (SOC_FAILURE(rv)) {
   4318          return SOC_E_NONE;
   4319      }
   4320      runt_threshold = soc_reg64_field32_get(unit, XMAC_RX_CTRLr, rval64, RUNT_THRESHOLDf);
   4321 
   4322      /* Recovery is needed only for packet size between 33 and 76 */
   4323      if (COMPILER_64_HI(rrpkt_diff) == 0 &&
   4324          COMPILER_64_LO(rrpkt_diff) == 1) {
   4325          if (COMPILER_64_LO(rrbyt_diff) >= runt_threshold) {
   4326              return SOC_E_NONE;
   4327          }
   4328      }
   4329      if (COMPILER_64_HI(rrbyt_diff) == 0 &&
   4330          COMPILER_64_LO(rrbyt_diff) <= 32) {
   4331          return SOC_E_NONE;
   4332      }
   4333 
   4334      ibod_ctrl->start_time = sal_time_usecs();
   4335      if (SOC_IS_HELIX4(unit)) {
   4336          int port_group_iter, port_iter, flex_port=0;
   4337          bcm_pbmp_t pbmp;
   4338          
   4339          port_group_iter=-1;
   4340          PBMP_ITER(PBMP_XW_ALL(unit), port_iter) {
   4341              /* coverity[overrun-call : FALSE] */
   4342              if (!(_bcm_tr3_port_is_control_port(unit, port_iter))) {
   4343                  continue;
   4344              }
   4345              flex_port = port_iter;
   4346              port_group_iter++;
   4347              BCM_IF_ERROR_RETURN(bcm_esw_port_subsidiary_ports_get(unit, flex_port, &pbmp));
   4348              if (SOC_PBMP_MEMBER(pbmp, port)) {
   4349                  break;
   4350              }
   4351          }
   4352          /* coverity[overrun-call : FALSE] */
   4353          rv = _bcm_hx4_ibod_sync_recovery_port(ibod_ctrl, port_group_iter, flex_port);
   4354          if (SOC_FAILURE(rv)) {
   4355             PORT_UNLOCK(unit);
   4356             /* Release the ibod recovery port group lock */
   4357             _bcm_esw_ibod_recovery_port_unlock(unit, flex_port);
   4358             _bcm_esw_lc_unlock(unit);
   4359          }
   4360      } else {
   4361          rv = _bcm_tr3_ibod_sync_recovery_port(ibod_ctrl, 1, port);
   4362      }
   4363 
   4364      if (SOC_FAILURE(rv)) {
   4365          LOG_ERROR(BSL_LS_BCM_PORT,
   4366                   (BSL_META_U(unit, "\n Error in RRPKT WAR %s"), SOC_PORT_NAME(unit, port)));
   4367      }
   4368      return SOC_E_NONE;
   4369 
   4370 }
   4371 
   4372 int
   4373 _bcm_esw_ibod_sync_recovery_start(int unit, sal_usecs_t interval)
   4374 {
   4375     int cnt;
   4376     bcm_pkt_t *pkt;
   4377     uint8 *buf;
   4378     int buf_size = 72;
   4379     uint32 rval;
   4380     int rv = BCM_E_NONE;
   4381     _port_ibod_ctrl_t *ibod_ctrl;
   4382     uint16 dev_id;
   4383     uint8 rev_id;
   4384 
   4385     if (!SOC_IS_TRIUMPH3(unit)) {
   4386         return BCM_E_NONE;
   4387     }
   4388 
   4389     /* APOLLO2 devices dont need ibod sync */ 
   4390     soc_cm_get_id(unit, &dev_id, &rev_id);
   4391     switch (dev_id) {
   4392     case BCM56542_DEVICE_ID:
   4393     case BCM56544_DEVICE_ID:
   4394         return BCM_E_NONE;
   4395     }
   4396 
   4397     ibod_ctrl = _port_ibod_ctrl[unit];
   4398     if (ibod_ctrl == NULL) {
   4399         ibod_ctrl = sal_alloc(sizeof(_port_ibod_ctrl_t), "_port_ibod_ctrl_t");
   4400         if (ibod_ctrl == NULL) {
   4401             return BCM_E_MEMORY;
   4402         }
   4403         sal_memset(ibod_ctrl, 0, sizeof(_port_ibod_ctrl_t));
   4404         _port_ibod_ctrl[unit] = ibod_ctrl;
   4405     }
   4406 
   4407     ibod_ctrl->interval = interval;
   4408 
   4409     if (ibod_ctrl->interval < IBOD_SYNC_INTERVAL_MIN) {
   4410         ibod_ctrl->interval = IBOD_SYNC_INTERVAL_MIN;
   4411     }
   4412 
   4413     if (ibod_ctrl->running) {
   4414         return BCM_E_NONE;
   4415     }
   4416 
   4417     ibod_ctrl->unit = unit;
   4418 
   4419     /* Setup packet field */
   4420     pkt = &ibod_ctrl->pkt;
   4421     buf = soc_cm_salloc(unit, buf_size, "pkt alloc data");
   4422     if (buf == NULL) {
   4423         return BCM_E_MEMORY;
   4424     }
   4425     BCM_PKT_ONE_BUF_SETUP(pkt, buf, buf_size);
   4426     pkt->unit = unit;
   4427     pkt->flags = BCM_TX_CRC_APPEND | BCM_TX_HG_READY | BCM_TX_NO_PAD |
   4428                  BCM_TX_LINKDOWN_TRANSMIT;
   4429     pkt->opcode = BCM_PKT_OPCODE_UC; /* do not to CPU */
   4430 
   4431     if (ibod_ctrl->sema == NULL) {
   4432         ibod_ctrl->sema = sal_sem_create("ibod recovery", sal_sem_BINARY, 0);
   4433         if (ibod_ctrl->sema == NULL) {
   4434             return BCM_E_MEMORY;
   4435         }
   4436     }
   4437 
   4438     sal_snprintf(ibod_ctrl->taskname, sizeof (ibod_ctrl->taskname),
   4439                  "bcmIbodSync.%d", unit);
   4440     ibod_ctrl->stop = 0;
   4441     SOC_IF_ERROR_RETURN(_bcm_esw_ibod_recovery_lock_init(unit));
   4442     rv = soc_tr3_mmu_store_alloc(unit);
   4443     if(BCM_FAILURE(rv)) {
   4444         return rv;
   4445     }
   4446     soc_ibod_recovery_in_progress_set(unit, 0);
   4447     _soc_egress_drain_timeout_flag_set(unit, 0);
   4448     sal_memset(txerr_trigger_flag, 0, sizeof(txerr_trigger_flag));
   4449     if (SOC_IS_HELIX4(unit)) {
   4450         SOC_IF_ERROR_RETURN(READ_IBOD_INTR_MASKr(unit, &rval));
   4451         soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL0_CTRL_FIFO_FULL_ERR_INTR_MASKf, 1);
   4452         soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL0_DATA_FIFO_FULL_ERR_INTR_MASKf, 1);
   4453         soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL1_CTRL_FIFO_FULL_ERR_INTR_MASKf, 1);
   4454         soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL1_DATA_FIFO_FULL_ERR_INTR_MASKf, 1);
   4455         soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL2_CTRL_FIFO_FULL_ERR_INTR_MASKf, 1);
   4456         soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL2_DATA_FIFO_FULL_ERR_INTR_MASKf, 1);
   4457         SOC_IF_ERROR_RETURN(WRITE_IBOD_INTR_MASKr(unit, rval));
   4458         if (sal_thread_create(ibod_ctrl->taskname, SAL_THREAD_STKSZ,
   4459                               soc_property_get(unit, spn_IBOD_SYNC_THREAD_PRI, 50),
   4460                               _bcm_hx4_ibod_sync_recovery_thread,
   4461                               ibod_ctrl) == SAL_THREAD_ERROR) {
   4462             return BCM_E_MEMORY;
   4463         }
   4464     } else {
   4465         if (sal_thread_create(ibod_ctrl->taskname, SAL_THREAD_STKSZ,
   4466                               soc_property_get(unit, spn_IBOD_SYNC_THREAD_PRI, 50),
   4467                               _bcm_tr3_ibod_sync_recovery_thread,
   4468                               ibod_ctrl) == SAL_THREAD_ERROR) {
   4469             return BCM_E_MEMORY;
   4470         }
   4471     }
   4472     cnt = 10;
   4473     while (!ibod_ctrl->running && cnt--) {
   4474         sal_usleep(100000);
   4475     }
   4476     if (!ibod_ctrl->running) {
   4477         LOG_ERROR(BSL_LS_BCM_PORT,
   4478                   (BSL_META_U(unit,
   4479                               "%s: Thread did not start\n"), ibod_ctrl->taskname));
   4480         return BCM_E_TIMEOUT;
   4481     }
   4482     return BCM_E_NONE;
   4483 }
   4484 
   4485 int
   4486 _bcm_esw_ibod_sync_recovery_stop(int unit)
   4487 {
   4488     int cnt;
   4489     bcm_pkt_t *pkt;
   4490     _port_ibod_ctrl_t *ibod_ctrl = _port_ibod_ctrl[unit];
   4491 
   4492     if (ibod_ctrl == NULL) {
   4493         return BCM_E_NONE;
   4494     }
   4495 
   4496     ibod_ctrl->stop = 1;
   4497     if (ibod_ctrl->sema != NULL) {
   4498         sal_sem_give(ibod_ctrl->sema);
   4499     }
   4500     cnt = 10;
   4501     while (ibod_ctrl->running && cnt--) {
   4502         sal_usleep(100000);
   4503     }
   4504     if (ibod_ctrl->running) {
   4505         LOG_ERROR(BSL_LS_BCM_PORT,
   4506                   (BSL_META_U(unit,
   4507                               "%s: Thread did not start\n"), ibod_ctrl->taskname));
   4508         return BCM_E_TIMEOUT;
   4509     }
   4510     pkt = &ibod_ctrl->pkt;
   4511     if (pkt->_pkt_data.data != NULL) {
   4512         soc_cm_sfree(unit, pkt->_pkt_data.data);
   4513         pkt->_pkt_data.data = NULL;
   4514         pkt->_pkt_data.len = 0;
   4515     }
   4516     if (ibod_ctrl->sema != NULL) {
   4517         sal_sem_destroy(ibod_ctrl->sema);
   4518     }
   4519 
   4520     sal_free(ibod_ctrl);
   4521     _port_ibod_ctrl[unit] = NULL;
   4522 
   4523     _bcm_esw_ibod_recovery_lock_deinit(unit);
   4524 
   4525     soc_tr3_mmu_store_free(unit);
   4526     return BCM_E_NONE;
   4527 }
   4528 
   4529 int _bcm_esw_ibod_sync_recovery_running(int unit, _port_ibod_ctrl_t *ibod_ctrl)
   4530 {
   4531     if (_port_ibod_ctrl[unit] == NULL) {
   4532         return BCM_E_FAIL;
   4533     }
   4534     if(ibod_ctrl != NULL) {
   4535         sal_memcpy(ibod_ctrl, _port_ibod_ctrl[unit], sizeof(_port_ibod_ctrl_t));
   4536     }
   4537     return BCM_E_NONE;
   4538 }
   4539 
   4540 STATIC int _bcm_tr3_xmac_fifo_check(int unit, bcm_port_t port, uint8 lu_tpo)
   4541 {
   4542     int rv_xmac_fifo = BCM_E_NONE;
   4543     int rv = BCM_E_NONE;
   4544     bcm_pkt_t *pkt = NULL;
   4545     uint8 *payload;
   4546     uint32 req_cnt = 0, cell_cnt = 0;
   4547     uint64 rval64;
   4548     int rx_enable_org = 0,speed_mode=0,port_enable;
   4549     pbmp_t act_tx_pbmp, tx_pbmp;
   4550 
   4551     COMPILER_64_ZERO(rval64);
   4552     SOC_PBMP_CLEAR(act_tx_pbmp);
   4553     SOC_PBMP_CLEAR(tx_pbmp);
   4554 
   4555     /* Create test packet */
   4556     pkt = soc_cm_salloc(unit, sizeof(bcm_pkt_t), "pkt buffer");
   4557     if (pkt == NULL) {
   4558         return BCM_E_FAIL;
   4559     }
   4560 
   4561     sal_memset(pkt, 0, sizeof(bcm_pkt_t));
   4562     payload = soc_cm_salloc(unit, _SOC_HX4_XMAC_FIFO_CHK_PKT_SZ,
   4563                             "pkt alloc data");
   4564     if (payload == NULL) {
   4565         soc_cm_sfree(unit, pkt);
   4566         return BCM_E_FAIL;
   4567     }
   4568     sal_memset(payload, 0, _SOC_HX4_XMAC_FIFO_CHK_PKT_SZ);
   4569     BCM_PKT_ONE_BUF_SETUP(pkt, payload, _SOC_HX4_XMAC_FIFO_CHK_PKT_SZ);
   4570     pkt->unit = unit;
   4571     pkt->flags = BCM_TX_CRC_APPEND | BCM_TX_HG_READY | BCM_TX_NO_PAD |
   4572                 BCM_TX_LINKDOWN_TRANSMIT;
   4573     pkt->call_back = NULL;
   4574 
   4575 #ifdef BCM_PORT_DEFAULT_DISABLE
   4576     port_enable = FALSE;
   4577 #else
   4578     port_enable = TRUE;
   4579 #endif  /* BCM_PORT_DEFAULT_DISABLE */
   4580 
   4581     if (BCM_E_NONE !=
   4582         (rv = MAC_ENABLE_GET(PORT(unit, port).p_mac, unit, port, &port_enable))) {
   4583         goto cleanup;
   4584     }
   4585     /* Put the port in MAC loopback and enable it for transmit */
   4586     if (BCM_E_NONE !=
   4587         (rv = MAC_LOOPBACK_SET(PORT(unit, port).p_mac, unit, port, TRUE))) {
   4588         goto cleanup;
   4589     }
   4590     if (BCM_E_NONE !=
   4591         (rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, TRUE))) {
   4592         goto cleanup;
   4593     }
   4594     /* Ensure that we are in MAC line-side loopback */
   4595     if (SOC_E_NONE != (rv = READ_XMAC_CTRLr(unit, port, &rval64))) {
   4596         goto cleanup;
   4597     }
   4598 
   4599     rx_enable_org = soc_reg64_field32_get(unit, XMAC_CTRLr, rval64, RX_ENf);
   4600     /* RX Disable */
   4601     soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf, 0);
   4602     /* Line local LB  */
   4603     soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, LINE_LOCAL_LPBKf, 1);
   4604     /* Core local LB */
   4605     soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, CORE_LOCAL_LPBKf, 0);
   4606     if (SOC_E_NONE != (rv = WRITE_XMAC_CTRLr(unit, port, rval64))) {
   4607         goto cleanup;
   4608     }
   4609     /* Ensure that we are back in same MAC MODE*/
   4610     if (SOC_E_NONE != (rv = READ_XMAC_MODEr(unit, port, &rval64))) {
   4611         goto cleanup;
   4612     }
   4613     speed_mode = soc_reg64_field32_get(unit, XMAC_MODEr, rval64, SPEED_MODEf);
   4614 
   4615     /* Stall the XMAC's transmit FIFO */
   4616     if (SOC_E_NONE !=
   4617         (rv = soc_reg_field32_modify(unit, XMAC_MODEr, port, SPEED_MODEf, 4))) {
   4618         goto cleanup;
   4619     }
   4620 
   4621     if (SOC_E_NONE !=
   4622         (rv = soc_reg_field32_modify(unit, XMAC_MACSEC_CTRLr, port,
   4623                                      MACSEC_TX_LAUNCH_ENf, 1))) {
   4624         goto cleanup;
   4625     }
   4626 
   4627     /* EPC_LINK */
   4628     soc_link_mask2_get(unit, &act_tx_pbmp);
   4629     SOC_PBMP_PORT_ADD(tx_pbmp, port);
   4630     if (!lu_tpo) {
   4631         /* Use original state and add new ports as well */
   4632         SOC_PBMP_OR(tx_pbmp, act_tx_pbmp);
   4633     }
   4634     if (SOC_E_NONE != (rv = soc_link_mask2_set(unit, tx_pbmp))) {
   4635         goto cleanup;
   4636     }
   4637     /* Transmit the test packet */
   4638     BCM_PKT_TX_LEN_SET(pkt, _SOC_HX4_XMAC_FIFO_CHK_PKT_SZ);
   4639     BCM_PKT_PORT_SET(pkt, port, TRUE, FALSE);
   4640     rv = bcm_esw_tx(unit, pkt, NULL);
   4641     if (BCM_FAILURE(rv)) {
   4642         rv = BCM_E_FAIL;
   4643         goto cleanup;
   4644     }
   4645 
   4646     /* Wait for a short period of time to allow
   4647        the packet to reach the end of the EP */
   4648     sal_udelay(1000);
   4649 
   4650     /* Read the request count value */
   4651     if (SOC_E_NONE !=
   4652         (rv = READ_PORT_TXFIFO_CELL_REQ_CNTr(unit, port, &req_cnt))) {
   4653         goto cleanup;
   4654     }
   4655     /* Read the cell count value */
   4656     if (SOC_E_NONE !=
   4657         (rv = READ_PORT_TXFIFO_CELL_CNTr(unit, port, &cell_cnt))) {
   4658         goto cleanup;
   4659     }
   4660     LOG_VERBOSE(BSL_LS_BCM_PORT,
   4661                 (BSL_META_U(unit,
   4662                             "Check: cell_req_cnt: %d cell_cnt: %d\n"),
   4663                  req_cnt, cell_cnt));
   4664     /* Check to make sure that the request count is exactly zero */
   4665     if (req_cnt != 0) {
   4666         rv_xmac_fifo = BCM_E_INTERNAL;
   4667         goto cleanup;
   4668     }
   4669 
   4670 cleanup:
   4671     /* free packet memory */
   4672     if (payload != NULL) {
   4673         soc_cm_sfree(unit, payload);
   4674     }
   4675     if (pkt != NULL) {
   4676         soc_cm_sfree(unit, pkt);
   4677     }
   4678     /* Clear the MAC loopback (flushes the test packet) */
   4679     if (SOC_E_NONE != MAC_LOOPBACK_SET(PORT(unit, port).p_mac,
   4680                                             unit, port, FALSE)) {
   4681         rv = BCM_E_FAIL;
   4682     }
   4683     /* Clear the MAC Enable Set */
   4684     if (SOC_E_NONE != MAC_ENABLE_SET(PORT(unit, port).p_mac,
   4685                                           unit, port, FALSE)) {
   4686         rv = BCM_E_FAIL;
   4687     }
   4688     /* Restoring the MAC Enable Set */
   4689     if (port_enable) {
   4690         if (SOC_E_NONE !=
   4691             (rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, TRUE))) {
   4692              rv = BCM_E_FAIL;
   4693         }
   4694     }
   4695     /* Remove the MAC FIFO stall */
   4696     if (SOC_E_NONE != soc_reg_field32_modify(unit, XMAC_MODEr, port,
   4697                                              SPEED_MODEf, speed_mode)) {
   4698         rv = BCM_E_FAIL;
   4699     }
   4700     if (SOC_E_NONE != soc_reg_field32_modify(unit, XMAC_MACSEC_CTRLr, port,
   4701                                              MACSEC_TX_LAUNCH_ENf, 0)) {
   4702         rv = BCM_E_FAIL;
   4703     }
   4704     /* revert rx_enable */
   4705     if (SOC_E_NONE != soc_reg_field32_modify(unit, XMAC_CTRLr, port, RX_ENf,
   4706                                              rx_enable_org)) {
   4707         rv = BCM_E_FAIL;
   4708     }
   4709     /* EPC_LINK restore */
   4710     if (SOC_E_NONE != soc_link_mask2_set(unit, act_tx_pbmp)) {
   4711         rv = BCM_E_FAIL;
   4712     }
   4713     /* Clear the counters from tx port*/
   4714     SOC_PBMP_PORT_SET(tx_pbmp, port);
   4715     if (SOC_E_NONE != soc_counter_set32_by_port(unit, tx_pbmp, 0))  {
   4716         rv = BCM_E_FAIL;
   4717     }
   4718     if (BCM_E_NONE != rv) {
   4719         return rv;
   4720     } else {
   4721         return rv_xmac_fifo;
   4722     }
   4723 }
   4724 
   4725 #define _BCM_TR3_PORT_UR_RETRY_MAX 15
   4726 int _bcm_tr3_port_ur_chk(int unit, int num_ports, bcm_port_t port)
   4727 {
   4728     uint8 lu_tpo = 0; /* link up test port only */
   4729     int retry = _BCM_TR3_PORT_UR_RETRY_MAX;
   4730     int fifo_underrun = FALSE, issue_overcome = TRUE;
   4731     soc_info_t *si = &SOC_INFO(unit);
   4732     int rv = BCM_E_NONE;
   4733     int okay = 0;
   4734     uint32 expected_cell_req_cnt, cell_req_cnt, cell_cnt;
   4735     soc_block_type_t pbt;
   4736     int _num_ports = (num_ports == -1) ? 4 : num_ports;
   4737     int phy_port = SOC_IS_HELIX4(unit) ?
   4738                    _SOC_HX4_MGMT_PHY_PORT : _SOC_TR3_MGMT_PHY_PORT;
   4739 
   4740 #ifdef BCM_TRIUMPH3_SUPPORT
   4741     if (!(SOC_IS_HELIX4(unit))) {
   4742         /* Skipping in for Disabled Ports */
   4743         SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &okay));
   4744         if (!okay) {
   4745             return BCM_E_NONE;
   4746         }
   4747     }
   4748 #endif
   4749 #ifdef BCM_HELIX4_SUPPORT
   4750      if ( SOC_IS_HELIX4(unit) &&
   4751      ((_tr3_port_config_id[unit] == 463)||
   4752         (_tr3_port_config_id[unit] == 413)) &&
   4753         (57 == si->port_l2p_mapping[port] || 61 == si->port_l2p_mapping[port]))
   4754      {
   4755         switch (_num_ports) {
   4756           case 1: expected_cell_req_cnt = 8; break;
   4757           case 2: expected_cell_req_cnt = 4; break;
   4758           case 4: expected_cell_req_cnt = 4; break;
   4759           default: expected_cell_req_cnt = 4;
   4760         }
   4761      }else
   4762 #endif
   4763     {
   4764     switch (_num_ports) {
   4765     case 1: expected_cell_req_cnt = 16; break;
   4766     case 2: expected_cell_req_cnt = 8; break;
   4767     case 4: expected_cell_req_cnt = 4; break;
   4768     default: expected_cell_req_cnt = 4;
   4769     }
   4770     }
   4771     if (-1 == port) {
   4772         lu_tpo = 1;
   4773         port = si->port_p2l_mapping[phy_port];
   4774     } else {
   4775         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   4776     }
   4777     LOG_VERBOSE(BSL_LS_BCM_PORT,
   4778                 (BSL_META_U(unit,
   4779                             "UR test: %s\n"), SOC_PORT_NAME(unit, port)));
   4780     
   4781     /* nothing to do if port is not a valid port */
   4782     if (!SOC_PORT_VALID(unit, port)) {
   4783         LOG_VERBOSE(BSL_LS_BCM_PORT, (BSL_META_U(unit,
   4784                     "Port %s is not valid - skipping WAR\n"), 
   4785                     SOC_PORT_NAME(unit, port)));
   4786         return BCM_E_NONE;
   4787     }    
   4788 
   4789     pbt = SOC_BLOCK_TYPE(unit, SOC_PORT_BLOCK(unit, phy_port));
   4790     while (retry--) {
   4791         rv = _bcm_tr3_xmac_fifo_check(unit, port, lu_tpo);
   4792         if (BCM_E_INTERNAL == rv) {
   4793             if (num_ports != -1 && (_num_ports > 1)) {
   4794                 /* This is a case of flex port transform to dual or quad lane
   4795                    mode and one of the newly created ports is failing */
   4796                 return BCM_E_PORT;
   4797             }
   4798             fifo_underrun = TRUE;
   4799             issue_overcome = FALSE;
   4800 
   4801             if (SOC_E_NONE != (rv = _soc_tr3_ur_port_reset(unit, _num_ports, port, pbt))) {
   4802                 rv = BCM_E_INTERNAL;
   4803                 goto cleanup;
   4804             }
   4805             if ((rv = _bcm_port_mac_init(unit, port, &okay)) != BCM_E_NONE) {
   4806                 goto cleanup;
   4807             }
   4808             /* Read cell req count value to see if reset cleared it */
   4809             if ((rv = READ_PORT_TXFIFO_CELL_REQ_CNTr(
   4810                           unit, port, &cell_req_cnt)) != SOC_E_NONE) {
   4811                 goto cleanup;
   4812             }
   4813             /* Read cell count value again to see if reset cleared it */
   4814             if ((rv = READ_PORT_TXFIFO_CELL_CNTr(
   4815                           unit, port, &cell_cnt))!= SOC_E_NONE) {
   4816                 goto cleanup;
   4817             }
   4818             LOG_VERBOSE(BSL_LS_BCM_PORT,
   4819                         (BSL_META_U(unit,
   4820                                     "After reset: cell_req_cnt: "
   4821                                     "%d cell_cnt: %d\n"), cell_req_cnt, cell_cnt));
   4822             /* Check to make sure that the request count is exactly zero */
   4823             if ((cell_req_cnt != expected_cell_req_cnt) || (cell_cnt != 0)) {
   4824                 rv = BCM_E_INTERNAL;
   4825                 goto cleanup;
   4826             }
   4827         } else {
   4828             if (BCM_E_NONE != rv) {
   4829                 goto cleanup;
   4830             }
   4831             if (TRUE == fifo_underrun) {
   4832                 issue_overcome = TRUE;
   4833             }
   4834             /* either underrun didn't occur or war fixed it */
   4835             break;
   4836         }
   4837     }/* while */
   4838 
   4839     if (fifo_underrun) {
   4840         rv = BCM_E_INTERNAL;
   4841         if (issue_overcome) {
   4842             rv = BCM_E_NONE;
   4843             LOG_VERBOSE(BSL_LS_BCM_PORT,
   4844                         (BSL_META_U(unit,
   4845                                     "Port %s recovered from XMAC FIFO underrun\n"),
   4846                          SOC_PORT_NAME(unit, port)));
   4847         } else {
   4848             LOG_ERROR(BSL_LS_BCM_PORT,
   4849                       (BSL_META_U(unit,
   4850                                   "Port %s did not recover from XMAC FIFO underrun\n"),
   4851                        SOC_PORT_NAME(unit, port)));
   4852         }
   4853     }
   4854 
   4855 cleanup:
   4856     if (BCM_E_NONE != rv) {
   4857         LOG_ERROR(BSL_LS_BCM_PORT,
   4858                   (BSL_META_U(unit,
   4859                               "Port %s, failed while checking/recovering "
   4860                               "XL port underrun\n"),
   4861                    SOC_PORT_NAME(unit, port)));
   4862     }
   4863 
   4864     return rv;
   4865 }
   4866 #endif /* BCM_TRIUMPH3_SUPPORT */
   4867 
   4868 
   4869 /*
   4870  * Function:
   4871  *      _bcm_esw_port_gport_validate
   4872  * Description:
   4873  *      Helper funtion to validate port/gport parameter
   4874  * Parameters:
   4875  *      unit  - (IN) BCM device number
   4876  *      port_in  - (IN) Port / Gport to validate
   4877  *      port_out - (OUT) Port number if valid.
   4878  * Return Value:
   4879  *      BCM_E_NONE - Port OK
   4880  *      BCM_E_INIT - Not initialized
   4881  *      BCM_E_PORT - Port Invalid
   4882  */
   4883 int
   4884 _bcm_esw_port_gport_validate(int unit, bcm_port_t port_in, bcm_port_t *port_out)
   4885 {
   4886     if (bcm_port_info[unit] == NULL) {
   4887         return BCM_E_INIT;
   4888     }
   4889 
   4890 #if defined (BCM_HGPROXY_COE_SUPPORT)
   4891     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 
   4892         BCM_GPORT_IS_SUBPORT_PORT(port_in)) {
   4893         return _bcm_xgs5_subport_gport_validate(unit,
   4894                                                 port_in, 
   4895                                                 port_out);
   4896     } else
   4897 #endif /* defined (BCM_HGPROXY_COE_SUPPORT) */
   4898 
   4899 #ifdef BCM_KATANA2_SUPPORT
   4900     if (soc_feature(unit, soc_feature_linkphy_coe) ||
   4901         soc_feature(unit, soc_feature_subtag_coe)) {
   4902         return _bcm_kt2_port_gport_validate(unit, port_in, port_out);
   4903     }
   4904 #endif
   4905 
   4906     if (BCM_GPORT_IS_SET(port_in)) {
   4907         BCM_IF_ERROR_RETURN(
   4908             bcm_esw_port_local_get(unit, port_in, port_out));
   4909     } else if (SOC_PORT_VALID(unit, port_in)) {
   4910         *port_out = port_in;
   4911     } else {
   4912         return BCM_E_PORT;
   4913     }
   4914 
   4915     return BCM_E_NONE;
   4916 }
   4917 
   4918 /*
   4919  * Function:
   4920  *      _bcm_port_link_delay_update
   4921  * Description:
   4922  *      Helper funtion: Update link delay based on configured values
   4923  * Parameters:
   4924  *      unit  - (IN) BCM device number
   4925  *      port  - (IN) Port number
   4926  *      speed - (IN) New speed
   4927  * Return Value:
   4928  *      BCM_E_XXX
   4929  */
   4930 int
   4931 _bcm_esw_port_link_delay_update(int unit, bcm_port_t port, int speed)
   4932 {
   4933     int32 link_delay;
   4934     int mac_rx_latency = 0;
   4935     _bcm_port_info_t *port_info;
   4936     int rv;
   4937 
   4938     _bcm_port_info_access(unit, port, &port_info);
   4939     rv = MAC_CONTROL_GET(port_info->p_mac, unit, port,
   4940                          SOC_MAC_CONTROL_EXPECTED_RX_LATENCY,
   4941                          &mac_rx_latency);
   4942     if (rv != BCM_E_NONE) {
   4943         LOG_INFO(BSL_LS_BCM_PORT, (BSL_META(
   4944            "Port updating LINK_DELAY, but MAC doesn't have a default value\n")
   4945         ));
   4946     }
   4947 
   4948     link_delay = (int32)soc_property_port_get(unit, port, spn_LINK_DELAY(speed), mac_rx_latency);
   4949     /* use bcmPortControl1588P2PDelay control field as an offset from this value */
   4950     link_delay += PORT(unit, port).link_delay_offset;
   4951 
   4952     if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAYr, port)) {
   4953         BCM_IF_ERROR_RETURN(
   4954             soc_reg_field32_modify(unit, EGR_1588_LINK_DELAYr,
   4955                 port, LINK_DELAYf, (uint32)link_delay));
   4956     } else if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAY_64r, port)) {
   4957         BCM_IF_ERROR_RETURN(
   4958             soc_reg_above_64_field32_modify(unit, EGR_1588_LINK_DELAY_64r,
   4959                 port, 0, LINK_DELAYf, (uint32)link_delay));
   4960     } else {
   4961         /* No LINK_DELAY register, so no-op */
   4962     }
   4963 
   4964     return BCM_E_NONE;
   4965 }
   4966 
   4967 STATIC int
   4968 _bcm_esw_port_link_delay_recover(int unit, bcm_port_t port, int speed)
   4969 {
   4970     uint32 link_delay = 0;
   4971     uint32 mac_rx_latency = 0;
   4972 
   4973     mac_rx_latency = soc_property_port_get(unit, port, spn_LINK_DELAY(speed), mac_rx_latency);
   4974 
   4975     if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAYr, port)) {
   4976         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, EGR_1588_LINK_DELAYr, port, LINK_DELAYf, &link_delay));
   4977     } else if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAY_64r, port)) {
   4978         SOC_IF_ERROR_RETURN(soc_reg_above_64_field32_read(unit, EGR_1588_LINK_DELAY_64r,
   4979                                                           port, 0, LINK_DELAYf, &link_delay));
   4980     }
   4981 
   4982     PORT(unit, port).link_delay_offset = link_delay - mac_rx_latency;
   4983 
   4984     return BCM_E_NONE;
   4985 }
   4986 
   4987 /*
   4988  * Function:
   4989  *      _bcm_port_info_get
   4990  * Description:
   4991  *      Helper funtion
   4992  * Parameters:
   4993  *      unit  - (IN) BCM device number
   4994  *      port  - (IN) Port number
   4995  *      pinfo - (OUT) Port info.
   4996  * Return Value:
   4997  *      BCM_E_XXX
   4998  */
   4999 int
   5000 _bcm_port_info_get(int unit, bcm_port_t port, _bcm_port_info_t **pinfo)
   5001 {
   5002     /* Input parameters check. */
   5003     if (NULL == pinfo) {
   5004         return (BCM_E_PARAM);
   5005     }
   5006 
   5007     PORT_INIT(unit);
   5008 
   5009     *pinfo = &PORT(unit, port);
   5010     return (BCM_E_NONE);
   5011 }
   5012 
   5013 /*
   5014  * Function:
   5015  *      _bcm_esw_iport_tab_set
   5016  * Description:
   5017  *      Set field in either IPORT_TABLE or the special CPU Higig entry in
   5018  *      the PORT_TAB.
   5019  * Parameters:
   5020  *      unit  - Device number
   5021  *      port  - Port number
   5022  *      field - Field name within PORT_TAB table entry
   5023  *      value - new field value
   5024  * Return Value:
   5025  *      BCM_E_NONE
   5026  *      BCM_E_XXX - an error occurred accessing PORT_TAB table.
   5027  */
   5028 int
   5029 _bcm_esw_iport_tab_set(int unit, bcm_port_t port,
   5030                        soc_field_t field, int value)
   5031 
   5032 {
   5033     port_tab_entry_t pent;
   5034     soc_mem_t mem;
   5035     int rv, index, cpu_hg_index, cur_val;
   5036 
   5037     cpu_hg_index = SOC_IS_KATANA2(unit) ?
   5038                    SOC_INFO(unit).cpu_hg_pp_port_index :
   5039                    SOC_INFO(unit).cpu_hg_index;
   5040 
   5041     if (SOC_MEM_IS_VALID(unit, IPORT_TABLEm)) {
   5042         mem = IPORT_TABLEm;
   5043         index = SOC_PORT_MOD_OFFSET(unit, port);
   5044     } else if (IS_CPU_PORT(unit, port) && cpu_hg_index != -1) {
   5045         mem = PORT_TABm;
   5046         index = cpu_hg_index;
   5047     } else {
   5048         return BCM_E_NONE;
   5049     }
   5050 
   5051     if (!SOC_MEM_FIELD_VALID(unit, mem, field)) {
   5052         return (BCM_E_UNAVAIL);
   5053     }
   5054 
   5055     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, &pent);
   5056     if (BCM_SUCCESS(rv)) {
   5057         cur_val = soc_mem_field32_get(unit, mem, &pent, field);
   5058         if (value != cur_val) {
   5059             soc_mem_field32_set(unit, mem, &pent, field, value);
   5060             rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, &pent);
   5061         }
   5062     }
   5063     return rv;
   5064 }
   5065 
   5066 /*
   5067  * Function:
   5068  *      _bcm_phy_cb_xlate_port
   5069  * Description:
   5070  *      Provides port translation for API call-backs
   5071  * Parameter:
   5072  *      unit -- unit number
   5073  *      port -- port number to be translated
   5074  * Returns:
   5075  *      SOC_E_xxx
   5076  */
   5077 STATIC int
   5078 _bcm_phy_cb_xlate_port(int unit, int *port)
   5079 {
   5080     BCM_API_XLATE_PORT_P2A(unit, port);
   5081 
   5082     return BCM_E_NONE;
   5083 }
   5084 
   5085 /*
   5086  * Function:
   5087  *      _bcm_port_autoneg_advert_remote_get
   5088  * Purpose:
   5089  *      Main part of bcm_port_advert_get_remote
   5090  */
   5091 
   5092 STATIC int
   5093 _bcm_port_autoneg_advert_remote_get(int unit, bcm_port_t port,
   5094                             bcm_port_ability_t *ability_mask)
   5095 {
   5096     int                 an, an_done;
   5097 
   5098     if(bcm_common_oamp_port_enable_get(unit, port)) {
   5099         LOG_ERROR(BSL_LS_BCM_PORT,
   5100                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
   5101                    port));
   5102         return BCM_E_PARAM;
   5103     }
   5104 
   5105     SOC_IF_ERROR_RETURN
   5106         (soc_phyctrl_auto_negotiate_get(unit,  port,
   5107                                 &an, &an_done));
   5108 
   5109     if (an && an_done) {
   5110         SOC_IF_ERROR_RETURN
   5111             (soc_phyctrl_ability_remote_get(unit, port, ability_mask));
   5112     }
   5113 
   5114     return BCM_E_NONE;
   5115 }
   5116 
   5117 /*
   5118  * Function:
   5119  *      _bcm_port_ability_local_get
   5120  * Purpose:
   5121  *      Main part of bcm_port_ability_local_get
   5122  */
   5123 
   5124 STATIC int
   5125 _bcm_port_ability_local_get(int unit, bcm_port_t port,
   5126                            bcm_port_ability_t *ability_mask)
   5127 {
   5128     soc_port_ability_t             mac_ability, phy_ability;
   5129     soc_pa_encap_t                 encap_ability;
   5130 #ifdef BCM_TRIUMPH3_SUPPORT
   5131     int lanes;
   5132 #endif
   5133 #ifdef INCLUDE_MACSEC
   5134     phy_ctrl_t         *ext_pc;
   5135     ext_pc = EXT_PHY_SW_STATE(unit, port);
   5136 #endif /* INCLUDE_MACSEC */
   5137     sal_memset(&phy_ability, 0, sizeof(soc_port_ability_t));
   5138     sal_memset(&mac_ability, 0, sizeof(soc_port_ability_t));
   5139 
   5140     if(bcm_common_oamp_port_enable_get(unit, port)) {
   5141         LOG_ERROR(BSL_LS_BCM_PORT,
   5142                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
   5143                    port));
   5144         return BCM_E_PARAM;
   5145     }
   5146 
   5147     SOC_IF_ERROR_RETURN
   5148         (soc_phyctrl_ability_local_get(unit, port, &phy_ability));
   5149 
   5150     if (!(IS_TDM_PORT(unit, port))) {
   5151         SOC_IF_ERROR_RETURN
   5152             (MAC_ABILITY_LOCAL_GET(PORT(unit, port).p_mac, unit,
   5153                                    port, &mac_ability));
   5154     }
   5155 
   5156     /* Combine MAC and PHY abilities */
   5157 
   5158 #ifdef INCLUDE_MACSEC
   5159     /*
   5160 	   MACSEC phys have their own MAC. If macsec is enabled,
   5161        phy's MAC is used for MAC operation on the line side.
   5162        Check added to use half duplex ability of phy/MAC.
   5163     */
   5164     if((NULL != ext_pc) && ext_pc->macsec_enable) {
   5165         ability_mask->speed_half_duplex = phy_ability.speed_half_duplex;
   5166     } else
   5167 #endif /* INCLUDE_MACSEC */
   5168     {
   5169         ability_mask->speed_half_duplex =
   5170             mac_ability.speed_half_duplex & phy_ability.speed_half_duplex;
   5171     }
   5172     ability_mask->speed_full_duplex =
   5173         mac_ability.speed_full_duplex & phy_ability.speed_full_duplex;
   5174     ability_mask->pause     = mac_ability.pause & phy_ability.pause;
   5175     if (phy_ability.interface == 0) {
   5176         ability_mask->interface = mac_ability.interface;
   5177     } else {
   5178         ability_mask->interface = phy_ability.interface;
   5179     }
   5180     ability_mask->medium    = phy_ability.medium;
   5181     ability_mask->channel   = phy_ability.channel;
   5182     ability_mask->fec       = phy_ability.fec;
   5183     /* mac_ability.eee without phy_ability.eee makes no sense */
   5184     ability_mask->eee    = phy_ability.eee;
   5185     ability_mask->loopback  = mac_ability.loopback | phy_ability.loopback |
   5186                                BCM_PORT_ABILITY_LB_NONE;
   5187     ability_mask->flags     = mac_ability.flags | phy_ability.flags;
   5188 
   5189     /* Get port encapsulation ability */
   5190     encap_ability = mac_ability.encap;
   5191 
   5192     if ((soc_feature(unit, soc_feature_embedded_higig))
   5193         && IS_E_PORT(unit, port)) {
   5194         encap_ability |= BCM_PA_ENCAP_HIGIG2_L2;
   5195         encap_ability |= BCM_PA_ENCAP_HIGIG2_IP_GRE;
   5196     }
   5197 
   5198 #if defined(BCM_RAPTOR_SUPPORT)
   5199     if ((SOC_IS_RAPTOR(unit) || SOC_IS_RAVEN(unit)) &&
   5200         IS_S_PORT(unit, port)) {
   5201         encap_ability |= BCM_PA_ENCAP_HIGIG2;
   5202         /* should be HiGig-Lite, not Higig2 */
   5203         encap_ability |= BCM_PA_ENCAP_HIGIG2_LITE;
   5204     }
   5205 #endif
   5206 
   5207 #ifdef BCM_TRIUMPH2_SUPPORT
   5208    if (IS_HL_PORT(unit, port) && (SOC_IS_APOLLO(unit) ||
   5209                                   SOC_IS_TRIUMPH2(unit) ||
   5210                                   SOC_IS_VALKYRIE2(unit))) {
   5211        /* HiGig-Lite port */
   5212        encap_ability |= BCM_PA_ENCAP_HIGIG2_LITE;
   5213    }
   5214 #endif
   5215 
   5216     if (IS_HL_PORT(unit, port) &&
   5217          (SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit) || 
   5218           SOC_IS_KATANA2(unit) )) {
   5219         encap_ability |= BCM_PA_ENCAP_HIGIG2;
   5220         /* should be HiGig-Lite, not Higig2 */
   5221         encap_ability |= BCM_PA_ENCAP_HIGIG2_LITE;
   5222     }
   5223 
   5224 #ifdef BCM_GREYHOUND_SUPPORT
   5225     if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
   5226         SOC_IS_GREYHOUND2(unit)) {
   5227         if (IS_HL_PORT(unit, port)) {
   5228             encap_ability |= BCM_PA_ENCAP_HIGIG2;
   5229             encap_ability |= BCM_PA_ENCAP_HIGIG2_LITE;
   5230         } else if (IS_HG_PORT(unit, port)) {
   5231             encap_ability |= BCM_PA_ENCAP_HIGIG;
   5232         }
   5233     }
   5234 #endif /* BCM_GREYHOUND_SUPPORT */
   5235 
   5236 #if defined (BCM_HURRICANE_SUPPORT)
   5237     if (IS_XQ_PORT(unit, port) && SOC_IS_HURRICANEX(unit) && (CMDEV(unit).dev.rev_id == BCM56142_A0_REV_ID) ) {
   5238         ability_mask->speed_half_duplex &= ~(BCM_PORT_ABILITY_100MB);
   5239         ability_mask->speed_full_duplex &= ~(BCM_PORT_ABILITY_100MB);
   5240     }
   5241 #endif
   5242 
   5243 #if defined (BCM_TRIUMPH3_SUPPORT)
   5244    if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit) &&
   5245        (_tr3_port_config_id[unit] == 112 || _tr3_port_config_id[unit] == 12) &&
   5246        (port == 54 || port == 55)) {
   5247         if (IS_XE_PORT(unit, port)) {
   5248             BCM_IF_ERROR_RETURN(_bcm_tr3_port_lanes_get(unit, port, &lanes));
   5249             if (lanes == 1) {
   5250                 /* In one lanes mode, only support 100Mbps */
   5251                 ability_mask->speed_full_duplex =  (BCM_PORT_ABILITY_100MB);
   5252             } else if (lanes == 4) {
   5253                 /* In four lanes mode, remove the 100Mbps ability */
   5254                 ability_mask->speed_full_duplex &=  ~(BCM_PORT_ABILITY_100MB);
   5255             }
   5256         }
   5257     }
   5258 #endif
   5259 
   5260 #ifdef BCM_SABER2_SUPPORT
   5261    if (SOC_IS_SABER2(unit)) {
   5262         if (IS_XE_PORT(unit, port) && IS_MXQ_PORT(unit, port)) {
   5263                 /*  XE port, only support 10Gbps */
   5264                 ability_mask->speed_full_duplex =  (BCM_PORT_ABILITY_10GB);
   5265        }  
   5266    } 
   5267 #endif
   5268 
   5269     ability_mask->encap = encap_ability;
   5270     return BCM_E_NONE;
   5271 }
   5272 
   5273 int
   5274 bcm_esw_port_lport_prof_src_check(int unit, int port_type, int *src_tbl_is_stm)
   5275 {
   5276     int rv = BCM_E_NONE;
   5277 #if defined(CANCUN_SUPPORT)
   5278     if (soc_feature(unit, soc_feature_cancun)) {
   5279         if (src_tbl_is_stm != NULL) {
   5280             switch (port_type) {
   5281                 case _BCM_ESW_PT_COE:
   5282                 case _BCM_ESW_PT_HGPROXY:
   5283                     *src_tbl_is_stm = 1;
   5284                     break;
   5285                 default:
   5286                     *src_tbl_is_stm = 0;
   5287                     break;
   5288             }
   5289         }
   5290     }
   5291 #endif
   5292     return rv;
   5293 }
   5294 
   5295 #ifdef BCM_TRIUMPH2_SUPPORT
   5296 /*
   5297  * Function:
   5298  *      bcm_esw_port_lport_profile_recover
   5299  * Description:
   5300  *      Recovers the LPORT profile reference count in the
   5301  *      Source Trunk Map Table.
   5302  * Parameters:
   5303  *      unit        - (IN) Device number
   5304  * Return Value:
   5305  *      BCM_E_NONE
   5306  *      BCM_E_XXX
   5307  * Note:
   5308  *     - Called when LPORT profile is supported.
   5309  */
   5310 STATIC int
   5311 bcm_esw_port_lport_profile_recover(int unit)
   5312 {
   5313     int rv = BCM_E_NONE;
   5314 #ifdef BCM_TOMAHAWK3_SUPPORT
   5315     int entries_per_pipe;
   5316 #endif
   5317 #if defined(BCM_TRX_SUPPORT)
   5318     int i, m;
   5319     uint32 lport_index;
   5320     soc_mem_t src_mem[2] = {SOURCE_TRUNK_MAP_TABLEm, INVALIDm};
   5321     int entry_count;
   5322     int table_sz;
   5323     uint32 *src_table;
   5324     uint32 *src_entry;
   5325     uint32 rtag7_index;
   5326     lport_tab_entry_t lport_entry;
   5327 
   5328     /* Make sure port module is initialized. */
   5329     PORT_INIT(unit);
   5330 
   5331     if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) {
   5332         src_mem[1] = ING_DEVICE_PORTm;
   5333     }
   5334 
   5335     for (m = 0; m < 2; m++) {
   5336         if (src_mem[m] == INVALIDm) {
   5337             continue;
   5338         }
   5339 
   5340         /* Alloc DMA memory */
   5341         entry_count = soc_mem_index_count(unit, src_mem[m]);
   5342         table_sz = SOC_MEM_TABLE_BYTES(unit, src_mem[m]);
   5343         src_table = soc_cm_salloc(unit, table_sz, "LPORT index recover\n");
   5344         if (src_table == NULL) {
   5345             return BCM_E_MEMORY;
   5346         }
   5347         sal_memset(src_table, 0, table_sz);
   5348 
   5349         /* DMA Read */
   5350         rv = soc_mem_read_range(unit, src_mem[m], MEM_BLOCK_ANY,
   5351                                 soc_mem_index_min(unit, src_mem[m]),
   5352                                 soc_mem_index_max(unit, src_mem[m]),
   5353                                 src_table);
   5354         /* Recover LPORT index reference count from Source Trunk Map table */
   5355         if (BCM_SUCCESS(rv)) {
   5356             for (i = 0; i < entry_count; i++) {
   5357                 src_entry =
   5358                     soc_mem_table_idx_to_pointer(unit, src_mem[m], void *,
   5359                                                  src_table, i);
   5360                 lport_index = soc_mem_field32_get(unit, src_mem[m], src_entry,
   5361                                                   LPORT_PROFILE_IDXf);
   5362 
   5363                 if (soc_feature(unit, soc_feature_separate_ing_lport_rtag7_profile)) {
   5364                     rv = _bcm_lport_ind_profile_mem_reference(unit, lport_index, 1);
   5365                     if (BCM_FAILURE(rv)) {
   5366                         break;
   5367                     }
   5368                     rv = READ_LPORT_TABm(unit, MEM_BLOCK_ANY, lport_index, &lport_entry);
   5369                     if (BCM_FAILURE(rv)) {
   5370                         break;
   5371                     }
   5372                     rtag7_index = soc_LPORT_TABm_field32_get(
   5373                             unit, &lport_entry, RTAG7_PORT_PROFILE_INDEXf);
   5374                     rv = _bcm_rtag7_ind_profile_mem_reference(unit, rtag7_index, 1);
   5375 
   5376                 } else {
   5377 #ifdef BCM_TOMAHAWK3_SUPPORT
   5378                     if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) {
   5379                         entries_per_pipe = SOC_MEM_SIZE(unit, LPORT_TABm);
   5380                         rv = _bcm_lport_profile_mem_reference_unique(unit, lport_index,
   5381                                                                 1, i/entries_per_pipe);
   5382                     } else
   5383 #endif
   5384                     {
   5385                         rv = _bcm_lport_profile_mem_reference(unit, lport_index, 1);
   5386                     }
   5387                 }
   5388                 if (BCM_FAILURE(rv)) {
   5389                     break;
   5390                 }
   5391             }
   5392         }
   5393 
   5394         soc_cm_sfree(unit, src_table);
   5395         if (BCM_FAILURE(rv)) {
   5396             break;
   5397         }
   5398     }
   5399 
   5400 #endif /* BCM_TRX_SUPPORT */
   5401 
   5402     return rv;
   5403 }
   5404 
   5405 STATIC int
   5406 _bcm_td3_port_egr_lport_profile_recover(int unit)
   5407 {
   5408     int rv = BCM_E_NONE;
   5409     int i, m;
   5410     uint32 egr_lport_index;
   5411     soc_mem_t ep_mem[2] = {EGR_GPP_ATTRIBUTESm, INVALIDm};
   5412     int ega_num_entries;
   5413     int ega_table_size;
   5414     void *ep_tbl;
   5415     void *ep_ent;
   5416 
   5417     /* Make sure port module is initialized. */
   5418     PORT_INIT(unit);
   5419 
   5420     if (SOC_IS_TRIDENT3X(unit)) {
   5421         ep_mem[1] = EGR_PORTm;
   5422     }
   5423 
   5424     /* Alloc DMA memory */
   5425     for (m = 0; m < 2; m++) {
   5426         if (ep_mem[m] == INVALIDm) {
   5427             continue;
   5428         }
   5429         ega_num_entries = soc_mem_index_count(unit, ep_mem[m]);
   5430         ega_table_size = soc_mem_entry_words(unit, ep_mem[m]) * 4 * ega_num_entries;
   5431         ep_tbl = soc_cm_salloc(unit, ega_table_size,
   5432                                   "EGA for EGR LPORT index recover\n");
   5433         if (ep_tbl == NULL) {
   5434             return BCM_E_MEMORY;
   5435         }
   5436         sal_memset(ep_tbl, 0, ega_table_size);
   5437 
   5438         /* DMA Read */
   5439         rv = soc_mem_read_range(unit, ep_mem[m], MEM_BLOCK_ANY,
   5440                                 soc_mem_index_min(unit, ep_mem[m]),
   5441                                 soc_mem_index_max(unit, ep_mem[m]),
   5442                                 ep_tbl);
   5443         /* Recover EGR LPORT index reference count from EGR GPP Attributes table */
   5444         if (SOC_SUCCESS(rv)) {
   5445             for (i = 0; i < ega_num_entries; i++) {
   5446                 ep_ent =
   5447                     soc_mem_table_idx_to_pointer(unit, ep_mem[m],
   5448                                                  void *, ep_tbl, i);
   5449                 egr_lport_index =
   5450                     soc_mem_field32_get(unit, ep_mem[m], ep_ent, EGR_LPORT_PROFILE_IDXf);
   5451                 rv = _bcm_egr_lport_profile_mem_reference(unit, egr_lport_index, 1);
   5452                 if (BCM_FAILURE(rv)) {
   5453                     break;
   5454                 }
   5455             }
   5456         }
   5457 
   5458         soc_cm_sfree(unit, ep_tbl);
   5459 
   5460         if (BCM_FAILURE(rv)) {
   5461             break;
   5462         }
   5463     }
   5464 
   5465     return rv;
   5466 }
   5467 
   5468 /*
   5469  * Function:
   5470  *      bcm_esw_port_egr_lport_profile_recover
   5471  * Description:
   5472  *      Recovers the EGR LPORT profile reference count in the
   5473  *      EGR GPP Attributes Table.
   5474  * Parameters:
   5475  *      unit        - (IN) Device number
   5476  * Return Value:
   5477  *      BCM_E_NONE
   5478  *      BCM_E_XXX
   5479  * Note:
   5480  *     - Called when EGR LPORT profile is supported.
   5481  */
   5482 STATIC int
   5483 bcm_esw_port_egr_lport_profile_recover(int unit)
   5484 {
   5485     int rv = BCM_E_NONE;
   5486     int i;
   5487     uint32 egr_lport_index;
   5488     soc_mem_t ega_mem;
   5489     int ega_num_entries;
   5490     int ega_table_size;
   5491     egr_gpp_attributes_entry_t *ega_table;
   5492     egr_gpp_attributes_entry_t *ega_entry;
   5493 
   5494     /* Make sure port module is initialized. */
   5495     PORT_INIT(unit);
   5496 
   5497     if (SOC_IS_TRIDENT3X(unit)) {
   5498         return _bcm_td3_port_egr_lport_profile_recover(unit);
   5499     }
   5500 
   5501     /* Alloc DMA memory */
   5502     ega_mem = EGR_GPP_ATTRIBUTESm;
   5503     ega_num_entries = soc_mem_index_count(unit, ega_mem);
   5504     ega_table_size = sizeof(egr_gpp_attributes_entry_t ) * ega_num_entries;
   5505     ega_table = soc_cm_salloc(unit, ega_table_size,
   5506                               "EGA for EGR LPORT index recover\n");
   5507     if (ega_table == NULL) {
   5508         return BCM_E_MEMORY;
   5509     }
   5510     sal_memset(ega_table, 0, ega_table_size);
   5511 
   5512     /* DMA Read */
   5513     rv = soc_mem_read_range(unit, ega_mem, MEM_BLOCK_ANY,
   5514                             soc_mem_index_min(unit, ega_mem),
   5515                             soc_mem_index_max(unit, ega_mem),
   5516                             ega_table);
   5517 
   5518     /* Recover EGR LPORT index reference count from EGR GPP Attributes table */
   5519     if (SOC_SUCCESS(rv)) {
   5520         for (i = 0; i < ega_num_entries; i++) {
   5521             ega_entry =
   5522                 soc_mem_table_idx_to_pointer(unit, ega_mem,
   5523                                              egr_gpp_attributes_entry_t *,
   5524                                              ega_table, i);
   5525             egr_lport_index =
   5526                 soc_EGR_GPP_ATTRIBUTESm_field32_get(unit, ega_entry,
   5527                                                         EGR_LPORT_PROFILE_IDXf);
   5528             rv = _bcm_egr_lport_profile_mem_reference(unit, egr_lport_index, 1);
   5529             if (BCM_FAILURE(rv)) {
   5530                 break;
   5531             }
   5532         }
   5533     }
   5534 
   5535     soc_cm_sfree(unit, ega_table);
   5536 
   5537     return rv;
   5538 }
   5539 #endif /* BCM_TRIUMPH2_SUPPORT */
   5540 
   5541 int
   5542 bcm_esw_port_egr_lport_prof_src_get(int unit,
   5543     bcm_module_t modid, bcm_port_t port, int *src_tbl_is_gpp)
   5544 {
   5545     int rv = BCM_E_NONE;
   5546 
   5547 #if defined(CANCUN_SUPPORT)
   5548     bcm_gport_t gport;
   5549 
   5550     if (soc_feature(unit, soc_feature_cancun)) {
   5551         soc_mem_t pfs_mem = EGR_PKT_FLOW_SELECT_TCAMm;
   5552 
   5553         gport = _bcm_esw_port_gport_get_from_modport(unit, modid, port);
   5554         /* COE flows use the port attrs from the EGR_GPP_ATTRIBUTES
   5555            table, rest all flows use the EGR_PORT table */
   5556         if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) {
   5557             *src_tbl_is_gpp = 1;
   5558         } else if (SOC_MEM_IS_VALID(unit, pfs_mem)) {
   5559             *src_tbl_is_gpp = 0;
   5560         }
   5561     }
   5562 #endif
   5563 
   5564     return rv;
   5565 }
   5566 
   5567 #if defined(BCM_TRX_SUPPORT)
   5568 /*
   5569  * Function:
   5570  *      bcm_esw_port_separate_lport_rtag7_profile_fields_set
   5571  * Description:
   5572  *      Sets the fields in the LPORT Profile Table and updates
   5573  *      the corresponding reference index in the Source Trunk Map Table.
   5574  * Parameters:
   5575  *      unit        - (IN) Device number
   5576  *      modid       - (IN) Module number for port
   5577  *      port        - (IN) Port number (NON gport)
   5578  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   5579  *      field_count - (IN) Number of fields to modify
   5580  *      fields      - (IN) Array of fields to modify
   5581  *      values      - (IN) Array of new field values
   5582  * Return Value:
   5583  *      BCM_E_NONE
   5584  *      BCM_E_XXX
   5585  * Note:
   5586  *     - Assumes: lock,
   5587  *                valid bcm module id and port number,
   5588  *                valid table id,
   5589  *                valid HW fields.
   5590  *     - Called when LPORT profile is supported.
   5591  *     - Helper routine for bcm_esw_port_lport_fields_set();
   5592  *       callers should be calling bcm_esw_port_lport_fields_set() instead.
   5593  */
   5594 STATIC int
   5595 bcm_esw_port_separate_lport_rtag7_profile_fields_set(int unit, int port_type,
   5596                                       bcm_module_t modid, bcm_port_t port,
   5597                                       int table_id, int field_count,
   5598                                       soc_field_t *fields, uint32 *values)
   5599 {
   5600     int i, rv;
   5601     int src_index;
   5602     uint32 src_ent[SOC_MAX_MEM_FIELD_WORDS];
   5603     lport_tab_entry_t lport_entry;
   5604     rtag7_port_based_hash_entry_t  rtag7_entry;
   5605     uint32 lport_index, rtag7_index, old_lport_index, old_rtag7_index = 0;
   5606     soc_mem_t mem;
   5607     void *entries[2], *entry;
   5608 
   5609     int src_tbl_is_stm = 1;
   5610     soc_mem_t src_mem = SOURCE_TRUNK_MAP_TABLEm;
   5611 
   5612     /* Make sure port module is initialized. */
   5613     PORT_INIT(unit);
   5614 
   5615     BCM_IF_ERROR_RETURN
   5616         (bcm_esw_port_lport_prof_src_check(unit, port_type, &src_tbl_is_stm));
   5617     if (!src_tbl_is_stm) {
   5618         src_mem = ING_DEVICE_PORTm;
   5619     }
   5620 
   5621     soc_mem_lock(unit, src_mem);
   5622 
   5623     if (src_tbl_is_stm) {
   5624         rv = _bcm_esw_src_mod_port_table_index_get(unit, modid, port,
   5625                                                    &src_index);
   5626     if(BCM_FAILURE(rv)) {
   5627             soc_mem_unlock(unit, src_mem);
   5628         return rv;
   5629     }
   5630     } else {
   5631         src_index = port;
   5632     }
   5633 
   5634     rv = soc_mem_read(unit, src_mem, MEM_BLOCK_ANY, src_index, src_ent);
   5635     if(BCM_FAILURE(rv)) {
   5636         soc_mem_unlock(unit, src_mem);
   5637         return rv;
   5638     }
   5639 
   5640     old_lport_index =
   5641         soc_mem_field32_get(unit, src_mem, src_ent, LPORT_PROFILE_IDXf);
   5642 
   5643     if (table_id == LPORT_PROFILE_RTAG7_TAB) {
   5644 
   5645         /* Get the associated LPORT entry */
   5646         rv = READ_LPORT_TABm(unit, MEM_BLOCK_ANY, old_lport_index,
   5647                              &lport_entry);
   5648         if(BCM_FAILURE(rv)) {
   5649             soc_mem_unlock(unit, src_mem);
   5650             return rv;
   5651         }
   5652 
   5653         /* Get the current RTAG7 index from there */
   5654         old_rtag7_index =
   5655             soc_LPORT_TABm_field32_get(unit, &lport_entry,
   5656                                                     RTAG7_PORT_PROFILE_INDEXf);
   5657     }
   5658 
   5659     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   5660         entries[0] = &lport_entry;
   5661         rv = _bcm_lport_ind_profile_entry_get(unit, old_lport_index,
   5662                                               1, entries);
   5663     } else {
   5664         entries[0] = &rtag7_entry;
   5665         rv = _bcm_rtag7_ind_profile_entry_get(unit, old_rtag7_index,
   5666                                               1, entries);
   5667     }
   5668 
   5669     if(BCM_FAILURE(rv)) {
   5670         soc_mem_unlock(unit, src_mem);
   5671         return rv;
   5672     }
   5673 
   5674     /* Update fields */
   5675     entry = entries[0];
   5676     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   5677         mem = LPORT_TABm;
   5678     } else if (table_id == LPORT_PROFILE_RTAG7_TAB) {
   5679         mem = RTAG7_PORT_BASED_HASHm;
   5680     } else {
   5681         soc_mem_unlock(unit, src_mem);
   5682         return BCM_E_INTERNAL;
   5683     }
   5684 
   5685     for (i = 0; i < field_count; i++) {
   5686         soc_mem_field32_set(unit, mem, entry, fields[i], values[i]);
   5687     }
   5688 
   5689     /* Note that when 'soc_feature_separate_ing_lport_rtag7_profiling' is in
   5690        effect, the LPORT and RTAG7 tables are profiled separately, due to which
   5691        we will be making separate calls and not a generic single call like
   5692        earlier */
   5693     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   5694 
   5695 #ifdef BCM_MONTEREY_SUPPORT
   5696         if (SOC_IS_MONTEREY(unit)) {  
   5697             soc_mem_field32_set(unit, mem, entry, MISC_PORT_PROFILE_INDEXf, port);
   5698         }
   5699 #endif
   5700 
   5701         rv = _bcm_lport_ind_profile_entry_add(unit, entries, 1, &lport_index);
   5702 
   5703     } else {
   5704         rv = _bcm_rtag7_ind_profile_entry_add(unit, entries, 1, &rtag7_index);
   5705     }
   5706 
   5707     if(BCM_FAILURE(rv)) {
   5708         soc_mem_unlock(unit, src_mem);
   5709         return rv;
   5710     }
   5711 
   5712     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   5713         /* Update Source Table LPORT profile index  */
   5714         soc_mem_field32_set(unit, src_mem, src_ent, LPORT_PROFILE_IDXf,
   5715                                                 lport_index);
   5716         rv = soc_mem_write(unit, src_mem, MEM_BLOCK_ALL, src_index, src_ent);
   5717     } else {
   5718         /* Write to the LPORT table here */
   5719         soc_LPORT_TABm_field32_set(unit, &lport_entry, RTAG7_PORT_PROFILE_INDEXf,
   5720                                                 rtag7_index);
   5721         if (SOC_IS_TRIDENT3X(unit)) {
   5722             entries[0] = &lport_entry;
   5723             rv = _bcm_lport_ind_profile_entry_add(unit, entries, 1, &lport_index);
   5724 
   5725             if(BCM_FAILURE(rv)) {
   5726                soc_mem_unlock(unit, src_mem);
   5727                return rv;
   5728             }
   5729             /* Update Source Table LPORT profile index  */
   5730             soc_mem_field32_set(unit, src_mem, src_ent, LPORT_PROFILE_IDXf,
   5731                                                           lport_index);
   5732             rv = soc_mem_write(unit, src_mem, MEM_BLOCK_ALL,
   5733                                src_index, src_ent);
   5734         } else {
   5735         rv = WRITE_LPORT_TABm(unit, MEM_BLOCK_ANY, old_lport_index, &lport_entry);
   5736     }
   5737     }
   5738 
   5739     soc_mem_unlock(unit, src_mem);
   5740     if(BCM_FAILURE(rv)) {
   5741         return rv;
   5742     }
   5743 
   5744     /*
   5745      * Entry must be 'deleted' because the mem profile 'add' routine
   5746      * always increments count even though the same entry is used.
   5747      */
   5748     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   5749         BCM_IF_ERROR_RETURN
   5750             (_bcm_lport_ind_profile_entry_delete(unit, old_lport_index));
   5751 
   5752     } else {
   5753         if (SOC_IS_TRIDENT3X(unit)) {
   5754             BCM_IF_ERROR_RETURN
   5755                   (_bcm_lport_ind_profile_entry_delete(unit, old_lport_index));
   5756         }
   5757         BCM_IF_ERROR_RETURN
   5758             (_bcm_rtag7_ind_profile_entry_delete(unit, old_rtag7_index));
   5759     }
   5760 
   5761     return BCM_E_NONE;
   5762 }
   5763 #endif /* BCM_TRX_SUPPORT */
   5764 
   5765 /*
   5766  * Function:
   5767  *      bcm_esw_port_lport_profile_fields_set
   5768  * Description:
   5769  *      Sets the fields in the LPORT Profile Table and updates
   5770  *      the corresponding reference index in the Source Trunk Map Table.
   5771  * Parameters:
   5772  *      unit        - (IN) Device number
   5773  *      modid       - (IN) Module number for port
   5774  *      port        - (IN) Port number (NON gport)
   5775  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   5776  *      field_count - (IN) Number of fields to modify
   5777  *      fields      - (IN) Array of fields to modify
   5778  *      values      - (IN) Array of new field values
   5779  * Return Value:
   5780  *      BCM_E_NONE
   5781  *      BCM_E_XXX
   5782  * Note:
   5783  *     - Assumes: lock,
   5784  *                valid bcm module id and port number,
   5785  *                valid table id,
   5786  *                valid HW fields.
   5787  *     - Called when LPORT profile is supported.
   5788  *     - Helper routine for bcm_esw_port_lport_fields_set();
   5789  *       callers should be calling bcm_esw_port_lport_fields_set() instead.
   5790  */
   5791 STATIC int
   5792 bcm_esw_port_lport_profile_fields_set(int unit, int port_type,
   5793                                       bcm_module_t modid, bcm_port_t port,
   5794                                       int table_id, int field_count,
   5795                                       soc_field_t *fields, uint32 *values)
   5796 {
   5797 #if defined(BCM_TRX_SUPPORT)
   5798     int i;
   5799     int src_index;
   5800     uint32 src_ent[SOC_MAX_MEM_FIELD_WORDS];
   5801     int src_tbl_is_stm = 1;
   5802     soc_mem_t src_mem = SOURCE_TRUNK_MAP_TABLEm;
   5803     lport_tab_entry_t lport_entry;
   5804     rtag7_port_based_hash_entry_t  rtag7_entry;
   5805     uint32 lport_index, old_lport_index;
   5806     void *entries[2];
   5807     soc_mem_t mem;
   5808     void *entry;
   5809     int rv;
   5810     int pipe = 0;
   5811     int num_entries_per_pipe = 0;
   5812 
   5813     if (soc_feature(unit, soc_feature_separate_ing_lport_rtag7_profile)) {
   5814         return bcm_esw_port_separate_lport_rtag7_profile_fields_set(unit,
   5815                     port_type, modid, port, table_id, field_count,
   5816                     fields, values);
   5817     }
   5818 
   5819     /* Make sure port module is initialized. */
   5820     PORT_INIT(unit);
   5821 
   5822     BCM_IF_ERROR_RETURN
   5823         (bcm_esw_port_lport_prof_src_check(unit, port_type, &src_tbl_is_stm));
   5824 #if defined(CANCUN_SUPPORT)
   5825     if (soc_feature(unit, soc_feature_cancun) && src_tbl_is_stm == 0) {
   5826         src_mem = ING_DEVICE_PORTm;
   5827     }
   5828 #endif
   5829 
   5830     soc_mem_lock(unit, src_mem);
   5831 
   5832     /* Get LPORT profile index Source table */
   5833     if (src_tbl_is_stm) {
   5834         rv = _bcm_esw_src_mod_port_table_index_get(unit, modid, port, &src_index);
   5835     if(BCM_FAILURE(rv)) {
   5836             soc_mem_unlock(unit, src_mem);
   5837         return rv;
   5838     }
   5839     } else {
   5840         src_index = port;
   5841     }
   5842 
   5843     rv = soc_mem_read(unit, src_mem, MEM_BLOCK_ANY, src_index, src_ent);
   5844     if(BCM_FAILURE(rv)) {
   5845         soc_mem_unlock(unit, src_mem);
   5846         return rv;
   5847     }
   5848 
   5849     old_lport_index =
   5850         soc_mem_field32_get(unit, src_mem, src_ent, LPORT_PROFILE_IDXf);
   5851 
   5852     /* Get LPORT profile entry */
   5853     entries[0] = &lport_entry;
   5854     entries[1] = &rtag7_entry;
   5855 
   5856     /* Tomahawk 3 split this memory into a per pipe unique access,
   5857      * so it is indexed in SOURCE_TRUNK_MAP on a per pipe basis */
   5858     if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) {
   5859         pipe = SOC_INFO(unit).port_pipe[src_index];
   5860         mem = SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)[pipe];
   5861         num_entries_per_pipe = SOC_MEM_SIZE(unit, mem);
   5862 
   5863         /* the profile cache is stored in one large logical table (all the pipes
   5864          * put together), so we need to index into the pipe being used so that
   5865          * we can access the index of that one big logical table */
   5866         old_lport_index += pipe*num_entries_per_pipe;
   5867     }
   5868 
   5869     rv = _bcm_lport_profile_entry_get(unit, old_lport_index, 1, entries);
   5870     if(BCM_FAILURE(rv)) {
   5871         soc_mem_unlock(unit, src_mem);
   5872         return rv;
   5873     }
   5874 
   5875     /* Update fields */
   5876     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   5877         mem = LPORT_TABm;
   5878         entry = entries[0];
   5879     } else if (table_id == LPORT_PROFILE_RTAG7_TAB) {
   5880         mem = RTAG7_PORT_BASED_HASHm;
   5881         entry = entries[1];
   5882     } else {
   5883         soc_mem_unlock(unit, src_mem);
   5884         return BCM_E_INTERNAL;
   5885     }
   5886 
   5887     for (i = 0; i < field_count; i++) {
   5888         soc_mem_field32_set(unit, mem, entry, fields[i], values[i]);
   5889     }
   5890 
   5891     /* Tomahawk 3 split this memory into a per pipe unique access,
   5892      * so it must be handled differently */
   5893     if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) {
   5894         /* Restore the old_lport_index to its per pipe index because the call
   5895          * below to entry_add_unique will get its lport_index based on a per
   5896          * pipe index and they will be compared. */
   5897         old_lport_index -= pipe*num_entries_per_pipe;
   5898 
   5899         rv = _bcm_lport_profile_entry_add_unique(unit, entries, 1, pipe, &lport_index);
   5900     } else {
   5901         rv = _bcm_lport_profile_entry_add(unit, entries, 1, &lport_index);
   5902     }
   5903     if(BCM_FAILURE(rv)) {
   5904         soc_mem_unlock(unit, src_mem);
   5905         return rv;
   5906     }
   5907 
   5908     /* Update STM LPORT profile index  */
   5909     if (old_lport_index != lport_index) {
   5910         soc_mem_field32_set(unit, src_mem, src_ent,
   5911                             LPORT_PROFILE_IDXf, lport_index);
   5912         rv = soc_mem_write(unit, src_mem, MEM_BLOCK_ALL,
   5913                            src_index, src_ent);
   5914     }
   5915 
   5916     soc_mem_unlock(unit, src_mem);
   5917     if(BCM_FAILURE(rv)) {
   5918         return rv;
   5919     }
   5920 
   5921     /*
   5922      * Entry must be 'deleted' because the mem profile 'add' routine
   5923      * always increments count even though the same entry is used.
   5924      */
   5925     if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) {
   5926         BCM_IF_ERROR_RETURN
   5927             (_bcm_lport_profile_entry_delete_unique(unit, old_lport_index, pipe));
   5928     } else {
   5929         BCM_IF_ERROR_RETURN
   5930             (_bcm_lport_profile_entry_delete(unit, old_lport_index));
   5931     }
   5932 
   5933     return BCM_E_NONE;
   5934 #else
   5935     return BCM_E_UNAVAIL;
   5936 #endif /* BCM_TRX_SUPPORT */
   5937 }
   5938 
   5939 /*
   5940  * Function:
   5941  *      bcm_esw_port_egr_lport_profile_fields_set
   5942  * Description:
   5943  *      Sets the fields in the EGR_LPORT Profile Table and updates
   5944  *      the corresponding reference index in the Source Trunk Map Table.
   5945  * Parameters:
   5946  *      unit        - (IN) Device number
   5947  *      modid       - (IN) Module number for port
   5948  *      port        - (IN) Port number (NON gport)
   5949  *      mem         - (IN) Table to modify
   5950  *      field_count - (IN) Number of fields to modify
   5951  *      fields      - (IN) Array of fields to modify
   5952  *      values      - (IN) Array of new field values
   5953  * Return Value:
   5954  *      BCM_E_NONE
   5955  *      BCM_E_XXX
   5956  * Note:
   5957  *     - Assumes: lock,
   5958  *                valid bcm module id and port number,
   5959  *                valid table id,
   5960  *                valid HW fields.
   5961  *     - Called when EGR_LPORT profile is supported.
   5962  *     - Helper routine for bcm_esw_port_egr_lport_fields_set();
   5963  *       callers should be calling bcm_esw_port_egr_lport_fields_set() instead.
   5964  */
   5965 STATIC int
   5966 bcm_esw_port_egr_lport_profile_fields_set(int unit,
   5967                                       bcm_module_t modid, bcm_port_t port,
   5968                                       soc_mem_t mem, int field_count,
   5969                                       soc_field_t *fields, uint32 *values)
   5970 {
   5971 #if defined(BCM_TRX_SUPPORT)
   5972     int i, index;
   5973     int egr_gpp_index = 0;
   5974     egr_gpp_attributes_entry_t egr_gpp_entry;
   5975     egr_lport_profile_entry_t egr_lport_entry;
   5976     egr_vlan_control_1_entry_t egr_vlan_control_1;
   5977     egr_vlan_control_2_entry_t egr_vlan_control_2;
   5978     egr_vlan_control_3_entry_t egr_vlan_control_3;
   5979     egr_ipmc_cfg2_entry_t egr_ipmc_cfg2;
   5980     egr_mtu_entry_t egr_mtu;
   5981     egr_port_1_entry_t egr_port_1;
   5982     egr_counter_control_entry_t egr_counter_control;
   5983     egr_shaping_control_entry_t egr_shaping_control;
   5984     egr_port_entry_t egr_port;
   5985     uint32 egr_lport_index, old_egr_lport_index;
   5986     void *entries[_BCM_EGR_LPROF_MEM_COUNT];
   5987     void *entry;
   5988     int use_gpp_index = 1;
   5989 
   5990     /* Make sure port module is initialized. */
   5991     PORT_INIT(unit);
   5992 
   5993     if (mem == EGR_GPP_ATTRIBUTESm) {
   5994         BCM_IF_ERROR_RETURN
   5995             (_bcm_esw_src_mod_port_table_index_get(unit, modid, port,
   5996                                                    &egr_gpp_index));
   5997         BCM_IF_ERROR_RETURN
   5998             (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY,
   5999                                       egr_gpp_index, &egr_gpp_entry));
   6000         for (i = 0; i < field_count; i++) {
   6001             soc_mem_field32_set(unit, EGR_GPP_ATTRIBUTESm,
   6002                                 &egr_gpp_entry, fields[i], values[i]);
   6003         }
   6004         BCM_IF_ERROR_RETURN
   6005             (WRITE_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ALL,
   6006                                        egr_gpp_index, &egr_gpp_entry));
   6007 
   6008         return BCM_E_NONE;
   6009     }
   6010 
   6011     BCM_IF_ERROR_RETURN(
   6012         bcm_esw_port_egr_lport_prof_src_get(unit, modid, port, &use_gpp_index));
   6013 
   6014     if (use_gpp_index) {
   6015     /* Get LPORT profile index Source Trunk Map table */
   6016     BCM_IF_ERROR_RETURN
   6017             (_bcm_esw_src_mod_port_table_index_get(unit, modid, port,
   6018                                                    &egr_gpp_index));
   6019     BCM_IF_ERROR_RETURN
   6020         (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY,
   6021                                       egr_gpp_index, &egr_gpp_entry));
   6022     old_egr_lport_index =
   6023         soc_EGR_GPP_ATTRIBUTESm_field32_get(unit, &egr_gpp_entry,
   6024                                                 EGR_LPORT_PROFILE_IDXf);
   6025     } else {
   6026         BCM_IF_ERROR_RETURN
   6027             (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, &egr_port));
   6028         old_egr_lport_index =
   6029             soc_mem_field32_get(unit, EGR_PORTm, &egr_port,
   6030                                 EGR_LPORT_PROFILE_IDXf);
   6031     }
   6032 
   6033     /* Get LPORT profile entry */
   6034     index = 0;
   6035     if (SOC_MEM_IS_VALID(unit, EGR_LPORT_PROFILEm)) {
   6036         entries[index++] = &egr_lport_entry;
   6037     }
   6038     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_1m)) {
   6039         entries[index++] = &egr_vlan_control_1;
   6040     }
   6041     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_2m)) {
   6042         entries[index++] = &egr_vlan_control_2;
   6043     }
   6044     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_3m)) {
   6045         entries[index++] = &egr_vlan_control_3;
   6046     }
   6047     if (SOC_MEM_IS_VALID(unit, EGR_IPMC_CFG2m)) {
   6048         entries[index++] = &egr_ipmc_cfg2;
   6049     }
   6050     if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) {
   6051         entries[index++] = &egr_mtu;
   6052     }
   6053     if (SOC_MEM_IS_VALID(unit, EGR_PORT_1m)) {
   6054         entries[index++] = &egr_port_1;
   6055     }
   6056     if (soc_feature(unit, soc_feature_egr_all_profile) == 0) {
   6057         if (SOC_MEM_IS_VALID(unit, EGR_COUNTER_CONTROLm)) {
   6058             entries[index++] = &egr_counter_control;
   6059         }
   6060         if (SOC_MEM_IS_VALID(unit, EGR_SHAPING_CONTROLm)) {
   6061             entries[index++] = &egr_shaping_control;
   6062         }
   6063     }
   6064 
   6065     BCM_IF_ERROR_RETURN
   6066         (_bcm_egr_lport_profile_entry_get(unit, old_egr_lport_index, 1, entries));
   6067 
   6068     BCM_IF_ERROR_RETURN
   6069         (_bcm_egr_lport_profile_mem_index_get(unit, mem, &index));
   6070     entry = entries[index];
   6071     /* Update fields */
   6072     for (i = 0; i < field_count; i++) {
   6073         soc_mem_field32_set(unit, mem, entry, fields[i], values[i]);
   6074     }
   6075 
   6076     BCM_IF_ERROR_RETURN
   6077         (_bcm_egr_lport_profile_entry_add(unit, entries, 1, &egr_lport_index));
   6078 
   6079     /* Update STM LPORT profile index  */
   6080     if (use_gpp_index) {
   6081     soc_EGR_GPP_ATTRIBUTESm_field32_set(unit, &egr_gpp_entry,
   6082                                             EGR_LPORT_PROFILE_IDXf,
   6083                                             egr_lport_index);
   6084     BCM_IF_ERROR_RETURN
   6085         (WRITE_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY,
   6086                                        egr_gpp_index, &egr_gpp_entry));
   6087     } else {
   6088         soc_mem_field32_set(unit, EGR_PORTm, &egr_port,
   6089                             EGR_LPORT_PROFILE_IDXf, egr_lport_index);
   6090         BCM_IF_ERROR_RETURN
   6091             (WRITE_EGR_PORTm(unit, MEM_BLOCK_ALL, port, &egr_port));
   6092     }
   6093     /*
   6094      * Entry must be 'deleted' because the mem profile 'add' routine
   6095      * always increments count even though the same entry is used.
   6096      */
   6097     if(old_egr_lport_index != 0) {
   6098         BCM_IF_ERROR_RETURN
   6099             (_bcm_egr_lport_profile_entry_delete(unit, old_egr_lport_index));
   6100     }
   6101 
   6102     return BCM_E_NONE;
   6103 #else
   6104     return BCM_E_UNAVAIL;
   6105 #endif /* BCM_TRX_SUPPORT */
   6106 }
   6107 
   6108 /*
   6109  * Function:
   6110  *      bcm_esw_port_egr_lport_profile_clear
   6111  * Description:
   6112  *      Similar function as bcm_esw_port_egr_lport_profile_fields_set,
   6113  *      for clear purpose only.
   6114  */
   6115 STATIC int
   6116 bcm_esw_port_egr_lport_profile_clear(int unit,
   6117                                      bcm_module_t modid, bcm_port_t port,
   6118                                      soc_mem_t mem)
   6119 {
   6120 #if defined(BCM_TRX_SUPPORT)
   6121     int index;
   6122     int egr_gpp_index = 0;
   6123     egr_gpp_attributes_entry_t egr_gpp_entry;
   6124     egr_lport_profile_entry_t egr_lport_entry;
   6125     egr_vlan_control_1_entry_t egr_vlan_control_1;
   6126     egr_vlan_control_2_entry_t egr_vlan_control_2;
   6127     egr_vlan_control_3_entry_t egr_vlan_control_3;
   6128     egr_ipmc_cfg2_entry_t egr_ipmc_cfg2;
   6129     egr_mtu_entry_t egr_mtu;
   6130     egr_port_1_entry_t egr_port_1;
   6131     egr_counter_control_entry_t egr_counter_control;
   6132     egr_shaping_control_entry_t egr_shaping_control;
   6133     egr_port_entry_t egr_port;
   6134     uint32 egr_lport_index, old_egr_lport_index;
   6135     void *entries[_BCM_EGR_LPROF_MEM_COUNT];
   6136     void *entry;
   6137     int ent_size[_BCM_EGR_LPROF_MEM_COUNT] = {0};
   6138     int use_gpp_index = 1;
   6139 
   6140     /* Make sure port module is initialized. */
   6141     PORT_INIT(unit);
   6142 
   6143     if (mem == EGR_GPP_ATTRIBUTESm) {
   6144         BCM_IF_ERROR_RETURN
   6145             (_bcm_esw_src_mod_port_table_index_get(unit, modid, port,
   6146                                                    &egr_gpp_index));
   6147         BCM_IF_ERROR_RETURN
   6148             (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY,
   6149                                       egr_gpp_index, &egr_gpp_entry));
   6150         sal_memset(&egr_gpp_entry, 0, sizeof(egr_gpp_entry));
   6151         BCM_IF_ERROR_RETURN
   6152             (WRITE_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ALL,
   6153                                        egr_gpp_index, &egr_gpp_entry));
   6154 
   6155         return BCM_E_NONE;
   6156     }
   6157 
   6158     BCM_IF_ERROR_RETURN(
   6159         bcm_esw_port_egr_lport_prof_src_get(unit, modid, port, &use_gpp_index));
   6160 
   6161     if (use_gpp_index) {
   6162         /* Get LPORT profile index Source Trunk Map table */
   6163         BCM_IF_ERROR_RETURN
   6164             (_bcm_esw_src_mod_port_table_index_get(unit, modid, port,
   6165                                                    &egr_gpp_index));
   6166         BCM_IF_ERROR_RETURN
   6167             (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY,
   6168                                       egr_gpp_index, &egr_gpp_entry));
   6169         old_egr_lport_index =
   6170             soc_EGR_GPP_ATTRIBUTESm_field32_get(unit, &egr_gpp_entry,
   6171                                                 EGR_LPORT_PROFILE_IDXf);
   6172     } else {
   6173         BCM_IF_ERROR_RETURN
   6174             (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, &egr_port));
   6175         old_egr_lport_index =
   6176             soc_mem_field32_get(unit, EGR_PORTm, &egr_port,
   6177                                 EGR_LPORT_PROFILE_IDXf);
   6178     }
   6179 
   6180     /* Get LPORT profile entry */
   6181     index = 0;
   6182     if (SOC_MEM_IS_VALID(unit, EGR_LPORT_PROFILEm)) {
   6183         ent_size[index] = sizeof(egr_lport_entry);
   6184         entries[index++] = &egr_lport_entry;
   6185     }
   6186     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_1m)) {
   6187         ent_size[index] = sizeof(egr_vlan_control_1);
   6188         entries[index++] = &egr_vlan_control_1;
   6189     }
   6190     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_2m)) {
   6191         ent_size[index] = sizeof(egr_vlan_control_2);
   6192         entries[index++] = &egr_vlan_control_2;
   6193     }
   6194     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_3m)) {
   6195         ent_size[index] = sizeof(egr_vlan_control_3);
   6196         entries[index++] = &egr_vlan_control_3;
   6197     }
   6198     if (SOC_MEM_IS_VALID(unit, EGR_IPMC_CFG2m)) {
   6199         ent_size[index] = sizeof(egr_ipmc_cfg2);
   6200         entries[index++] = &egr_ipmc_cfg2;
   6201     }
   6202     if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) {
   6203         ent_size[index] = sizeof(egr_mtu);
   6204         entries[index++] = &egr_mtu;
   6205     }
   6206     if (SOC_MEM_IS_VALID(unit, EGR_PORT_1m)) {
   6207         ent_size[index] = sizeof(egr_port_1);
   6208         entries[index++] = &egr_port_1;
   6209     }
   6210     if (soc_feature(unit, soc_feature_egr_all_profile) == 0) {
   6211         if (SOC_MEM_IS_VALID(unit, EGR_COUNTER_CONTROLm)) {
   6212             ent_size[index] = sizeof(egr_counter_control);
   6213             entries[index++] = &egr_counter_control;
   6214         }
   6215         if (SOC_MEM_IS_VALID(unit, EGR_SHAPING_CONTROLm)) {
   6216             ent_size[index] = sizeof(egr_shaping_control);
   6217             entries[index++] = &egr_shaping_control;
   6218         }
   6219     }
   6220 
   6221     BCM_IF_ERROR_RETURN
   6222         (_bcm_egr_lport_profile_entry_get(unit, old_egr_lport_index, 1, entries));
   6223 
   6224     BCM_IF_ERROR_RETURN
   6225         (_bcm_egr_lport_profile_mem_index_get(unit, mem, &index));
   6226     entry = entries[index];
   6227     /* Clear fields */
   6228     sal_memset(entry, 0, ent_size[index]);
   6229 
   6230     BCM_IF_ERROR_RETURN
   6231         (_bcm_egr_lport_profile_entry_add(unit, entries, 1, &egr_lport_index));
   6232 
   6233     /* Update STM LPORT profile index  */
   6234     if (use_gpp_index) {
   6235         soc_EGR_GPP_ATTRIBUTESm_field32_set(unit, &egr_gpp_entry,
   6236                                             EGR_LPORT_PROFILE_IDXf,
   6237                                             egr_lport_index);
   6238         BCM_IF_ERROR_RETURN
   6239             (WRITE_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY,
   6240                                        egr_gpp_index, &egr_gpp_entry));
   6241     } else {
   6242         soc_mem_field32_set(unit, EGR_PORTm, &egr_port,
   6243                             EGR_LPORT_PROFILE_IDXf, egr_lport_index);
   6244         BCM_IF_ERROR_RETURN
   6245             (WRITE_EGR_PORTm(unit, MEM_BLOCK_ALL, port, &egr_port));
   6246     }
   6247     /*
   6248      * Entry must be 'deleted' because the mem profile 'add' routine
   6249      * always increments count even though the same entry is used.
   6250      */
   6251     if (old_egr_lport_index != 0) {
   6252         BCM_IF_ERROR_RETURN
   6253             (_bcm_egr_lport_profile_entry_delete(unit, old_egr_lport_index));
   6254     }
   6255 
   6256     return BCM_E_NONE;
   6257 #else
   6258     return BCM_E_UNAVAIL;
   6259 #endif /* BCM_TRX_SUPPORT */
   6260 }
   6261 
   6262 /*
   6263  * Function:
   6264  *      _bcm_esw_egr_port_tab_multi_set
   6265  * Description:
   6266  *      Function to set multiple fields in EGR port tables
   6267  * Parameters:
   6268  *      unit        - Device number
   6269  *      port        - Port number
   6270  *      field_count - Number of fields to modify
   6271  *      fields      - Array of fields to modify
   6272  *      values      - Array of new field values
   6273  * Return Value:
   6274  *      BCM_E_NONE
   6275  *      BCM_E_XXX - an error occurred accessing EGR_PORT table.
   6276  */
   6277 int
   6278 _bcm_esw_egr_port_tab_multi_set(int unit, bcm_port_t port, int field_count,
   6279         soc_field_t *fields, uint32 *values)
   6280 
   6281 {
   6282     soc_mem_t mem = EGR_PORTm;
   6283     int rv = BCM_E_NONE, i, index;
   6284 
   6285     soc_field_t egr_port_tab_fields[SOC_MAX_MEM_FIELD_NUM];
   6286     uint32 egr_port_tab_values[SOC_MAX_MEM_FIELD_NUM];
   6287     int egr_port_tab_field_count = 0;
   6288     soc_field_t egr_lport_tab_fields[SOC_MAX_MEM_FIELD_NUM];
   6289     uint32 egr_lport_tab_values[SOC_MAX_MEM_FIELD_NUM];
   6290     int egr_lport_tab_field_count = 0;
   6291     soc_field_t egr_gpp_fields[SOC_MAX_MEM_FIELD_NUM];
   6292     uint32 egr_gpp_values[SOC_MAX_MEM_FIELD_NUM];
   6293     int egr_gpp_field_count = 0;
   6294 #if defined BCM_HGPROXY_COE_SUPPORT
   6295     int is_lport_cfg = 0;
   6296 #endif
   6297 
   6298 
   6299     if ((fields == NULL) || (values == NULL) ) {
   6300         return BCM_E_PARAM;
   6301     }
   6302     if (field_count <= 0) {
   6303         return BCM_E_NONE;
   6304     }
   6305 
   6306 #if defined BCM_HGPROXY_COE_SUPPORT
   6307     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   6308         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   6309         is_lport_cfg = 1;
   6310     }
   6311 
   6312     if (is_lport_cfg == 1) {
   6313         mem = EGR_LPORT_PROFILEm;
   6314     } else
   6315 #endif
   6316     if (BCM_GPORT_IS_SET(port)) {
   6317         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
   6318     }
   6319 
   6320     for(i = 0; i < field_count; i++) {
   6321 #if defined(CANCUN_SUPPORT)
   6322         if (SOC_IS_TRIDENT3X(unit)) {
   6323             if (soc_cancun_cmh_check(unit, mem, fields[i]) == SOC_E_NONE) {
   6324                 rv = soc_cancun_cmh_mem_set(unit, mem, port, fields[i],
   6325                                             values[i]);
   6326             }
   6327             _bcm_td3_egr_port_tab_conv(unit, &fields[i], &mem);
   6328         }
   6329 #endif
   6330         if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) {
   6331             return (SOC_E_UNAVAIL);
   6332         }
   6333 
   6334         switch (mem) {
   6335             case EGR_GPP_ATTRIBUTESm:
   6336                 soc_mem_set_field_value_array(egr_gpp_fields, fields[i],
   6337                                               egr_gpp_values, values[i],
   6338                                               egr_gpp_field_count);
   6339                 break;
   6340             case EGR_PORTm:
   6341                 soc_mem_set_field_value_array(egr_port_tab_fields, fields[i],
   6342                                               egr_port_tab_values, values[i],
   6343                                               egr_port_tab_field_count);
   6344                 break;
   6345             case EGR_LPORT_PROFILEm:
   6346                 soc_mem_set_field_value_array(egr_lport_tab_fields, fields[i],
   6347                                               egr_lport_tab_values, values[i],
   6348                                               egr_lport_tab_field_count);
   6349                 break;
   6350             default:
   6351                 BCM_IF_ERROR_RETURN
   6352                     (soc_mem_field32_modify(unit, mem, port, fields[i],
   6353                                             values[i]));
   6354                 break;
   6355         }
   6356     }
   6357 
   6358 #if defined BCM_HGPROXY_COE_SUPPORT
   6359     if (is_lport_cfg == 1) { /* remote port */
   6360         return bcm_esw_port_egr_lport_fields_set(unit, port,
   6361                                                  EGR_LPORT_PROFILEm,
   6362                                                  egr_lport_tab_field_count,
   6363                                                  egr_lport_tab_fields,
   6364                                                  egr_lport_tab_values);
   6365     }
   6366 #endif
   6367 
   6368     index = SOC_PORT_MOD_OFFSET(unit, port);
   6369 
   6370     if (egr_port_tab_field_count) {
   6371         rv = soc_mem_fields32_modify(unit, EGR_PORTm, index,
   6372                                      egr_port_tab_field_count,
   6373                                      egr_port_tab_fields, egr_port_tab_values);
   6374     }
   6375 
   6376     if (egr_lport_tab_field_count && BCM_SUCCESS(rv)) {
   6377         rv = bcm_esw_port_egr_lport_fields_set(unit, index,
   6378                 EGR_LPORT_PROFILEm, egr_lport_tab_field_count,
   6379                 egr_lport_tab_fields, egr_lport_tab_values);
   6380     }
   6381 
   6382     if (egr_gpp_field_count && BCM_SUCCESS(rv)) {
   6383         rv = bcm_esw_port_egr_lport_fields_set(unit, index,
   6384                 EGR_GPP_ATTRIBUTESm, egr_gpp_field_count,
   6385                 egr_gpp_fields, egr_gpp_values);
   6386     }
   6387 
   6388     return rv;
   6389 }
   6390 
   6391 /*
   6392  * Function:
   6393  *      _bcm_esw_egr_port_tab_set
   6394  * Description:
   6395  *      Helper funtion for bcm_esw_port_control_set.
   6396  * Parameters:
   6397  *      unit  - Device number
   6398  *      port  - Port number
   6399  *      field - Field name within EGR_PORT table entry
   6400  *      value - new field value
   6401  * Return Value:
   6402  *      BCM_E_NONE
   6403  *      BCM_E_XXX - an error occurred accessing EGR_PORT table.
   6404  */
   6405 int
   6406 _bcm_esw_egr_port_tab_set(int unit, bcm_port_t port,
   6407         soc_field_t field, uint32 value)
   6408 
   6409 {
   6410     return (_bcm_esw_egr_port_tab_multi_set(unit, port, 1, &field, &value));
   6411 }
   6412 
   6413 /*
   6414  * Function:
   6415  *      _bcm_esw_egr_port_tab_get
   6416  * Description:
   6417  *      Helper funtion for bcm_esw_port_control_get.
   6418  * Parameters:
   6419  *      unit  - Device number
   6420  *      port  - Port number
   6421  *      field - Field name within PORT_TAB table entry
   6422  *      value - (OUT) field value
   6423  * Return Value:
   6424  *      BCM_E_NONE
   6425  *      BCM_E_XXX - an error occurred accessing PORT_TAB table.
   6426  * Notes:
   6427  *      Due to the large number of callers for this routine,
   6428  *      function is expanded to take a GPORT PROXY, which
   6429  *      get the property from the LPORT profile table.
   6430  *
   6431  *      Current valid port types are:
   6432  *          GPORT SUBPORT
   6433  *          BCM port (non-gport), assumes a valid local physical port
   6434  */
   6435 
   6436 int
   6437 _bcm_esw_egr_port_tab_get(int unit, bcm_port_t port,
   6438                           soc_field_t field, int *value)
   6439 {
   6440     int rv = BCM_E_UNAVAIL;
   6441     egr_port_entry_t pent;
   6442     soc_mem_t mem;
   6443     int index, is_lport_cfg = 0, is_gpp_attr = 0;
   6444     uint32 value32;
   6445 
   6446     mem = EGR_PORTm;
   6447 #if defined(BCM_TRIDENT3_SUPPORT)
   6448     if (SOC_IS_TRIDENT3X(unit)) {
   6449         BCM_IF_ERROR_RETURN(_bcm_td3_egr_port_tab_conv(unit, &field, &mem));
   6450         if (mem == EGR_GPP_ATTRIBUTESm) {
   6451             is_gpp_attr = 1;
   6452         } else if (mem != EGR_PORTm) {
   6453             is_lport_cfg = 1;
   6454         }
   6455     }
   6456 #endif
   6457 
   6458     if (!SOC_MEM_FIELD_VALID(unit, mem, field)) {
   6459         return (BCM_E_UNAVAIL);
   6460     }
   6461 
   6462 #if defined BCM_HGPROXY_COE_SUPPORT
   6463     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   6464         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   6465         is_lport_cfg = 1;
   6466     } else
   6467 #endif
   6468     if (BCM_GPORT_IS_PROXY(port)) {
   6469         is_lport_cfg = 1;
   6470     }
   6471 
   6472     /* If LPORT, then get property from LPORT table */
   6473     if (is_lport_cfg) {
   6474         rv = bcm_esw_port_egr_lport_field_get(unit, port,
   6475                                               EGR_LPORT_PROFILEm,
   6476                                               field, &value32);
   6477         *value = value32;
   6478         return rv;
   6479     } else if (is_gpp_attr) {
   6480         rv = bcm_esw_port_egr_lport_field_get(unit, port,
   6481                                               EGR_GPP_ATTRIBUTESm,
   6482                                               field, &value32);
   6483         *value = value32;
   6484         return rv;
   6485     }
   6486 
   6487     /* At this point, 'port' needs to be a BCM port (non-gport) */
   6488     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
   6489 
   6490     index = SOC_PORT_MOD_OFFSET(unit, port);
   6491     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, &pent);
   6492 
   6493     if (BCM_SUCCESS(rv)) {
   6494         *value = soc_mem_field32_get(unit, mem, &pent, field);
   6495     }
   6496 
   6497     return rv;
   6498 }
   6499 
   6500 
   6501 #if defined(BCM_TRX_SUPPORT)
   6502 /*
   6503  * Function:
   6504  *      bcm_esw_port_separate_lport_rtag7_profile_fields_get
   6505  * Description:
   6506  *      Gets the fields from the LPORT Profile Table.
   6507  * Parameters:
   6508  *      unit        - (IN) Device number
   6509  *      modid       - (IN) Module number for port
   6510  *      port        - (IN) Port number (NON gport)
   6511  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   6512  *      field_count - (IN) Number of fields to read
   6513  *      fields      - (IN) Array of fields to return
   6514  *      values      - (OUT) Array of return values
   6515  * Return Value:
   6516  *      BCM_E_NONE
   6517  *      BCM_E_XXX
   6518  * Note:
   6519  *     - Assumes: lock,
   6520  *                valid bcm module id and port number,
   6521  *                valid table id,
   6522  *                valid HW fields.
   6523  *     - Called when LPORT profile is supported.
   6524  *     - Helper routine for bcm_esw_port_lport_fields_get();
   6525  *       callers should be calling bcm_esw_port_lport_fields_get() instead.
   6526  */
   6527 STATIC int
   6528 bcm_esw_port_separate_lport_rtag7_profile_fields_get(int unit, int port_type,
   6529                                       bcm_module_t modid, bcm_port_t port,
   6530                                       int table_id, int field_count,
   6531                                       soc_field_t *fields, uint32 *values)
   6532 {
   6533     int i;
   6534     int src_index;
   6535     uint32 src_ent[SOC_MAX_MEM_FIELD_WORDS];
   6536     int src_tbl_is_stm = 1;
   6537     soc_mem_t src_mem = SOURCE_TRUNK_MAP_TABLEm;
   6538     lport_tab_entry_t lport_entry;
   6539     rtag7_port_based_hash_entry_t  rtag7_entry;
   6540     uint32 lport_index = 0, rtag7_index = 0;
   6541     void *entries[1];
   6542     soc_mem_t mem;
   6543     void *entry;
   6544 
   6545     BCM_IF_ERROR_RETURN
   6546         (bcm_esw_port_lport_prof_src_check(unit, port_type, &src_tbl_is_stm));
   6547 
   6548     /* Get LPORT profile index Source table */
   6549     if (src_tbl_is_stm) {
   6550     BCM_IF_ERROR_RETURN
   6551             (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, &src_index));
   6552     } else {
   6553         src_mem = ING_DEVICE_PORTm;
   6554         src_index = port;
   6555     }
   6556 
   6557     BCM_IF_ERROR_RETURN
   6558         (soc_mem_read(unit, src_mem, MEM_BLOCK_ANY,
   6559                       src_index, src_ent));
   6560 
   6561     lport_index =
   6562         soc_mem_field32_get(unit, src_mem, src_ent, LPORT_PROFILE_IDXf);
   6563 
   6564     /* If this is a RTAG7 table, extract the RTAG7 index from the LPORT table */
   6565     if(table_id == LPORT_PROFILE_RTAG7_TAB) {
   6566 
   6567         /* Get the associated LPORT entry */
   6568         BCM_IF_ERROR_RETURN
   6569             (READ_LPORT_TABm(unit, MEM_BLOCK_ANY, lport_index, &lport_entry));
   6570 
   6571         rtag7_index =
   6572             soc_LPORT_TABm_field32_get(unit, &lport_entry,
   6573                                                     RTAG7_PORT_PROFILE_INDEXf);
   6574     }
   6575 
   6576     /* Read the appropriate profile table entry */
   6577     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   6578         mem = LPORT_TABm;
   6579         entries[0] = &lport_entry;
   6580         entry = entries[0];
   6581         BCM_IF_ERROR_RETURN
   6582             (_bcm_lport_ind_profile_entry_get(unit, lport_index,
   6583                                             1, entries));
   6584     } else if (table_id == LPORT_PROFILE_RTAG7_TAB) {
   6585         mem = RTAG7_PORT_BASED_HASHm;
   6586         entries[0] = &rtag7_entry;
   6587         entry = entries[0];
   6588         BCM_IF_ERROR_RETURN
   6589             (_bcm_rtag7_ind_profile_entry_get(unit, rtag7_index,
   6590                                             1, entries));
   6591     } else {
   6592         return BCM_E_INTERNAL;
   6593     }
   6594 
   6595     for (i = 0; i < field_count; i++) {
   6596         values[i] = soc_mem_field32_get(unit, mem, entry, fields[i]);
   6597     }
   6598 
   6599     return BCM_E_NONE;
   6600 }
   6601 #endif /* BCM_TRX_SUPPORT */
   6602 
   6603 
   6604 /*
   6605  * Function:
   6606  *      bcm_esw_port_egr_lport_profile_fields_get
   6607  * Description:
   6608  *      Gets the fields from the LPORT Profile Table.
   6609  * Parameters:
   6610  *      unit        - (IN) Device number
   6611  *      modid       - (IN) Module number for port
   6612  *      port        - (IN) Port number (NON gport)
   6613  *      mem         - (IN) Table to modify
   6614  *      field_count - (IN) Number of fields to read
   6615  *      fields      - (IN) Array of fields to return
   6616  *      values      - (OUT) Array of return values
   6617  * Return Value:
   6618  *      BCM_E_NONE
   6619  *      BCM_E_XXX
   6620  * Note:
   6621  *     - Assumes: lock,
   6622  *                valid bcm module id and port number,
   6623  *                valid table id,
   6624  *                valid HW fields.
   6625  *     - Called when LPORT profile is supported.
   6626  *     - Helper routine for bcm_esw_port_egr_lport_fields_get();
   6627  *       callers should be calling bcm_esw_port_egr_lport_fields_get() instead.
   6628  */
   6629 STATIC int
   6630 bcm_esw_port_egr_lport_profile_fields_get(int unit,
   6631                                       bcm_module_t modid, bcm_port_t port,
   6632                                       soc_mem_t mem, int field_count,
   6633                                       soc_field_t *fields, uint32 *values)
   6634 {
   6635 #if defined(BCM_TRX_SUPPORT)
   6636     int i, index;
   6637     int egr_gpp_index = 0;
   6638     egr_gpp_attributes_entry_t egr_gpp_entry;
   6639     egr_lport_profile_entry_t egr_lport_entry;
   6640     egr_vlan_control_1_entry_t egr_vlan_control_1;
   6641     egr_vlan_control_2_entry_t egr_vlan_control_2;
   6642     egr_vlan_control_3_entry_t egr_vlan_control_3;
   6643     egr_ipmc_cfg2_entry_t egr_ipmc_cfg2;
   6644     egr_mtu_entry_t egr_mtu;
   6645     egr_port_1_entry_t egr_port_1;
   6646     egr_counter_control_entry_t egr_counter_control;
   6647     egr_shaping_control_entry_t egr_shaping_control;
   6648     uint32 egr_lport_index;
   6649     void *entries[_BCM_EGR_LPROF_MEM_COUNT];
   6650     void *entry = NULL;
   6651     int use_gpp_index = 1;
   6652 
   6653     if (mem == EGR_GPP_ATTRIBUTESm) {
   6654         BCM_IF_ERROR_RETURN
   6655             (_bcm_esw_src_mod_port_table_index_get(unit, modid, port,
   6656                                                    &egr_gpp_index));
   6657         BCM_IF_ERROR_RETURN
   6658             (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY,
   6659                                       egr_gpp_index, &egr_gpp_entry));
   6660         for (i = 0; i < field_count; i++) {
   6661             values[i] = soc_mem_field32_get(unit, EGR_GPP_ATTRIBUTESm,
   6662                                             &egr_gpp_entry, fields[i]);
   6663         }
   6664         return BCM_E_NONE;
   6665     }
   6666 
   6667     BCM_IF_ERROR_RETURN(
   6668         bcm_esw_port_egr_lport_prof_src_get(unit, modid, port, &use_gpp_index));
   6669 
   6670     if (use_gpp_index) {
   6671     /* Get LPORT profile index Source Trunk Map table */
   6672     BCM_IF_ERROR_RETURN
   6673             (_bcm_esw_src_mod_port_table_index_get(unit, modid, port,
   6674                                                    &egr_gpp_index));
   6675     BCM_IF_ERROR_RETURN
   6676         (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY,
   6677                                       egr_gpp_index, &egr_gpp_entry));
   6678     egr_lport_index =
   6679         soc_EGR_GPP_ATTRIBUTESm_field32_get(unit, &egr_gpp_entry,
   6680                                             EGR_LPORT_PROFILE_IDXf);
   6681     } else {
   6682         egr_port_entry_t entry2;
   6683         BCM_IF_ERROR_RETURN
   6684             (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, &entry2));
   6685         egr_lport_index =
   6686             soc_mem_field32_get(unit, EGR_PORTm, &entry2,
   6687                                 EGR_LPORT_PROFILE_IDXf);
   6688     }
   6689 
   6690     /* Get EGR_LPORT profile entry */
   6691     index = 0;
   6692     if (SOC_MEM_IS_VALID(unit, EGR_LPORT_PROFILEm)) {
   6693         entries[index++] = &egr_lport_entry;
   6694     }
   6695     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_1m)) {
   6696         entries[index++] = &egr_vlan_control_1;
   6697     }
   6698     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_2m)) {
   6699         entries[index++] = &egr_vlan_control_2;
   6700     }
   6701     if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_3m)) {
   6702         entries[index++] = &egr_vlan_control_3;
   6703     }
   6704     if (SOC_MEM_IS_VALID(unit, EGR_IPMC_CFG2m)) {
   6705         entries[index++] = &egr_ipmc_cfg2;
   6706     }
   6707     if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) {
   6708         entries[index++] = &egr_mtu;
   6709     }
   6710     if (SOC_MEM_IS_VALID(unit, EGR_PORT_1m)) {
   6711         entries[index++] = &egr_port_1;
   6712     }
   6713     if (soc_feature(unit, soc_feature_egr_all_profile) == 0) {
   6714         if (SOC_MEM_IS_VALID(unit, EGR_COUNTER_CONTROLm)) {
   6715             entries[index++] = &egr_counter_control;
   6716         }
   6717         if (SOC_MEM_IS_VALID(unit, EGR_SHAPING_CONTROLm)) {
   6718             entries[index++] = &egr_shaping_control;
   6719         }
   6720     }
   6721 
   6722     BCM_IF_ERROR_RETURN
   6723             (_bcm_egr_lport_profile_entry_get(unit, egr_lport_index, 1, entries));
   6724 
   6725     BCM_IF_ERROR_RETURN
   6726         (_bcm_egr_lport_profile_mem_index_get(unit, mem, &index));
   6727     entry = entries[index];
   6728     /* Get fields */
   6729 
   6730     for (i = 0; i < field_count; i++) {
   6731         values[i] = soc_mem_field32_get(unit, mem, entry, fields[i]);
   6732     }
   6733 
   6734     return BCM_E_NONE;
   6735 #else
   6736     return BCM_E_UNAVAIL;
   6737 #endif /* BCM_TRX_SUPPORT */
   6738 }
   6739 
   6740 /*
   6741  * Function:
   6742  *      bcm_esw_port_lport_profile_fields_get
   6743  * Description:
   6744  *      Gets the fields from the LPORT Profile Table.
   6745  * Parameters:
   6746  *      unit        - (IN) Device number
   6747  *      modid       - (IN) Module number for port
   6748  *      port        - (IN) Port number (NON gport)
   6749  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   6750  *      field_count - (IN) Number of fields to read
   6751  *      fields      - (IN) Array of fields to return
   6752  *      values      - (OUT) Array of return values
   6753  * Return Value:
   6754  *      BCM_E_NONE
   6755  *      BCM_E_XXX
   6756  * Note:
   6757  *     - Assumes: lock,
   6758  *                valid bcm module id and port number,
   6759  *                valid table id,
   6760  *                valid HW fields.
   6761  *     - Called when LPORT profile is supported.
   6762  *     - Helper routine for bcm_esw_port_lport_fields_get();
   6763  *       callers should be calling bcm_esw_port_lport_fields_get() instead.
   6764  */
   6765 STATIC int
   6766 bcm_esw_port_lport_profile_fields_get(int unit, int port_type,
   6767                                       bcm_module_t modid, bcm_port_t port,
   6768                                       int table_id, int field_count,
   6769                                       soc_field_t *fields, uint32 *values)
   6770 {
   6771 #if defined(BCM_TRX_SUPPORT)
   6772     int i;
   6773     int src_index;
   6774     uint32 src_ent[SOC_MAX_MEM_FIELD_WORDS];
   6775     int src_tbl_is_stm = 1;
   6776     soc_mem_t src_mem = SOURCE_TRUNK_MAP_TABLEm;
   6777     lport_tab_entry_t lport_entry;
   6778     rtag7_port_based_hash_entry_t  rtag7_entry;
   6779     uint32 lport_index;
   6780     void *entries[2];
   6781     soc_mem_t mem;
   6782     void *entry;
   6783     int pipe;
   6784 
   6785     if (soc_feature(unit, soc_feature_separate_ing_lport_rtag7_profile)) {
   6786         return bcm_esw_port_separate_lport_rtag7_profile_fields_get(unit,
   6787                 port_type, modid, port, table_id, field_count, fields, values);
   6788     }
   6789 
   6790     BCM_IF_ERROR_RETURN
   6791         (bcm_esw_port_lport_prof_src_check(unit, port_type, &src_tbl_is_stm));
   6792 
   6793     /* Get LPORT profile index Source table */
   6794     if (src_tbl_is_stm) {
   6795     BCM_IF_ERROR_RETURN
   6796             (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, &src_index));
   6797     } else {
   6798         src_mem = ING_DEVICE_PORTm;
   6799         src_index = port;
   6800     }
   6801 
   6802     BCM_IF_ERROR_RETURN
   6803         (soc_mem_read(unit, src_mem, MEM_BLOCK_ANY, src_index, src_ent));
   6804 
   6805     lport_index =
   6806         soc_mem_field32_get(unit, src_mem, src_ent, LPORT_PROFILE_IDXf);
   6807 
   6808     /* Get LPORT profile entry */
   6809     entries[0] = &lport_entry;
   6810     entries[1] = &rtag7_entry;
   6811     if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) {
   6812         pipe = SOC_INFO(unit).port_pipe[src_index];
   6813         mem = SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)[pipe];
   6814         /* Need to index into the proper entry of the profile table,
   6815          * which is stored as one logical table while LPORT_PROFILE_IDX
   6816          * is from 0-19 of each pipe */
   6817         lport_index += pipe*SOC_MEM_SIZE(unit, mem);
   6818     }
   6819 
   6820     BCM_IF_ERROR_RETURN
   6821             (_bcm_lport_profile_entry_get(unit, lport_index, 1, entries));
   6822 
   6823     /* Get fields */
   6824     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   6825         mem = LPORT_TABm;
   6826         if (SOC_MEM_UNIQUE_ACC(unit, mem)) {
   6827             int pipe = SOC_INFO(unit).port_pipe[src_index];
   6828             mem = SOC_MEM_UNIQUE_ACC(unit, mem)[pipe];
   6829         }
   6830         entry = entries[0];
   6831     } else if (table_id == LPORT_PROFILE_RTAG7_TAB) {
   6832         mem = RTAG7_PORT_BASED_HASHm;
   6833         entry = entries[1];
   6834     } else {
   6835         return BCM_E_INTERNAL;
   6836     }
   6837 
   6838     for (i = 0; i < field_count; i++) {
   6839         values[i] = soc_mem_field32_get(unit, mem, entry, fields[i]);
   6840     }
   6841 
   6842     return BCM_E_NONE;
   6843 #else
   6844     return BCM_E_UNAVAIL;
   6845 #endif /* BCM_TRX_SUPPORT */
   6846 }
   6847 
   6848 /*
   6849  * Function:
   6850  *      bcm_esw_port_lport_non_profile_fields_set
   6851  * Description:
   6852  *      Sets the fields only in the LPORT Table for local HG ports.
   6853  *      There is no reference update to the SOURCE TRUNK MAP table.
   6854  * Parameters:
   6855  *      unit        - (IN) Device number
   6856  *      port        - (IN) Local Port number (NON gport)
   6857  *      field_count - (IN) Number of fields to modify
   6858  *      fields      - (IN) Array of fields to modify
   6859  *      values      - (IN) Array of new field values
   6860  * Return Value:
   6861  *      BCM_E_NONE
   6862  *      BCM_E_XXX
   6863  * Note:
   6864  *     Assumes: lock,
   6865  *              valid bcm port number,
   6866  *              valid HW fields.
   6867  *     - Maintained for backwards compatibility with old code.  This only
   6868  *       updates local HG ports.
   6869  *     - Called when LPORT profile is NOT supported.
   6870  *     - Helper routine for bcm_esw_port_lport_fields_set();
   6871  *       callers should be calling bcm_esw_port_lport_fields_set() instead.
   6872  */
   6873 STATIC int
   6874 bcm_esw_port_lport_non_profile_fields_set(int unit, bcm_port_t port,
   6875                                           int field_count,
   6876                                           soc_field_t *fields, uint32 *values)
   6877 {
   6878     bcm_port_config_t port_config;
   6879     soc_mem_t mem = LPORT_TABm;
   6880     int lport_index;
   6881 
   6882     BCM_IF_ERROR_RETURN(bcm_esw_port_config_get(unit, &port_config));
   6883 
   6884     if (PBMP_MEMBER(port_config.hg, port) == 0) {
   6885         return BCM_E_NONE;
   6886     }
   6887 
   6888     lport_index = SOC_PORT_MOD_OFFSET(unit, port);
   6889 
   6890     return soc_mem_fields32_modify(unit, mem, lport_index,
   6891                                    field_count, fields, values);
   6892 }
   6893 
   6894 /*
   6895  * Function:
   6896  *      bcm_esw_port_lport_non_profile_fields_get
   6897  * Description:
   6898  *      Gets the fields from the LPORT Table for local HG ports.
   6899  * Parameters:
   6900  *      unit        - (IN) Device number
   6901  *      port        - (IN) Local Port number (NON gport)
   6902  *      field_count - (IN) Number of fields to read
   6903  *      fields      - (IN) Array of fields to return
   6904  *      values      - (OUT) Array of return values
   6905  * Return Value:
   6906  *      BCM_E_NONE
   6907  *      BCM_E_XXX
   6908  * Note:
   6909  *     Assumes: lock,
   6910  *              valid bcm port number,
   6911  *              valid HW fields.
   6912  *     - Maintained for backwards compatibility with old code.  This only
   6913  *       updates local HG ports.
   6914  *     - Called when LPORT profile is NOT supported.
   6915  *     - Helper routine for bcm_esw_port_lport_fields_get();
   6916  *       callers should be calling bcm_esw_port_lport_fields_get() instead.
   6917  */
   6918 STATIC int
   6919 bcm_esw_port_lport_non_profile_fields_get(int unit, bcm_port_t port,
   6920                                           int field_count,
   6921                                           soc_field_t *fields, uint32 *values)
   6922 {
   6923     lport_tab_entry_t lport_entry;
   6924     int lport_index;
   6925     int i;
   6926 
   6927     if (!IS_HG_PORT(unit,port)) {
   6928         return BCM_E_NONE;
   6929     }
   6930 
   6931     lport_index = SOC_PORT_MOD_OFFSET(unit, port);
   6932 
   6933     BCM_IF_ERROR_RETURN
   6934         (READ_LPORT_TABm(unit, MEM_BLOCK_ANY, lport_index, &lport_entry));
   6935 
   6936     for (i = 0; i < field_count; i++) {
   6937         values[i] = soc_LPORT_TABm_field32_get(unit, &lport_entry, fields[i]);
   6938     }
   6939 
   6940     return BCM_E_NONE;
   6941 }
   6942 
   6943 /*
   6944  * Function:
   6945  *      bcm_esw_port_lport_resolve
   6946  * Description:
   6947  *      Resolves given port to use in the LPORT table as follows.
   6948  *      Current valid "port" for LPORT are:
   6949  *        GPORT_PROXY  - Resolve to module ID and port
   6950  *        GPORT_xxx    - Should result in a valid local physical port
   6951  *        Not GPORT    - Should be a valid local port number
   6952  * Parameters:
   6953  *      unit        - (IN) Device number
   6954  *      port        - (IN) Port number or GPORT
   6955  *      modid_out   - (OUT) Module ID
   6956  *      port_out    - (OUT) Port number
   6957  * Return Value:
   6958  *      BCM_E_XXX
   6959  * Notes:
   6960  *      If port is GPORT_PROXY, then module-id is derived from GPORT.
   6961  *      Else, module-is is the id of the local device.
   6962  */
   6963 STATIC int
   6964 bcm_esw_port_lport_resolve(int unit, bcm_port_t port,
   6965                            bcm_module_t *modid_out, bcm_port_t *port_out)
   6966 {
   6967     bcm_trunk_t trunk;
   6968     int id, rv;
   6969 
   6970     /* Make sure port module is initialized. */
   6971     PORT_INIT(unit);
   6972 
   6973     /* Resolve port */
   6974     if (BCM_GPORT_IS_PROXY(port)) {
   6975         if (!soc_feature(unit, soc_feature_proxy_port_property)) {
   6976             return BCM_E_PORT;
   6977         }
   6978         BCM_IF_ERROR_RETURN
   6979             (_bcm_esw_gport_resolve(unit, port,
   6980                                     modid_out, port_out,
   6981                                     &trunk, &id));
   6982     } else {
   6983 
   6984 #if defined BCM_HGPROXY_COE_SUPPORT
   6985         if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   6986              _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   6987                 BCM_IF_ERROR_RETURN
   6988                     (_bcm_esw_gport_resolve(unit, port,
   6989                                         modid_out, port_out,
   6990                                         &trunk, &id));
   6991         } else
   6992 #endif
   6993 
   6994 #if defined(BCM_KATANA2_SUPPORT)
   6995         if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port) && 
   6996                 (soc_feature(unit, soc_feature_subtag_coe) ||
   6997                  soc_feature(unit, soc_feature_linkphy_coe))) {
   6998             BCM_IF_ERROR_RETURN
   6999                 (_bcm_esw_gport_resolve(unit, port,
   7000                                     modid_out, port_out,
   7001                                     &trunk, &id));
   7002         } else 
   7003 #endif
   7004 
   7005         {
   7006             /* Gport should resolve to a local valid port */
   7007             BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, modid_out));
   7008             rv = _bcm_esw_port_gport_validate(unit, port, port_out);
   7009 
   7010             if (rv == BCM_E_PORT &&
   7011                 SOC_IS_TRIDENT3X(unit) &&
   7012                 SOC_INFO(unit).cpu_hg_index == port) {
   7013                 *port_out = port;
   7014                 rv = BCM_E_NONE;
   7015             }
   7016             BCM_IF_ERROR_RETURN(rv);
   7017         }
   7018     }
   7019 
   7020     return BCM_E_NONE;
   7021 }
   7022 
   7023 /*
   7024  * Function:
   7025  *      bcm_esw_port_egr_lport_resolve
   7026  * Description:
   7027  *      Resolves given port to use in the EGR_LPORT table as follows.
   7028  *      Current valid "port" for EGR_LPORT are:
   7029  *        GPORT_SUBPORT - Resolve to module ID and port
   7030  * Parameters:
   7031  *      unit        - (IN) Device number
   7032  *      port        - (IN) Port number or GPORT
   7033  *      modid_out   - (OUT) Module ID
   7034  *      port_out    - (OUT) Port number
   7035  * Return Value:
   7036  *      BCM_E_XXX
   7037  * Notes:
   7038  *      If port is GPORT_PROXY, then module-id is derived from GPORT.
   7039  *      Else, module-is is the id of the local device.
   7040  */
   7041 STATIC int
   7042 bcm_esw_port_egr_lport_resolve(int unit, bcm_port_t port,
   7043                            bcm_module_t *modid_out, bcm_port_t *port_out)
   7044 {
   7045 #if defined BCM_HGPROXY_COE_SUPPORT
   7046     bcm_trunk_t trunk;
   7047     int         id;
   7048 #endif
   7049 
   7050     /* Make sure port module is initialized. */
   7051     PORT_INIT(unit);
   7052 
   7053     /* Resolve port */
   7054 #if defined BCM_HGPROXY_COE_SUPPORT
   7055     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   7056          _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   7057             BCM_IF_ERROR_RETURN
   7058                 (_bcm_esw_gport_resolve(unit, port,
   7059                                     modid_out, port_out,
   7060                                     &trunk, &id));
   7061     } else
   7062 #endif
   7063     {
   7064         /* Gport should resolve to a local valid port */
   7065         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, modid_out));
   7066         BCM_IF_ERROR_RETURN
   7067             (_bcm_esw_port_gport_validate(unit, port, port_out));
   7068     }
   7069 
   7070     return BCM_E_NONE;
   7071 }
   7072 
   7073 
   7074 /*
   7075  * Function:
   7076  *      bcm_esw_port_lport_fields_set
   7077  * Description:
   7078  *      Sets the fields in the LPORT Table as follows:
   7079  *      - If LPORT profile is available, update fields in the
   7080  *        LPORT Profile Table and corresponding index in the
   7081  *        Source Trunk Map table.
   7082  *      - Else, update fields in the LPORT table only (old logic).
   7083  * Parameters:
   7084  *      unit        - (IN) Device number
   7085  *      port        - (IN) Port number or GPORT (see Notes)
   7086  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   7087  *      field_count - (IN) Number of fields to modify
   7088  *      fields      - (IN) Array of fields to modify
   7089  *      values      - (IN) Array of new field values
   7090  * Return Value:
   7091  *      BCM_E_XXX
   7092  * Notes:
   7093  *      Current valid port/gport types:
   7094  *        GPORT_PROXY
   7095  *        GPORT_xxx    - should result in a valid local physical port
   7096  *        Not GPORT    - assumes a valid local port number
   7097  */
   7098 int
   7099 bcm_esw_port_lport_fields_set(int unit, bcm_port_t port,
   7100                               int table_id, int field_count,
   7101                               soc_field_t *fields, uint32 *values)
   7102 {
   7103     int rv = BCM_E_NONE;
   7104     int i;
   7105     soc_mem_t mem;
   7106     bcm_module_t lmodid;
   7107     bcm_port_t lport;
   7108     int ptype = _BCM_ESW_PT_PORT;
   7109 
   7110     /* Make sure port module is initialized. */
   7111     PORT_INIT(unit);
   7112 
   7113 #if defined BCM_HGPROXY_COE_SUPPORT
   7114     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   7115          _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   7116         ptype = _BCM_ESW_PT_COE;
   7117     } else
   7118 #endif
   7119     if (BCM_GPORT_IS_PROXY(port)) {
   7120         ptype = _BCM_ESW_PT_HGPROXY;
   7121     }
   7122 
   7123     /* Check table */
   7124     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   7125         mem = LPORT_TABm;
   7126     } else if (table_id == LPORT_PROFILE_RTAG7_TAB) {
   7127         if (!SOC_MEM_IS_VALID(unit, RTAG7_PORT_BASED_HASHm)) {
   7128             return BCM_E_UNAVAIL;
   7129         }
   7130         mem = RTAG7_PORT_BASED_HASHm;
   7131     } else {
   7132         return BCM_E_INTERNAL;
   7133     }
   7134 
   7135     /* Check all fields are valid */
   7136     for (i = 0; i < field_count; i++) {
   7137         if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) {
   7138             return BCM_E_UNAVAIL;
   7139         }
   7140     }
   7141 
   7142     /* Resolve port */
   7143     BCM_IF_ERROR_RETURN
   7144         (bcm_esw_port_lport_resolve(unit, port,
   7145                                     &lmodid, &lport));
   7146 
   7147     if (soc_feature(unit, soc_feature_lport_tab_profile)) {
   7148         rv = bcm_esw_port_lport_profile_fields_set(unit, ptype,
   7149                 lmodid, lport, table_id, field_count, fields, values);
   7150     } else {
   7151         rv = bcm_esw_port_lport_non_profile_fields_set(unit,
   7152                 lport, field_count, fields, values);
   7153     }
   7154 
   7155     return rv;
   7156 }
   7157 
   7158 /*
   7159  * Function:
   7160  *      bcm_esw_port_egr_lport_fields_set
   7161  * Description:
   7162  *      Sets the fields in the LPORT Table as follows:
   7163  *      - If LPORT profile is available, update fields in the
   7164  *        LPORT Profile Table and corresponding index in the
   7165  *        Source Trunk Map table.
   7166  *      - Else, update fields in the LPORT table only (old logic).
   7167  * Parameters:
   7168  *      unit        - (IN) Device number
   7169  *      port        - (IN) Port number or GPORT (see Notes)
   7170  *      mem         - (IN) Table to modify
   7171  *      field_count - (IN) Number of fields to modify
   7172  *      fields      - (IN) Array of fields to modify
   7173  *      values      - (IN) Array of new field values
   7174  * Return Value:
   7175  *      BCM_E_XXX
   7176  * Notes:
   7177  *      Current valid port/gport types:
   7178  *        GPORT_PROXY
   7179  *        GPORT_xxx    - should result in a valid local physical port
   7180  *        Not GPORT    - assumes a valid local port number
   7181  */
   7182 int
   7183 bcm_esw_port_egr_lport_fields_set(int unit, bcm_port_t port,
   7184                               soc_mem_t mem, int field_count,
   7185                               soc_field_t *fields, uint32 *values)
   7186 {
   7187     int rv = BCM_E_NONE;
   7188     int i;
   7189     bcm_module_t lmodid;
   7190     bcm_port_t lport;
   7191 
   7192     /* Make sure port module is initialized. */
   7193     PORT_INIT(unit);
   7194 
   7195     /* Check all fields are valid */
   7196     for (i = 0; i < field_count; i++) {
   7197         if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) {
   7198             return BCM_E_UNAVAIL;
   7199         }
   7200     }
   7201 
   7202     /* Resolve port */
   7203     BCM_IF_ERROR_RETURN
   7204         (bcm_esw_port_egr_lport_resolve(unit, port,
   7205                                     &lmodid, &lport));
   7206 
   7207     PORT_LOCK(unit);
   7208     if (soc_feature(unit, soc_feature_egr_lport_tab_profile)) {
   7209         rv = bcm_esw_port_egr_lport_profile_fields_set(unit, lmodid, lport,
   7210                                                    mem, field_count,
   7211                                                    fields, values);
   7212     }
   7213 
   7214     PORT_UNLOCK(unit);
   7215 
   7216     return rv;
   7217 }
   7218 
   7219 /*
   7220  * Function:
   7221  *      bcm_esw_port_egr_lport_fields_clear
   7222  * Description:
   7223  *      Similar function as bcm_esw_port_egr_lport_fields_set.
   7224  *      For clear purpose only.
   7225  * Parameters:
   7226  *      unit        - (IN) Device number
   7227  *      port        - (IN) Port number or GPORT (see Notes)
   7228  *      mem         - (IN) Table to modify
   7229  * Return Value:
   7230  *      BCM_E_XXX
   7231  * Notes:
   7232  *      Current valid port/gport types:
   7233  *        GPORT_PROXY
   7234  *        GPORT_xxx    - should result in a valid local physical port
   7235  *        Not GPORT    - assumes a valid local port number
   7236  */
   7237 int
   7238 bcm_esw_port_egr_lport_fields_clear(int unit, bcm_port_t port,
   7239                                     soc_mem_t mem)
   7240 {
   7241     int rv = BCM_E_NONE;
   7242     bcm_module_t lmodid;
   7243     bcm_port_t lport;
   7244 
   7245     /* Make sure port module is initialized. */
   7246     PORT_INIT(unit);
   7247 
   7248     /* Resolve port */
   7249     BCM_IF_ERROR_RETURN
   7250         (bcm_esw_port_egr_lport_resolve(unit, port,
   7251                                     &lmodid, &lport));
   7252 
   7253     PORT_LOCK(unit);
   7254     if (soc_feature(unit, soc_feature_egr_lport_tab_profile)) {
   7255         rv = bcm_esw_port_egr_lport_profile_clear(unit, lmodid, lport, mem);
   7256     }
   7257 
   7258     PORT_UNLOCK(unit);
   7259 
   7260     return rv;
   7261 }
   7262 
   7263 /*
   7264  * Function:
   7265  *      bcm_esw_port_lport_fields_get
   7266  * Description:
   7267  *      Gets the values from the LPORT Table fields as follows:
   7268  *      - If LPORT profile is available, gets fields from the
   7269  *        LPORT Profile Table and corresponding index in the
   7270  *        Source Trunk Map table.
   7271  *      - Else, get fields from the LPORT table only (old logic).
   7272  * Parameters:
   7273  *      unit        - (IN) Device number
   7274  *      port        - (IN) Port number or GPORT (see Notes)
   7275  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   7276  *      field_count - (IN) Number of fields to get
   7277  *      fields      - (IN) Array of fields values to get
   7278  *      values      - (OUT) Array of returned values
   7279  * Return Value:
   7280  *      BCM_E_XXX
   7281  * Notes:
   7282  *      Current valid port/gport types:
   7283  *        GPORT_PROXY
   7284  *        GPORT_xxx    - should result in a valid local physical port
   7285  *        Not GPORT    - assumes a valid local port number
   7286  */
   7287 int
   7288 bcm_esw_port_lport_fields_get(int unit, bcm_port_t port,
   7289                               int table_id, int field_count,
   7290                               soc_field_t *fields, uint32 *values)
   7291 {
   7292     int rv = BCM_E_NONE;
   7293     int i;
   7294     soc_mem_t mem;
   7295     bcm_module_t lmodid;
   7296     bcm_port_t lport;
   7297     int ptype = _BCM_ESW_PT_PORT;
   7298 
   7299     /* Make sure port module is initialized. */
   7300     PORT_INIT(unit);
   7301 
   7302 #if defined BCM_HGPROXY_COE_SUPPORT
   7303     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   7304          _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   7305         ptype = _BCM_ESW_PT_COE;
   7306     } else
   7307 #endif
   7308     if (BCM_GPORT_IS_PROXY(port)) {
   7309         ptype = _BCM_ESW_PT_HGPROXY;
   7310     }
   7311 
   7312     /* Check table */
   7313     if (table_id == LPORT_PROFILE_LPORT_TAB) {
   7314         mem = LPORT_TABm;
   7315     } else if (table_id == LPORT_PROFILE_RTAG7_TAB) {
   7316         if (!SOC_MEM_IS_VALID(unit, RTAG7_PORT_BASED_HASHm)) {
   7317             return BCM_E_UNAVAIL;
   7318         }
   7319         mem = RTAG7_PORT_BASED_HASHm;
   7320     } else {
   7321         return BCM_E_INTERNAL;
   7322     }
   7323 
   7324     /* Check all fields are valid */
   7325     for (i = 0; i < field_count; i++) {
   7326         if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) {
   7327             return BCM_E_UNAVAIL;
   7328         }
   7329     }
   7330 
   7331     /* Resolve port */
   7332     BCM_IF_ERROR_RETURN
   7333         (bcm_esw_port_lport_resolve(unit, port,
   7334                                     &lmodid, &lport));
   7335 
   7336     if (soc_feature(unit, soc_feature_lport_tab_profile)) {
   7337         rv = bcm_esw_port_lport_profile_fields_get(unit, ptype,
   7338                 lmodid, lport, table_id, field_count, fields, values);
   7339     } else {
   7340         rv = bcm_esw_port_lport_non_profile_fields_get(unit, lport,
   7341                 field_count, fields, values);
   7342     }
   7343 
   7344     return rv;
   7345 }
   7346 
   7347 /*
   7348  * Function:
   7349  *      bcm_esw_port_egr_lport_fields_get
   7350  * Description:
   7351  *      Gets the values from the LPORT Table fields as follows:
   7352  *      - If LPORT profile is available, gets fields from the
   7353  *        LPORT Profile Table and corresponding index in the
   7354  *        Source Trunk Map table.
   7355  *      - Else, get fields from the LPORT table only (old logic).
   7356  * Parameters:
   7357  *      unit        - (IN) Device number
   7358  *      port        - (IN) Port number or GPORT (see Notes)
   7359  *      mem         - (IN) Table to modify
   7360  *      field_count - (IN) Number of fields to get
   7361  *      fields      - (IN) Array of fields values to get
   7362  *      values      - (OUT) Array of returned values
   7363  * Return Value:
   7364  *      BCM_E_XXX
   7365  * Notes:
   7366  *      Current valid port/gport types:
   7367  *        GPORT_PROXY
   7368  *        GPORT_xxx    - should result in a valid local physical port
   7369  *        Not GPORT    - assumes a valid local port number
   7370  */
   7371 int
   7372 bcm_esw_port_egr_lport_fields_get(int unit, bcm_port_t port,
   7373                               soc_mem_t mem, int field_count,
   7374                               soc_field_t *fields, uint32 *values)
   7375 {
   7376     int rv = BCM_E_NONE;
   7377     int i;
   7378     bcm_module_t lmodid;
   7379     bcm_port_t lport;
   7380 
   7381     /* Sanity check */
   7382     if((fields == NULL) || (values == NULL)) {
   7383         return BCM_E_PARAM;
   7384     }
   7385 
   7386     /* Make sure port module is initialized. */
   7387     PORT_INIT(unit);
   7388 
   7389     /* Check all fields are valid */
   7390     for (i = 0; i < field_count; i++) {
   7391         if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) {
   7392             return BCM_E_UNAVAIL;
   7393         }
   7394     }
   7395 
   7396     /* Resolve port */
   7397     BCM_IF_ERROR_RETURN
   7398         (bcm_esw_port_egr_lport_resolve(unit, port,
   7399                                     &lmodid, &lport));
   7400 
   7401     PORT_LOCK(unit);
   7402     rv = bcm_esw_port_egr_lport_profile_fields_get(unit, lmodid, lport,
   7403                                                mem, field_count,
   7404                                                fields, values);
   7405     PORT_UNLOCK(unit);
   7406 
   7407     return rv;
   7408 }
   7409 
   7410 /*
   7411  * Function:
   7412  *      bcm_esw_port_lport_field_set
   7413  * Description:
   7414  *      Sets given field in the LPORT Table as follows:
   7415  *      - If LPORT profile is available, update field in the
   7416  *        LPORT Profile Table and corresponding index in the
   7417  *        Source Trunk Map table.
   7418  *      - Else, update field in the LPORT table only (old logic).
   7419  * Parameters:
   7420  *      unit        - (IN) Device number
   7421  *      port        - (IN) Port number or GPORT (see Notes)
   7422  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   7423  *      field       - (IN) Field to modify
   7424  *      value       - (IN) New field value
   7425  * Return Value:
   7426  *      BCM_E_XXX
   7427  * Notes:
   7428  *      See bcm_esw_port_lport_fields_set().
   7429  */
   7430 int
   7431 bcm_esw_port_lport_field_set(int unit, bcm_port_t port,
   7432                              int table_id, soc_field_t field, uint32 value)
   7433 {
   7434     /* Make sure port module is initialized. */
   7435     PORT_INIT(unit);
   7436 
   7437     return bcm_esw_port_lport_fields_set(unit, port,
   7438                                          table_id, 1, &field, &value);
   7439 }
   7440 
   7441 /*
   7442  * Function:
   7443  *      bcm_esw_port_egr_lport_field_set
   7444  * Description:
   7445  *      Sets given field in the LPORT Table as follows:
   7446  *      - If LPORT profile is available, update field in the
   7447  *        LPORT Profile Table and corresponding index in the
   7448  *        Source Trunk Map table.
   7449  *      - Else, update field in the LPORT table only (old logic).
   7450  * Parameters:
   7451  *      unit        - (IN) Device number
   7452  *      port        - (IN) Port number or GPORT (see Notes)
   7453  *      mem         - (IN) Table to modify
   7454  *      field       - (IN) Field to modify
   7455  *      value       - (IN) New field value
   7456  * Return Value:
   7457  *      BCM_E_XXX
   7458  * Notes:
   7459  *      See bcm_esw_port_egr_lport_fields_set().
   7460  */
   7461 int
   7462 bcm_esw_port_egr_lport_field_set(int unit, bcm_port_t port, soc_mem_t mem,
   7463                                  soc_field_t field, uint32 value)
   7464 {
   7465     /* Make sure port module is initialized. */
   7466     PORT_INIT(unit);
   7467 
   7468     return bcm_esw_port_egr_lport_fields_set(unit, port, mem, 1, &field, &value);
   7469 }
   7470 
   7471 
   7472 /*
   7473  * Function:
   7474  *      bcm_esw_port_lport_field_get
   7475  * Description:
   7476  *      Gets given field from the LPORT Table as follows:
   7477  *      - If LPORT profile is available, gets fields from the
   7478  *        LPORT Profile Table and corresponding index in the
   7479  *        Source Trunk Map table.
   7480  *      - Else, get fields from the LPORT table only (old logic).
   7481  * Parameters:
   7482  *      unit        - (IN) Device number
   7483  *      port        - (IN) Port number or GPORT (see Notes)
   7484  *      table_id    - (IN) Index of table to modify, LPORT or RTAG7
   7485  *      field       - (IN) Field value to get
   7486  *      value       - (OUT) Returned value
   7487  * Return Value:
   7488  *      BCM_E_XXX
   7489  * Notes:
   7490  *      See bcm_esw_port_lport_fields_get().
   7491  */
   7492 int
   7493 bcm_esw_port_lport_field_get(int unit, bcm_port_t port,
   7494                              int table_id, soc_field_t field, uint32 *value)
   7495 {
   7496     /* Make sure port module is initialized. */
   7497     PORT_INIT(unit);
   7498 
   7499     return bcm_esw_port_lport_fields_get(unit, port,
   7500                                          table_id, 1, &field, value);
   7501 }
   7502 
   7503 
   7504 /*
   7505  * Function:
   7506  *      bcm_esw_port_egr_lport_field_get
   7507  * Description:
   7508  *      Gets given field from the LPORT Table as follows:
   7509  *      - If LPORT profile is available, gets fields from the
   7510  *        LPORT Profile Table and corresponding index in the
   7511  *        Source Trunk Map table.
   7512  *      - Else, get fields from the LPORT table only (old logic).
   7513  * Parameters:
   7514  *      unit        - (IN) Device number
   7515  *      port        - (IN) Port number or GPORT (see Notes)
   7516  *      mem         - (IN) Table to modify
   7517  *      field       - (IN) Field value to get
   7518  *      value       - (OUT) Returned value
   7519  * Return Value:
   7520  *      BCM_E_XXX
   7521  * Notes:
   7522  *      See bcm_esw_port_egr_lport_fields_get().
   7523  */
   7524 int
   7525 bcm_esw_port_egr_lport_field_get(int unit, bcm_port_t port, soc_mem_t mem,
   7526                                  soc_field_t field, uint32 *value)
   7527 {
   7528     /* Make sure port module is initialized. */
   7529     PORT_INIT(unit);
   7530 
   7531     return bcm_esw_port_egr_lport_fields_get(unit, port, mem, 1, &field, value);
   7532 }
   7533 
   7534 /*
   7535  * Function:
   7536  *      _bcm_esw_port_tab_multi_set
   7537  * Description:
   7538  *      Sets multiple port property fields in the HW table.
   7539  *      Helper funtion for bcm_esw_port_control_set.
   7540  * Parameters:
   7541  *      unit        - Device number
   7542  *      port        - Port number (see Notes for valid port formats)
   7543  *      cpu_tabs - If CPU port, which ingress tables should be written?
   7544  *      field_count - Number of fields to modify
   7545  *      fields      - Array of fields to modify
   7546  *      values      - Array of new field values
   7547  * Return Value:
   7548  *      BCM_E_NONE
   7549  *      BCM_E_XXX - an error occurred accessing PORT_TAB table.
   7550  * Notes:
   7551  *      Due to the large number of callers for this routine,
   7552  *      function is expanded to take a GPORT PROXY, which
   7553  *      sets the property in the LPORT profile table (similar
   7554  *      to what was done for the GPORT_WLAN_PORT).
   7555  *
   7556  *      Current valid port types are:
   7557  *          GPORT WLAN
   7558  *          GPORT PROXY
   7559  *          GPORT SUBPORT
   7560  *          BCM port (non-gport), assumes a valid local physical port
   7561  *
   7562  *     For GPORT PROXY port, this routine only accesses the properties
   7563  *     in the LPORT table (not the RTAG7).
   7564  */
   7565 int
   7566 _bcm_esw_port_tab_multi_set(int unit, bcm_port_t port, int cpu_tabs,
   7567                             int field_count, soc_field_t *fields,
   7568                             uint32 *values)
   7569 {
   7570     soc_mem_t port_tab_mem = PORT_TABm;
   7571     int rv = BCM_E_NONE, i, cpu_hg_index = -1;
   7572     int is_lport_cfg=0, is_wlan_cfg = 0, is_in_warm_boot = 0;
   7573     int index = 0, is_local_port = 0;
   7574     int ptype = _BCM_ESW_PT_PORT;
   7575 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
   7576      && defined(INCLUDE_L3))
   7577     bcm_port_t wport = 0;
   7578 #endif
   7579     port_tab_entry_t pent;
   7580 
   7581     soc_field_t port_tab_fields[SOC_MAX_MEM_FIELD_NUM];
   7582     uint32 port_tab_values[SOC_MAX_MEM_FIELD_NUM];
   7583     int port_tab_field_count = 0;
   7584     soc_field_t lport_tab_fields[SOC_MAX_MEM_FIELD_NUM];
   7585     uint32 lport_tab_values[SOC_MAX_MEM_FIELD_NUM];
   7586     int lport_tab_field_count = 0;
   7587     soc_field_t ing_dev_port_fields[SOC_MAX_MEM_FIELD_NUM];
   7588     uint32 ing_dev_port_values[SOC_MAX_MEM_FIELD_NUM];
   7589     int ing_dev_port_field_count = 0;
   7590 
   7591     if ((fields == NULL) || (values == NULL) ) {
   7592         return BCM_E_PARAM;
   7593     }
   7594     if (field_count <= 0) {
   7595         return BCM_E_NONE;
   7596     }
   7597 
   7598 #if defined BCM_HGPROXY_COE_SUPPORT
   7599     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   7600          _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   7601         is_lport_cfg = 1;
   7602         ptype = _BCM_ESW_PT_COE;
   7603     } else
   7604 #endif
   7605     if (BCM_GPORT_IS_PROXY(port)) {
   7606         is_lport_cfg = 1;
   7607         ptype = _BCM_ESW_PT_HGPROXY;
   7608         if(bcm_esw_port_local_get(unit, port, &port) == BCM_E_NONE) {
   7609             is_local_port = 1;
   7610             index = SOC_PORT_MOD_OFFSET(unit, port);
   7611         }
   7612     }
   7613 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
   7614      && defined(INCLUDE_L3))
   7615     else if (BCM_GPORT_IS_WLAN_PORT(port)) {
   7616         is_wlan_cfg = 1;
   7617         wport = port;
   7618     }
   7619 #endif
   7620 
   7621     if (is_lport_cfg) {
   7622         port_tab_mem = LPORT_TABm;
   7623     } else if (!is_wlan_cfg) {
   7624         /*
   7625          * At this point, 'port' needs to be a BCM port (non-gport)
   7626          * convert the gport to local port
   7627          */
   7628         if (BCM_GPORT_IS_SET(port)) {
   7629             BCM_IF_ERROR_RETURN(
   7630                 _bcm_esw_port_gport_validate(unit, port, &port));
   7631         }
   7632         index = SOC_PORT_MOD_OFFSET(unit, port);
   7633         port_tab_mem = SOC_PORT_MEM_TAB(unit, port);
   7634     }
   7635 
   7636     if (!is_wlan_cfg && port_tab_mem == PORT_TABm &&
   7637         (!IS_CPU_PORT(unit, port) || (cpu_tabs & _BCM_CPU_TABS_ETHER))) {
   7638         sal_memset(&pent, 0, sizeof(pent));
   7639         if (port_tab_mem == PORT_TABm &&
   7640             SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) {
   7641             port_tab_mem = ING_DEVICE_PORTm;
   7642         }
   7643         BCM_IF_ERROR_RETURN(
   7644             soc_mem_read(unit, port_tab_mem, MEM_BLOCK_ANY, index, &pent));
   7645     }
   7646 
   7647     /* Loop to set field values into corresponding memory */
   7648     for (i = 0; i < field_count; i++) {
   7649         /* If LPORT, then set property in LPORT table */
   7650         if (is_lport_cfg) {
   7651 #if defined(CANCUN_SUPPORT)
   7652             if(SOC_IS_TRIDENT3X(unit)) {
   7653                 if(soc_cancun_cmh_check(unit, port_tab_mem, fields[i])
   7654                        == SOC_E_NONE) {
   7655                     rv = soc_cancun_cmh_mem_set(unit, port_tab_mem, port,
   7656                              fields[i], values[i]);
   7657                 }
   7658                 _bcm_td3_port_tab_conv(unit, &fields[i], &port_tab_mem);
   7659             }
   7660 #endif
   7661             soc_mem_set_field_value_array(lport_tab_fields, fields[i],
   7662                                           lport_tab_values, values[i],
   7663                                           lport_tab_field_count);
   7664 
   7665             /* Synchronize PORT and LPORT profile tables if port is local*/
   7666             if(is_local_port) {
   7667                 if(SOC_MEM_FIELD_VALID(unit, port_tab_mem, fields[i])) {
   7668                     soc_mem_set_field_value_array(port_tab_fields, fields[i],
   7669                                                   port_tab_values, values[i],
   7670                                                   port_tab_field_count);
   7671                 }
   7672             }
   7673 
   7674             continue;
   7675         }
   7676 
   7677         /* GPORT WLAN */
   7678 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
   7679      && defined(INCLUDE_L3))
   7680         
   7681         if (is_wlan_cfg) {
   7682 #if defined(BCM_TRIUMPH3_SUPPORT)
   7683             if (soc_feature(unit, soc_feature_axp)) {
   7684                 rv = _bcm_tr3_wlan_port_set(unit, wport, fields[i], values[i]);
   7685             } else
   7686 #endif /* BCM_TRIUMPH3_SUPPORT */
   7687             if (soc_feature(unit, soc_feature_wlan)) {
   7688                 rv = _bcm_tr2_wlan_port_set(unit, wport, fields[i], values[i]);
   7689             }
   7690             if (rv != BCM_E_NONE) {
   7691                 return rv;
   7692             }
   7693             continue;
   7694         }
   7695 #endif
   7696 
   7697         /*  BCM port (non-gport)  */
   7698 #if defined(CANCUN_SUPPORT)
   7699         if (SOC_IS_TRIDENT3X(unit)) {
   7700             port_tab_mem = PORT_TABm;
   7701             if (soc_cancun_cmh_check(unit, port_tab_mem, fields[i])
   7702                    == SOC_E_NONE) {
   7703                 rv = soc_cancun_cmh_mem_set(unit, port_tab_mem, port,
   7704                          fields[i], values[i]);
   7705                 continue;
   7706             }
   7707             _bcm_td3_port_tab_conv(unit, &fields[i], &port_tab_mem);
   7708         }
   7709 #endif
   7710         if (!SOC_MEM_FIELD_VALID(unit, port_tab_mem, fields[i])) {
   7711             LOG_INFO(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
   7712                 "%s.%s is INVALID\n"),
   7713                     SOC_MEM_NAME(unit, port_tab_mem),
   7714                     SOC_FIELD_NAME(unit, fields[i])));
   7715             return (BCM_E_UNAVAIL);
   7716         }
   7717 
   7718         if ((!IS_CPU_PORT(unit, port) || (cpu_tabs & _BCM_CPU_TABS_ETHER)) ||
   7719             (IS_CPU_PORT(unit, port) &&
   7720              (cpu_tabs & _BCM_CPU_TABS_HIGIG) &&
   7721              (port_tab_mem == PORT_TABm))) {
   7722             switch (port_tab_mem) {
   7723 #ifdef  BCM_TUCANA_SUPPORT
   7724                 case PORT_TAB1m:
   7725 #endif
   7726                 case PORT_TABm:
   7727                     if ((soc_mem_field32_get(unit, port_tab_mem,
   7728                                              &pent, fields[i]) != values[i]) ||
   7729                         (fields[i] == TRILL_ENABLEf) ||
   7730                         (fields[i] == ALLOW_TRILL_FRAMESf) ||
   7731                         (fields[i] == ALLOW_NON_TRILL_FRAMESf) ||
   7732                         (fields[i] == COPY_CORE_IS_IS_TO_CPUf) ||
   7733                         (fields[i] == RTAG7_HASH_CFG_SEL_TRILL_ECMPf)) {
   7734                         soc_mem_field32_set(unit, port_tab_mem,
   7735                                             &pent, fields[i], values[i]);
   7736                         soc_mem_set_field_value_array(port_tab_fields,
   7737                             fields[i], port_tab_values, values[i],
   7738                             port_tab_field_count);
   7739                         if ((SOC_MEM_IS_VALID(unit, LPORT_TABm)) &&
   7740                             (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TD2P_TT2P(unit) ||
   7741                              SOC_IS_APACHE(unit) ||
   7742                              soc_feature(unit,
   7743                                          soc_feature_sync_port_lport_tab))) {
   7744                             soc_mem_set_field_value_array(lport_tab_fields,
   7745                                 fields[i], lport_tab_values, values[i],
   7746                                 lport_tab_field_count);
   7747                         }
   7748                     }
   7749                     break;
   7750                 case LPORT_TABm:
   7751                     soc_mem_set_field_value_array(lport_tab_fields, fields[i],
   7752                                                   lport_tab_values, values[i],
   7753                                                   lport_tab_field_count);
   7754                     break;
   7755                 case ING_DEVICE_PORTm:
   7756                     soc_mem_set_field_value_array(ing_dev_port_fields,
   7757                                                   fields[i],
   7758                                                   ing_dev_port_values,
   7759                                                   values[i],
   7760                                                   ing_dev_port_field_count);
   7761                     break;
   7762                 default:
   7763                     soc_mem_field32_modify(unit, port_tab_mem, port,
   7764                                                 fields[i], values[i]);
   7765                     continue;
   7766             }
   7767         }
   7768     }
   7769 
   7770     /* wlan_cfg is handled outside of this function */
   7771     if (is_wlan_cfg == 1) {
   7772         return BCM_E_NONE;
   7773     }
   7774 
   7775     is_in_warm_boot = (inside_bcm_shutdown[unit] == TRUE) ||
   7776                       SOC_WARM_BOOT(unit);
   7777 
   7778     /* Apply the changes to tables their field_count is not 0 */
   7779     if (port_tab_field_count != 0) {
   7780         if (port_tab_mem == PORT_TABm &&
   7781             (!IS_CPU_PORT(unit, port) || (cpu_tabs & _BCM_CPU_TABS_ETHER))) {
   7782             BCM_IF_ERROR_RETURN
   7783                 (soc_mem_write(unit, port_tab_mem, MEM_BLOCK_ALL, index, &pent));
   7784         } else {
   7785             if ((!IS_CPU_PORT(unit, port)) ||
   7786                 (IS_CPU_PORT(unit, port) && (cpu_tabs & _BCM_CPU_TABS_ETHER))) {
   7787                 BCM_IF_ERROR_RETURN
   7788                     (soc_mem_fields32_modify(unit, port_tab_mem, index,
   7789                                              port_tab_field_count, port_tab_fields,
   7790                                              port_tab_values));
   7791             }
   7792         }
   7793     }
   7794 
   7795     if (ing_dev_port_field_count != 0) {
   7796         if(is_in_warm_boot) {
   7797             SOC_WARM_BOOT_DONE(unit);
   7798         }
   7799 
   7800         BCM_IF_ERROR_RETURN
   7801             (soc_mem_fields32_modify(unit, ING_DEVICE_PORTm, index,
   7802                                      ing_dev_port_field_count,
   7803                                      ing_dev_port_fields,
   7804                                      ing_dev_port_values));
   7805         if(is_in_warm_boot) {
   7806             SOC_WARM_BOOT_START(unit);
   7807         }
   7808     }
   7809 
   7810     if (lport_tab_field_count != 0) {
   7811 #if defined(BCM_KATANA2_SUPPORT)
   7812         if (SOC_IS_KATANA2(unit) && (port > KT2_MAX_PHYSICAL_PORTS)) {
   7813             /* Skip programming */;
   7814         } else
   7815 #endif
   7816 #if defined(BCM_SABER2_SUPPORT)
   7817         if (SOC_IS_SABER2(unit) && (port > SB2_MAX_PHYSICAL_PORTS)) {
   7818             /* Skip programming */;
   7819         } else
   7820 #endif
   7821         {
   7822             if (is_in_warm_boot) {
   7823                 SOC_WARM_BOOT_DONE(unit);
   7824             }
   7825 
   7826             if (is_lport_cfg == 1) { /* remote port */
   7827                 rv = bcm_esw_port_lport_fields_set(unit, port,
   7828                                                    LPORT_PROFILE_LPORT_TAB,
   7829                                                    lport_tab_field_count,
   7830                                                    lport_tab_fields,
   7831                                                    lport_tab_values);
   7832 
   7833                 if (is_in_warm_boot) {
   7834                     SOC_WARM_BOOT_START(unit);
   7835                 }
   7836                 return rv;
   7837             }
   7838 
   7839             BCM_IF_ERROR_RETURN
   7840                 (bcm_esw_port_lport_fields_set(unit, 
   7841                                                index,
   7842                                                LPORT_PROFILE_LPORT_TAB,
   7843                                                lport_tab_field_count,
   7844                                                lport_tab_fields,
   7845                                                lport_tab_values));
   7846             if (is_in_warm_boot) {
   7847                 SOC_WARM_BOOT_START(unit);
   7848             }
   7849         }
   7850     }
   7851     
   7852     /* Copy to Higig port if needed */
   7853     if (IS_CPU_PORT(unit, port) && (cpu_tabs & _BCM_CPU_TABS_HIGIG)) {
   7854         cpu_hg_index = SOC_IS_KATANA2(unit) ?
   7855                        SOC_INFO(unit).cpu_hg_pp_port_index :
   7856                        SOC_INFO(unit).cpu_hg_index;
   7857 
   7858         if (SOC_MEM_IS_VALID(unit, IPORT_TABLEm)) {
   7859             if (port_tab_field_count != 0) {
   7860                 BCM_IF_ERROR_RETURN
   7861                     (soc_mem_fields32_modify(unit, IPORT_TABLEm, index,
   7862                                              port_tab_field_count,
   7863                                              port_tab_fields, port_tab_values));
   7864             }
   7865         } else if (cpu_hg_index != -1) {
   7866             if (port_tab_field_count != 0) {
   7867                 BCM_IF_ERROR_RETURN
   7868                     (soc_mem_fields32_modify(unit, port_tab_mem, cpu_hg_index,
   7869                                              port_tab_field_count,
   7870                                              port_tab_fields,
   7871                                              port_tab_values));
   7872             }
   7873             if (ing_dev_port_field_count != 0) {
   7874                 BCM_IF_ERROR_RETURN
   7875                     (soc_mem_fields32_modify(unit, ING_DEVICE_PORTm,
   7876                                              cpu_hg_index,
   7877                                              ing_dev_port_field_count,
   7878                                              ing_dev_port_fields,
   7879                                              ing_dev_port_values));
   7880             }
   7881             if (lport_tab_field_count != 0) {
   7882                 if (SOC_IS_TRIDENT3X(unit)) {
   7883                     /* TD3TBD Should use a feature check? */
   7884                     int my_modid = 0;
   7885                     BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
   7886                     if (soc_feature(unit, soc_feature_lport_tab_profile)) {
   7887                         BCM_IF_ERROR_RETURN(
   7888                             bcm_esw_port_lport_profile_fields_set(unit, ptype,
   7889                                 my_modid, cpu_hg_index, LPORT_PROFILE_LPORT_TAB,
   7890                                 lport_tab_field_count, lport_tab_fields,
   7891                                 lport_tab_values));
   7892                     }
   7893                 }
   7894             }
   7895         }
   7896     }
   7897 
   7898     return rv;
   7899 }
   7900 
   7901 int
   7902 _bcm_esw_port_tab_set_without_portlock(int unit, bcm_port_t port, int cpu_tabs,
   7903                                        soc_field_t field, int value)
   7904 {
   7905     return (_bcm_esw_port_tab_multi_set(unit, port, cpu_tabs, 1, &field,
   7906                                 (uint32*) &value));
   7907 }
   7908 
   7909 /*
   7910  * Function:
   7911  *      _bcm_esw_port_tab_set
   7912  * Description:
   7913  *      Sets the port property field in the HW table.
   7914  *      Helper funtion for bcm_esw_port_control_set.
   7915  * Parameters:
   7916  *      unit  - Device number
   7917  *      port  - Port number (see Notes for valid port formats)
   7918  *      cpu_tabs - If CPU port, which ingress tables should be written?
   7919  *      field - Field name within PORT_TAB table entry
   7920  *      value - new field value
   7921  * Return Value:
   7922  *      BCM_E_NONE
   7923  *      BCM_E_XXX - an error occurred accessing PORT_TAB table.
   7924  * Notes:
   7925  *      Due to the large number of callers for this routine,
   7926  *      function is expanded to take a GPORT PROXY, which
   7927  *      sets the property in the LPORT profile table (similar
   7928  *      to what was done for the GPORT_WLAN_PORT).
   7929  *
   7930  *      Current valid port types are:
   7931  *          GPORT WLAN
   7932  *          GPORT PROXY
   7933  *          GPORT SUBPORT
   7934  *          BCM port (non-gport), assumes a valid local physical port
   7935  *
   7936  *     For GPORT PROXY port, this routine only accesses the properties
   7937  *     in the LPORT table (not the RTAG7).
   7938  */
   7939 int
   7940 _bcm_esw_port_tab_set(int unit, bcm_port_t port, int cpu_tabs,
   7941                       soc_field_t field, int value)
   7942 {
   7943     int rv = BCM_E_UNAVAIL;
   7944     PORT_LOCK(unit);
   7945     rv = _bcm_esw_port_tab_set_without_portlock(unit, port, cpu_tabs, field,
   7946                                                 value);
   7947     PORT_UNLOCK(unit);
   7948 
   7949     return rv;
   7950 }
   7951 
   7952 #if defined(BCM_TRX_SUPPORT)
   7953 /*
   7954  * Function:
   7955  *      _bcm_esw_iport_tab_get
   7956  * Description:
   7957  *      Helper funtion for bcm_esw_port_control_get.
   7958  * Parameters:
   7959  *      unit  - Device number
   7960  *      port  - Port number
   7961  *      field - Field name within IPORT_TAB table entry
   7962  *      value - (OUT) field value
   7963  * Return Value:
   7964  *      BCM_E_NONE
   7965  *      BCM_E_XXX - an error occurred accessing IPORT_TAB table.
   7966  */
   7967 STATIC int
   7968 _bcm_esw_iport_tab_get(int unit, bcm_port_t port,
   7969                       soc_field_t field, int *value)
   7970 {
   7971     port_tab_entry_t pent;
   7972     soc_mem_t mem = INVALIDm;
   7973     int rv, index = -1;
   7974 
   7975     if (SOC_MEM_IS_VALID(unit, IPORT_TABLEm)) {
   7976         mem = IPORT_TABLEm;
   7977         index = SOC_PORT_MOD_OFFSET(unit, port);
   7978     } else if (IS_CPU_PORT(unit, port)) {
   7979         int cpu_hg_index;
   7980 
   7981         cpu_hg_index = SOC_IS_KATANA2(unit) ?
   7982                        SOC_INFO(unit).cpu_hg_pp_port_index :
   7983                        SOC_INFO(unit).cpu_hg_index;
   7984         if (cpu_hg_index != -1){
   7985             mem = PORT_TABm;
   7986             index = cpu_hg_index;
   7987         }
   7988     }
   7989     if (index == -1) {
   7990         return BCM_E_UNAVAIL;
   7991     }
   7992 
   7993     if (!SOC_MEM_FIELD_VALID(unit, mem, field)) {
   7994         return (BCM_E_UNAVAIL);
   7995     }
   7996     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY,
   7997                       index, &pent);
   7998 
   7999     if (BCM_SUCCESS(rv)) {
   8000         *value = soc_mem_field32_get(unit, mem, &pent, field);
   8001     }
   8002 
   8003     return rv;
   8004 }
   8005 #endif /* BCM_TRX_SUPPORT */
   8006 
   8007 /*
   8008  * Function:
   8009  *      _bcm_esw_port_tab_get
   8010  * Description:
   8011  *      Helper funtion for bcm_esw_port_control_get.
   8012  * Parameters:
   8013  *      unit  - Device number
   8014  *      port  - Port number
   8015  *      field - Field name within PORT_TAB table entry
   8016  *      value - (OUT) field value
   8017  * Return Value:
   8018  *      BCM_E_NONE
   8019  *      BCM_E_XXX - an error occurred accessing PORT_TAB table.
   8020  * Notes:
   8021  *      Due to the large number of callers for this routine,
   8022  *      function is expanded to take a GPORT PROXY, which
   8023  *      get the property from the LPORT profile table (similar
   8024  *      to what was done for the GPORT_WLAN_PORT).
   8025  *
   8026  *      Current valid port types are:
   8027  *          GPORT WLAN
   8028  *          GPORT PROXY
   8029  *          GPORT SUBPORT
   8030  *          BCM port (non-gport), assumes a valid local physical port
   8031  *          GPORT Local
   8032  *
   8033  *     For GPORT PROXY port, this routine only accesses the properties
   8034  *     in the LPORT table (not the RTAG7).
   8035  */
   8036 int
   8037 _bcm_esw_port_tab_get(int unit, bcm_port_t port,
   8038                       soc_field_t field, int *value)
   8039 {
   8040     int rv = BCM_E_UNAVAIL;
   8041     port_tab_entry_t pent;
   8042     soc_mem_t mem;
   8043     int index, is_lport_cfg = 0;
   8044     uint32 value32;
   8045 
   8046     mem = SOC_PORT_MEM_TAB(unit, port);
   8047 #if defined(BCM_TRIDENT3_SUPPORT)
   8048     if (SOC_IS_TRIDENT3X(unit)) {
   8049         _bcm_td3_port_tab_conv(unit, &field, &mem);
   8050         if (mem == LPORT_TABm) {
   8051             is_lport_cfg = 1;
   8052         }
   8053     }
   8054 #endif
   8055 
   8056 #if defined BCM_HGPROXY_COE_SUPPORT
   8057     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   8058          _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   8059             is_lport_cfg = 1;
   8060     } else
   8061 #endif
   8062     if (BCM_GPORT_IS_PROXY(port)) {
   8063         is_lport_cfg = 1;
   8064     }
   8065 
   8066     /* If LPORT, then get property from LPORT table */
   8067     if (is_lport_cfg) {
   8068         rv = bcm_esw_port_lport_field_get(unit, port,
   8069                                           LPORT_PROFILE_LPORT_TAB,
   8070                                           field, &value32);
   8071         *value = value32;
   8072         return rv;
   8073     }
   8074 
   8075     /* GPORT WLAN */
   8076 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
   8077      && defined(INCLUDE_L3))
   8078     if (BCM_GPORT_IS_WLAN_PORT(port)) {
   8079 #if defined(BCM_TRIUMPH3_SUPPORT)
   8080         if (soc_feature(unit, soc_feature_axp)) {
   8081             rv = bcm_tr3_wlan_lport_field_get(unit, port, field, value);
   8082         } else
   8083 #endif /* BCM_TRIUMPH3_SUPPORT */
   8084         if (soc_feature(unit, soc_feature_wlan)) {
   8085             rv = bcm_tr2_wlan_lport_field_get(unit, port, field, value);
   8086         }
   8087         return rv;
   8088     }
   8089 #endif
   8090 
   8091     /* At this point, 'port' needs to be a BCM port (non-gport).
   8092      * convert the gport to local port.
   8093      */
   8094     if (BCM_GPORT_IS_SET(port)) {
   8095             BCM_IF_ERROR_RETURN(
   8096                 _bcm_esw_port_gport_validate(unit, port, &port));
   8097     }
   8098 
   8099 #if defined(CANCUN_SUPPORT)
   8100     if (soc_feature(unit, soc_feature_cancun)) {
   8101         if (soc_cancun_cmh_check(unit, mem, field) == SOC_E_NONE) {
   8102             rv = soc_cancun_cmh_mem_get(unit, mem, port,
   8103                      field, (void *)value);
   8104             if (!BCM_SUCCESS(rv)) {
   8105                 return rv;
   8106             }
   8107         }
   8108     }
   8109 #endif
   8110 
   8111     index = SOC_PORT_MOD_OFFSET(unit, port);
   8112     if (!SOC_MEM_FIELD_VALID(unit, mem, field)) {
   8113         return (BCM_E_UNAVAIL);
   8114     }
   8115 
   8116     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY,
   8117                       index, &pent);
   8118 
   8119     if (BCM_SUCCESS(rv)) {
   8120         *value = soc_mem_field32_get(unit, mem, &pent, field);
   8121     }
   8122 
   8123     return rv;
   8124 }
   8125 
   8126 /*
   8127  * Function:
   8128  *      bcm_port_untagged_vlan_get
   8129  * Purpose:
   8130  *      Retrieve the default VLAN ID for the port.
   8131  *      This is the VLAN ID assigned to received untagged packets.
   8132  * Parameters:
   8133  *      unit - StrataSwitch unit number.
   8134  *      port - StrataSwitch port number of port to get info for
   8135  *      vid_ptr - (OUT) Pointer to VLAN ID for return
   8136  * Returns:
   8137  *      BCM_E_NONE
   8138  *      BCM_E_INTERNAL if table read failed.
   8139  */
   8140 
   8141 int
   8142 bcm_esw_port_untagged_vlan_get(int unit, bcm_port_t port, bcm_vlan_t *vid_ptr)
   8143 {
   8144     bcm_port_cfg_t              pcfg;
   8145     int                         vid;
   8146     int                         rv;
   8147 
   8148     /* Make sure port module is initialized. */
   8149     PORT_INIT(unit);
   8150 
   8151     if(bcm_common_oamp_port_enable_get(unit, port)) {
   8152         LOG_ERROR(BSL_LS_BCM_PORT,
   8153                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
   8154                    port));
   8155         return BCM_E_PARAM;
   8156     }
   8157 
   8158 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
   8159      && defined(INCLUDE_L3))
   8160     if (BCM_GPORT_IS_WLAN_PORT(port)) {
   8161 #if defined(BCM_TRIUMPH3_SUPPORT)
   8162         if (SOC_IS_TRIUMPH3(unit)) {
   8163             return bcm_tr3_wlan_port_untagged_vlan_get(unit, port, vid_ptr);
   8164         } else
   8165 #endif /* BCM_TRIUMPH3_SUPPORT */
   8166         {
   8167             return bcm_tr2_wlan_port_untagged_vlan_get(unit, port, vid_ptr);
   8168         }
   8169     }
   8170 #endif
   8171 
   8172 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
   8173     if (BCM_GPORT_IS_NIV_PORT(port)) {
   8174         return bcm_trident_niv_port_untagged_vlan_get(unit, port, vid_ptr);
   8175     }
   8176 #endif
   8177 
   8178 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
   8179     if (BCM_GPORT_IS_EXTENDER_PORT(port)) {
   8180         return bcm_tr3_extender_port_untagged_vlan_get(unit, port, vid_ptr);
   8181     }
   8182 #endif
   8183 
   8184 #ifdef BCM_HGPROXY_COE_SUPPORT
   8185     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   8186         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   8187         rv = _bcm_esw_port_tab_get(unit, port, PORT_VIDf, &vid);
   8188     } else
   8189 #endif
   8190     {
   8191         BCM_IF_ERROR_RETURN(
   8192             _bcm_esw_port_gport_validate(unit, port, &port));
   8193 
   8194         PORT_LOCK(unit);
   8195         rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
   8196         PORT_UNLOCK(unit);
   8197         vid = pcfg.pc_vlan;
   8198     }
   8199 
   8200     if (BCM_SUCCESS(rv)) {
   8201         *vid_ptr = vid;
   8202     } else {
   8203         *vid_ptr = BCM_VLAN_INVALID;
   8204     }
   8205 
   8206     LOG_INFO(BSL_LS_BCM_PORT,
   8207              (BSL_META_U(unit,
   8208                          "bcm_port_untagged_vlan_get: u=%d p=%d vid=%d rv=%d\n"),
   8209               unit, port, *vid_ptr, rv));
   8210 
   8211     return rv;
   8212 }
   8213 
   8214 
   8215 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_SCORPION_SUPPORT)
   8216 /*
   8217  * Function:
   8218  *      _bcm_port_mmu_update
   8219  * Purpose:
   8220  *      Adjust MMU settings depending on port status.
   8221  * Parameters:
   8222  *      unit - StrataSwitch Unit #.
   8223  *      port - StrataSwitch port #.
   8224  *      link -  True if link is active, false if link is inactive.
   8225  * Returns:
   8226  *      BCM_E_NONE
   8227  *      BCM_E_XXX
   8228  */
   8229 
   8230 STATIC int
   8231 _bcm_port_mmu_update(int unit, bcm_port_t port, int link)
   8232 {
   8233     int pause_tx, pause_rx, q_limit_enable, cos;
   8234     uint32 psl_rval, opc_rval, oqc_rval;
   8235 
   8236     if (!SOC_IS_HBX(unit)) {
   8237         return (BCM_E_UNAVAIL);
   8238     }
   8239 
   8240     if (link < 0) {
   8241         SOC_IF_ERROR_RETURN
   8242             (bcm_esw_port_link_status_get(unit, port, &link));
   8243     }
   8244 
   8245     SOC_IF_ERROR_RETURN
   8246         (MAC_PAUSE_GET(PORT(unit, port).p_mac, unit, port,
   8247                        &pause_tx, &pause_rx));
   8248 
   8249     SOC_IF_ERROR_RETURN(READ_PORT_SHARED_LIMITr(unit, port, &psl_rval));
   8250     SOC_IF_ERROR_RETURN(READ_OP_PORT_CONFIGr(unit, port, &opc_rval));
   8251     if (link && pause_tx) {
   8252         soc_reg_field_set(unit, PORT_SHARED_LIMITr, &psl_rval,
   8253                           PORT_SHARED_LIMITf,
   8254                           SOC_IS_SC_CQ(unit) ? 0x5 : 0x3);
   8255         soc_reg_field_set(unit, PORT_SHARED_LIMITr, &psl_rval,
   8256                           PORT_SHARED_DYNAMICf, 1);
   8257         soc_reg_field_set(unit, OP_PORT_CONFIGr, &opc_rval,
   8258                           PORT_LIMIT_ENABLEf, 1);
   8259         q_limit_enable = 0;
   8260     } else {
   8261         /* Turn off */
   8262         soc_reg_field_set(unit, PORT_SHARED_LIMITr, &psl_rval,
   8263                           PORT_SHARED_LIMITf,
   8264                           SOC_IS_SC_CQ(unit) ? 0x3fff : 0x3000);
   8265         soc_reg_field_set(unit, PORT_SHARED_LIMITr, &psl_rval,
   8266                           PORT_SHARED_DYNAMICf, 0);
   8267         soc_reg_field_set(unit, OP_PORT_CONFIGr, &opc_rval,
   8268                           PORT_LIMIT_ENABLEf, 0);
   8269         q_limit_enable = 1;
   8270     }
   8271     SOC_IF_ERROR_RETURN(WRITE_PORT_SHARED_LIMITr(unit, port, psl_rval));
   8272     SOC_IF_ERROR_RETURN(WRITE_OP_PORT_CONFIGr(unit, port, opc_rval));
   8273     for (cos = 0; cos < NUM_COS(unit); cos++) {
   8274         SOC_IF_ERROR_RETURN
   8275             (READ_OP_QUEUE_CONFIGr(unit, port, cos, &oqc_rval));
   8276         soc_reg_field_set(unit, OP_QUEUE_CONFIGr, &oqc_rval,
   8277                           Q_LIMIT_ENABLEf, q_limit_enable);
   8278         SOC_IF_ERROR_RETURN
   8279             (WRITE_OP_QUEUE_CONFIGr(unit, port, cos, oqc_rval));
   8280     }
   8281 
   8282     return (BCM_E_NONE);
   8283 }
   8284 #endif /* BCM_BRADLEY_SUPPORT || BCM_SCORPION_SUPPORT */
   8285 
   8286 /*
   8287  * Function:
   8288  *      _bcm_port_untagged_vlan_set
   8289  * Purpose:
   8290  *      Main part of bcm_port_untagged_vlan_set.
   8291  * Notes:
   8292  *      Port does not have to be a member of the VLAN.
   8293  */
   8294 
   8295 STATIC int
   8296 _bcm_port_untagged_vlan_set(int unit, bcm_port_t port, bcm_vlan_t vid)
   8297 {
   8298     bcm_port_cfg_t      pcfg;
   8299     int                 ut_prio;
   8300 #if defined(BCM_FIREBOLT_SUPPORT)
   8301     bcm_vlan_t          pdvid;
   8302 #endif /* BCM_FIREBOLT_SUPPORT */
   8303 
   8304 #ifdef BCM_TRX_SUPPORT
   8305     if (soc_feature(unit, soc_feature_vlan_action)) {
   8306         bcm_port_t local_port;
   8307         bcm_vlan_action_set_t action;
   8308 #if defined(BCM_TOMAHAWK_SUPPORT)
   8309         bcm_port_cfg_t pcfg;
   8310 #endif
   8311         BCM_IF_ERROR_RETURN(
   8312             _bcm_esw_port_gport_validate(unit, port, &local_port));
   8313 
   8314 #if defined(BCM_TOMAHAWK3_SUPPORT)
   8315 		if (SOC_IS_TOMAHAWK3(unit)) {
   8316              BCM_IF_ERROR_RETURN
   8317                  (_bcm_th3_vlan_port_default_action_get(unit, port, &action));
   8318 		} else 
   8319 #endif
   8320 		{
   8321              BCM_IF_ERROR_RETURN
   8322                  (_bcm_trx_vlan_port_default_action_get(unit, port, &action));
   8323         }
   8324         action.new_outer_vlan = vid;
   8325         action.priority = PORT(unit, local_port).p_ut_prio;
   8326 #if defined(BCM_TOMAHAWK_SUPPORT)
   8327         if (soc_feature(unit, soc_feature_decouple_protocol_vlan)){
   8328             BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, &action));
   8329             BCM_IF_ERROR_RETURN
   8330                 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg));
   8331             pcfg.pc_vlan = action.new_outer_vlan;
   8332             if (action.priority >= BCM_PRIO_MIN &&
   8333                 action.priority <= BCM_PRIO_MAX) {
   8334                 pcfg.pc_new_opri = action.priority;
   8335             }
   8336             return (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg));
   8337         }
   8338 #endif /* BCM_TOMAHAWK2_SUPPORT */
   8339 #if defined(BCM_TOMAHAWK3_SUPPORT) 
   8340 		if(SOC_IS_TOMAHAWK3(unit)) {
   8341 			return _bcm_th3_vlan_port_default_action_set(unit, port, &action);
   8342 		} else 
   8343 #endif
   8344 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
   8345         if (SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
   8346             return _bcm_trx_vlan_port_default_action_profile_set(unit, port, &action);
   8347         } else
   8348 #endif
   8349         {
   8350             return _bcm_trx_vlan_port_default_action_set(unit, port, &action);
   8351         }
   8352     }
   8353 #endif
   8354 
   8355     BCM_IF_ERROR_RETURN
   8356         (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg));
   8357 
   8358 #if defined(BCM_FIREBOLT_SUPPORT)
   8359     pdvid = pcfg.pc_vlan;
   8360 #endif /* BCM_FIREBOLT_SUPPORT */
   8361     pcfg.pc_vlan = vid;
   8362 
   8363     BCM_IF_ERROR_RETURN
   8364         (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg));
   8365 
   8366 #if defined(BCM_FIREBOLT_SUPPORT)
   8367     if (SOC_IS_FBX(unit)) {
   8368         /*
   8369          * Update default VLAN ID in VLAN_PROTOCOL_DATA
   8370          */
   8371         int rv = _bcm_fb_port_untagged_vlan_data_update(unit, port,
   8372                                                         pdvid, vid);
   8373         if (rv != BCM_E_NONE) {
   8374             LOG_ERROR(BSL_LS_BCM_PORT,
   8375                       (BSL_META_U(unit,
   8376                                   "failed updating default VLAN ID "
   8377                                   "in VLAN_PROTOCOL_DATA: %s\n"), bcm_errmsg(rv)));
   8378         }
   8379     }
   8380 #endif /* BCM_FIREBOLT_SUPPORT */
   8381 
   8382     if (!soc_feature(unit, soc_feature_remap_ut_prio)) {
   8383         /* Reset the untagged port priority filter entry, if any */
   8384 
   8385         BCM_IF_ERROR_RETURN
   8386             (bcm_esw_port_untagged_priority_get(unit, port, &ut_prio));
   8387 
   8388         BCM_IF_ERROR_RETURN
   8389             (bcm_esw_port_untagged_priority_set(unit, port, ut_prio));
   8390     }
   8391 
   8392     return BCM_E_NONE;
   8393 }
   8394 
   8395 /*
   8396  * Function:
   8397  *      bcm_port_untagged_vlan_set
   8398  * Purpose:
   8399  *      Set the default VLAN ID for the port.
   8400  *      This is the VLAN ID assigned to received untagged packets.
   8401  * Parameters:
   8402  *      unit - StrataSwitch unit number.
   8403  *      port - StrataSwitch port number.
   8404  *      vid -  VLAN ID used for packets that ingress the port untagged
   8405  * Returns:
   8406  *      BCM_E_NONE
   8407  *      BCM_E_NOT_FOUND if vid not in VTABLE
   8408  *      BCM_E_INTERNAL if table read failed.
   8409  *      BCM_E_CONFIG - port does not belong to the VLAN
   8410  * Notes:
   8411  *      BCM_LOCK is used because bcm_vlan_port_get is called internally
   8412  *      which also takes it.  BCM_LOCK must be taken before PORT_LOCK.
   8413  */
   8414 
   8415 int
   8416 bcm_esw_port_untagged_vlan_set(int unit, bcm_port_t port, bcm_vlan_t vid)
   8417 {
   8418     int rv;
   8419 
   8420     VLAN_CHK_ID(unit, vid);
   8421 
   8422     /* Make sure port module is initialized. */
   8423     PORT_INIT(unit);
   8424 
   8425     if(bcm_common_oamp_port_enable_get(unit, port)) {
   8426         LOG_ERROR(BSL_LS_BCM_PORT,
   8427                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
   8428                    port));
   8429         return BCM_E_PARAM;
   8430     }
   8431 
   8432 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
   8433      && defined(INCLUDE_L3))
   8434     if (BCM_GPORT_IS_WLAN_PORT(port)) {
   8435 #if defined(BCM_TRIUMPH3_SUPPORT)
   8436         if (SOC_IS_TRIUMPH3(unit)) {
   8437             return bcm_tr3_wlan_port_untagged_vlan_set(unit, port, vid);
   8438         } else
   8439 #endif /* BCM_TRIUMPH3_SUPPORT */
   8440         {
   8441             return bcm_tr2_wlan_port_untagged_vlan_set(unit, port, vid);
   8442         }
   8443     }
   8444 #endif
   8445 
   8446 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
   8447     if (BCM_GPORT_IS_NIV_PORT(port)) {
   8448         return bcm_trident_niv_port_untagged_vlan_set(unit, port, vid);
   8449     }
   8450 #endif
   8451 
   8452 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
   8453     if (BCM_GPORT_IS_EXTENDER_PORT(port)) {
   8454         return bcm_tr3_extender_port_untagged_vlan_set(unit, port, vid);
   8455     }
   8456 #endif
   8457 
   8458 #ifdef BCM_HGPROXY_COE_SUPPORT
   8459     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
   8460         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   8461     } else
   8462 #endif
   8463     {
   8464         BCM_IF_ERROR_RETURN(
   8465             _bcm_esw_port_gport_validate(unit, port, &port));
   8466     }
   8467 
   8468     if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TD2P_TT2P(unit) ||
   8469         SOC_IS_TRIDENT3X(unit) ||
   8470         SOC_IS_KATANAX(unit) || SOC_IS_SABER2(unit)) {
   8471         BCM_IF_ERROR_RETURN
   8472         (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
   8473                                                PORT_VIDf, vid));
   8474     }
   8475 
   8476     PORT_LOCK(unit);
   8477     rv = _bcm_port_untagged_vlan_set(unit, port, vid);
   8478     PORT_UNLOCK(unit);
   8479 
   8480     LOG_INFO(BSL_LS_BCM_PORT,
   8481              (BSL_META_U(unit,
   8482                          "bcm_port_untagged_vlan_set: u=%d p=%d vid=%d rv=%d\n"),
   8483               unit, port, vid, rv));
   8484 
   8485     return rv;
   8486 }
   8487 
   8488 /*
   8489  * Function:
   8490  *      _bcm_esw_port_ingress_dest_enable
   8491  * Purpose:
   8492  *      Enables/disables all forwarding to port in the last stage
   8493  *      of the ingress pipeline, including SOBMH and all
   8494  *      other types of traffic.  Works for all egress ports,
   8495  *      including CPU port.
   8496  * Parameters:
   8497  *      unit   - (IN) Device number.
   8498  *      port   - (IN) Port number.
   8499  *      enable - (IN) TRUE, forward traffic
   8500  *                    FALSE, block traffic
   8501  * Returns:
   8502  *      BCM_E_XXX
   8503  */
   8504 int
   8505 _bcm_esw_port_ingress_dest_enable(int unit, bcm_port_t port, int enable)
   8506 {
   8507 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK2_SUPPORT) 
   8508     ing_dest_port_enable_entry_t dest_e;
   8509     bcm_pbmp_t dest_e_pbmp;
   8510     sal_usecs_t delay;
   8511     int speed;
   8512     int change = FALSE;
   8513 
   8514     SOC_IF_ERROR_RETURN
   8515         (READ_ING_DEST_PORT_ENABLEm(unit, MEM_BLOCK_ANY, 0, &dest_e));
   8516 
   8517     soc_mem_pbmp_field_get(unit, ING_DEST_PORT_ENABLEm,
   8518                            &dest_e, PORT_BITMAPf, &dest_e_pbmp);
   8519 
   8520     if (enable) {
   8521         if (!SOC_PBMP_MEMBER(dest_e_pbmp, port)) {
   8522             SOC_PBMP_PORT_ADD(dest_e_pbmp, port);
   8523             change = TRUE;
   8524         }
   8525     } else {
   8526         if (SOC_PBMP_MEMBER(dest_e_pbmp, port)) {
   8527             SOC_PBMP_PORT_REMOVE(dest_e_pbmp, port);
   8528             change = TRUE;
   8529         }
   8530     }
   8531 
   8532     if (change) {
   8533         soc_mem_pbmp_field_set(unit, ING_DEST_PORT_ENABLEm,
   8534                                &dest_e, PORT_BITMAPf, &dest_e_pbmp);
   8535         SOC_IF_ERROR_RETURN
   8536             (WRITE_ING_DEST_PORT_ENABLEm(unit, MEM_BLOCK_ANY, 0, &dest_e));
   8537 
   8538         /*
   8539          * On a disable operation, ensure that no further cells
   8540          * arrive to MMU in order to reconfigure the MMU safely,
   8541          * and the flush mechanism in the MMU to work properly.
   8542          *
   8543          * This requires a delay to ensure packet EOP has arrived at MMU
   8544          * (the is the only method.  The time is based on the largest
   8545          * possible frame at the slowest possible source port speed.
   8546          */
   8547         if (!enable) {
   8548             BCM_IF_ERROR_RETURN
   8549                 (bcm_esw_port_speed_get(unit, port, &speed));
   8550 
   8551             if ((speed == 10) || (speed == 100)) {
   8552                 delay = 8000;  /* 8 msecs */
   8553             } else {
   8554                 /*
   8555                  * This assumes the CPU port can sustain 1GE performance
   8556                  * over the duration of an MTU.
   8557                  */
   8558                 delay = 80;    /* 80 usecs */
   8559             }
   8560             sal_udelay(delay);
   8561         }
   8562     }
   8563 
   8564     return BCM_E_NONE;
   8565 #else  /* BCM_TRIDENT2PLUS_SUPPORT */
   8566     return BCM_E_UNAVAIL;
   8567 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
   8568 }
   8569 
   8570 /*
   8571  * Function:
   8572  *      _bcmi_esw_port_linkphy_subport_dfc_update
   8573  * Purpose:
   8574  *      Updates the DFC for the stream ids associated with Linkphy gport.
   8575  * Parameters:
   8576  *      unit   - (IN) Device number.
   8577  *      subport_gport - (IN) Linkphy gport.
   8578  *      enable - (IN) Port enable/disable status.
   8579  * Returns:
   8580  *      BCM_E_XXX
   8581  */
   8582 
   8583 #ifdef BCM_KATANA2_SUPPORT
   8584 int
   8585 _bcmi_esw_port_linkphy_subport_dfc_update(int unit, bcm_port_t subport_gport,
   8586                                           int enable)
   8587 {
   8588     bcm_subport_config_t config;
   8589     int stream_id = 0;
   8590 
   8591     BCM_IF_ERROR_RETURN(bcm_esw_subport_port_get(unit, subport_gport, &config));
   8592 
   8593     /* Run through the streams and perform needed actions */
   8594     for (stream_id = 0; stream_id < config.num_streams; stream_id++) {
   8595             BCM_IF_ERROR_RETURN(_bcmi_linkphy_subport_stream_dfc_update(unit,
   8596                                    &config,
   8597                                   _BCM_KT2_SUBPORT_PORT_ID_GET(subport_gport),
   8598                                    config.stream_id_array[stream_id], enable));
   8599     }
   8600 
   8601     return BCM_E_NONE;
   8602 }
   8603 
   8604 int
   8605 _bcmi_esw_port_linkphy_subport_flush(int unit, bcm_port_t subport_gport)
   8606 {
   8607     bcm_subport_config_t config;
   8608     int stream_id = 0;
   8609 
   8610     BCM_IF_ERROR_RETURN(bcm_esw_subport_port_get(unit, subport_gport, &config));
   8611 
   8612     /* Run through the streams and perform needed actions */
   8613     for (stream_id = 0; stream_id < config.num_streams; stream_id++) {
   8614             BCM_IF_ERROR_RETURN(_bcmi_linkphy_subport_stream_flush(unit,
   8615                                    &config,
   8616                                   _BCM_KT2_SUBPORT_PORT_ID_GET(subport_gport),
   8617                                    config.stream_id_array[stream_id]));
   8618     }
   8619 
   8620     return BCM_E_NONE;
   8621 }
   8622 #endif
   8623 
   8624 /*
   8625  * Function:
   8626  *      _bcmi_esw_port_subport_enable_set
   8627  * Purpose:
   8628  *      Enable/disable a subport.
   8629  * Parameters:
   8630  *      unit - StrataSwitch unit #.
   8631  *      port - StrataSwitch port #.
   8632  *      is_subtag_port - TRUE if this is subtag port, linkphy otherwise
   8633  *      enable - TRUE, port is enabled, FALSE port is disabled.
   8634  * Returns:
   8635  *      BCM_E_XXX
   8636  */
   8637 int
   8638 _bcmi_esw_port_subport_enable_set(int unit, bcm_port_t port,
   8639                                   int is_subtag_port, int enable)
   8640 {
   8641 
   8642     int rv = BCM_E_NONE;
   8643 
   8644 #ifdef BCM_KATANA2_SUPPORT
   8645     pbmp_t      mask;
   8646     int         subport_gport = port;
   8647 
   8648     BCM_IF_ERROR_RETURN(
   8649         _bcm_esw_port_gport_validate(unit, port, &port));
   8650 
   8651     /* Set/Unset the port in the relevant enabled pbmp */
   8652     if(is_subtag_port) {
   8653 
   8654         /* Check if the setting is already in effect */
   8655         if((enable &&
   8656             BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_subtag_pp_port_pbm,
   8657                                   port)) ||
   8658            (!enable &&
   8659             !(BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_subtag_pp_port_pbm,
   8660                                   port)))) {
   8661             /* Already in effect, return OK */
   8662             return  BCM_E_NONE;
   8663         }
   8664 
   8665         if(enable) {
   8666             BCM_PBMP_PORT_ADD(SOC_INFO(unit).enabled_subtag_pp_port_pbm,
   8667                               port);
   8668         } else {
   8669             BCM_PBMP_PORT_REMOVE(SOC_INFO(unit).enabled_subtag_pp_port_pbm,
   8670                               port);
   8671         }
   8672     } else {
   8673 
   8674         /* Check if the setting is already in effect */
   8675         if((enable &&
   8676             BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_linkphy_pp_port_pbm,
   8677                                   port)) ||
   8678            (!enable &&
   8679             !(BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_linkphy_pp_port_pbm,
   8680                                   port)))) {
   8681             /* Already in effect, return OK */
   8682             return  BCM_E_NONE;
   8683         }
   8684 
   8685         if(enable) {
   8686             BCM_PBMP_PORT_ADD(SOC_INFO(unit).enabled_linkphy_pp_port_pbm,
   8687                               port);
   8688         } else {
   8689             BCM_PBMP_PORT_REMOVE(SOC_INFO(unit).enabled_linkphy_pp_port_pbm,
   8690                               port);
   8691         }
   8692     }
   8693 
   8694     /* Get the current mask */
   8695     soc_link_mask2_get(unit, &mask);
   8696     /* Make a call so that the enable/disable we did above take effect,
   8697      * note that 'soc_link_mask2_set' works on the pbmps we updated above,
   8698      * we still pass the existing bpmp since it gets re-assigned
   8699      */
   8700     SOC_IF_ERROR_RETURN(soc_link_mask2_set(unit, mask));
   8701 
   8702     /* Some special processing needed for enable/disable of LinkPhy ports */
   8703     if (!is_subtag_port) {
   8704 
   8705         /* Updates DFC for the streams */
   8706         BCM_IF_ERROR_RETURN(_bcmi_esw_port_linkphy_subport_dfc_update(unit,
   8707                             subport_gport, enable));
   8708         if (!enable) {
   8709             /* Flush the related MMU queues */
   8710             BCM_IF_ERROR_RETURN(bcm_kt2_cosq_port_flush(unit,
   8711                         port, bcmCosqFlushTypeQueue));
   8712 
   8713             /* Flush the relevant RXLP */
   8714             BCM_IF_ERROR_RETURN(_bcmi_esw_port_linkphy_subport_flush(unit,
   8715                         subport_gport));
   8716         }
   8717     }
   8718 
   8719 #endif
   8720 
   8721     return rv;
   8722 }
   8723 
   8724 /*
   8725  * Function:
   8726  *      _bcmi_esw_port_subport_enable_get
   8727  * Purpose:
   8728  *      Get Enable/disable state of a subport.
   8729  * Parameters:
   8730  *      unit - StrataSwitch unit #.
   8731  *      port - StrataSwitch port #.
   8732  *      is_subtag_port - TRUE if this is subtag port, linkphy otherwise
   8733  *      *enable - Return enable value.
   8734  * Returns:
   8735  *      BCM_E_XXX
   8736  */
   8737 int
   8738 _bcmi_esw_port_subport_enable_get(int unit, bcm_port_t port,
   8739                                   int is_subtag_port, int *enable)
   8740 {
   8741     int rv = BCM_E_NONE;
   8742 
   8743 #ifdef BCM_KATANA2_SUPPORT
   8744     /* Start with enabled set to 0 */
   8745     *enable = 0;
   8746 
   8747     BCM_IF_ERROR_RETURN(
   8748         _bcm_esw_port_gport_validate(unit, port, &port));
   8749 
   8750     /* Depending on subtag/linkphy, check if the port is enabled */
   8751     if(is_subtag_port) {
   8752         if (BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_subtag_pp_port_pbm,
   8753                         port)) {
   8754             *enable = 1;
   8755         }
   8756     } else {
   8757         if (BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_linkphy_pp_port_pbm,
   8758                         port)) {
   8759             *enable = 1;
   8760         }
   8761     }
   8762     rv = BCM_E_NONE;
   8763 #endif
   8764 
   8765     return rv;
   8766 }
   8767 
   8768 /*
   8769  * Function:
   8770  *      bcm_port_enable_set
   8771  * Purpose:
   8772  *      Physically enable/disable the MAC/PHY on this port.
   8773  * Parameters:
   8774  *      unit - StrataSwitch unit #.
   8775  *      port - StrataSwitch port #.
   8776  *      enable - TRUE, port is enabled, FALSE port is disabled.
   8777  * Returns:
   8778  *      BCM_E_XXX
   8779  * Notes:
   8780  *      If linkscan is running, it also controls the MAC enable state.
   8781  */
   8782 
   8783 int
   8784 bcm_esw_port_enable_set(int unit, bcm_port_t port, int enable)
   8785 {
   8786     int         rv = BCM_E_NONE;
   8787     int         link, loopback = BCM_PORT_LOOPBACK_NONE;
   8788     pbmp_t      mask;
   8789 
   8790 #if defined (BCM_TRIUMPH3_SUPPORT) || defined (BCM_MONTEREY_SUPPPORT)
   8791     int         skip_phy_en = 0;
   8792 #endif /* BCM_TRIUMPH3_SUPPORT */
   8793     soc_persist_t       *sop = SOC_PERSIST(unit);
   8794 
   8795 #if defined(BCM_KATANA2_SUPPORT)
   8796     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
   8797     uint8 is_subtag_port = FALSE, is_linkphy_port = FALSE;
   8798 #endif
   8799     /* Make sure port module is initialized. */
   8800     PORT_INIT(unit);
   8801 
   8802 #ifdef BCM_KATANA2_SUPPORT
   8803     if(BCM_GPORT_IS_SUBPORT_PORT(port)) {
   8804         if (soc_feature(unit, soc_feature_subtag_coe) &&
   8805             _BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   8806            is_subtag_port = TRUE;
   8807        } else if (soc_feature(unit, soc_feature_linkphy_coe) &&
   8808                   _BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port)) {
   8809            is_linkphy_port = TRUE;
   8810        }
   8811        if(is_subtag_port || is_linkphy_port) {
   8812            PORT_LOCK(unit);
   8813            rv = _bcmi_esw_port_subport_enable_set(unit, port,
   8814                                                   is_subtag_port, enable);
   8815            PORT_UNLOCK(unit);
   8816            return rv;
   8817         }
   8818     }
   8819 #endif
   8820 
   8821     /* Call Port Control module */
   8822     if (SOC_USE_PORTCTRL(unit)) {
   8823         return (bcmi_esw_portctrl_enable_set(unit, port, enable));
   8824     }
   8825 
   8826     if(bcm_common_oamp_port_enable_get(unit, port)) {
   8827         LOG_ERROR(BSL_LS_BCM_PORT,
   8828                   (BSL_META("Error: Cannot enable OAMP Port %d.\n"),
   8829                    port));
   8830         return BCM_E_PARAM;
   8831     }
   8832 
   8833 #if defined(BCM_KATANA2_SUPPORT)
   8834 #if defined(BCM_SABER2_SUPPORT)
   8835     if(SOC_IS_SABER2(unit)) {
   8836         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
   8837     }
   8838 #endif
   8839     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
   8840         (!((port >= 1) && (port <= max_phy_port)))) {
   8841          return BCM_E_PORT;
   8842     }
   8843 #endif
   8844 
   8845     if (!BCM_GPORT_IS_SET(port)) {  
   8846         if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit),port)) {  
   8847             return BCM_E_PORT;  
   8848         }  
   8849     } 
   8850 
   8851     BCM_IF_ERROR_RETURN(
   8852         _bcm_esw_port_gport_validate(unit, port, &port));
   8853 
   8854 #ifdef BCM_RCPU_SUPPORT
   8855     if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
   8856         return BCM_E_PORT;
   8857     }
   8858 #endif /* BCM_RCPU_SUPPORT */
   8859 
   8860 #ifdef BCM_TRIUMPH3_SUPPORT
   8861     if (SOC_IS_TRIUMPH3(unit) && !enable) {
   8862         _bcm_esw_ibod_syn_port_down(unit, port);
   8863     }
   8864 #endif /* BCM_TRIUMPH3_SUPPORT */
   8865 
   8866     PORT_LOCK(unit);
   8867 
   8868     bcm_esw_port_loopback_get(unit, port, &loopback);
   8869 
   8870     if (enable) {
   8871         if (SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port)) {
   8872             PORT_UNLOCK(unit);
   8873             return BCM_E_NONE;
   8874         }
   8875 
   8876 #ifdef BCM_TRIUMPH3_SUPPORT
   8877         if (!skip_phy_en) {
   8878 #endif /* BCM_TRIUMPH3_SUPPORT */
   8879 #ifdef BCM_TRIDENT2_SUPPORT
   8880             /*
   8881              * When the PHY is TSC and port is configured to MAC loopback,
   8882              * need to unsquelch TX LANE.
   8883              */
   8884             if ((SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit))
   8885                 && (loopback == BCM_PORT_LOOPBACK_MAC)) {
   8886                 (void)soc_phyctrl_notify(unit, port, phyEventTxSquelch, FALSE);
   8887             }
   8888 #endif /* BCM_TRIDENT2_SUPPORT */
   8889             rv = soc_phyctrl_enable_set(unit, port, TRUE);
   8890 #ifdef BCM_TRIUMPH3_SUPPORT
   8891         }
   8892 #endif /* BCM_TRIUMPH3_SUPPORT */
   8893         if (SOC_SUCCESS(rv)) {
   8894             /* Get link status after PHY state has been set */
   8895             rv = bcm_esw_port_link_status_get(unit, port, &link);
   8896             if (BCM_FAILURE(rv)) {
   8897                 if (rv == BCM_E_INIT) {
   8898                     link = FALSE;
   8899                     rv = BCM_E_NONE;
   8900                 } else {
   8901                     PORT_UNLOCK(unit);
   8902                     return rv;
   8903                 }
   8904             }
   8905 
   8906             if (link || (loopback != BCM_PORT_LOOPBACK_NONE)
   8907                 || SOC_PBMP_MEMBER(sop->lc_pbm_fc, port)
   8908                 || SOC_PBMP_MEMBER(sop->lc_pbm_linkdown_tx, port)) {
   8909                 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, TRUE);
   8910                 if (loopback == BCM_PORT_LOOPBACK_MAC) {
   8911                     /* Add port to EPC_LINK */
   8912                     soc_link_mask2_get(unit, &mask);
   8913                     SOC_PBMP_PORT_ADD(mask, port);
   8914                     rv = soc_link_mask2_set(unit, mask);
   8915                     if (BCM_FAILURE(rv)) {
   8916                         PORT_UNLOCK(unit);
   8917                         return (rv);
   8918                     }
   8919                 }              
   8920             }
   8921         }
   8922 
   8923         if (SOC_SUCCESS(rv)) {
   8924             /* Enable forwarding traffic */
   8925             if (soc_feature(unit, soc_feature_ingress_dest_port_enable)) {
   8926                 rv = _bcm_esw_port_ingress_dest_enable(unit, port, enable);
   8927                 if (BCM_FAILURE(rv)) {
   8928                     PORT_UNLOCK(unit);
   8929                     return rv;
   8930                 }
   8931             }
   8932         }
   8933 
   8934     } else {
   8935 
   8936         /* Disable all forwarding traffic */
   8937         if (soc_feature(unit, soc_feature_ingress_dest_port_enable)) {
   8938             rv = _bcm_esw_port_ingress_dest_enable(unit, port, enable);
   8939             if (BCM_FAILURE(rv)) {
   8940                 PORT_UNLOCK(unit);
   8941                 return rv;
   8942             }
   8943         }
   8944 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT)
   8945     if (soc_feature(unit, soc_feature_epc_linkflap_recover)) {
   8946         bcm_port_info_t tmp_port_info;
   8947         bcm_port_info_t_init(&tmp_port_info);
   8948         tmp_port_info.linkstatus = BCM_PORT_LINK_STATUS_DOWN;
   8949         SOC_LINKSCAN_MODPORT_MAP_LOCK(unit);
   8950         rv = _bcm_td_stk_modport_map_linkscan_handler(unit, port,
   8951                                                       &tmp_port_info);
   8952         SOC_LINKSCAN_MODPORT_MAP_UNLOCK(unit);
   8953         if (BCM_FAILURE(rv)) {
   8954             PORT_UNLOCK(unit);
   8955             return (rv);
   8956         }
   8957     }
   8958 #endif /* #(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT) */
   8959         /* Remove from EPC_LINK to prevent packet queued to this port from TX */
   8960         soc_link_mask2_get(unit, &mask);
   8961         SOC_PBMP_PORT_REMOVE(mask, port);
   8962         rv = soc_link_mask2_set(unit, mask);
   8963         if (BCM_FAILURE(rv)) {
   8964             PORT_UNLOCK(unit);
   8965             return (rv);
   8966         }
   8967         LOG_VERBOSE(BSL_LS_BCM_PORT,
   8968                     (BSL_META_U(unit,
   8969                                 "Disable and isolate port %d..\n"),
   8970                      port));
   8971         if ((!SOC_IS_TD2_TT2(unit) && (loopback != BCM_PORT_LOOPBACK_MAC)) ||
   8972             (SOC_IS_TOMAHAWKX(unit) && (loopback != BCM_PORT_LOOPBACK_MAC))) {
   8973             /* Disable MAC RX to prevent traffic going into this port */
   8974             MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
   8975                             SOC_MAC_CONTROL_RX_SET, FALSE);
   8976             sal_udelay(100); /* Wait for 1 jumbo packet transmission time */
   8977         }
   8978 
   8979 #ifdef BCM_KATANA_SUPPORT
   8980         if (SOC_IS_KATANA(unit)) {
   8981             /*
   8982              * When the port is configured to MAC loopback,
   8983              * can't disabling MAC.
   8984              * But in Saber2, credits are released when MAC goes down.
   8985              */
   8986             if (SOC_IS_SABER2(unit) || (loopback != BCM_PORT_LOOPBACK_MAC)) {
   8987                 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, FALSE);
   8988             }
   8989             if ((SOC_SUCCESS(rv))) {
   8990                 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
   8991                                 SOC_MAC_CONTROL_DISABLE_PHY, TRUE);
   8992                 rv = soc_phyctrl_enable_set(unit, port, FALSE);
   8993                 if (BCM_FAILURE(rv)) {
   8994                     LOG_WARN(BSL_LS_BCM_PORT,
   8995                              (BSL_META_U(unit,
   8996                                          "u=%d p=%d soc_phyctrl_enable_set rv=%d\n"),
   8997                               unit, port, rv));
   8998                 }
   8999                 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
   9000                                 SOC_MAC_CONTROL_DISABLE_PHY, FALSE);
   9001             }
   9002         } else
   9003 #endif /* BCM_KATANA_SUPPORT */
   9004         {
   9005             MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
   9006                             SOC_MAC_CONTROL_DISABLE_PHY, TRUE);
   9007 
   9008 #ifdef BCM_TRIDENT2_SUPPORT
   9009             /*
   9010              * When the PHY is TSC and port is configured to MAC loopback,
   9011              * need to squelch the TX lane instead of disabling PHY.
   9012              */
   9013             if ((SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit))
   9014                 && (loopback == BCM_PORT_LOOPBACK_MAC)) {
   9015                 (void)soc_phyctrl_notify(unit, port, phyEventTxSquelch, TRUE);
   9016             } else
   9017 #endif /* BCM_TRIDENT2_SUPPORT */
   9018             {
   9019                 rv = soc_phyctrl_enable_set(unit, port, FALSE);
   9020             }
   9021 
   9022             MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
   9023                             SOC_MAC_CONTROL_DISABLE_PHY, FALSE);
   9024             /*
   9025              * When the port is configured to MAC loopback,
   9026              * can't disabling MAC.
   9027              */
   9028             if (SOC_IS_SABER2(unit) || (loopback != BCM_PORT_LOOPBACK_MAC)) {
   9029                 if (SOC_SUCCESS(rv)) {
   9030                     rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, FALSE);
   9031                 }
   9032             }
   9033         }
   9034     }
   9035 
   9036 #ifdef BCM_SABER2_SUPPORT
   9037     if (SOC_IS_SABER2(unit)) {
   9038         rv = soc_saber2_port_enable_set(unit, port, enable);
   9039         if (BCM_FAILURE(rv)) {
   9040             LOG_WARN(BSL_LS_BCM_PORT,
   9041                      (BSL_META_U(unit,
   9042                                  "u=%d p=%d soc_saber2_port_enable_set rv=%d\n"),
   9043                       unit, port, rv));
   9044         }
   9045     } else
   9046 #endif
   9047 #ifdef BCM_KATANA2_SUPPORT
   9048     if (SOC_IS_KATANA2(unit)) {
   9049         rv = soc_katana2_port_enable_set(unit, port, enable);
   9050         if (BCM_FAILURE(rv)) {
   9051             LOG_WARN(BSL_LS_BCM_PORT,
   9052                      (BSL_META_U(unit,
   9053                                  "u=%d p=%d soc_katana2_port_enable_set rv=%d\n"),
   9054                       unit, port, rv));
   9055         }
   9056     }
   9057 #endif
   9058 #ifdef BCM_TRIDENT2_SUPPORT
   9059     if (SOC_IS_TD2_TT2(unit)) {
   9060         PORT(unit, port).enable = enable;
   9061     }
   9062 #endif /* BCM_TRIDENT2_SUPPORT */
   9063 
   9064 #ifdef SW_AUTONEG_SUPPORT
   9065     rv = _bcm_esw_port_notify_link_down_evt(unit, port);
   9066             if (BCM_FAILURE(rv)) {
   9067                 LOG_WARN(BSL_LS_BCM_PORT,
   9068                          (BSL_META_U(unit,
   9069                              "u=%d p=%d NOTIFY LINK DOWN EVT rv=%d\n"),
   9070                           unit, port, rv));
   9071                 PORT_UNLOCK(unit);
   9072                 return rv;
   9073             }
   9074 #endif    
   9075          
   9076     PORT_UNLOCK(unit);
   9077 
   9078     if (loopback != BCM_PORT_LOOPBACK_NONE) {
   9079         if (loopback == BCM_PORT_LOOPBACK_MAC) {
   9080             rv = _bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, TRUE);
   9081         } else {
   9082             rv = _bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, enable);
   9083         }
   9084     }
   9085     LOG_INFO(BSL_LS_BCM_PORT,
   9086              (BSL_META_U(unit,
   9087                          "bcm_port_enable_set: u=%d p=%d enable=%d rv=%d\n"),
   9088               unit, port, enable, rv));
   9089 
   9090 #ifdef BCM_WARM_BOOT_SUPPORT
   9091     SOC_CONTROL_LOCK(unit);
   9092     SOC_CONTROL(unit)->scache_dirty = 1;
   9093     SOC_CONTROL_UNLOCK(unit);
   9094 #endif
   9095 
   9096     return rv;
   9097 }
   9098 
   9099 /*
   9100  * Function:
   9101  *      bcm_port_enable_get
   9102  * Purpose:
   9103  *      Gets the enable state as defined by bcm_port_enable_set()
   9104  * Parameters:
   9105  *      unit - StrataSwitch unit #.
   9106  *      port - StrataSwitch port #.
   9107  *      enable - (OUT) TRUE, port is enabled, FALSE port is disabled.
   9108  * Returns:
   9109  *      BCM_E_XXX
   9110  * Notes:
   9111  *      The PHY enable holds the port enable state set by the user.
   9112  *      The MAC enable transitions up and down automatically via linkscan
   9113  *      even if user port enable is always up.
   9114  */
   9115 
   9116 int
   9117 bcm_esw_port_enable_get(int unit, bcm_port_t port, int *enable)
   9118 {
   9119     int                 rv=BCM_E_NONE;
   9120 #if defined(BCM_KATANA2_SUPPORT)
   9121     uint8       is_subtag_port = FALSE, is_linkphy_port = FALSE;
   9122     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
   9123 #endif
   9124 
   9125     /* Make sure port module is initialized. */
   9126     PORT_INIT(unit);
   9127 
   9128     /* Check for PortMod */
   9129     if (SOC_USE_PORTCTRL(unit)) {
   9130         return bcmi_esw_portctrl_enable_get(unit, port, enable);
   9131     }
   9132     
   9133     if(bcm_common_oamp_port_enable_get(unit, port)) {
   9134         LOG_ERROR(BSL_LS_BCM_PORT,
   9135                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
   9136                    port));
   9137         return BCM_E_PARAM;
   9138     }
   9139 
   9140 #if defined(BCM_KATANA2_SUPPORT)
   9141 #if defined(BCM_SABER2_SUPPORT)
   9142     if(SOC_IS_SABER2(unit)) {
   9143         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
   9144     }
   9145 #endif
   9146     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
   9147         (!((port >= 1) && (port <= max_phy_port)))) {
   9148          return BCM_E_PORT;
   9149     }
   9150 #endif
   9151 
   9152 
   9153 #ifdef BCM_KATANA2_SUPPORT
   9154     if(BCM_GPORT_IS_SUBPORT_PORT(port)) {
   9155         if (soc_feature(unit, soc_feature_subtag_coe) &&
   9156            _BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
   9157            is_subtag_port = TRUE;
   9158        } else if (soc_feature(unit, soc_feature_linkphy_coe) &&
   9159            _BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port)) {
   9160            is_linkphy_port = TRUE;
   9161        }
   9162 
   9163        if (is_subtag_port || is_linkphy_port) {
   9164             return _bcmi_esw_port_subport_enable_get(unit, port,
   9165                                                      is_subtag_port, enable);
   9166        }
   9167     }
   9168 #endif
   9169 
   9170     BCM_IF_ERROR_RETURN(
   9171         _bcm_esw_port_gport_validate(unit, port, &port));
   9172 
   9173     if (SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port)) {
   9174         *enable = 0;
   9175         return BCM_E_NONE;
   9176     }
   9177 
   9178     PORT_LOCK(unit);
   9179     rv = soc_phyctrl_enable_get(unit, port, enable);
   9180 #ifdef BCM_TRIDENT2_SUPPORT
   9181     if (SOC_IS_TD2_TT2(unit)) {
   9182         *enable = (PORT(unit, port).enable) & (*enable);
   9183     }
   9184 #endif /* BCM_TRIDENT2_SUPPORT */
   9185 
   9186     PORT_UNLOCK(unit);
   9187 
   9188     LOG_INFO(BSL_LS_BCM_PORT,
   9189              (BSL_META_U(unit,
   9190                          "bcm_port_enable_get: u=%d p=%d rv=%d enable=%d\n"),
   9191               unit, port, rv, *enable));
   9192 
   9193     return rv;
   9194 }
   9195 
   9196 /*
   9197  * Function:
   9198  *      _bcm_port_mode_setup
   9199  * Purpose:
   9200  *      Set initial operating mode for a port.
   9201  * Parameters:
   9202  *      unit - StrataSwitch unit #.
   9203  *      port - StrataSwitch port #.
   9204  *      enable - Whether to enable or disable
   9205  * Returns:
   9206  *      BCM_E_XXX
   9207  * Notes:
   9208  *      Must be called with PORT_LOCK held.
   9209  */
   9210 
   9211 int
   9212 _bcm_port_mode_setup(int unit, bcm_port_t port, int enable)
   9213 {
   9214     soc_port_if_t       pif;
   9215     bcm_port_ability_t  local_pa, advert_pa;
   9216 
   9217     if (SOC_USE_PORTCTRL(unit)) {
   9218         return (bcmi_esw_portctrl_mode_setup(unit, port, enable));
   9219     }
   9220 
   9221     sal_memset(&local_pa,  0, sizeof(bcm_port_ability_t));
   9222     sal_memset(&advert_pa, 0, sizeof(bcm_port_ability_t));
   9223 
   9224     LOG_INFO(BSL_LS_BCM_PORT,
   9225              (BSL_META_U(unit,
   9226                          "_bcm_port_mode_setup: u=%d p=%d\n"), unit, port));
   9227 
   9228     SOC_IF_ERROR_RETURN(bcm_esw_port_ability_local_get(unit, port, &local_pa));
   9229 
   9230     if (IS_TDM_PORT(unit, port)) {
   9231         return BCM_E_NONE;
   9232     }
   9233 
   9234     /* If MII supported, enable it, otherwise use TBI */
   9235     if (local_pa.interface & (SOC_PA_INTF_MII | SOC_PA_INTF_GMII |
   9236                               SOC_PA_INTF_SGMII | SOC_PA_INTF_XGMII)) {
   9237         if (IS_GE_PORT(unit, port)) {
   9238             pif = SOC_PORT_IF_GMII;
   9239         } else if (IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port)) {
   9240             if (local_pa.interface & SOC_PA_INTF_XGMII) {
   9241                 pif = SOC_PORT_IF_XGMII;
   9242             } else { /*  external GbE phy in xe port mode */
   9243                 pif = SOC_PORT_IF_SGMII;
   9244             }
   9245         } else {
   9246             pif = SOC_PORT_IF_MII;
   9247         }
   9248     } else if (local_pa.interface & SOC_PA_INTF_CGMII) {
   9249         pif = SOC_PORT_IF_CGMII;
   9250     } else {
   9251         pif = SOC_PORT_IF_TBI;
   9252     }
   9253 
   9254     SOC_IF_ERROR_RETURN
   9255         (soc_phyctrl_interface_set(unit, port, pif));
   9256     SOC_IF_ERROR_RETURN
   9257         (MAC_INTERFACE_SET(PORT(unit, port).p_mac, unit, port, pif));
   9258 
   9259     if (IS_ST_PORT(unit, port)) {
   9260 
   9261         /* Since stacking port doesn't support flow control,
   9262          * make sure that PHY is not advertising flow control capabilities.
   9263          */
   9264         SOC_IF_ERROR_RETURN(
   9265             soc_phyctrl_ability_advert_get(unit, port, &advert_pa));
   9266         advert_pa.pause &= ~(SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM);
   9267         SOC_IF_ERROR_RETURN(
   9268             soc_phyctrl_ability_advert_set(unit, port, &advert_pa));
   9269     }
   9270 
   9271     if (!SOC_WARM_BOOT(unit) &&
   9272         !(SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port)) ) {
   9273 #ifdef BCM_RCPU_SUPPORT
   9274         if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
   9275             /* Do not enable/disable rcpu port. */
   9276             return BCM_E_NONE;
   9277         }
   9278 #endif /* BCM_RCPU_SUPPORT */
   9279         SOC_IF_ERROR_RETURN
   9280             (MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, enable));
   9281     }
   9282 
   9283     return BCM_E_NONE;
   9284 }
   9285 
   9286 STATIC int
   9287 _bcm_esw_port_e2ecc_hdr_set(int unit, int port, soc_higig_e2ecc_hdr_t *e2ecc_hdr)
   9288 {
   9289     uint64 rval64;
   9290 
   9291     if (SOC_USE_PORTCTRL(unit)) {
   9292         return bcmi_esw_portctrl_e2ecc_hdr_set(unit, port, e2ecc_hdr);
   9293     }
   9294 
   9295     if (!e2ecc_hdr) {
   9296         return BCM_E_PARAM;
   9297     }
   9298 
   9299     if (SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) || 
   9300         SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
   9301         if (IS_CL_PORT(unit, port)) {
   9302             COMPILER_64_ZERO(rval64);
   9303             soc_reg64_field32_set(unit, CLMAC_E2ECC_MODULE_HDR_0r, &rval64,
   9304                                   E2ECC_MODULE_HDR_0_HIf, e2ecc_hdr->overlay1.words[0]);
   9305             soc_reg64_field32_set(unit, CLMAC_E2ECC_MODULE_HDR_0r, &rval64,
   9306                                   E2ECC_MODULE_HDR_0_LOf, e2ecc_hdr->overlay1.words[1]);
   9307             BCM_IF_ERROR_RETURN(soc_reg_set(unit, CLMAC_E2ECC_MODULE_HDR_0r,
   9308                                             port, 0, rval64));
   9309     
   9310             COMPILER_64_ZERO(rval64);
   9311             soc_reg64_field32_set(unit, CLMAC_E2ECC_MODULE_HDR_1r, &rval64,
   9312                                   E2ECC_MODULE_HDR_1_HIf, e2ecc_hdr->overlay1.words[2]);
   9313             soc_reg64_field32_set(unit, CLMAC_E2ECC_MODULE_HDR_1r, &rval64,
   9314                                   E2ECC_MODULE_HDR_1_LOf, e2ecc_hdr->overlay1.words[3]);
   9315             BCM_IF_ERROR_RETURN(soc_reg_set(unit, CLMAC_E2ECC_MODULE_HDR_1r,
   9316                                             port, 0, rval64));
   9317     
   9318             COMPILER_64_ZERO(rval64);
   9319             soc_reg64_field32_set(unit, CLMAC_E2ECC_DATA_HDR_0r, &rval64,
   9320                                   E2ECC_DATA_HDR_0_HIf, e2ecc_hdr->overlay1.words[4]);
   9321             soc_reg64_field32_set(unit, CLMAC_E2ECC_DATA_HDR_0r, &rval64,
   9322                                   E2ECC_DATA_HDR_0_LOf, e2ecc_hdr->overlay1.words[5]);
   9323             BCM_IF_ERROR_RETURN(soc_reg_set(unit, CLMAC_E2ECC_DATA_HDR_0r,
   9324                                             port, 0, rval64));
   9325     
   9326             COMPILER_64_ZERO(rval64);
   9327             soc_reg64_field32_set(unit, CLMAC_E2ECC_DATA_HDR_1r, &rval64,
   9328                                   E2ECC_DATA_HDR_1_HIf, e2ecc_hdr->overlay1.words[6]);
   9329             soc_reg64_field32_set(unit, CLMAC_E2ECC_DATA_HDR_1r, &rval64,
   9330                                   E2ECC_DATA_HDR_1_LOf, e2ecc_hdr->overlay1.words[7]);
   9331             BCM_IF_ERROR_RETURN(soc_reg_set(unit, CLMAC_E2ECC_DATA_HDR_1r,
   9332                                             port, 0, rval64));
   9333         } else {
   9334         COMPILER_64_ZERO(rval64);
   9335         soc_reg64_field32_set(unit, XLMAC_E2ECC_MODULE_HDR_0r, &rval64,
   9336                               E2ECC_MODULE_HDR_0_HIf, e2ecc_hdr->overlay1.words[0]);
   9337         soc_reg64_field32_set(unit, XLMAC_E2ECC_MODULE_HDR_0r, &rval64,
   9338                               E2ECC_MODULE_HDR_0_LOf, e2ecc_hdr->overlay1.words[1]);
   9339         BCM_IF_ERROR_RETURN(soc_reg_set(unit, XLMAC_E2ECC_MODULE_HDR_0r,
   9340                                         port, 0, rval64));
   9341 
   9342         COMPILER_64_ZERO(rval64);
   9343         soc_reg64_field32_set(unit, XLMAC_E2ECC_MODULE_HDR_1r, &rval64,
   9344                               E2ECC_MODULE_HDR_1_HIf, e2ecc_hdr->overlay1.words[2]);
   9345         soc_reg64_field32_set(unit, XLMAC_E2ECC_MODULE_HDR_1r, &rval64,
   9346                               E2ECC_MODULE_HDR_1_LOf, e2ecc_hdr->overlay1.words[3]);
   9347         BCM_IF_ERROR_RETURN(soc_reg_set(unit, XLMAC_E2ECC_MODULE_HDR_1r,
   9348                                         port, 0, rval64));
   9349 
   9350         COMPILER_64_ZERO(rval64);
   9351         soc_reg64_field32_set(unit, XLMAC_E2ECC_DATA_HDR_0r, &rval64,
   9352                               E2ECC_DATA_HDR_0_HIf, e2ecc_hdr->overlay1.words[4]);
   9353         soc_reg64_field32_set(unit, XLMAC_E2ECC_DATA_HDR_0r, &rval64,
   9354                               E2ECC_DATA_HDR_0_LOf, e2ecc_hdr->overlay1.words[5]);
   9355         BCM_IF_ERROR_RETURN(soc_reg_set(unit, XLMAC_E2ECC_DATA_HDR_0r,
   9356                                         port, 0, rval64));
   9357 
   9358         COMPILER_64_ZERO(rval64);
   9359         soc_reg64_field32_set(unit, XLMAC_E2ECC_DATA_HDR_1r, &rval64,
   9360                               E2ECC_DATA_HDR_1_HIf, e2ecc_hdr->overlay1.words[6]);
   9361         soc_reg64_field32_set(unit, XLMAC_E2ECC_DATA_HDR_1r, &rval64,
   9362                               E2ECC_DATA_HDR_1_LOf, e2ecc_hdr->overlay1.words[7]);
   9363         BCM_IF_ERROR_RETURN(soc_reg_set(unit, XLMAC_E2ECC_DATA_HDR_1r,
   9364                                         port, 0, rval64));
   9365         }
   9366     } else {
   9367         SOC_IF_ERROR_RETURN
   9368             (WRITE_XHOL_MH0r(unit, port, e2ecc_hdr->overlay1.words[0]));
   9369         SOC_IF_ERROR_RETURN
   9370             (WRITE_XHOL_MH1r(unit, port, e2ecc_hdr->overlay1.words[1]));
   9371         SOC_IF_ERROR_RETURN
   9372             (WRITE_XHOL_MH2r(unit, port, e2ecc_hdr->overlay1.words[2]));
   9373         SOC_IF_ERROR_RETURN
   9374             (WRITE_XHOL_MH3r(unit, port, e2ecc_hdr->overlay1.words[3]));
   9375 
   9376         SOC_IF_ERROR_RETURN
   9377             (WRITE_XHOL_D0r(unit, port, e2ecc_hdr->overlay1.words[4]));
   9378         SOC_IF_ERROR_RETURN
   9379             (WRITE_XHOL_D1r(unit, port, e2ecc_hdr->overlay1.words[5]));
   9380         SOC_IF_ERROR_RETURN
   9381             (WRITE_XHOL_D2r(unit, port, e2ecc_hdr->overlay1.words[6]));
   9382         SOC_IF_ERROR_RETURN
   9383             (WRITE_XHOL_D3r(unit, port, e2ecc_hdr->overlay1.words[7]));
   9384     }
   9385 
   9386     return BCM_E_NONE;
   9387 }
   9388 
   9389 #ifdef BCM_WARM_BOOT_SUPPORT
   9390 #if defined(BCM_TRX_SUPPORT)
   9391 STATIC int
   9392 _bcm_esw_port_e2ecc_hdr_get(int unit, int port, soc_higig_e2ecc_hdr_t *e2ecc_hdr)
   9393 {
   9394     uint64 rval64;
   9395 
   9396     if (SOC_USE_PORTCTRL(unit)) {
   9397         return bcmi_esw_portctrl_e2ecc_hdr_get(unit, port, e2ecc_hdr);
   9398     }
   9399 
   9400     if (!e2ecc_hdr) {
   9401         return BCM_E_PARAM;
   9402     }
   9403 
   9404     sal_memset(e2ecc_hdr, 0, sizeof(soc_higig_e2ecc_hdr_t));
   9405 
   9406     if (SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) ||
   9407         SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
   9408         if (IS_CL_PORT(unit, port)) {
   9409             BCM_IF_ERROR_RETURN(soc_reg_get(unit, CLMAC_E2ECC_MODULE_HDR_0r,
   9410                                             port, 0, &rval64));
   9411             e2ecc_hdr->overlay1.words[0] = soc_reg64_field32_get(unit,
   9412                 CLMAC_E2ECC_MODULE_HDR_0r, rval64, E2ECC_MODULE_HDR_0_HIf);
   9413             e2ecc_hdr->overlay1.words[1] = soc_reg64_field32_get(unit,
   9414                 CLMAC_E2ECC_MODULE_HDR_0r, rval64, E2ECC_MODULE_HDR_0_LOf);
   9415     
   9416             BCM_IF_ERROR_RETURN(soc_reg_get(unit, CLMAC_E2ECC_MODULE_HDR_1r,
   9417                                             port, 0, &rval64));
   9418             e2ecc_hdr->overlay1.words[2] = soc_reg64_field32_get(unit,
   9419                 CLMAC_E2ECC_MODULE_HDR_1r, rval64, E2ECC_MODULE_HDR_1_HIf);
   9420             e2ecc_hdr->overlay1.words[3] = soc_reg64_field32_get(unit,
   9421                 CLMAC_E2ECC_MODULE_HDR_1r, rval64, E2ECC_MODULE_HDR_1_LOf);
   9422 
   9423             BCM_IF_ERROR_RETURN(soc_reg_get(unit, CLMAC_E2ECC_DATA_HDR_0r,
   9424                                             port, 0, &rval64));
   9425             e2ecc_hdr->overlay1.words[4] = soc_reg64_field32_get(unit,
   9426                 CLMAC_E2ECC_DATA_HDR_0r, rval64, E2ECC_DATA_HDR_0_HIf);
   9427             e2ecc_hdr->overlay1.words[5] = soc_reg64_field32_get(unit,
   9428                 CLMAC_E2ECC_DATA_HDR_0r, rval64, E2ECC_DATA_HDR_0_LOf);
   9429 
   9430             BCM_IF_ERROR_RETURN(soc_reg_get(unit, CLMAC_E2ECC_DATA_HDR_1r,
   9431                                             port, 0, &rval64));
   9432             e2ecc_hdr->overlay1.words[6] = soc_reg64_field32_get(unit,
   9433                 CLMAC_E2ECC_DATA_HDR_1r, rval64, E2ECC_DATA_HDR_1_HIf);
   9434             e2ecc_hdr->overlay1.words[7] = soc_reg64_field32_get(unit,
   9435                 CLMAC_E2ECC_DATA_HDR_1r, rval64, E2ECC_DATA_HDR_1_LOf);
   9436         } else {
   9437         BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_E2ECC_MODULE_HDR_0r,
   9438                                         port, 0, &rval64));
   9439         e2ecc_hdr->overlay1.words[0] = soc_reg64_field32_get(unit,
   9440             XLMAC_E2ECC_MODULE_HDR_0r, rval64, E2ECC_MODULE_HDR_0_HIf);
   9441         e2ecc_hdr->overlay1.words[1] = soc_reg64_field32_get(unit,
   9442             XLMAC_E2ECC_MODULE_HDR_0r, rval64, E2ECC_MODULE_HDR_0_LOf);
   9443 
   9444         BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_E2ECC_MODULE_HDR_1r,
   9445                                         port, 0, &rval64));
   9446         e2ecc_hdr->overlay1.words[2] = soc_reg64_field32_get(unit,
   9447             XLMAC_E2ECC_MODULE_HDR_1r, rval64, E2ECC_MODULE_HDR_1_HIf);
   9448         e2ecc_hdr->overlay1.words[3] = soc_reg64_field32_get(unit,
   9449             XLMAC_E2ECC_MODULE_HDR_1r, rval64, E2ECC_MODULE_HDR_1_LOf);
   9450 
   9451         BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_E2ECC_DATA_HDR_0r,
   9452                                         port, 0, &rval64));
   9453         e2ecc_hdr->overlay1.words[4] = soc_reg64_field32_get(unit,
   9454             XLMAC_E2ECC_DATA_HDR_0r, rval64, E2ECC_DATA_HDR_0_HIf);
   9455         e2ecc_hdr->overlay1.words[5] = soc_reg64_field32_get(unit,
   9456             XLMAC_E2ECC_DATA_HDR_0r, rval64, E2ECC_DATA_HDR_0_LOf);
   9457 
   9458         BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_E2ECC_DATA_HDR_1r,
   9459                                         port, 0, &rval64));
   9460         e2ecc_hdr->overlay1.words[6] = soc_reg64_field32_get(unit,
   9461             XLMAC_E2ECC_DATA_HDR_1r, rval64, E2ECC_DATA_HDR_1_HIf);
   9462         e2ecc_hdr->overlay1.words[7] = soc_reg64_field32_get(unit,
   9463             XLMAC_E2ECC_DATA_HDR_1r, rval64, E2ECC_DATA_HDR_1_LOf);
   9464         }
   9465     } else {
   9466         SOC_IF_ERROR_RETURN
   9467             (READ_XHOL_MH0r(unit, port, &e2ecc_hdr->overlay1.words[0]));
   9468         SOC_IF_ERROR_RETURN
   9469             (READ_XHOL_MH1r(unit, port, &e2ecc_hdr->overlay1.words[1]));
   9470         SOC_IF_ERROR_RETURN
   9471             (READ_XHOL_MH2r(unit, port, &e2ecc_hdr->overlay1.words[2]));
   9472         SOC_IF_ERROR_RETURN
   9473             (READ_XHOL_MH3r(unit, port, &e2ecc_hdr->overlay1.words[3]));
   9474 
   9475         SOC_IF_ERROR_RETURN
   9476             (READ_XHOL_D0r(unit, port, &e2ecc_hdr->overlay1.words[4]));
   9477         SOC_IF_ERROR_RETURN
   9478             (READ_XHOL_D1r(unit, port, &e2ecc_hdr->overlay1.words[5]));
   9479         SOC_IF_ERROR_RETURN
   9480             (READ_XHOL_D2r(unit, port, &e2ecc_hdr->overlay1.words[6]));
   9481         SOC_IF_ERROR_RETURN
   9482             (READ_XHOL_D3r(unit, port, &e2ecc_hdr->overlay1.words[7]));
   9483     }
   9484 
   9485     return BCM_E_NONE;
   9486 }
   9487 #endif
   9488 #endif /* BCM_WARM_BOOT_SUPPORT */
   9489 
   9490 #ifdef BCM_WARM_BOOT_SUPPORT
   9491 
   9492 STATIC int
   9493 _bcm_port_vd_pbvl_reinit(int unit)
   9494 {
   9495 
   9496 #if defined(BCM_TRX_SUPPORT)
   9497     if (SOC_IS_TRX(unit)) {
   9498         /*
   9499          * Reinit of vd_pbvl takes place at the end of function
   9500          * _bcm_trx_vlan_action_profile_init().  This routine initializes
   9501          * the VLAN profile tables first, which need to happen before
   9502          * the vd_pbvl data is recovered.
   9503          */
   9504         return BCM_E_NONE;
   9505     }
   9506 #endif /* BCM_TRX_SUPPORT */
   9507 
   9508 #ifdef BCM_FIREBOLT_SUPPORT
   9509     if (SOC_IS_FBX(unit)) {
   9510         bcm_port_t port;
   9511         _bcm_port_info_t *pinfo;
   9512         int        idxmin, idx, i, index;
   9513         int start, end;
   9514         vlan_protocol_data_entry_t   vde;
   9515         vlan_protocol_entry_t vpe;
   9516         bcm_vlan_t            cvid, defvid;
   9517         uint32                ft;
   9518         bcm_pbmp_t            all_pbmp;
   9519 
   9520         BCM_PBMP_CLEAR(all_pbmp);
   9521         BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
   9522 
   9523 #ifdef BCM_KATANA2_SUPPORT
   9524         if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
   9525             BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
   9526         }
   9527         if (soc_feature(unit, soc_feature_linkphy_coe) ||
   9528             soc_feature(unit, soc_feature_subtag_coe)) {
   9529             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
   9530         }
   9531 #endif
   9532 
   9533         idxmin = soc_mem_index_min(unit, VLAN_PROTOCOL_DATAm);
   9534         idx = soc_mem_index_min(unit, VLAN_PROTOCOLm);
   9535         PBMP_ITER(all_pbmp, port) {
   9536 
   9537             start = idxmin + port*16;
   9538             end   = start + 16;
   9539             BCM_IF_ERROR_RETURN
   9540                 (bcm_esw_port_untagged_vlan_get(unit, port, &defvid));
   9541             for (i = start; i < end; i++) {
   9542 
   9543                 SOC_IF_ERROR_RETURN
   9544                     (READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY,
   9545                                               i, &vde));
   9546                 cvid = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde,
   9547                                                            VLAN_IDf);
   9548                 if ((cvid == 0) || (cvid == defvid)) {
   9549                     
   9550                     continue;
   9551                 }
   9552 
   9553                 /*
   9554                  * Check against the VLAN_PROTOCOL table to see if a
   9555                  * valid entry exists for matching the packet protocol
   9556                  */
   9557                 index = i - start;
   9558                 SOC_IF_ERROR_RETURN
   9559                     (READ_VLAN_PROTOCOLm(unit, MEM_BLOCK_ANY,
   9560                                          idx+index, &vpe));
   9561                 ft = 0;
   9562                 if (soc_VLAN_PROTOCOLm_field32_get(unit, &vpe, ETHERIIf)) {
   9563                     ft |= BCM_PORT_FRAMETYPE_ETHER2;
   9564                 }
   9565                 if (soc_VLAN_PROTOCOLm_field32_get(unit, &vpe, SNAPf)) {
   9566                     ft |= BCM_PORT_FRAMETYPE_8023;
   9567                 }
   9568                 if (soc_VLAN_PROTOCOLm_field32_get(unit, &vpe, LLCf)) {
   9569                     ft |= BCM_PORT_FRAMETYPE_LLC;
   9570                 }
   9571                 if (ft == 0) {
   9572                     /*
   9573                      * Something wrong here.. bail out
   9574                      */
   9575                     continue;
   9576                 }
   9577                 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
   9578                 if (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, idx+index)) {
   9579                     /* Set as explicit VID */
   9580                     _BCM_PORT_VD_PBVL_SET(pinfo, idx+index);
   9581                 }
   9582             }
   9583         }
   9584         return BCM_E_NONE;
   9585     }
   9586 #endif /* BCM_FIREBOLT_SUPPORT */
   9587 
   9588     return BCM_E_NONE;
   9589 }
   9590 
   9591 #if defined(BCM_TRX_SUPPORT)
   9592 /* Recover the port dtag_mode from Warm Boot cached info, if available. */
   9593 STATIC int
   9594 _bcm_trx_port_dtag_mode_reinit(int unit, bcm_pbmp_t dtm_pbmp, int use_pbmp)
   9595 {
   9596     uint32   tpid_enable;
   9597     bcm_port_t port;
   9598     _bcm_port_info_t *pinfo;
   9599     bcm_vlan_action_set_t action;
   9600     bcm_pbmp_t all_pbmp;
   9601 
   9602     BCM_PBMP_CLEAR(all_pbmp);
   9603     BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
   9604     sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t));
   9605 
   9606 #ifdef BCM_KATANA2_SUPPORT
   9607     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
   9608         BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
   9609     }
   9610     if (soc_feature(unit, soc_feature_linkphy_coe) ||
   9611         soc_feature(unit, soc_feature_subtag_coe)) {
   9612         _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
   9613     }
   9614 #endif
   9615 
   9616 #if defined(BCM_SABER2_SUPPORT)
   9617     if(SOC_IS_SABER2(unit)){
   9618         int oamp_enable;
   9619         (void)bcm_sb2_sat_oamp_enable_get(unit, &oamp_enable);
   9620         /* Skip OAMP port for saber2 device */
   9621         if(oamp_enable) {
   9622             SOC_PBMP_PORT_REMOVE(all_pbmp,
   9623                     _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER);
   9624         }
   9625     }
   9626 #endif
   9627 
   9628     PBMP_ITER(all_pbmp, port) {
   9629         BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
   9630         BCM_IF_ERROR_RETURN
   9631             (_bcm_esw_port_tab_get(unit, port, OUTER_TPID_ENABLEf, (int *)&tpid_enable));
   9632 
   9633         if (0 == tpid_enable) {
   9634             if (use_pbmp && !BCM_PBMP_MEMBER(dtm_pbmp, port)) {
   9635                 /* Bitmap claims this is DT mode NONE, but it is
   9636                  * configured for EXTERNAL */
   9637                 BCM_IF_ERROR_RETURN
   9638                     (soc_event_generate(unit,
   9639                                         BCM_SWITCH_EVENT_STABLE_ERROR,
   9640                                         SOC_STABLE_STALE,
   9641                                         SOC_STABLE_BASIC, 0));
   9642                 use_pbmp = FALSE; /* Cached info is not trustworthy */
   9643             } else {
   9644                 pinfo->dtag_mode = BCM_PORT_DTAG_MODE_EXTERNAL;
   9645             }
   9646         } else {
   9647             if (use_pbmp && BCM_PBMP_MEMBER(dtm_pbmp, port)) {
   9648                 pinfo->dtag_mode = BCM_PORT_DTAG_MODE_INTERNAL;
   9649             } else {
   9650                 pinfo->dtag_mode = BCM_PORT_DTAG_MODE_NONE;
   9651             }
   9652         }
   9653 
   9654         if (!SOC_IS_SHADOW(unit) && !SOC_IS_TOMAHAWK3(unit)) {
   9655             if (soc_feature(unit, soc_feature_vlan_action)) {
   9656                 BCM_IF_ERROR_RETURN
   9657                     (_bcm_trx_vlan_port_default_action_get(unit, port, &action));
   9658             
   9659 
   9660                 if (bcmVlanActionAdd == action.ut_inner) {
   9661                     pinfo->dtag_mode |= BCM_PORT_DTAG_ADD_EXTERNAL_TAG;
   9662                 }
   9663 
   9664             
   9665                 BCM_IF_ERROR_RETURN
   9666                     (_bcm_trx_vlan_port_egress_default_action_get(unit, port,
   9667                                                                   &action));
   9668                 if ((bcmVlanActionDelete == action.dt_inner) &&
   9669                     (bcmVlanActionDelete == action.dt_inner_prio)) {
   9670                     pinfo->dtag_mode |= BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG;
   9671                 }
   9672             }
   9673         }
   9674     }
   9675     return BCM_E_NONE;
   9676 }
   9677 
   9678 /**
   9679  * Function:
   9680  *      _bcm_esw_hcfc_ingress_enable_check();
   9681  * Purpose:
   9682  *      check HCFC ingress enable status of unit. If any port ingress enable, enable =1;
   9683  *
   9684  * Parameters:
   9685  *      unit     - (IN)device number 
   9686  *      enable - (OUT) hcfc ingress enable 
   9687  *
   9688  * Returns:
   9689  *      BCM_E_xxx
   9690  * Notes:
   9691  */
   9692 STATIC int
   9693 _bcm_esw_hcfc_ingress_enable_check(int unit, int *enable)
   9694 {
   9695     soc_reg_t reg0, reg1;
   9696     uint64 rval64, fval64;
   9697 
   9698     if (SOC_REG_IS_VALID(unit, OOBFC_ING_PORT_EN0_64r)) {
   9699         reg0 = OOBFC_ING_PORT_EN0_64r;
   9700         reg1 = OOBFC_ING_PORT_EN1_64r;
   9701     } else {
   9702         reg0 = OOBFC_ING_PORT_EN_0_64r;
   9703         reg1 = OOBFC_ING_PORT_EN_1_64r;
   9704     }
   9705 
   9706     if (!(SOC_REG_IS_VALID(unit, reg0) && SOC_REG_IS_VALID(unit, reg1))) {
   9707         *enable = 0;
   9708         return BCM_E_NONE;
   9709     }
   9710 
   9711     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg0, REG_PORT_ANY, 0, &rval64));
   9712     fval64 = soc_reg64_field_get(unit, reg0, rval64, ING_PORT_ENf);
   9713     if(0 != fval64) {       
   9714         *enable = 1;
   9715         return BCM_E_NONE;
   9716     }
   9717     else {
   9718         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg1, REG_PORT_ANY, 0, &rval64));
   9719         fval64 = soc_reg64_field_get(unit, reg1, rval64, ING_PORT_ENf);
   9720         if(0 != fval64) {       
   9721             *enable = 1;
   9722             return BCM_E_NONE;
   9723         }
   9724     }
   9725 
   9726     return BCM_E_NONE;
   9727 }
   9728 
   9729 /**
   9730  * Function:
   9731  *      _bcm_esw_hcfc_egress_enable_check();
   9732  * Purpose:
   9733  *      check HCFC ingress enable status of unit. If any port egress enable, enable =1;
   9734  *
   9735  * Parameters:
   9736  *      unit     - (IN)device number 
   9737  *      enable - (OUT) hcfc egress enable
   9738  *
   9739  * Returns:
   9740  *      BCM_E_xxx
   9741  * Notes:
   9742  */
   9743 STATIC int
   9744 _bcm_esw_hcfc_egress_enable_check(int unit, int *enable)
   9745 {
   9746     soc_reg_t reg0, reg1;
   9747     uint64 rval64, fval64;
   9748 
   9749     if (SOC_REG_IS_VALID(unit, OOBFC_ENG_PORT_EN0_64r)) {
   9750         reg0 = OOBFC_ENG_PORT_EN0_64r;
   9751         reg1 = OOBFC_ENG_PORT_EN1_64r;
   9752     } else {
   9753         reg0 = OOBFC_ENG_PORT_EN_0_64r;
   9754         reg1 = OOBFC_ENG_PORT_EN_1_64r;
   9755     }
   9756 
   9757     if (!(SOC_REG_IS_VALID(unit, reg0) && SOC_REG_IS_VALID(unit, reg1))) {
   9758        *enable = 0;
   9759        return BCM_E_NONE;
   9760     }
   9761 
   9762     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg0, REG_PORT_ANY, 0, &rval64));
   9763     fval64 = soc_reg64_field_get(unit, reg0, rval64, ENG_PORT_ENf);
   9764     if(0 != fval64) {       
   9765         *enable = 1;
   9766         return BCM_E_NONE;
   9767     }
   9768     else {
   9769         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg1, REG_PORT_ANY, 0, &rval64));
   9770         fval64 = soc_reg64_field_get(unit, reg1, rval64, ENG_PORT_ENf);
   9771         if(0 != fval64) {       
   9772             *enable = 1;
   9773             return BCM_E_NONE;
   9774         }
   9775     }
   9776 
   9777     return BCM_E_NONE;
   9778 }
   9779 
   9780 /**
   9781  * Function:
   9782  *      _bcm_esw_port_hcfc_ingress_enable_check();
   9783  * Purpose:
   9784  *     check HCFC ingress enable status of given port. 
   9785  *
   9786  * Parameters:
   9787  *      unit     - (IN)device number
   9788  *      port     - (IN)port number 
   9789  *      enable - (OUT)hcfc ingress enable  
   9790  *
   9791  * Returns:
   9792  *      BCM_E_xxx
   9793  * Notes:
   9794  */
   9795 STATIC int
   9796 _bcm_esw_port_hcfc_ingress_enable_check(int unit, bcm_port_t port, int *enable)
   9797 {
   9798     soc_reg_t reg, reg0, reg1;
   9799     int len;
   9800     uint64 rval64, fval64;
   9801     uint32 fval_hi, fval_lo;
   9802 
   9803     if (!SOC_PORT_VALID(unit, port)) {
   9804         return BCM_E_PORT;
   9805     }
   9806 
   9807     if (SOC_REG_IS_VALID(unit, OOBFC_ING_PORT_EN0_64r)) {
   9808         reg0 = OOBFC_ING_PORT_EN0_64r;
   9809         reg1 = OOBFC_ING_PORT_EN1_64r;
   9810     } else {
   9811         reg0 = OOBFC_ING_PORT_EN_0_64r;
   9812         reg1 = OOBFC_ING_PORT_EN_1_64r;
   9813     }
   9814     if (!(SOC_REG_IS_VALID(unit, reg0)) || !(SOC_REG_IS_VALID(unit, reg1))) {
   9815         *enable = 0;
   9816         return BCM_E_NONE;
   9817     }
   9818 
   9819     /* Configure ingress status reporting */
   9820     len = soc_reg_field_length(unit, reg0, ING_PORT_ENf);
   9821     if (len < 1) {
   9822         return BCM_E_PORT;
   9823     }
   9824     if (port < len) { /* First half of logical ports (not mmu port) */
   9825         reg = reg0;
   9826     } else {          /* Second half of logical ports (not mmu port) */
   9827         reg = reg1;
   9828     }
   9829     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64));
   9830     fval64 = soc_reg64_field_get(unit, reg, rval64, ING_PORT_ENf);
   9831     fval_hi = COMPILER_64_HI(fval64);
   9832     fval_lo = COMPILER_64_LO(fval64);
   9833 
   9834     if (port < len) {
   9835         if ( port < 32 ) {
   9836             *enable = fval_lo & (1 << port);
   9837         } else {
   9838             /* coverity[large_shift : FALSE] */
   9839             *enable = fval_hi & (1 << (port - 32));
   9840         }
   9841     } else {
   9842         int port_offset = port - len;
   9843         if ( port_offset < 32 ) {
   9844             *enable = fval_lo & (1 << port_offset);
   9845         } else {
   9846             *enable = fval_hi & (1 << (port_offset - 32));
   9847         }
   9848     }
   9849 
   9850     return BCM_E_NONE;
   9851 }
   9852 
   9853 /**
   9854  * Function:
   9855  *      _bcm_esw_port_hcfc_egress_enable_check();
   9856  * Purpose:
   9857  *      check HCFC egress enable status of given port. 
   9858  *
   9859  * Parameters:
   9860  *      unit     - (IN)device number
   9861  *      port     - (IN)port number 
   9862  *      enable - (OUT)hcfc egress enable  
   9863  *
   9864  * Returns:
   9865  *      BCM_E_xxx
   9866  * Notes:
   9867  */
   9868 STATIC int
   9869 _bcm_esw_port_hcfc_egress_enable_check(int unit, bcm_port_t port, int *enable)
   9870 {
   9871     soc_reg_t reg, reg0, reg1;
   9872     int len;
   9873     uint64 rval64, fval64;
   9874     uint32 fval_hi, fval_lo;
   9875 
   9876     if (!SOC_PORT_VALID(unit, port)) {
   9877         return BCM_E_PORT;
   9878     }
   9879 
   9880     if (SOC_REG_IS_VALID(unit, OOBFC_ENG_PORT_EN0_64r)) {
   9881         reg0 = OOBFC_ENG_PORT_EN0_64r;
   9882         reg1 = OOBFC_ENG_PORT_EN1_64r;
   9883     } else {
   9884         reg0 = OOBFC_ENG_PORT_EN_0_64r;
   9885         reg1 = OOBFC_ENG_PORT_EN_1_64r;
   9886     }
   9887     if (!(SOC_REG_IS_VALID(unit, reg0)) || !(SOC_REG_IS_VALID(unit, reg1))) {
   9888         *enable = 0;
   9889         return BCM_E_NONE;
   9890     }
   9891 
   9892     /* Configure egress status reporting */
   9893     len = soc_reg_field_length(unit, reg0, ENG_PORT_ENf);
   9894     if (len < 1) {
   9895         return BCM_E_PORT;
   9896     }
   9897     if (port < len) { /* First half of logical ports (not mmu port) */
   9898         reg = reg0;
   9899     } else {          /* Second half of logical ports (not mmu port) */
   9900         reg = reg1;
   9901     }
   9902     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64));
   9903     fval64 = soc_reg64_field_get(unit, reg, rval64, ENG_PORT_ENf);
   9904     fval_hi = COMPILER_64_HI(fval64);
   9905     fval_lo = COMPILER_64_LO(fval64);
   9906     if (port < len) {
   9907         if ( port < 32 ) {
   9908             *enable = fval_lo & (1 << port);
   9909         } else {
   9910             /* coverity[large_shift : FALSE] */
   9911             *enable = fval_hi & (1 << (port - 32));
   9912         }
   9913     } else {
   9914         int port_offset = port - len;
   9915         if ( port_offset < 32 ) {
   9916             *enable = fval_lo & (1 << port_offset);
   9917         } else {
   9918             *enable = fval_hi & (1 << (port_offset - 32));
   9919         }
   9920     }
   9921 
   9922     return BCM_E_NONE;
   9923 }
   9924 
   9925 
   9926 STATIC int
   9927 _bcm_esw_port_e2ecc_reinit(int unit)
   9928 {
   9929     bcm_port_t port, phy_port;
   9930     bcm_port_congestion_config_t *config;
   9931     int    time_unit_sel = 0, time_units = 0;
   9932     soc_higig_e2ecc_hdr_t e2ecc_hdr;
   9933     int    src_modid, src_pid;
   9934     uint64 regval64;
   9935     uint32 regval, field_val = 0;
   9936     int tx_enabled = FALSE, rx_enabled = FALSE;
   9937     int port_tx_enabled, port_rx_enabled, voqfc = 0;
   9938     int hcfc_tx = 0, hcfc_rx = 0;
   9939     int port_hcfc_tx = 0, port_hcfc_rx = 0;
   9940     int blk, blk_num = -1, bindex = 0;
   9941 #ifdef  BCM_KATANA2_SUPPORT
   9942     uint16      dev_id;
   9943     uint8       rev_id;
   9944     int e2ecc_coe = 0;
   9945     int e2ecc_strict = 0;
   9946 #endif
   9947 #ifdef  BCM_TRIDENT2PLUS_SUPPORT
   9948     int fc_format;
   9949     int copy_to_cpu = 0 ;
   9950 #endif 
   9951     if (SOC_IS_SC_CQ(unit)) {
   9952         SOC_IF_ERROR_RETURN(READ_E2E_HOL_ENr(unit, &regval));
   9953         if (0 != soc_reg_field_get(unit, E2E_HOL_ENr, regval, ENf)) {
   9954             tx_enabled = TRUE;
   9955         }
   9956     } else {
   9957         SOC_IF_ERROR_RETURN(READ_E2ECC_HOL_ENr(unit, &regval));
   9958         if (0 != soc_reg_field_get(unit, E2ECC_HOL_ENr, regval, ENf)) {
   9959             tx_enabled = TRUE;
   9960         }
   9961     }
   9962 
   9963     BCM_IF_ERROR_RETURN(_bcm_esw_hcfc_egress_enable_check(unit, &hcfc_tx));
   9964     if (hcfc_tx) {
   9965         tx_enabled = TRUE;
   9966     } 
   9967 
   9968     SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, &regval64));
   9969     if (0 == soc_reg64_field32_get(unit, ING_CONFIG_64r, regval64,
   9970                               DISABLE_E2E_HOL_CHECKf)) {
   9971         rx_enabled = TRUE;
   9972     }
   9973 
   9974     BCM_IF_ERROR_RETURN(_bcm_esw_hcfc_ingress_enable_check(unit, &hcfc_rx));
   9975     if (hcfc_rx) {
   9976         rx_enabled = TRUE;
   9977     }
   9978 
   9979     if (!tx_enabled && !rx_enabled) {
   9980         /* Nothing further to do */
   9981         return BCM_E_NONE;
   9982     }
   9983 
   9984     PBMP_HG_ITER(unit, port) {
   9985         port_tx_enabled = port_rx_enabled = FALSE;
   9986 
   9987         if (tx_enabled) {
   9988             if (hcfc_tx) {
   9989                 port_hcfc_tx = 0;
   9990                 BCM_IF_ERROR_RETURN(_bcm_esw_port_hcfc_egress_enable_check(unit, port, &port_hcfc_tx));
   9991                 if (port_hcfc_tx) {
   9992                     port_tx_enabled = 1;              
   9993                 }
   9994             }
   9995             else {
   9996                 if (soc_reg_field_valid(unit, XPORT_CONFIGr, E2E_HOL_ENf)) {
   9997                     SOC_IF_ERROR_RETURN(READ_XPORT_CONFIGr(unit, port, &regval));
   9998                     port_tx_enabled =
   9999                         (0 != soc_reg_field_get(unit, XPORT_CONFIGr, regval,
  10000                                                 E2E_HOL_ENf));
  10001                 } else {
  10002                     if (soc_feature(unit, soc_feature_logical_port_num)) {
  10003                         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  10004                     } else {
  10005                         phy_port = port;
  10006                     }
  10007                     blk = SOC_PORT_BLOCK(unit, phy_port);
  10008 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
  10009                    if (SOC_IS_TRIDENT2X(unit)) {
  10010                        blk_num = SOC_INFO(unit).port_serdes[port];
  10011                    } else
  10012 #endif 
  10013                    { 
  10014                     blk_num = SOC_BLOCK_INFO(unit, blk).number;
  10015                    }
  10016                     bindex = SOC_PORT_BINDEX(unit, phy_port);
  10017                     /* In TR3 E2ECC is implemented only in blocks CL, XL1 */
  10018                     if (!SOC_IS_TRIUMPH3(unit) || (IS_CL_PORT(unit, port) || (blk == 13))) {
  10019                         if (SOC_IS_TRIUMPH3(unit)) {
  10020                             if (IS_CL_PORT(unit, port)) {
  10021                                 blk_num = (blk_num ?  4 + bindex/4 : bindex/4);
  10022                                 bindex = bindex%4;
  10023                             } else {
  10024                                 blk_num = 3;
  10025                             }
  10026                         }
  10027                         if (SOC_IS_KATANA2(unit)) {
  10028                         /* In KT2 E2ECC is implemented only in blocks 6..9 */
  10029                             if (blk_num >= 6) {
  10030                                 blk_num -= 6;
  10031                             }
  10032                         }
  10033                         SOC_IF_ERROR_RETURN(READ_E2ECC_TX_ENABLE_BMPr(unit, blk_num,
  10034                                                                       &regval));
  10035                         if ((regval & (1 << bindex))) {
  10036                             port_tx_enabled= TRUE;
  10037                         }
  10038                     }
  10039                 }
  10040             }
  10041         }
  10042 
  10043         if (rx_enabled) { 
  10044             if (hcfc_rx) {
  10045                 port_hcfc_rx = 0;
  10046                 BCM_IF_ERROR_RETURN(_bcm_esw_port_hcfc_ingress_enable_check(unit, port, &port_hcfc_rx));
  10047                 if (port_hcfc_rx) {
  10048                     port_rx_enabled = 1;              
  10049                 }
  10050             }
  10051             else {
  10052                 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &regval));
  10053                 port_rx_enabled = 0;
  10054                 voqfc = 0;            
  10055                 if (0 != soc_reg_field_get(unit, IE2E_CONTROLr, regval, HOL_ENABLEf)) {
  10056                     port_rx_enabled = 1;
  10057                 }
  10058 
  10059                 if (soc_reg_field_valid(unit, IE2E_CONTROLr, VOQFC_ENABLEf)) {
  10060                     if (0 != soc_reg_field_get(unit, IE2E_CONTROLr,
  10061                                                regval, VOQFC_ENABLEf)) {
  10062                         port_rx_enabled = 1;
  10063                         voqfc = 1;
  10064                     }
  10065                 }  
  10066             }
  10067         }
  10068 
  10069         /* For HX4 and TR3, tx restore from OP_QUEUE_CONFIG1_CELLr */
  10070         if (SOC_IS_TRIUMPH3(unit)) {
  10071             BCM_IF_ERROR_RETURN(READ_OP_QUEUE_CONFIG1_CELLr(unit, port, 0, &regval));
  10072             port_tx_enabled = soc_reg_field_get(unit,OP_QUEUE_CONFIG1_CELLr, regval, Q_E2E_DS_EN_CELLf);
  10073         }
  10074 
  10075         if (!port_tx_enabled && !port_rx_enabled) {
  10076             /* On to the next port */
  10077             continue;
  10078         }
  10079 
  10080         /* Allocate space for the E2ECC configuration */
  10081         if (PORT(unit, port).e2ecc_config == NULL) {
  10082             PORT(unit, port).e2ecc_config =
  10083                 sal_alloc(sizeof(bcm_port_congestion_config_t),
  10084                           "bcm_port_congestion_config");
  10085             if (PORT(unit, port).e2ecc_config == NULL) {
  10086                 LOG_ERROR(BSL_LS_BCM_PORT,
  10087                           (BSL_META_U(unit,
  10088                                       "Error: unable to allocate memory for"
  10089                                       " bcm_port_congestion_config.\n")));
  10090                 return BCM_E_MEMORY;
  10091             }
  10092         } else {
  10093             /* This is initialized to NULL pointers by
  10094              * port init.  How did it get changed? */
  10095             return BCM_E_INTERNAL;
  10096         }
  10097 
  10098         config = PORT(unit, port).e2ecc_config;
  10099         bcm_port_congestion_config_t_init(config);
  10100 
  10101         if (port_tx_enabled) {
  10102             if (port_hcfc_tx) {
  10103                 config->flags |= BCM_PORT_CONGESTION_CONFIG_HCFC|
  10104                    BCM_PORT_CONGESTION_CONFIG_TX;
  10105             } else {
  10106                 /* Recover TX state */
  10107                 config->flags |= BCM_PORT_CONGESTION_CONFIG_E2ECC |
  10108                     BCM_PORT_CONGESTION_CONFIG_TX;
  10109 
  10110                 /* Message timer paramters to packets/sec */
  10111                 if (SOC_IS_SC_CQ(unit)) {
  10112                     SOC_IF_ERROR_RETURN(READ_E2E_MAX_TX_TIMERr(unit, &regval));
  10113                     time_unit_sel = soc_reg_field_get(unit, E2E_MAX_TX_TIMERr,
  10114                                                       regval, LGf);
  10115                     time_units = soc_reg_field_get(unit, E2E_MAX_TX_TIMERr,
  10116                                                    regval, TIMERf);
  10117                 } else {
  10118                     SOC_IF_ERROR_RETURN(READ_E2ECC_MAX_TX_TIMERr(unit, &regval));
  10119                     time_unit_sel = soc_reg_field_get(unit, E2ECC_MAX_TX_TIMERr,
  10120                                                       regval, LGf);
  10121                     time_units = soc_reg_field_get(unit, E2ECC_MAX_TX_TIMERr,
  10122                                                    regval, TIMERf);
  10123                     SOC_IF_ERROR_RETURN(WRITE_E2ECC_MAX_TX_TIMERr(unit, regval));
  10124                 }
  10125 
  10126                 /* See _bcm_esw_port_e2ecc_tx for an explanation of
  10127                  * the timer calculation. */
  10128                 config->packets_per_sec = time_unit_sel ?
  10129                     (40000 / time_units) : (4000000 / time_units);
  10130 
  10131                 /* Recover the E2ECC module header
  10132                  * (see _bcm_esw_port_e2ecc_tx for the header format) */
  10133                 BCM_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_hdr_get(unit, port, &e2ecc_hdr));
  10134 
  10135                 config->traffic_class =
  10136                     (e2ecc_hdr.overlay1.words[0] >> 16) & 0x0F;
  10137                 config->multicast_id  = e2ecc_hdr.overlay1.words[0] & 0xFFFF;
  10138 
  10139                 src_modid = (e2ecc_hdr.overlay1.words[1] >> 24) & 0xFF;
  10140                 src_pid = (e2ecc_hdr.overlay1.words[1] >> 16) & 0xFF;
  10141                 BCM_GPORT_MODPORT_SET(config->src_port, src_modid, src_pid);
  10142 
  10143                 config->color = (e2ecc_hdr.overlay1.words[1] >> 6) & 0x3;
  10144 
  10145                 config->pri = (e2ecc_hdr.overlay1.words[3] >> 29) & 0x7;
  10146                 config->cfi = (e2ecc_hdr.overlay1.words[3] >> 28) & 0x1;
  10147                 config->vlan = (e2ecc_hdr.overlay1.words[3] >> 16) & 0xfff;
  10148 
  10149                 config->dest_mac[0] =
  10150                     ((e2ecc_hdr.overlay1.words[4] >> 24) & 0xff);
  10151                 config->dest_mac[1] =
  10152                     ((e2ecc_hdr.overlay1.words[4] >> 16) & 0xff);
  10153                 config->dest_mac[2] =
  10154                     ((e2ecc_hdr.overlay1.words[4] >> 8) & 0xff);
  10155                 config->dest_mac[3] =
  10156                     (e2ecc_hdr.overlay1.words[4] & 0xff);
  10157                 config->dest_mac[4] =
  10158                     ((e2ecc_hdr.overlay1.words[5] >> 24) & 0xff);
  10159                 config->dest_mac[5] =
  10160                     ((e2ecc_hdr.overlay1.words[5] >> 16) & 0xff);
  10161 
  10162                 config->src_mac[0] =
  10163                     ((e2ecc_hdr.overlay1.words[5] >> 8) & 0xff);
  10164                 config->src_mac[1] =
  10165                     (e2ecc_hdr.overlay1.words[5] & 0xff);
  10166                 config->src_mac[2] =
  10167                     ((e2ecc_hdr.overlay1.words[6] >> 24) & 0xff);
  10168                 config->src_mac[3] =
  10169                     ((e2ecc_hdr.overlay1.words[6] >> 16) & 0xff);
  10170                 config->src_mac[4] =
  10171                     ((e2ecc_hdr.overlay1.words[6] >> 8) & 0xff);
  10172                 config->src_mac[5] =
  10173                     (e2ecc_hdr.overlay1.words[6] & 0xff);
  10174 
  10175                 config->ethertype =
  10176                     (e2ecc_hdr.overlay1.words[7] >> 16) & 0xFFFF;
  10177                 config->opcode = e2ecc_hdr.overlay1.words[7] & 0xFFFF;
  10178 
  10179                 /* All the info from RX is encoded in the header, so
  10180                  * just mark if it is enabled. */
  10181                 if (port_rx_enabled) {
  10182                     config->flags |= BCM_PORT_CONGESTION_CONFIG_RX;
  10183                 }
  10184             }
  10185         } else if (port_rx_enabled) {
  10186             /* Recover RX state */
  10187             config->flags |= BCM_PORT_CONGESTION_CONFIG_RX;
  10188 
  10189             if (port_hcfc_rx) {
  10190                 config->flags |= BCM_PORT_CONGESTION_CONFIG_HCFC;
  10191             } else if (voqfc) {
  10192                 config->flags |= BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL;
  10193                 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_MSr(unit, &regval));
  10194                 field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_MSr,
  10195                                               regval, DAf);
  10196                 config->dest_mac[0] = ((field_val >> 8) & 0xff);
  10197                 config->dest_mac[1] = (field_val & 0xff);
  10198 
  10199                 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_LSr(unit, &regval));
  10200                 field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_LSr,
  10201                                               regval, DAf);
  10202                 config->dest_mac[2] = ((field_val >> 24) & 0xff);
  10203                 config->dest_mac[3] = ((field_val >> 16) & 0xff);
  10204                 config->dest_mac[4] = ((field_val >> 8) & 0xff);
  10205                 config->dest_mac[5] = (field_val & 0xff);
  10206 
  10207                 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_IDr(unit, &regval));
  10208                 config->ethertype =
  10209                     soc_reg_field_get(unit, ING_VOQFC_IDr, regval, LENGTH_TYPEf);
  10210                 config->opcode =
  10211                     soc_reg_field_get(unit, ING_VOQFC_IDr, regval, OPCODEf);
  10212 
  10213             } else {
  10214                 config->flags |= BCM_PORT_CONGESTION_CONFIG_E2ECC;
  10215                 SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_DA_MSr(unit, &regval));
  10216                 field_val = soc_reg_field_get(unit, E2E_HOL_RX_DA_MSr,
  10217                                               regval, DAf);
  10218                 config->dest_mac[0] = ((field_val >> 8) & 0xff);
  10219                 config->dest_mac[1] = (field_val & 0xff);
  10220 
  10221                 SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_DA_LSr(unit, &regval));
  10222                 field_val = soc_reg_field_get(unit, E2E_HOL_RX_DA_LSr,
  10223                                               regval, DAf);
  10224                 config->dest_mac[2] = ((field_val >> 24) & 0xff);
  10225                 config->dest_mac[3] = ((field_val >> 16) & 0xff);
  10226                 config->dest_mac[4] = ((field_val >> 8) & 0xff);
  10227                 config->dest_mac[5] = (field_val & 0xff);
  10228 
  10229                 SOC_IF_ERROR_RETURN
  10230                     (READ_E2E_HOL_RX_LENGTH_TYPEr(unit, &regval));
  10231                 config->ethertype =
  10232                     soc_reg_field_get(unit, E2E_HOL_RX_LENGTH_TYPEr,
  10233                                       regval, LENGTH_TYPEf);
  10234 
  10235                 SOC_IF_ERROR_RETURN
  10236                     (READ_E2E_HOL_RX_OPCODEr(unit, &regval));
  10237                 config->opcode =
  10238                     soc_reg_field_get(unit, E2E_HOL_RX_OPCODEr,
  10239                                       regval, OPCODEf);
  10240             }
  10241         }
  10242     }
  10243 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  10244     if (SOC_IS_TRIDENT2PLUS(unit) ||
  10245         (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit))) {
  10246         PBMP_ALL_ITER(unit, port) {
  10247 
  10248             if (IS_HG_PORT(unit, port)) {
  10249                 continue;
  10250             }
  10251             SOC_IF_ERROR_RETURN(
  10252                READ_COE_FLOW_CONTROL_CONFIGr (unit, port, &regval));
  10253 
  10254            fc_format = soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr,
  10255                                 regval, FLOW_CONTROL_FORMATf);
  10256            copy_to_cpu = soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr,
  10257                                 regval, COPY_TO_CPUf);
  10258            if(!fc_format) 
  10259            {
  10260               continue;
  10261            } 
  10262 
  10263             /* Allocate space for the E2ECC configuration */
  10264             if (PORT(unit, port).e2ecc_config == NULL) {
  10265                 PORT(unit, port).e2ecc_config =
  10266                     sal_alloc(sizeof(bcm_port_congestion_config_t),
  10267                               "bcm_port_congestion_config");
  10268                 if (PORT(unit, port).e2ecc_config == NULL) {
  10269                     LOG_ERROR(BSL_LS_BCM_PORT,
  10270                               (BSL_META_U(unit,
  10271                                  "Error: unable to allocate memory for"
  10272                                  " bcm_port_congestion_config.\n")));
  10273                     return BCM_E_MEMORY;
  10274                 }
  10275             } else {
  10276                 /* This is initialized to NULL pointers by
  10277                  * port init.  How did it get changed? */
  10278                 return BCM_E_INTERNAL;
  10279             }
  10280 
  10281             config = PORT(unit, port).e2ecc_config;
  10282             bcm_port_congestion_config_t_init(config);
  10283 
  10284             /* Recover RX state */
  10285             config->flags |= BCM_PORT_CONGESTION_CONFIG_RX;
  10286             if (copy_to_cpu == 1) {
  10287                 config->flags |=
  10288                 BCM_PORT_CONGESTION_CONFIG_COPY_TO_CPU;
  10289             } 
  10290             if (fc_format == 1) {
  10291                 config->flags |=
  10292                 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE;
  10293                 SOC_IF_ERROR_RETURN(
  10294                         READ_ING_VOQFC_MACDA_MSr(unit, &regval));
  10295                 field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_MSr,
  10296                                             regval, DAf);
  10297                 config->dest_mac[0] = ((field_val >> 8) & 0xff);
  10298                 config->dest_mac[1] = (field_val & 0xff);
  10299                 SOC_IF_ERROR_RETURN(
  10300                          READ_ING_VOQFC_MACDA_LSr(unit, &regval));
  10301                 field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_LSr,
  10302                                               regval, DAf);
  10303                 config->dest_mac[2] = ((field_val >> 24) & 0xff);
  10304                 config->dest_mac[3] = ((field_val >> 16) & 0xff);
  10305                 config->dest_mac[4] = ((field_val >> 8) & 0xff);
  10306                 config->dest_mac[5] = (field_val & 0xff);
  10307                 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_IDr(unit, &regval));
  10308                 config->ethertype =
  10309                   soc_reg_field_get(unit, ING_VOQFC_IDr,
  10310                                              regval, LENGTH_TYPEf);
  10311                 config->opcode =
  10312                    soc_reg_field_get(unit, ING_VOQFC_IDr,
  10313                                          regval, OPCODEf);
  10314 
  10315             } else if (fc_format == 2) {
  10316                 config->flags |=
  10317                 BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE;
  10318                 SOC_IF_ERROR_RETURN(
  10319                         READ_COE_VLAN_PAUSE_MACDA_MSr(unit, &regval));
  10320                 field_val = soc_reg_field_get(unit, COE_VLAN_PAUSE_MACDA_MSr,
  10321                                             regval, DAf);
  10322                 config->dest_mac[0] = ((field_val >> 8) & 0xff);
  10323                 config->dest_mac[1] = (field_val & 0xff);
  10324                 SOC_IF_ERROR_RETURN(
  10325                         READ_COE_VLAN_PAUSE_MACDA_LSr(unit, &regval));
  10326                 field_val = soc_reg_field_get(unit, COE_VLAN_PAUSE_MACDA_LSr,
  10327                                             regval, DAf);
  10328                 config->dest_mac[2] = ((field_val >> 24) & 0xff);
  10329                 config->dest_mac[3] = ((field_val >> 16) & 0xff);
  10330                 config->dest_mac[4] = ((field_val >> 8) & 0xff);
  10331                 config->dest_mac[5] = (field_val & 0xff);
  10332                 SOC_IF_ERROR_RETURN(READ_COE_VLAN_PAUSE_IDr(unit, &regval));
  10333                 config->ethertype =
  10334                   soc_reg_field_get(unit, COE_VLAN_PAUSE_IDr,
  10335                                              regval, LENGTH_TYPEf);
  10336                 config->opcode =
  10337                    soc_reg_field_get(unit, COE_VLAN_PAUSE_IDr,
  10338                                          regval, OPCODEf);
  10339             } 
  10340   
  10341         }
  10342      }
  10343 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  10344 #ifdef     BCM_KATANA2_SUPPORT
  10345     if (SOC_IS_KATANA2(unit)) {
  10346         PBMP_ALL_ITER(unit, port) {
  10347             port_rx_enabled = 0;
  10348             e2ecc_coe = 0;
  10349 
  10350             if (IS_HG_PORT(unit, port)) {
  10351                 continue;
  10352             }
  10353             soc_cm_get_id(unit, &dev_id, &rev_id);
  10354 
  10355             if ((rev_id >= BCM56450_B0_REV_ID) || SOC_IS_SABER2(unit)) {
  10356                 SOC_IF_ERROR_RETURN(
  10357                   READ_COE_FLOW_CONTROL_CONFIGr (unit, port, &regval));
  10358 
  10359                 if (soc_reg_field_valid(unit, COE_FLOW_CONTROL_CONFIGr,
  10360                          FLOW_CONTROL_FORMATf)) {
  10361                     if (0 != soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr,
  10362                                 regval, FLOW_CONTROL_FORMATf)) {
  10363                         port_rx_enabled = 1;
  10364                         e2ecc_coe = 1;
  10365                         e2ecc_strict = soc_reg_field_get(unit,
  10366                                          COE_FLOW_CONTROL_CONFIGr,
  10367                                          regval, E2ECC_MODEf);
  10368                      }
  10369                 }
  10370             } else if (rev_id == BCM56450_A0_REV_ID) {
  10371                 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &regval));
  10372                 if (soc_reg_field_valid(unit, IE2E_CONTROLr, VOQFC_ENABLEf)) {
  10373                     if (0 != soc_reg_field_get(unit, IE2E_CONTROLr,
  10374                                                regval, VOQFC_ENABLEf)) {
  10375                         port_rx_enabled = 1;
  10376                         e2ecc_coe = 1;
  10377                     }
  10378                 }
  10379             }
  10380             if (!port_rx_enabled) {
  10381                 /* On to the next port */
  10382                 continue;
  10383             }
  10384 
  10385             /* Allocate space for the E2ECC configuration */
  10386             if (PORT(unit, port).e2ecc_config == NULL) {
  10387                 PORT(unit, port).e2ecc_config =
  10388 
  10389                     sal_alloc(sizeof(bcm_port_congestion_config_t),
  10390                               "bcm_port_congestion_config");
  10391                 if (PORT(unit, port).e2ecc_config == NULL) {
  10392                     LOG_ERROR(BSL_LS_BCM_PORT,
  10393                               (BSL_META_U(unit,
  10394                                  "Error: unable to allocate memory for"
  10395                                  " bcm_port_congestion_config.\n")));
  10396                     return BCM_E_MEMORY;
  10397                 }
  10398             } else {
  10399                 /* This is initialized to NULL pointers by
  10400                  * port init.  How did it get changed? */
  10401                 return BCM_E_INTERNAL;
  10402             }
  10403 
  10404             config = PORT(unit, port).e2ecc_config;
  10405             bcm_port_congestion_config_t_init(config);
  10406 
  10407             if (port_rx_enabled) {
  10408                 /* Recover RX state */
  10409                 config->flags |= BCM_PORT_CONGESTION_CONFIG_RX;
  10410                 if (e2ecc_coe) {
  10411                     if ((rev_id >= BCM56450_B0_REV_ID) || SOC_IS_SABER2(unit)) {
  10412                         if (e2ecc_strict) {
  10413                             config->flags |=
  10414                               BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE;
  10415                         } else {
  10416                             config->flags |=
  10417                               BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE;
  10418                         }
  10419                     } else if (rev_id == BCM56450_A0_REV_ID) {
  10420                         config->flags |=
  10421                              BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE;
  10422                     }
  10423                     SOC_IF_ERROR_RETURN(
  10424                                READ_ING_VOQFC_MACDA_MSr(unit, &regval));
  10425                     field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_MSr,
  10426                                                   regval, DAf);
  10427                     config->dest_mac[0] = ((field_val >> 8) & 0xff);
  10428                     config->dest_mac[1] = (field_val & 0xff);
  10429 
  10430                     SOC_IF_ERROR_RETURN(
  10431                                READ_ING_VOQFC_MACDA_LSr(unit, &regval));
  10432                     field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_LSr,
  10433                                                   regval, DAf);
  10434                     config->dest_mac[2] = ((field_val >> 24) & 0xff);
  10435                     config->dest_mac[3] = ((field_val >> 16) & 0xff);
  10436                     config->dest_mac[4] = ((field_val >> 8) & 0xff);
  10437                     config->dest_mac[5] = (field_val & 0xff);
  10438 
  10439                     SOC_IF_ERROR_RETURN(READ_ING_VOQFC_IDr(unit, &regval));
  10440                     config->ethertype =
  10441                         soc_reg_field_get(unit, ING_VOQFC_IDr,
  10442                                                regval, LENGTH_TYPEf);
  10443                     config->opcode =
  10444                         soc_reg_field_get(unit, ING_VOQFC_IDr,
  10445                                                regval, OPCODEf);
  10446                 }
  10447             }
  10448         }
  10449     }
  10450 #endif /* BCM_KATANA2_SUPPORT */
  10451 
  10452     return BCM_E_NONE;
  10453 }
  10454 #endif /* BCM_TRX_SUPPORT */
  10455 
  10456 /*
  10457  * Function:
  10458  *      _bcm_esw_port_sync
  10459  * Purpose:
  10460  *      Record Port module persisitent info for Level 2 Warm Boot
  10461  *
  10462  * Warm Boot Version Map:
  10463  *      Fields for previous version to be documented
  10464  *  BCM_PORT_WB_VERSION_1_0
  10465  *      ...
  10466  *  BCM_PORT_WB_VERSION_1_1
  10467  *      ...
  10468  *  BCM_PORT_WB_VERSION_1_2
  10469  *    rx_los            SW RX LOS
  10470  *      ...
  10471  *  BCM_PORT_WB_VERSION_1_3
  10472  *    enable            port eanble status
  10473  *
  10474  * Parameters:
  10475  *      unit - StrataSwitch unit number.
  10476  * Returns:
  10477  *      BCM_E_XXX
  10478  */
  10479 int
  10480 _bcm_esw_port_sync(int unit)
  10481 {
  10482     int rv = BCM_E_NONE;
  10483 
  10484 #if defined(BCM_TRX_SUPPORT)
  10485     if (SOC_IS_TRX(unit)) {
  10486         int alloc_sz;
  10487         bcm_port_t port;
  10488         uint8 *port_state;
  10489         _bcm_port_info_t *pinfo = NULL;
  10490         bcm_pbmp_t dtm_pbmp;
  10491         int stable_size;
  10492         soc_scache_handle_t scache_handle;
  10493 #ifdef BCM_TRIDENT_SUPPORT
  10494         soc_info_t *si = &SOC_INFO(unit);
  10495 #endif
  10496         bcm_pbmp_t all_pbmp;
  10497 #ifdef  BCM_TOMAHAWK_SUPPORT
  10498         uint32 asf_wbmem_sz = 0;
  10499         /* Switch Latency Bypass WB will move to a different module later */
  10500         uint32 latency_wbmem_sz = 0;
  10501 #endif
  10502 
  10503         BCM_PBMP_CLEAR(all_pbmp);
  10504         BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  10505 
  10506 #ifdef BCM_KATANA2_SUPPORT
  10507         if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  10508             BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  10509         }
  10510         if (soc_feature(unit, soc_feature_linkphy_coe) ||
  10511             soc_feature(unit, soc_feature_subtag_coe)) {
  10512             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  10513         }
  10514 #endif
  10515 
  10516 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  10517         if (SOC_IS_TD2P_TT2P(unit)) {
  10518             BCM_IF_ERROR_RETURN(bcm_td2p_flexport_pbmp_update(unit,
  10519                                                  &all_pbmp));
  10520         }
  10521 #endif
  10522 #ifdef BCM_MONTEREY_SUPPORT
  10523             if (SOC_IS_MONTEREY(unit)) {
  10524                 BCM_IF_ERROR_RETURN(bcm_monterey_flexport_pbmp_update(unit, &all_pbmp));
  10525             }  
  10526 #endif 
  10527 #ifdef BCM_APACHE_SUPPORT
  10528         if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
  10529             BCM_IF_ERROR_RETURN(bcm_apache_flexport_pbmp_update(unit, &all_pbmp));
  10530         }    
  10531 #endif
  10532 
  10533         alloc_sz = 0;
  10534         SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
  10535         PBMP_ITER(all_pbmp, port) {
  10536 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
  10537             if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit))) {
  10538                 /* vp entry and vlan prot ptr */
  10539                 alloc_sz += (sizeof(int) + sizeof(uint32));
  10540             }
  10541 #endif
  10542             alloc_sz += sizeof(int); /* vp count */
  10543         }
  10544         alloc_sz += sizeof(dtm_pbmp); /* Bitmap of dtag_mode set */
  10545 
  10546         PBMP_ITER(all_pbmp, port) {
  10547             if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) {
  10548                 if (SOC_REG_IS_VALID(unit, COSMASKr)) {
  10549                     alloc_sz += sizeof(uint32);
  10550                 } else {
  10551                     alloc_sz += sizeof(_bcm_port_metering_info_t);
  10552                 }
  10553                 alloc_sz += sizeof(uint8); /* flags */
  10554             }
  10555         }
  10556 
  10557 #ifdef BCM_TRIDENT_SUPPORT
  10558         if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) &&
  10559             soc_feature(unit, soc_feature_flex_port)) {
  10560             /* Number of lanes per port needs to be stored.*/
  10561             alloc_sz += (SOC_MAX_NUM_PORTS * sizeof(int));
  10562         }
  10563 #endif
  10564 
  10565         /* Size for SW RX LOS status */
  10566         PBMP_ITER(all_pbmp, port) {
  10567             alloc_sz += sizeof(uint8);
  10568         }
  10569 
  10570 #ifdef BCM_TRIDENT2_SUPPORT
  10571         if (SOC_IS_TD2_TT2(unit)) {
  10572             /* Size for port enable status */
  10573             PBMP_ITER(all_pbmp, port) {
  10574                 alloc_sz += sizeof(int);
  10575             }
  10576         }
  10577 #endif /* BCM_TRIDENT2_SUPPORT */
  10578 #ifdef BCM_TRIUMPH3_SUPPORT
  10579         if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit)) {
  10580             alloc_sz += 2 * sizeof(((_port_ibod_ctrl_t *)0)->rrbyt)
  10581                         + sizeof((((_port_ibod_ctrl_t *)0)->event_count));
  10582         }
  10583 #endif /* BCM_TRIUMPH3_SUPPORT */
  10584 #if defined(BCM_TRIUMPH3_SUPPORT) 
  10585         if (soc_feature(unit, soc_feature_epc_linkflap_recover)) {
  10586             int port_forward_size;
  10587             BCM_IF_ERROR_RETURN(
  10588                 _bcm_port_force_forward_scache_size(unit, 
  10589                                                     &port_forward_size));
  10590             alloc_sz += port_forward_size;
  10591         }
  10592 #endif
  10593 
  10594 #ifdef  BCM_TOMAHAWK_SUPPORT
  10595         /* ASF WB */
  10596         rv = _bcm_esw_asf_wb_memsz_get(unit, &asf_wbmem_sz,
  10597                                        BCM_PORT_WB_DEFAULT_VERSION);
  10598         if (BCM_E_NONE == rv) {
  10599             alloc_sz += asf_wbmem_sz;
  10600         }
  10601 
  10602         /* Switch Latency Bypass WB */
  10603         rv = bcmi_esw_switch_latency_wb_memsz_get(unit, &latency_wbmem_sz,
  10604                                                   BCM_PORT_WB_DEFAULT_VERSION);
  10605         if (BCM_E_NONE == rv) {
  10606             alloc_sz += latency_wbmem_sz;
  10607         }
  10608 #endif /* BCM_TOMAHAWK_SUPPORT */
  10609 
  10610         /*IFG WB*/
  10611         if (soc_feature(unit, soc_feature_xmac) ||
  10612                 soc_feature(unit, soc_feature_xlmac) ||
  10613                 soc_feature(unit, soc_feature_cmac) ||
  10614                 soc_feature(unit, soc_feature_clmac)) {
  10615             PBMP_ITER(all_pbmp, port) {
  10616                 alloc_sz += sizeof(uint32);
  10617             }
  10618         }
  10619         /* PORT DSCP MAP SETTING */
  10620         if (soc_feature(unit, soc_feature_dscp) &&
  10621             soc_feature(unit, soc_feature_egr_dscp_map_per_port)) {
  10622             /* Allocate size for port dscp map setting status */
  10623             PBMP_ITER(all_pbmp, port) {
  10624                 alloc_sz += sizeof(int);
  10625             }
  10626         }
  10627 
  10628 #ifdef  BCM_TOMAHAWK_SUPPORT
  10629         if (SOC_IS_TOMAHAWK(unit)) {
  10630             /* Allocate size for port interface type */
  10631             PBMP_ITER(all_pbmp, port) {
  10632                 alloc_sz += sizeof(int);
  10633             }
  10634         }
  10635 #endif /* BCM_TOMAHAWK_SUPPORT */
  10636 
  10637        if (soc_feature(unit, soc_feature_phy_interface_wb)) {
  10638             /* Allocate size for port interface type */
  10639             PBMP_ITER(PBMP_PORT_ALL(unit), port) {
  10640                 alloc_sz += sizeof(int);
  10641             }
  10642        }
  10643 
  10644         SOC_SCACHE_HANDLE_SET(scache_handle,
  10645                               unit, BCM_MODULE_PORT,
  10646                               BCM_PORT_WB_SCACHE_PART_DEFAULT);
  10647         rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE,
  10648                                      alloc_sz, (uint8**)&port_state,
  10649                                      BCM_PORT_WB_DEFAULT_VERSION, NULL);
  10650         if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
  10651             return rv;
  10652         }
  10653 
  10654         BCM_PBMP_CLEAR(dtm_pbmp);
  10655 
  10656         PORT_LOCK(unit);
  10657         PBMP_ITER(all_pbmp, port) {
  10658             if (port < SOC_MAX_NUM_PORTS) {
  10659 	    rv = _bcm_port_info_get(unit, port, &pinfo);
  10660             }
  10661 	    if (BCM_FAILURE(rv)) {
  10662             PORT_UNLOCK(unit);
  10663             return (rv);
  10664 	    }
  10665 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
  10666             if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit))) {
  10667                 int idxmin, idxmax, idx;
  10668                 idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm);
  10669                 idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm);
  10670 
  10671                 for (idx = idxmin; idx <= idxmax; idx++) {
  10672                     if (_BCM_PORT_VD_PBVL_IS_SET(pinfo, idx)) {
  10673                         sal_memcpy(port_state, &idx, sizeof(int));
  10674                         port_state += sizeof(int);
  10675                         break;
  10676                     }
  10677                 }
  10678                 if (idx > idxmax) {
  10679                     idx = -1;
  10680                     sal_memcpy(port_state, &idx, sizeof(int));
  10681                     port_state += sizeof(int);
  10682                 }
  10683                 sal_memcpy(port_state, &(pinfo->vlan_prot_ptr),
  10684                         sizeof(uint32));
  10685                 port_state += sizeof(uint32);
  10686             }
  10687 #endif
  10688             /* In Apache information is saved and recovered for 76 ports which is
  10689              * greater than SOC_MAX_NUM_PORTS value of 75. These checks are
  10690              * needed to prevent invalid memory access.
  10691              */
  10692             if (port < SOC_MAX_NUM_PORTS) {
  10693             if (0 != (pinfo->dtag_mode &
  10694                          (BCM_PORT_DTAG_MODE_INTERNAL | BCM_PORT_DTAG_MODE_EXTERNAL))) {
  10695                 /* Some sort of double-tagged mode */
  10696                 BCM_PBMP_PORT_ADD(dtm_pbmp, port);
  10697             }
  10698                 sal_memcpy(port_state, &(pinfo->vp_count), sizeof(pinfo->vp_count));
  10699             }
  10700             port_state += sizeof(int);
  10701         }
  10702         sal_memcpy(port_state, &dtm_pbmp, sizeof(dtm_pbmp));
  10703         port_state += sizeof(dtm_pbmp);
  10704         PBMP_ITER(all_pbmp, port) {
  10705             if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) {
  10706                 if (SOC_REG_IS_VALID(unit, COSMASKr)) {
  10707                     if (port < SOC_MAX_NUM_PORTS) {
  10708                     sal_memcpy(port_state, &(PORT(unit, port).cosmask), sizeof(uint32));
  10709                     }
  10710                     port_state += sizeof(uint32);
  10711                 } else {
  10712                     if (port < SOC_MAX_NUM_PORTS) {
  10713                     sal_memcpy(port_state, &(PORT(unit, port).m_info),
  10714                                sizeof(_bcm_port_metering_info_t));
  10715                     }
  10716                     port_state += sizeof(_bcm_port_metering_info_t);
  10717                 }
  10718                 if (port < SOC_MAX_NUM_PORTS) {
  10719                 sal_memcpy(port_state, &(PORT(unit, port).flags), sizeof(uint8));
  10720                 }
  10721                 port_state += sizeof(uint8);
  10722             }
  10723         }
  10724 #ifdef BCM_TRIDENT_SUPPORT
  10725         if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) &&
  10726             soc_feature(unit, soc_feature_flex_port)) {
  10727             /* coverity[overrun-local] */
  10728             PBMP_ALL_ITER(unit, port) {
  10729                 if (port < SOC_MAX_NUM_PORTS) {
  10730                     sal_memcpy(port_state, &(si->port_num_lanes[port]), sizeof(int));
  10731                 }
  10732                 port_state += sizeof(int);
  10733             }
  10734         }
  10735 #endif
  10736 
  10737         /* Restore SW RX LOS status */
  10738         PBMP_ITER(all_pbmp, port) {
  10739             if (port < SOC_MAX_NUM_PORTS) {
  10740             sal_memcpy(port_state, &(PORT(unit, port).rx_los), sizeof(uint8));
  10741             }
  10742             port_state += sizeof(uint8);
  10743         }
  10744 
  10745 #ifdef BCM_TRIDENT2_SUPPORT
  10746         if (SOC_IS_TD2_TT2(unit)) {
  10747             /* Restore port enable status */
  10748             PBMP_ITER(all_pbmp, port) {
  10749                 if (port < SOC_MAX_NUM_PORTS) {
  10750                 sal_memcpy(port_state, &(PORT(unit, port).enable), sizeof(int));
  10751                 }
  10752                 port_state += sizeof(int);
  10753             }
  10754         }
  10755 #endif /* BCM_TRIDENT2_SUPPORT */
  10756 #ifdef BCM_TRIUMPH3_SUPPORT
  10757         if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit)) {
  10758             if (_port_ibod_ctrl[unit]) {
  10759                 sal_memcpy(port_state, _port_ibod_ctrl[unit]->rrbyt,
  10760                            sizeof(((_port_ibod_ctrl_t *)0)->rrbyt));
  10761                 port_state += sizeof(((_port_ibod_ctrl_t *)0)->rrbyt);
  10762                 sal_memcpy(port_state, _port_ibod_ctrl[unit]->rrpkt,
  10763                            sizeof(((_port_ibod_ctrl_t *)0)->rrpkt));
  10764                 port_state += sizeof(((_port_ibod_ctrl_t *)0)->rrpkt);
  10765                 sal_memcpy(port_state, &(_port_ibod_ctrl[unit]->event_count),
  10766                            sizeof(((_port_ibod_ctrl_t *)0)->event_count));
  10767                 port_state += sizeof(((_port_ibod_ctrl_t *)0)->event_count);
  10768             }  else {
  10769                 sal_memset(port_state, 0,
  10770                            2 * sizeof(((_port_ibod_ctrl_t *)0)->rrbyt)
  10771                            + sizeof((((_port_ibod_ctrl_t *)0)->event_count)));
  10772                 port_state += 2 * sizeof(((_port_ibod_ctrl_t *)0)->rrbyt)
  10773                               + sizeof((((_port_ibod_ctrl_t *)0)->event_count));
  10774             }
  10775 
  10776         }
  10777         if (soc_feature(unit, soc_feature_epc_linkflap_recover)) {
  10778             rv = _bcm_port_force_forward_sync(unit, &port_state);
  10779             if (BCM_FAILURE(rv)) {
  10780                 PORT_UNLOCK(unit);
  10781                 return (rv);
  10782             }
  10783         }
  10784 #endif /* BCM_TRIUMPH3_SUPPORT */
  10785 
  10786 #ifdef  BCM_TOMAHAWK_SUPPORT
  10787         /* ASF WB */
  10788         rv = _bcm_esw_asf_wb_sync(unit, port_state);
  10789 
  10790         if (BCM_E_NONE == rv) {
  10791             port_state += asf_wbmem_sz;
  10792         }
  10793 
  10794         /* Switch Latency Bypass WB */
  10795         rv = bcmi_esw_switch_latency_wb_sync(unit, port_state);
  10796 
  10797         if (BCM_E_NONE == rv) {
  10798             port_state += latency_wbmem_sz;
  10799         }
  10800 #endif /* BCM_TOMAHAWK_SUPPORT */
  10801 
  10802         /*IFG WB*/
  10803         if (soc_feature(unit, soc_feature_xmac) ||
  10804                 soc_feature(unit, soc_feature_xlmac) ||
  10805                 soc_feature(unit, soc_feature_cmac) ||
  10806                 soc_feature(unit, soc_feature_clmac)) {
  10807             rv = _bcm_esw_port_ifg_wb_sync(unit, &port_state);
  10808         }
  10809         /* PORT DSCP MAP SETTING */
  10810         if (soc_feature(unit, soc_feature_dscp) &&
  10811             soc_feature(unit, soc_feature_egr_dscp_map_per_port)) {
  10812             /* Allocate size for port dscp map setting status */
  10813             PBMP_ITER(all_pbmp, port) {
  10814                 sal_memcpy(port_state, &(PORT(unit, port).port_dscp_map_set), sizeof(int));
  10815                 port_state += sizeof(int);
  10816             }
  10817         }
  10818 
  10819 #if defined(BCM_CLMAC_SUPPORT)
  10820         if (SOC_IS_TOMAHAWK(unit)) {
  10821             soc_port_if_t       pif;
  10822             /* Restore port interface type */
  10823             PBMP_ITER(all_pbmp, port) {
  10824                 if (IS_XE_PORT(unit, port) ||
  10825                     IS_CE_PORT(unit, port) ||
  10826                     IS_HG_PORT(unit, port) ||
  10827                     IS_GE_PORT(unit, port) ||
  10828                     IS_MANAGEMENT_PORT(unit, port)) {
  10829                         SOC_IF_ERROR_RETURN
  10830                             (soc_phyctrl_interface_get(unit, port, &pif));
  10831                         sal_memcpy(port_state, &pif, sizeof(int));
  10832                         port_state += sizeof(int);
  10833                 }
  10834             }
  10835         }
  10836 #endif
  10837 
  10838         if (soc_feature(unit, soc_feature_phy_interface_wb)) {
  10839             soc_port_if_t       pif;
  10840 
  10841             /* Restore port interface type */
  10842             PBMP_ITER(PBMP_PORT_ALL(unit), port) {
  10843                 rv = soc_phyctrl_interface_get(unit, port, &pif);
  10844                 if (BCM_FAILURE(rv)) {
  10845                     pif = 0;
  10846                 }
  10847                 sal_memcpy(port_state, &pif, sizeof(int));
  10848                 port_state += sizeof(int);
  10849             }
  10850         }
  10851         PORT_UNLOCK(unit);
  10852     }
  10853 #endif /* BCM_TRX_SUPPORT */
  10854 
  10855 #ifdef BCM_PREEMPTION_SUPPORT
  10856     if (BCM_SUCCESS(rv) && soc_feature(unit, soc_feature_preemption)) {
  10857         soc_scache_handle_t scache_handle;
  10858 
  10859         SOC_SCACHE_HANDLE_SET(scache_handle,
  10860                               unit, BCM_MODULE_PORT,
  10861                               BCM_PORT_WB_SCACHE_PART_PREMMPTION);
  10862         BCM_IF_ERROR_RETURN(
  10863             bcmi_esw_preemption_sync(unit, scache_handle));
  10864     }
  10865 #endif /* BCM_PREEMPTION_SUPPORT */
  10866 
  10867     return rv;
  10868 }
  10869 
  10870 int
  10871 _bcm_esw_port_wb_alloc(int unit)
  10872 {
  10873 
  10874 #if defined(BCM_TRX_SUPPORT)
  10875     if (SOC_IS_TRX(unit)) {
  10876         int alloc_sz, rv = BCM_E_NONE;
  10877         bcm_port_t port;
  10878         uint8 *port_state;
  10879         int stable_size;
  10880         bcm_pbmp_t all_pbmp;
  10881         soc_scache_handle_t scache_handle;
  10882 #ifdef  BCM_TOMAHAWK_SUPPORT
  10883         uint32 asf_wbmem_sz = 0;
  10884 
  10885         /* Switch Latency Bypass WB will move to a different module later */
  10886         uint32 latency_wbmem_sz = 0;
  10887 #endif /* BCM_TOMAHAWK_SUPPORT */
  10888 
  10889         BCM_PBMP_CLEAR(all_pbmp);
  10890         BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  10891 
  10892 #ifdef BCM_KATANA2_SUPPORT
  10893         if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  10894             BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  10895         }
  10896         if (soc_feature(unit, soc_feature_linkphy_coe) ||
  10897             soc_feature(unit, soc_feature_subtag_coe)) {
  10898             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  10899         }
  10900 #endif
  10901 
  10902 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  10903         if (SOC_IS_TD2P_TT2P(unit)) {
  10904             BCM_IF_ERROR_RETURN(bcm_td2p_flexport_pbmp_update(unit,
  10905                                                  &all_pbmp));
  10906         }
  10907 #endif
  10908 #ifdef BCM_MONTEREY_SUPPORT
  10909             if (SOC_IS_MONTEREY(unit)) {
  10910                 BCM_IF_ERROR_RETURN(bcm_monterey_flexport_pbmp_update(unit, &all_pbmp));
  10911             }  
  10912 #endif 
  10913 #ifdef BCM_APACHE_SUPPORT
  10914         if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
  10915             BCM_IF_ERROR_RETURN(bcm_apache_flexport_pbmp_update(unit, &all_pbmp));
  10916         }
  10917 #endif
  10918         alloc_sz = 0;
  10919         SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
  10920         PBMP_ITER(all_pbmp, port) {
  10921 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
  10922             if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit))) {
  10923                 /* vp entry and vlan prot ptr */
  10924                 alloc_sz += (sizeof(int) + sizeof(uint32));
  10925             }
  10926 #endif
  10927             alloc_sz += sizeof(int); /* vp count */
  10928         }
  10929         alloc_sz += sizeof(bcm_pbmp_t); /* Bitmap of dtag_mode == NONE */
  10930         PBMP_ITER(all_pbmp, port) {
  10931             if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) {
  10932                 if (SOC_REG_IS_VALID(unit, COSMASKr)) {
  10933                     alloc_sz += sizeof(uint32);
  10934                 } else {
  10935                     alloc_sz += sizeof(_bcm_port_metering_info_t);
  10936                 }
  10937                 alloc_sz += sizeof(uint8); /* flags */
  10938             }
  10939         }
  10940 
  10941 #ifdef BCM_TRIDENT_SUPPORT
  10942         if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) &&
  10943             soc_feature(unit, soc_feature_flex_port)) {
  10944             alloc_sz += (SOC_MAX_NUM_PORTS * sizeof(int));
  10945         }
  10946 #endif
  10947 
  10948         /* Restore SW RX LOS status */
  10949         PBMP_ITER(all_pbmp, port) {
  10950             alloc_sz += sizeof(uint8);
  10951         }
  10952 
  10953 #ifdef BCM_TRIDENT2_SUPPORT
  10954         if (SOC_IS_TD2_TT2(unit)) {
  10955             /* Allocate size for port enable status */
  10956             PBMP_ITER(all_pbmp, port) {
  10957                 alloc_sz += sizeof(int);
  10958             }
  10959         }
  10960 #endif /* BCM_TRIDENT2_SUPPORT */
  10961 #ifdef BCM_TRIUMPH3_SUPPORT
  10962         if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit)) {
  10963             alloc_sz += 2 * sizeof(((_port_ibod_ctrl_t *)0)->rrbyt)
  10964                          + sizeof((((_port_ibod_ctrl_t *)0)->event_count));
  10965         }
  10966 #endif /* BCM_TRIUMPH3_SUPPORT */
  10967 #if defined(BCM_TRIUMPH3_SUPPORT)
  10968         if (soc_feature(unit, soc_feature_epc_linkflap_recover)) {
  10969             int port_forward_size;
  10970             BCM_IF_ERROR_RETURN(
  10971                 _bcm_port_force_forward_scache_size(unit, &port_forward_size));
  10972             alloc_sz += port_forward_size;
  10973         }
  10974 #endif /* defined(BCM_TRIUMPH3_SUPPORT) */
  10975 
  10976 #ifdef  BCM_TOMAHAWK_SUPPORT
  10977         /* ASF WB */
  10978         rv = _bcm_esw_asf_wb_memsz_get(unit, &asf_wbmem_sz, BCM_PORT_WB_DEFAULT_VERSION);
  10979         if (BCM_E_NONE == rv) {
  10980             alloc_sz += asf_wbmem_sz;
  10981         }
  10982 
  10983         /* Switch Latency Bypass WB */
  10984         rv = bcmi_esw_switch_latency_wb_memsz_get(unit, &latency_wbmem_sz,
  10985                                                   BCM_PORT_WB_DEFAULT_VERSION);
  10986         if (BCM_E_NONE == rv) {
  10987             alloc_sz += latency_wbmem_sz;
  10988         }
  10989 #endif /* BCM_TOMAHAWK_SUPPORT */
  10990 
  10991         /*IFG WB*/
  10992         if (soc_feature(unit, soc_feature_xmac) ||
  10993                 soc_feature(unit, soc_feature_xlmac) ||
  10994                 soc_feature(unit, soc_feature_cmac) ||
  10995                 soc_feature(unit, soc_feature_clmac)) {
  10996             PBMP_ITER(all_pbmp, port) {
  10997                 alloc_sz += sizeof(uint32);
  10998             }
  10999         }
  11000         /* PORT DSCP MAP SETTING */
  11001         if (soc_feature(unit, soc_feature_dscp) &&
  11002             soc_feature(unit, soc_feature_egr_dscp_map_per_port)) {
  11003             /* Allocate size for port dscp map setting status */
  11004             PBMP_ITER(all_pbmp, port) {
  11005                 alloc_sz += sizeof(int);
  11006             }
  11007         }
  11008         
  11009 #ifdef  BCM_TOMAHAWK_SUPPORT
  11010         if (SOC_IS_TOMAHAWK(unit)) {
  11011             /* Allocate size for port interface type */
  11012             PBMP_ITER(all_pbmp, port) {
  11013                 alloc_sz += sizeof(int);
  11014             }
  11015         }
  11016 #endif /* BCM_TOMAHAWK_SUPPORT */
  11017 
  11018         if (soc_feature(unit, soc_feature_phy_interface_wb)) {
  11019             /* Allocate size for port interface type */
  11020             PBMP_ITER(PBMP_PORT_ALL(unit), port) {
  11021                 alloc_sz += sizeof(int);
  11022             }
  11023         }
  11024 
  11025         SOC_SCACHE_HANDLE_SET(scache_handle,
  11026                               unit, BCM_MODULE_PORT,
  11027                               BCM_PORT_WB_SCACHE_PART_DEFAULT);
  11028         rv = _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE,
  11029                                      alloc_sz, (uint8**)&port_state,
  11030                                      BCM_PORT_WB_DEFAULT_VERSION, NULL);
  11031         if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
  11032             return rv;
  11033         }
  11034     }
  11035 #endif /* BCM_TRX_SUPPORT */
  11036 
  11037 #ifdef BCM_PREEMPTION_SUPPORT
  11038     if (soc_feature(unit, soc_feature_preemption)) {
  11039         soc_scache_handle_t scache_handle;
  11040 
  11041         SOC_SCACHE_HANDLE_SET(scache_handle,
  11042                               unit, BCM_MODULE_PORT,
  11043                               BCM_PORT_WB_SCACHE_PART_PREMMPTION);
  11044         BCM_IF_ERROR_RETURN(
  11045             bcmi_esw_preemption_wb_alloc(unit, scache_handle));
  11046     }
  11047 #endif /* BCM_PREEMPTION_SUPPORT */
  11048 
  11049     return BCM_E_NONE;
  11050 }
  11051 
  11052 #ifdef BCM_TRIUMPH2_SUPPORT
  11053 /*
  11054  * Function:
  11055  *      _bcm_tr2_flexport_recover
  11056  * Purpose:
  11057  *     To recover/reconstruct the HL port configuration
  11058  *     during warmboot. This is a 'level one' warmboot
  11059  *     recovery. It depends on the reg configuration of
  11060  *     EDATABUF_XQP_FLEXPORT_CONFIGr which maintains the
  11061  *     flexport config of the HL ports that was done
  11062  *     in coldboot mode.
  11063  * Parameters:
  11064  *      unit - StrataSwitch unit number.
  11065  *      port - Port number of the HL
  11066  *             flexport controlling port.
  11067  * Returns:
  11068  *      BCM_E_XXX
  11069  */
  11070 STATIC int
  11071 _bcm_tr2_flexport_recover(int unit, bcm_port_t port)
  11072 {
  11073     uint8 rev_id;
  11074     uint16 dev_id;
  11075     uint32 port_type;
  11076     int i, old_value, rv;
  11077     bcm_port_t it_port;
  11078     port_tab_entry_t pent;
  11079     soc_info_t *si = &SOC_INFO(unit);
  11080 
  11081     soc_cm_get_id(unit, &dev_id, &rev_id);
  11082     BCM_IF_ERROR_RETURN(_bcm_tr2_port_lanes_get(unit, port, &old_value));
  11083 
  11084 #define RECONFIGURE_TR2_PORT_TYPE_INFO(ptype) \
  11085     si->ptype.num = 0; \
  11086     si->ptype.min = si->ptype.max = -1; \
  11087     PBMP_ITER(si->ptype.bitmap, it_port) { \
  11088         si->ptype.port[si->ptype.num++] = it_port; \
  11089         if (si->ptype.min < 0) { \
  11090             si->ptype.min = it_port; \
  11091         } \
  11092         if (it_port > si->ptype.max) { \
  11093             si->ptype.max = it_port; \
  11094         } \
  11095     }
  11096 
  11097     /* Step 1: Change the SOC bitmaps */
  11098     if ((old_value == 1)) {
  11099         /* The block originally had 4 GE ports */
  11100         SOC_CONTROL_LOCK(unit);
  11101         SOC_PBMP_PORT_REMOVE(si->st.bitmap, port);
  11102         SOC_PBMP_PORT_REMOVE(si->hg.bitmap, port);
  11103         SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port);
  11104         SOC_PBMP_PORT_ADD(si->ether.bitmap, port);
  11105         SOC_PBMP_PORT_ADD(si->ge.bitmap, port);
  11106         si->port_speed_max[port] = 1000;
  11107         soc_port_cmap_set(unit, port, SOC_CTR_TYPE_GE);
  11108         for (i = port + 1; i < port + 4; i++) {
  11109             SOC_PBMP_PORT_REMOVE(si->ge.disabled_bitmap, i);
  11110             SOC_PBMP_PORT_REMOVE(si->ether.disabled_bitmap, i);
  11111             SOC_PBMP_PORT_REMOVE(si->port.disabled_bitmap, i);
  11112             SOC_PBMP_PORT_REMOVE(si->all.disabled_bitmap, i);
  11113             si->port_speed_max[i] = 1000;
  11114             soc_port_cmap_set(unit, i, SOC_CTR_TYPE_GE);
  11115         }
  11116         RECONFIGURE_TR2_PORT_TYPE_INFO(ether);
  11117         RECONFIGURE_TR2_PORT_TYPE_INFO(st);
  11118         RECONFIGURE_TR2_PORT_TYPE_INFO(hg);
  11119         RECONFIGURE_TR2_PORT_TYPE_INFO(xe);
  11120         RECONFIGURE_TR2_PORT_TYPE_INFO(ge);
  11121         SOC_CONTROL_UNLOCK(unit);
  11122     } else if (old_value == 4) {
  11123         /* The block was originally a single high-speed port */
  11124         SOC_CONTROL_LOCK(unit);
  11125         rv = soc_mem_read(unit, SOC_PORT_MEM_TAB(unit, port),
  11126                 MEM_BLOCK_ANY, SOC_PORT_MOD_OFFSET(unit, port), &pent);
  11127         if (BCM_FAILURE(rv)) {
  11128             SOC_CONTROL_UNLOCK(unit);
  11129             return rv;
  11130         }
  11131         port_type = soc_PORT_TABm_field32_get(unit, &pent, PORT_TYPEf);
  11132         switch(port_type) {
  11133           case 0 : /* xe */
  11134             SOC_PBMP_PORT_ADD(si->xe.bitmap, port);
  11135             SOC_PBMP_PORT_ADD(si->ether.bitmap, port);
  11136             SOC_PBMP_PORT_REMOVE(si->hg.bitmap, port);
  11137             SOC_PBMP_PORT_REMOVE(si->st.bitmap, port);
  11138             break;
  11139           case 1 : /* hg */
  11140             SOC_PBMP_PORT_ADD(si->hg.bitmap, port);
  11141             SOC_PBMP_PORT_ADD(si->st.bitmap, port);
  11142             SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port);
  11143             SOC_PBMP_PORT_REMOVE(si->ether.bitmap, port);
  11144           default:
  11145             break;
  11146         }
  11147         SOC_PBMP_PORT_REMOVE(si->ge.bitmap, port);
  11148 	switch (dev_id) {
  11149 	case BCM56526_DEVICE_ID:
  11150 	  si->port_speed_max[port] = 13000;
  11151 	  break;
  11152 	case BCM56636_DEVICE_ID:
  11153 	case BCM56638_DEVICE_ID:
  11154 	  si->port_speed_max[port] = 12000;
  11155 	  break;
  11156 	default:
  11157 	  si->port_speed_max[port] = 10000;
  11158 	}
  11159         soc_port_cmap_set(unit, port, SOC_CTR_TYPE_XE);
  11160         for (i = port + 1; i < port + 4; i++) {
  11161             SOC_PBMP_PORT_ADD(si->ge.disabled_bitmap, i);
  11162             SOC_PBMP_PORT_ADD(si->ether.disabled_bitmap, i);
  11163             SOC_PBMP_PORT_ADD(si->port.disabled_bitmap, i);
  11164             SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, i);
  11165         }
  11166         RECONFIGURE_TR2_PORT_TYPE_INFO(ether);
  11167         RECONFIGURE_TR2_PORT_TYPE_INFO(st);
  11168         RECONFIGURE_TR2_PORT_TYPE_INFO(hg);
  11169         RECONFIGURE_TR2_PORT_TYPE_INFO(ge);
  11170         SOC_CONTROL_UNLOCK(unit);
  11171     }
  11172 #undef RECONFIGURE_PORT_TYPE_INFO
  11173     soc_dport_map_update(unit);
  11174 
  11175     return BCM_E_NONE;
  11176 }
  11177 #endif /* BCM_TRIUMPH2_SUPPORT */
  11178 
  11179 #ifdef BCM_TRIDENT2_SUPPORT
  11180 /*
  11181  * Function:
  11182  *      _bcm_td2_flexport_recover
  11183  * Purpose:
  11184  *     To recover/reconstruct the HL port configuration
  11185  *     during warmboot. This is a 'level one' warmboot
  11186  *     recovery. It depends on the reg configuration of
  11187  *     XLPORT_MODE_REGr which maintains the
  11188  *     flexport config of the HL ports that was done
  11189  *     in coldboot mode.
  11190  * Parameters:
  11191  *      unit - StrataSwitch unit number.
  11192  *      port - Port number of the HL
  11193  *             flexport controlling port.
  11194  * Returns:
  11195  *      BCM_E_XXX
  11196  */
  11197 STATIC int
  11198 _bcm_td2_flexport_recover(int unit, bcm_port_t port)
  11199 {
  11200     soc_info_t *si = &SOC_INFO(unit);
  11201     int i, phy_port, phy_port_base, port_base, lp;
  11202     int mode, phy_port_actived[4];
  11203     uint32 rval;
  11204 
  11205     phy_port      = si->port_l2p_mapping[port];
  11206     phy_port_base = (phy_port & ~0x3) + 1;
  11207     port_base     = si->port_p2l_mapping[phy_port_base];
  11208 
  11209     if (phy_port == -1 || phy_port != phy_port_base) {
  11210         return BCM_E_NONE;
  11211     }
  11212 
  11213     sal_memset(phy_port_actived, 0, sizeof(phy_port_actived));
  11214 
  11215     /* Get the current mode */
  11216     if (SOC_USE_PORTCTRL(unit)) {
  11217         BCM_IF_ERROR_RETURN(bcmi_esw_portctrl_mode_get(unit, port, &mode));
  11218     } else {
  11219         SOC_IF_ERROR_RETURN(READ_XLPORT_MODE_REGr(unit, port_base, &rval));
  11220         mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval,
  11221                                  XPORT0_CORE_PORT_MODEf);
  11222     }
  11223 
  11224     switch(mode) {
  11225     case SOC_TD2_PORT_MODE_QUAD:
  11226         phy_port_actived[0] =
  11227         phy_port_actived[1] =
  11228         phy_port_actived[2] =
  11229         phy_port_actived[3] = 1;
  11230         break;
  11231     case SOC_TD2_PORT_MODE_TRI_012:
  11232         phy_port_actived[0] =
  11233         phy_port_actived[1] =
  11234         phy_port_actived[2] = 1;
  11235         break;
  11236     case SOC_TD2_PORT_MODE_TRI_023:
  11237         phy_port_actived[0] =
  11238         phy_port_actived[2] =
  11239         phy_port_actived[3] = 1;
  11240         break;
  11241     case SOC_TD2_PORT_MODE_DUAL:
  11242         phy_port_actived[0] =
  11243         phy_port_actived[2] = 1;
  11244         break;
  11245     case SOC_TD2_PORT_MODE_SINGLE:
  11246         phy_port_actived[0] = 1;
  11247         break;
  11248     default:
  11249         return SOC_E_FAIL;
  11250     }
  11251 
  11252     SOC_CONTROL_LOCK(unit);
  11253     for (i = 0; i < 4; i++) {
  11254         lp = si->port_p2l_mapping[phy_port_base + i];
  11255         if (lp != -1 &&
  11256             BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), lp)) {
  11257             if (phy_port_actived[i]) {
  11258                 SOC_PBMP_PORT_REMOVE(/* port(s) to be added */
  11259                     SOC_PORT_DISABLED_BITMAP(unit, all), lp);
  11260             } else {
  11261                 SOC_PBMP_PORT_ADD(   /* port(s) to be removed */
  11262                     SOC_PORT_DISABLED_BITMAP(unit, all), lp);
  11263             }
  11264         }
  11265     }
  11266     SOC_CONTROL_UNLOCK(unit);
  11267 
  11268     return SOC_E_NONE;
  11269 }
  11270 #endif /* BCM_TRIDENT2_SUPPORT */
  11271 
  11272 void bcm_esw_port_mdix_wb_update(int unit)
  11273 {
  11274     int p;
  11275     bcm_port_mdix_t mdix;
  11276 
  11277     PBMP_ITER(PBMP_PORT_ALL(unit), p) {
  11278        /* Intentionally return value is not checked as this function
  11279         * is called to wb update mdix value for the port, if it exists.
  11280         */ 
  11281         bcm_esw_port_mdix_get(unit,p,&mdix);
  11282         LOG_VERBOSE(BSL_LS_BCM_PORT,
  11283                        (BSL_META_U(unit, "Port %d MDIX udate in wb !!\n"), p));
  11284     }
  11285 }
  11286 
  11287 int
  11288 _bcm_esw_port_wb_recover(int unit)
  11289 {
  11290     int rv = BCM_E_NONE;
  11291 
  11292 #if defined(BCM_TRX_SUPPORT)
  11293     if (SOC_IS_TRX(unit)) {
  11294         int alloc_sz, use_pbmp = FALSE;
  11295         uint8 *port_state;
  11296         uint16 recovered_ver;
  11297         bcm_port_t port;
  11298         _bcm_port_info_t *pinfo;
  11299         bcm_pbmp_t dtm_pbmp;
  11300         int stable_size;
  11301         soc_scache_handle_t scache_handle;
  11302 #if defined(BCM_SABER2_SUPPORT)
  11303         uint32 rval = 0, oamp_status = 0;
  11304 #endif
  11305 #ifdef BCM_TRIUMPH2_SUPPORT
  11306         pbmp_t port_bitmap;
  11307 #ifdef BCM_TRIDENT_SUPPORT
  11308         soc_info_t *si = &SOC_INFO(unit);
  11309         int _port_lanes_valid = 0;
  11310 #ifdef BCM_TRIUMPH3_SUPPORT
  11311         int _port_num_lanes[SOC_MAX_NUM_PORTS] = {0};
  11312 #endif /* BCM_TRIUMPH3_SUPPORT */
  11313 #endif /* BCM_TRIDENT_SUPPORT */
  11314 #endif /* BCM_TRIUMPH2_SUPPORT */
  11315         bcm_pbmp_t all_pbmp;
  11316         int realloc_size = 0;
  11317 #ifdef  BCM_TOMAHAWK_SUPPORT
  11318         uint32 asf_wbmem_sz = 0;
  11319         uint16 scache_ver = BCM_PORT_WB_DEFAULT_VERSION;
  11320 
  11321         /* Switch Latency Bypass WB will move to a different module later */
  11322         uint32 latency_wbmem_sz = 0;
  11323 #endif
  11324 
  11325         BCM_PBMP_CLEAR(all_pbmp);
  11326         BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  11327 
  11328         SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_PORT,
  11329                               BCM_PORT_WB_SCACHE_PART_DEFAULT);
  11330         rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE,
  11331                                      0, (uint8**)&port_state,
  11332                                      BCM_PORT_WB_DEFAULT_VERSION, &recovered_ver);
  11333         if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
  11334             return rv;
  11335         }
  11336 
  11337 #if defined(BCM_SABER2_SUPPORT)
  11338         if(SOC_IS_SABER2(unit)) {
  11339             SOC_IF_ERROR_RETURN(READ_OAMP_ENABLEr(unit, &rval));
  11340             oamp_status = soc_reg_field_get(unit, OAMP_ENABLEr, rval, ENABLEf);
  11341         }
  11342 #endif
  11343 #ifdef BCM_KATANA2_SUPPORT
  11344         if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  11345 #if defined(BCM_SABER2_SUPPORT)
  11346             if ( SOC_IS_SABER2(unit) && !SOC_IS_METROLITE(unit) &&
  11347                 (recovered_ver < BCM_PORT_WB_VERSION_1_10) ) {
  11348                 BCM_IF_ERROR_RETURN(_bcm_sb2_wb_v1_flexio_pbmp_update(unit, &all_pbmp));
  11349             } else
  11350 #endif
  11351             {
  11352             BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  11353 #if defined(BCM_SABER2_SUPPORT)
  11354                 bcm_sb2_wb_v2_flexio_update = 1;
  11355 #endif
  11356             }
  11357         }
  11358         if (soc_feature(unit, soc_feature_linkphy_coe) ||
  11359             soc_feature(unit, soc_feature_subtag_coe)) {
  11360             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  11361         }
  11362 #endif
  11363 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  11364         if (SOC_IS_TD2P_TT2P(unit)) {
  11365             BCM_IF_ERROR_RETURN(bcm_td2p_flexport_pbmp_update(unit,
  11366                                                  &all_pbmp));
  11367         }
  11368 #endif
  11369 #ifdef BCM_MONTEREY_SUPPORT
  11370         if (SOC_IS_MONTEREY(unit)) {
  11371             BCM_IF_ERROR_RETURN(bcm_monterey_flexport_pbmp_update(unit, &all_pbmp));
  11372         }
  11373 #endif
  11374 #ifdef BCM_APACHE_SUPPORT
  11375         if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
  11376             BCM_IF_ERROR_RETURN(bcm_apache_flexport_pbmp_update(unit, &all_pbmp));
  11377         }
  11378 #endif
  11379 
  11380         alloc_sz = 0;
  11381         SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
  11382         PBMP_ITER(all_pbmp, port) {
  11383 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
  11384             if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit))) {
  11385                 /* vp entry and vlan prot ptr */
  11386                 alloc_sz += (sizeof(int) + sizeof(uint32));
  11387             }
  11388 #endif
  11389             alloc_sz += sizeof(int); /* vp count */
  11390         }
  11391         alloc_sz += sizeof(bcm_pbmp_t); /* Bitmap of dtag_mode == NONE */
  11392         PBMP_ITER(all_pbmp, port) {
  11393             if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) {
  11394                 if (SOC_REG_IS_VALID(unit, COSMASKr)) {
  11395                     alloc_sz += sizeof(uint32);
  11396                 } else {
  11397                     alloc_sz += sizeof(_bcm_port_metering_info_t);
  11398                 }
  11399                 alloc_sz += sizeof(uint8);
  11400             }
  11401         }
  11402 
  11403 #ifdef BCM_TRIDENT_SUPPORT
  11404         if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) &&
  11405             soc_feature(unit, soc_feature_flex_port)) {
  11406             alloc_sz += (SOC_MAX_NUM_PORTS * sizeof(int));
  11407         }
  11408 #endif
  11409 
  11410         /* Restore SW RX LOS status */
  11411         PBMP_ITER(all_pbmp, port) {
  11412             alloc_sz += sizeof(uint8);
  11413         }
  11414 
  11415 #ifdef BCM_TRIDENT2_SUPPORT
  11416         if (SOC_IS_TD2_TT2(unit)) {
  11417             /* Allocate size for port enable status */
  11418             PBMP_ITER(all_pbmp, port) {
  11419                 alloc_sz += sizeof(int);
  11420             }
  11421         }
  11422 #endif /* BCM_TRIDENT2_SUPPORT */
  11423 #ifdef BCM_TRIUMPH3_SUPPORT
  11424         if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit)) {
  11425             alloc_sz += 2 * sizeof(((_port_ibod_ctrl_t *)0)->rrbyt)
  11426                             + sizeof((((_port_ibod_ctrl_t *)0)->event_count));
  11427         }
  11428 #endif /* BCM_TRIUMPH3_SUPPORT */
  11429 #if defined(BCM_TRIUMPH3_SUPPORT)
  11430         if (soc_feature(unit, soc_feature_epc_linkflap_recover)) {
  11431             int port_forward_size;
  11432             BCM_IF_ERROR_RETURN(
  11433                 _bcm_port_force_forward_scache_size(unit, &port_forward_size));
  11434             alloc_sz += port_forward_size;
  11435         }
  11436 #endif /* defined(BCM_TRIUMPH3_SUPPORT) */
  11437 
  11438 #ifdef  BCM_TOMAHAWK_SUPPORT
  11439         if (SOC_WARM_BOOT(unit)) {
  11440             BCM_IF_ERROR_RETURN(
  11441                 bcm_esw_scache_ver_get(unit, BCM_MODULE_PORT, &scache_ver));
  11442         }
  11443         /* ASF WB */
  11444         rv = _bcm_esw_asf_wb_memsz_get(unit, &asf_wbmem_sz, scache_ver);
  11445         if (BCM_E_NONE == rv) {
  11446             alloc_sz += asf_wbmem_sz;
  11447         }
  11448 
  11449         /* Switch Latency Bypass WB */
  11450         rv = bcmi_esw_switch_latency_wb_memsz_get(unit, &latency_wbmem_sz,
  11451                                                   scache_ver);
  11452         if (BCM_E_NONE == rv) {
  11453             alloc_sz += latency_wbmem_sz;
  11454         }
  11455 #endif /* BCM_TOMAHAWK_SUPPORT */
  11456 
  11457         /*IFG WB*/
  11458         if (soc_feature(unit, soc_feature_xmac) ||
  11459                 soc_feature(unit, soc_feature_xlmac) ||
  11460                 soc_feature(unit, soc_feature_cmac) ||
  11461                 soc_feature(unit, soc_feature_clmac)) {
  11462             PBMP_ITER(all_pbmp, port) {
  11463                 alloc_sz += sizeof(uint32);
  11464             }
  11465         }
  11466         /* PORT DSCP MAP SETTING */
  11467         if (soc_feature(unit, soc_feature_dscp) &&
  11468             soc_feature(unit, soc_feature_egr_dscp_map_per_port)) {
  11469             /* Allocate size for port dscp map setting status */
  11470             PBMP_ITER(all_pbmp, port) {
  11471                 alloc_sz += sizeof(int);
  11472             }
  11473         }
  11474 
  11475 #ifdef  BCM_TOMAHAWK_SUPPORT
  11476         if (SOC_IS_TOMAHAWK(unit)) {
  11477             /* Allocate size for port interface type */
  11478             PBMP_ITER(all_pbmp, port) {
  11479                 alloc_sz += sizeof(int);
  11480             }
  11481         }
  11482 #endif /* BCM_TOMAHAWK_SUPPORT */
  11483 
  11484         if (soc_feature(unit, soc_feature_phy_interface_wb)) {
  11485             /* Allocate size for port interface type */
  11486             PBMP_ITER(PBMP_PORT_ALL(unit), port) {
  11487                 alloc_sz += sizeof(int);
  11488             }
  11489         }
  11490 
  11491         SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_PORT,
  11492                               BCM_PORT_WB_SCACHE_PART_DEFAULT);
  11493         rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE,
  11494                                      alloc_sz, (uint8**)&port_state,
  11495                                      BCM_PORT_WB_DEFAULT_VERSION, &recovered_ver);
  11496         if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
  11497             return rv;
  11498         }
  11499         if (BCM_SUCCESS(rv)) {
  11500             PBMP_ITER(all_pbmp, port) {
  11501                 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
  11502 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
  11503                 if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit)) &&
  11504                         (recovered_ver >= BCM_PORT_WB_VERSION_1_9)) {
  11505                     /* Recover vp entry and vlan prot ptr */
  11506                     uint32 vlan_protocol_data_index = 0;
  11507                     int idxmin, idxmax, vpentry = 0;
  11508                     idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm);
  11509                     idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm);
  11510 
  11511                     sal_memcpy(&vpentry, port_state, sizeof(int));
  11512                     port_state += sizeof(int);
  11513                     if ((vpentry >= idxmin) && (vpentry <= idxmax) &&
  11514                             (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, vpentry))) {
  11515                         /* Set as explicit VID */
  11516                         _BCM_PORT_VD_PBVL_SET(pinfo, vpentry);
  11517                     }
  11518 
  11519                     sal_memcpy(&vlan_protocol_data_index, port_state,
  11520                             sizeof(uint32));
  11521                     port_state += sizeof(uint32);
  11522                         pinfo->vp_count = 0;
  11523                     /* update vlan port protocol data memory */
  11524                     if (!IS_LB_PORT(unit, port)) {
  11525                         BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
  11526                                     _BCM_CPU_TABS_ETHER,
  11527                                     VLAN_PROTOCOL_DATA_INDEXf,
  11528                                     vlan_protocol_data_index / 16));
  11529 
  11530                         pinfo->vlan_prot_ptr = vlan_protocol_data_index;
  11531                         BCM_IF_ERROR_RETURN(
  11532                                 _bcm_port_vlan_protocol_data_entry_reference (unit,
  11533                                     vlan_protocol_data_index, 16));
  11534                     }
  11535                 }
  11536 #endif
  11537                 /* In Apache information is saved and recovered for 76 ports which is
  11538                  * greater than SOC_MAX_NUM_PORTS value of 75. These checks are
  11539                  * needed to prevent invalid memory access.
  11540                  */
  11541                 if (port < SOC_MAX_NUM_PORTS) {
  11542                 /* Recover VP reference counts */
  11543                     sal_memcpy(&(pinfo->vp_count), port_state, sizeof(pinfo->vp_count));
  11544                 }
  11545                 port_state += sizeof(int);
  11546             }
  11547 #ifdef BCM_KATANA2_SUPPORT
  11548             if (SOC_IS_KATANA2(unit) && (recovered_ver >= BCM_PORT_WB_VERSION_1_9)) {
  11549                 /* Keep one extra reference to the default profile */
  11550                 BCM_IF_ERROR_RETURN(
  11551                         _bcm_port_vlan_protocol_data_entry_reference (unit,
  11552                             0, 16));
  11553             }
  11554 #endif
  11555             /* Recover dtag_mode port bitmap */
  11556             sal_memcpy(&dtm_pbmp, port_state, sizeof(dtm_pbmp));
  11557             port_state += sizeof(dtm_pbmp);
  11558             use_pbmp = TRUE; /* Cached info available */
  11559 
  11560             if (recovered_ver >= BCM_PORT_WB_VERSION_1_1) {
  11561                 PBMP_ITER(all_pbmp, port) {
  11562                     if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) {
  11563                         /* Recover port tx stop related info */
  11564                         if (SOC_REG_IS_VALID(unit, COSMASKr)) {
  11565                             if (port < SOC_MAX_NUM_PORTS) {
  11566                             sal_memcpy(&(PORT(unit, port).cosmask), port_state,
  11567                                        sizeof(uint32));
  11568                             }
  11569                             port_state += sizeof(uint32);
  11570                         } else {
  11571                             if (port < SOC_MAX_NUM_PORTS) {
  11572                             sal_memcpy(&(PORT(unit, port).m_info), port_state,
  11573                                        sizeof(_bcm_port_metering_info_t));
  11574                             }
  11575                             port_state += sizeof(_bcm_port_metering_info_t);
  11576                         }
  11577                         if (port < SOC_MAX_NUM_PORTS) {
  11578                         /* Recover flags */
  11579                         sal_memcpy(&(PORT(unit, port).flags), port_state, sizeof(uint8));
  11580                         }
  11581                         port_state += sizeof(uint8);
  11582                     }
  11583                 }
  11584 #if defined(BCM_TOMAHAWK_SUPPORT)
  11585                 if (SOC_IS_TOMAHAWK(unit)) {
  11586                     PBMP_ALL_ITER(unit, port) {
  11587                         SOC_IF_ERROR_RETURN(soc_th_port_speed_recover(unit, port));
  11588                     }
  11589                 }
  11590 #endif
  11591 #ifdef BCM_TRIDENT_SUPPORT
  11592                 if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) &&
  11593                     soc_feature(unit, soc_feature_flex_port)) {
  11594                     int num_lanes = 0;
  11595                     if (SOC_IS_TD_TT(unit)) {
  11596                         PBMP_ALL_ITER(unit, port) {
  11597                             sal_memcpy(&num_lanes, port_state, sizeof(int));
  11598                             port_state += sizeof(int);
  11599                             if (si->port_num_lanes[port] != num_lanes) {
  11600 #if defined(BCM_TOMAHAWK_SUPPORT)
  11601                                 if (SOC_IS_TOMAHAWK(unit)) {
  11602                                     SOC_IF_ERROR_RETURN
  11603                                         (soc_th_flexport_recover(unit, port));
  11604                                 }
  11605 #endif /* BCM_TOMAHAWK_SUPPORT */
  11606 #ifdef BCM_TRIDENT2_SUPPORT
  11607                                 if (SOC_IS_TD2_TT2(unit) &&
  11608                                    (!(SOC_IS_TD2P_TT2P(unit) ||
  11609                                       SOC_IS_APACHE(unit) ||
  11610                                       SOC_IS_TOMAHAWK2(unit)))) {
  11611                                     BCM_IF_ERROR_RETURN(
  11612                                         _bcm_td2_flexport_recover(unit, port));
  11613                                 }
  11614 #endif /* BCM_TRIDENT2_SUPPORT */
  11615                                 si->port_num_lanes[port] = num_lanes;
  11616                                 _port_lanes_valid++;
  11617                             }
  11618                         }
  11619                     }
  11620 #ifdef BCM_TRIUMPH3_SUPPORT
  11621                     else if (SOC_IS_TRIUMPH3(unit)) {
  11622                         PBMP_ALL_ITER(unit, port) {
  11623                             sal_memcpy(&_port_num_lanes[port], port_state,
  11624                                        sizeof(int));
  11625                             port_state += sizeof(int);
  11626                             _port_lanes_valid++;
  11627                         }
  11628                     }
  11629 #endif /* BCM_TRIUMPH2_SUPPORT */
  11630                     if (SOC_IS_TD_TT(unit) && (_port_lanes_valid > 0)) {
  11631                         /* Call PHY probe for flex port config to take effect */
  11632                         if ((rv = bcm_esw_port_probe(unit, PBMP_PORT_ALL(unit),
  11633                                &port_bitmap)) != BCM_E_NONE) {
  11634                             LOG_ERROR(BSL_LS_BCM_PORT, \
  11635                                       (BSL_META_U(unit, \
  11636                                                   "Error unit %d:\
  11637                                                   Failed port probe: %s\n"),
  11638                                        unit, bcm_errmsg(rv)));
  11639                             return rv;
  11640                         }
  11641                     }
  11642                 }
  11643 #endif /* BCM_TRIDENT_SUPPORT */
  11644             } else {
  11645                 PBMP_ITER(all_pbmp, port) {
  11646                     if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) {
  11647                         /* Recover port tx stop related info */
  11648                         if (SOC_REG_IS_VALID(unit, COSMASKr)) {
  11649                             realloc_size += sizeof(uint32);
  11650                         } else {
  11651                             realloc_size += sizeof(_bcm_port_metering_info_t);
  11652                         }
  11653                         /* Recover flags */
  11654                         realloc_size += sizeof(uint8);
  11655                     }
  11656                 }
  11657             }
  11658 
  11659             if (recovered_ver >= BCM_PORT_WB_VERSION_1_2) {
  11660                 uint8 rx_los = 0;
  11661                 PBMP_ITER(all_pbmp, port) {
  11662 #if defined(BCM_SABER2_SUPPORT)
  11663                     if(SOC_IS_SABER2(unit)) {
  11664                         if ((port == SOC_SB2_SAT_OAMP_PHY_PORT_NUMBER) && (oamp_status == 1)){
  11665                             continue;
  11666                         }
  11667                     }
  11668 #endif
  11669                     /* Recover RX_LOS */
  11670                     rx_los = *port_state;
  11671                     port_state += sizeof(uint8);
  11672 
  11673                     if (IS_E_PORT(unit, port)) {
  11674                         /* Call PHY control for RX_lOS config to take effect */
  11675                         if (rx_los == BCM_PORT_PHY_CONTROL_RX_LOS_NONE ||
  11676                             rx_los == BCM_PORT_PHY_CONTROL_RX_LOS_SOFTWARE) {
  11677 
  11678                             if (!soc_feature(unit, soc_feature_no_sw_rx_los)){
  11679                             rv = bcm_esw_port_phy_control_set(unit, port,
  11680                                   BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS, rx_los);
  11681                             if (BCM_FAILURE(rv) && (rv != BCM_E_UNAVAIL)) {
  11682                                 LOG_ERROR(BSL_LS_BCM_PORT,
  11683                                           (BSL_META_U(unit,
  11684                                                       "Error unit %d: "
  11685                                                       "Failed port phy control set: %s\n"),
  11686                                            unit, bcm_errmsg(rv)));
  11687                                 return rv;
  11688                             }
  11689                         }
  11690                     }
  11691                 }
  11692                 }
  11693             } else {
  11694                 PBMP_ITER(all_pbmp, port) {
  11695                     if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)
  11696                         && (stable_size > 0)) {
  11697                         /* Recover SW RX LOS status */
  11698                         realloc_size += sizeof(uint8);
  11699                     }
  11700                 }
  11701             }
  11702 
  11703 #ifdef BCM_TRIDENT2_SUPPORT
  11704             if (SOC_IS_TD2_TT2(unit)) {
  11705                 if (recovered_ver >= BCM_PORT_WB_VERSION_1_3) {
  11706                     PBMP_ITER(all_pbmp, port) {
  11707                         if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)
  11708                             && (stable_size > 0)) {
  11709                             if (port < SOC_MAX_NUM_PORTS) {
  11710                             /* Recover port enable status */
  11711                             sal_memcpy(&(PORT(unit, port).enable),
  11712                                         port_state, sizeof(int));
  11713                             }
  11714                             port_state += sizeof(int);
  11715                         }
  11716                     }
  11717                 } else {
  11718                     PBMP_ITER(all_pbmp, port) {
  11719                         if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)
  11720                             && (stable_size > 0)) {
  11721                             /* Recover SW port enable status */
  11722                             realloc_size += sizeof(int);
  11723                         }
  11724                     }
  11725                 }
  11726             }
  11727 #endif /* BCM_TRIDENT2_SUPPORT */
  11728 #ifdef BCM_TRIUMPH3_SUPPORT
  11729         if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit)) {
  11730             if ((recovered_ver >= BCM_PORT_WB_VERSION_1_4) && _port_ibod_ctrl[unit]) {
  11731                 sal_memcpy(_port_ibod_ctrl[unit]->rrbyt, port_state,
  11732                            sizeof(((_port_ibod_ctrl_t *)0)->rrbyt));
  11733                 port_state += sizeof(((_port_ibod_ctrl_t *)0)->rrbyt);
  11734                 sal_memcpy(_port_ibod_ctrl[unit]->rrpkt, port_state,
  11735                            sizeof(((_port_ibod_ctrl_t *)0)->rrpkt));
  11736                 port_state += sizeof(((_port_ibod_ctrl_t *)0)->rrpkt);
  11737                 sal_memcpy(&(_port_ibod_ctrl[unit]->event_count), port_state,
  11738                              sizeof(((_port_ibod_ctrl_t *)0)->event_count));
  11739                 port_state += sizeof(((_port_ibod_ctrl_t *)0)->event_count);
  11740             } else {
  11741                 realloc_size +=  sizeof(((_port_ibod_ctrl_t *)0)->rrbyt);
  11742                 realloc_size +=  sizeof(((_port_ibod_ctrl_t *)0)->rrpkt);
  11743                 realloc_size += sizeof(((_port_ibod_ctrl_t *)0)->event_count);
  11744             }
  11745         }
  11746             /*
  11747              * Recover the port force forward information from scache.
  11748              * If the recovered version is lower than 1.5, allocate
  11749              * space in scache for any further sync.
  11750              */
  11751             if (soc_feature(unit, soc_feature_epc_linkflap_recover)) {
  11752                if (recovered_ver >= BCM_PORT_WB_VERSION_1_5) {
  11753                    BCM_IF_ERROR_RETURN(
  11754                        _bcm_port_force_forward_reinit(unit, &port_state));
  11755                } else {
  11756                    bcm_port_t egr_port;
  11757                    int enabled = 0;
  11758                    int port_forward_size = 0;
  11759                    PBMP_ITER(all_pbmp, port) {
  11760                        BCM_IF_ERROR_RETURN
  11761                            (bcm_esw_port_force_forward_get(unit, port,
  11762                                                    &egr_port, &enabled));
  11763                        if (enabled) {
  11764                            _bcm_port_force_forward_add(unit, port,
  11765                                                    egr_port);
  11766                        }
  11767                    }
  11768                    BCM_IF_ERROR_RETURN(
  11769                        _bcm_port_force_forward_scache_size(unit, 
  11770                                         &port_forward_size));
  11771                    realloc_size += port_forward_size;
  11772                }
  11773             }
  11774 #endif /* defined(BCM_TRIUMPH3_SUPPORT) */
  11775 
  11776 #ifdef  BCM_TOMAHAWK_SUPPORT
  11777             if (recovered_ver >= BCM_PORT_WB_VERSION_1_6) {
  11778                 /* ASF WB Recovery */
  11779                 rv = _bcm_esw_asf_wb_recover(unit, port_state, recovered_ver);
  11780                 if (BCM_E_NONE != rv) {
  11781                     LOG_ERROR(BSL_LS_BCM_PORT, \
  11782                               (BSL_META_U(unit, \
  11783                                           "Error unit %d:\
  11784                                           ASF Warmboot Recovery Failed: %s\n"), \
  11785                                unit, bcm_errmsg(rv)));
  11786                     return rv;
  11787                 }
  11788                 port_state += asf_wbmem_sz;
  11789             }
  11790 
  11791             if (recovered_ver >= BCM_PORT_WB_VERSION_1_6) {
  11792                 /* Switch Latency Bypass WB Recovery */
  11793                 rv = bcmi_esw_switch_latency_wb_recover(unit, port_state, recovered_ver);
  11794                 if (BCM_E_NONE != rv) {
  11795                     LOG_ERROR(BSL_LS_BCM_PORT, \
  11796                               (BSL_META_U(unit, \
  11797                                           "Error unit %d:\
  11798                                           Switch Latency Bypass \
  11799                                           Warmboot Recovery Failed: %s\n"), \
  11800                                unit, bcm_errmsg(rv)));
  11801                     return rv;
  11802                 }
  11803                 port_state += latency_wbmem_sz;
  11804             }
  11805 
  11806             /* sflow WB recovery */
  11807             rv = _bcm_esw_sflow_wb_recover(unit);
  11808             if (BCM_E_NONE != rv) {
  11809             LOG_ERROR(BSL_LS_BCM_PORT, (BSL_META_U(unit, "Error \
  11810                       unit %d: sflow Warmboot Recovery Failed: %s\n"), unit,
  11811                       bcm_errmsg(rv)));
  11812             return rv;
  11813             }
  11814 #endif /* BCM_TOMAHAWK_SUPPORT */
  11815             /*IFG WB*/
  11816             if (soc_feature(unit, soc_feature_xmac) ||
  11817                     soc_feature(unit, soc_feature_xlmac) ||
  11818                     soc_feature(unit, soc_feature_cmac) ||
  11819                     soc_feature(unit, soc_feature_clmac)) {
  11820                 if (recovered_ver >= BCM_PORT_WB_VERSION_1_7) {
  11821                     BCM_IF_ERROR_RETURN(
  11822                         _bcm_esw_port_ifg_wb_reinit(unit, &port_state));
  11823                 } else {
  11824                     PBMP_ITER(all_pbmp, port) {
  11825                         if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)
  11826                             && (stable_size > 0)) {
  11827                             realloc_size += sizeof(uint32);
  11828                         }
  11829                     }
  11830                 }
  11831             }
  11832             /* PORT DSCP MAP SETTING */
  11833             if (soc_feature(unit, soc_feature_dscp) &&
  11834                 soc_feature(unit, soc_feature_egr_dscp_map_per_port)) {
  11835                 if (recovered_ver >= BCM_PORT_WB_VERSION_1_11) {
  11836                     PBMP_ITER(all_pbmp, port) {
  11837                         if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)
  11838                             && (stable_size > 0)) {
  11839                             /* Recover port dscp map status */
  11840                             sal_memcpy(&(PORT(unit, port).port_dscp_map_set),
  11841                                         port_state, sizeof(int));
  11842                             port_state += sizeof(int);
  11843                             if (PORT(unit, port).port_dscp_map_set) {
  11844                                 BCM_IF_ERROR_RETURN(
  11845                                     _bcm_egr_dscp_table_entry_reference(
  11846                                         unit, port * _BCM_QOS_MAP_CHUNK_EGR_DSCP, 
  11847                                         _BCM_QOS_MAP_CHUNK_EGR_DSCP));
  11848                             }
  11849                         }
  11850                     }
  11851                 } else {
  11852                     PBMP_ITER(all_pbmp, port) {
  11853                         if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit)
  11854                             && (stable_size > 0)) {
  11855                             /* Recover SW port dscp map status */
  11856                             realloc_size += sizeof(int);
  11857                         }
  11858                     }
  11859                 }
  11860             }
  11861             
  11862 #ifdef  BCM_TOMAHAWK_SUPPORT
  11863             if (SOC_IS_TOMAHAWK(unit) && recovered_ver >= BCM_PORT_WB_VERSION_1_12) {
  11864                 /* Recover port interface type */
  11865                 int pif;
  11866                 PBMP_ITER(all_pbmp, port) {
  11867                     if (IS_XE_PORT(unit, port) ||
  11868                         IS_CE_PORT(unit, port) ||
  11869                         IS_HG_PORT(unit, port) ||
  11870                         IS_GE_PORT(unit, port) ||
  11871                         IS_MANAGEMENT_PORT(unit, port)) {
  11872                             sal_memcpy(&pif, port_state, sizeof(int));
  11873                             port_state += sizeof(int);
  11874                             SOC_IF_ERROR_RETURN
  11875                                 (soc_phyctrl_interface_set(unit, port, pif));
  11876                     }
  11877                 }
  11878             }
  11879 #endif /* BCM_TOMAHAWK_SUPPORT */
  11880             if (soc_feature(unit, soc_feature_phy_interface_wb) &&
  11881                 (recovered_ver >= BCM_PORT_WB_VERSION_1_13)) {
  11882                 /* Recover port interface type */
  11883                 int pif;
  11884 
  11885                 PBMP_ITER(PBMP_PORT_ALL(unit), port) {
  11886                     sal_memcpy(&pif, port_state, sizeof(int));
  11887                     port_state += sizeof(int);
  11888                     if (pif) {
  11889                         SOC_IF_ERROR_RETURN
  11890                                 (soc_phyctrl_interface_set(unit, port, pif));
  11891                     }
  11892                 }
  11893             }
  11894 
  11895             if (realloc_size > 0) {
  11896                 SOC_IF_ERROR_RETURN
  11897                     (soc_scache_realloc(unit, scache_handle, realloc_size));
  11898             }
  11899         } else {
  11900             /*
  11901              * No level-2 cache configured. Proceed to Level-1 only recovery
  11902              */
  11903             BCM_PBMP_CLEAR(dtm_pbmp); /* Default is dtag_mode == NONE */
  11904 #if defined(BCM_TRIUMPH3_SUPPORT)
  11905             if (soc_feature(unit, soc_feature_epc_linkflap_recover)) {
  11906                 bcm_port_t egr_port;
  11907                 int enabled = 0;
  11908 
  11909                 PBMP_ITER(all_pbmp, port) {
  11910                     SOC_IF_ERROR_RETURN
  11911                         (bcm_esw_port_force_forward_get(unit, port,
  11912                                                 &egr_port, &enabled));
  11913                     if (enabled) {
  11914                         _bcm_port_force_forward_add(unit, port,
  11915                                                 egr_port);
  11916                     }
  11917                 }
  11918             }
  11919 #endif /* defined(BCM_TRIUMPH3_SUPPORT) */
  11920         }
  11921 
  11922 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) || \
  11923     defined(BCM_KATANA2_SUPPORT)
  11924         if (SOC_IS_TOMAHAWK(unit) || SOC_IS_TOMAHAWK2(unit) ||
  11925             SOC_IS_TRIDENT3X(unit) || SOC_IS_KATANA2(unit)) {
  11926             /* Recover port vlan action profile */
  11927             rv = _bcm_th_port_vlan_action_profile_reinit(unit);
  11928             if (BCM_FAILURE(rv)) {
  11929                 return rv;
  11930             }
  11931         }
  11932 #endif
  11933 
  11934         /* Recover DT mode */
  11935         rv = _bcm_trx_port_dtag_mode_reinit(unit, dtm_pbmp, use_pbmp);
  11936         if (BCM_FAILURE(rv)) {
  11937             return rv;
  11938         }
  11939 #ifdef BCM_TRIUMPH2_SUPPORT
  11940         if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  11941             /* Recover ING_PRI_CNG_MAP references */
  11942             port_tab_entry_t pent;
  11943             int ptr;
  11944             uint32 ipc_ref_bmp[3];
  11945             /* Required: ING_PRI_CNG_MAP size <= 3 * 32 * 16 = 1536 */
  11946 
  11947             SHR_BITCLR_RANGE(ipc_ref_bmp, 0, 3*32);
  11948 
  11949             /* Read port pointer, recover reference count */
  11950             PBMP_ITER(all_pbmp, port) {
  11951 #ifdef BCM_TRIDENT3_SUPPORT
  11952                 if (SOC_IS_TRIDENT3X(unit)) {
  11953                     rv = _bcm_esw_port_tab_get(unit, port,
  11954                                                TRUST_DOT1P_PTRf, &ptr);
  11955                     if (BCM_FAILURE(rv)) {
  11956                         break;
  11957                     }
  11958                     if (0 != ptr) {
  11959                         rv = _bcm_ing_pri_cng_map_entry_reference(unit,
  11960                                 ptr * _BCM_TD3_PRI_CNG_MAP_SIZE,
  11961                                 _BCM_TD3_PRI_CNG_MAP_SIZE);
  11962                         if (BCM_FAILURE(rv)) {
  11963                             break;
  11964                         }
  11965                     }
  11966 
  11967                     /* Recover PROTOCOL_PKT_CONTROL &
  11968                      * IGMP_MLD_PKT_CONTROL references */
  11969                     if (SOC_REG_INFO(unit, PROTOCOL_PKT_CONTROLr).regtype ==
  11970                         soc_portreg) {
  11971                         /* Memory not allocated so no need to proceed */
  11972                         continue;
  11973                     }
  11974                     rv = _bcm_esw_port_tab_get(unit, port,
  11975                                                PROTOCOL_PKT_INDEXf, &ptr);
  11976                     if (BCM_FAILURE(rv)) {
  11977                         break;
  11978                     }
  11979                     if (0 != ptr) {
  11980                         rv = _bcm_prot_pkt_ctrl_reference(unit, ptr);
  11981                         if (BCM_FAILURE(rv)) {
  11982                             break;
  11983                         }
  11984                         /* Remove default reference */
  11985                         rv = _bcm_prot_pkt_ctrl_delete(unit, 0);
  11986                         if (BCM_FAILURE(rv)) {
  11987                             break;
  11988                         }
  11989                     }
  11990                 } else
  11991 #endif
  11992                 {
  11993                     rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY,
  11994                                       SOC_PORT_MOD_OFFSET(unit, port), &pent);
  11995                     if (BCM_FAILURE(rv)) {
  11996                         break;
  11997                     }
  11998                     if (soc_feature(unit, soc_feature_color)) {
  11999                         ptr = soc_PORT_TABm_field32_get(unit, &pent,
  12000                                                         TRUST_DOT1P_PTRf);
  12001                         if (0 != ptr) {
  12002                             rv = _bcm_ing_pri_cng_map_entry_reference(unit,
  12003                                       ptr * _BCM_TR2_PRI_CNG_MAP_SIZE,
  12004                                             _BCM_TR2_PRI_CNG_MAP_SIZE);
  12005                             if (BCM_FAILURE(rv)) {
  12006                                 break;
  12007                             }
  12008                         }
  12009                     }
  12010 
  12011                     /* Recover PROTOCOL_PKT_CONTROL &
  12012                      * IGMP_MLD_PKT_CONTROL references */
  12013                     if (soc_mem_field_valid(unit, PORT_TABm,
  12014                                             PROTOCOL_PKT_INDEXf)) {
  12015                         if (SOC_REG_INFO(unit, PROTOCOL_PKT_CONTROLr).regtype ==
  12016                             soc_portreg) {
  12017                             /* ========================================== */
  12018                             /* Memory not allocated so no need to proceed */
  12019                             /* if (SOC_IS_HURRICANE(unit))                */
  12020                             /* ========================================== */
  12021                             continue;
  12022                         }
  12023                         ptr = soc_PORT_TABm_field32_get(unit, &pent,
  12024                                                         PROTOCOL_PKT_INDEXf);
  12025                         if (0 != ptr) {
  12026                             rv = _bcm_prot_pkt_ctrl_reference(unit, ptr);
  12027                             if (BCM_FAILURE(rv)) {
  12028                                 break;
  12029                             }
  12030                             /* Remove default reference */
  12031                             rv = _bcm_prot_pkt_ctrl_delete(unit, 0);
  12032                             if (BCM_FAILURE(rv)) {
  12033                                 break;
  12034                             }
  12035                         }
  12036                     }
  12037                 }
  12038             }
  12039         }
  12040         if (BCM_FAILURE(rv)) {
  12041             return rv;
  12042         }
  12043 #endif /* BCM_TRIUMPH2_SUPPORT */
  12044 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  12045         if (soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) {
  12046             port_tab_entry_t pent;
  12047             int ptr;
  12048             PBMP_ITER(all_pbmp, port) {
  12049                 if (port > SOC_MAX_NUM_PORTS) {
  12050                     break;
  12051                 }
  12052                 rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY,
  12053                                   SOC_PORT_MOD_OFFSET(unit, port), &pent);
  12054                 if (BCM_FAILURE(rv)) {
  12055                     break;
  12056                 }
  12057                 ptr = soc_PORT_TABm_field32_get(unit, &pent,
  12058                                                      MISC_PORT_PROFILE_INDEXf);
  12059                 if (0 != ptr) {
  12060                    rv  = _bcm_misc_port_profile_mem_reference(unit, ptr, 1);
  12061                    if (BCM_FAILURE(rv)) {
  12062                       break;
  12063                    }
  12064                }
  12065            }
  12066         }
  12067         if (BCM_FAILURE(rv)) {
  12068             return rv;
  12069         }
  12070 #endif
  12071 
  12072         if (soc_feature(unit, soc_feature_e2ecc)) {
  12073             rv = _bcm_esw_port_e2ecc_reinit(unit);
  12074         }
  12075         if (BCM_FAILURE(rv)) {
  12076             return rv;
  12077         }
  12078 
  12079 #ifdef BCM_TRIUMPH2_SUPPORT
  12080         /* Recover source modid egress blocking profiles */
  12081         if (soc_feature(unit, soc_feature_src_modid_blk_profile)) {
  12082             uint32 regval, srcmod_index;
  12083             int i, modid_count;
  12084 
  12085             modid_count = SOC_MODID_MAX(unit) + 1;
  12086 
  12087             PBMP_ITER(all_pbmp, port) {
  12088                 BCM_IF_ERROR_RETURN
  12089                     (READ_SRC_MODID_EGRESS_SELr(unit, port, &regval));
  12090                 if (soc_reg_field_get(unit,
  12091                             SRC_MODID_EGRESS_SELr, regval, ENABLEf)) {
  12092                     srcmod_index = soc_reg_field_get(unit,
  12093                             SRC_MODID_EGRESS_SELr, regval, SRCMOD_INDEXf);
  12094                     PORT_SRC_MOD_EGR_PROF_PTR(unit, port) = srcmod_index;
  12095                     srcmod_index *= modid_count;
  12096                     for (i = 0; i < modid_count; i++) {
  12097                         SOC_PROFILE_MEM_REFERENCE(unit,
  12098                                         PORT_SRC_MOD_EGR_PROFILE(unit),
  12099                                                   srcmod_index + i, 1);
  12100                         SOC_PROFILE_MEM_ENTRIES_PER_SET(unit,
  12101                                         PORT_SRC_MOD_EGR_PROFILE(unit),
  12102                                                         srcmod_index + i,
  12103                                                         modid_count);
  12104                     }
  12105                 }
  12106             }
  12107         }
  12108 #endif /* BCM_TRIUMPH2_SUPPORT */
  12109 
  12110 #ifdef BCM_TRIUMPH2_SUPPORT
  12111         if ((SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  12112              SOC_IS_VALKYRIE2(unit)) &&
  12113             soc_feature(unit, soc_feature_flex_port)) {
  12114             PBMP_ALL_ITER(unit, port) {
  12115                 if (_bcm_esw_valid_flex_port_controlling_port(unit, port)) {
  12116                     BCM_IF_ERROR_RETURN(_bcm_tr2_flexport_recover(unit, port));
  12117                 }
  12118             }
  12119             /* Call PHY probe for config to take effect */
  12120             if ((rv = bcm_esw_port_probe(unit, PBMP_PORT_ALL(unit),
  12121                    &port_bitmap)) != BCM_E_NONE) {
  12122                 LOG_ERROR(BSL_LS_BCM_PORT, \
  12123                           (BSL_META_U(unit, \
  12124                                       "Error unit %d:\
  12125                                       Failed port probe: %s\n"),
  12126                            unit, bcm_errmsg(rv)));
  12127                 return rv;
  12128             }
  12129         }
  12130 #endif /* BCM_TRIUMPH2_SUPPORT */
  12131 
  12132 #if defined(BCM_GREYHOUND_SUPPORT)
  12133         if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) {
  12134             /*
  12135              * Recover the ref_cnt of enabling treat packet priority as
  12136              * dot1p priority for different packet types or port controls,
  12137              * if available.
  12138              */
  12139             rv = bcmi_esw_port_treat_pktpri_as_dot1p_reinit(unit);
  12140             if (BCM_FAILURE(rv)) {
  12141                 return rv;
  12142             }
  12143         }
  12144 #endif /* BCM_GREYHOUND_SUPPORT */
  12145 
  12146         if (SOC_IS_HURRICANEX(unit) || SOC_IS_TRIUMPH2(unit) || \
  12147                 SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA(unit) || \
  12148                 SOC_IS_ENDURO(unit) || SOC_IS_GREYHOUND(unit) || \
  12149                 SOC_IS_VALKYRIE(unit)) {
  12150             bcm_esw_port_mdix_wb_update(unit);
  12151         }
  12152     }
  12153 #endif /* BCM_TRX_SUPPORT */
  12154 #if defined(BCM_RAVEN_SUPPORT)
  12155     if (SOC_IS_RAVEN(unit)) {
  12156         bcm_esw_port_mdix_wb_update(unit);
  12157     }
  12158 #endif /* BCM_RAVEN_SUPPORT */
  12159 #ifdef BCM_PREEMPTION_SUPPORT
  12160     if (soc_feature(unit, soc_feature_preemption)) {
  12161         soc_scache_handle_t scache_handle;
  12162 
  12163         SOC_SCACHE_HANDLE_SET(scache_handle,
  12164                               unit, BCM_MODULE_PORT,
  12165                               BCM_PORT_WB_SCACHE_PART_PREMMPTION);
  12166         rv = bcmi_esw_preemption_recover(unit, scache_handle);
  12167         if (BCM_FAILURE(rv)) {
  12168             return rv;
  12169         }
  12170     }
  12171 #endif /* BCM_PREEMPTION_SUPPORT */
  12172 
  12173     return rv;
  12174 }
  12175 #else
  12176 #define _bcm_port_vd_pbvl_reinit(u)  (BCM_E_NONE)
  12177 #define _bcm_esw_port_wb_recover(u)  (BCM_E_NONE)
  12178 #define _bcm_esw_port_wb_alloc(u) (BCM_E_NONE)
  12179 #endif /* BCM_WARM_BOOT_SUPPORT */
  12180 
  12181 #ifndef BCM_SW_STATE_DUMP_DISABLE
  12182 /*
  12183  * Function:
  12184  *     _bcm_esw_flexport_sw_dump
  12185  * Purpose:
  12186  *     Displays port information after flexport.
  12187  * Parameters:
  12188  *     unit - Device unit number
  12189  * Returns:
  12190  *     None
  12191  * Note:
  12192  */
  12193 void
  12194 _bcm_esw_flexport_sw_dump(int unit)
  12195 {
  12196 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  12197     if (SOC_IS_TRIDENT2PLUS(unit)) {
  12198         soc_flexport_sw_dump(unit);
  12199     }
  12200 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  12201 
  12202 #if defined(BCM_TOMAHAWK3_SUPPORT)
  12203     if (SOC_IS_TOMAHAWK3(unit)) {
  12204         soc_th3_flexport_sw_dump(unit);
  12205     }
  12206 #endif /* BCM_TOMAHAWK3_SUPPORT */
  12207 
  12208 #if defined(BCM_TOMAHAWK2_SUPPORT)
  12209     if (SOC_IS_TOMAHAWK2(unit)) {
  12210         soc_th2_flexport_sw_dump(unit);
  12211     }
  12212 #endif /* BCM_TOMAHAWK2_SUPPORT */
  12213 
  12214 #if defined(BCM_TOMAHAWK_SUPPORT)
  12215     if (SOC_IS_TOMAHAWK(unit)) {
  12216         soc_th_flexport_sw_dump(unit);
  12217     }
  12218 #endif /* BCM_TOMAHAWK_SUPPORT */
  12219 
  12220 }
  12221 
  12222 void
  12223 _bcm_esw_flexport_sw_pipe_speed_group_dump(
  12224         int unit,
  12225         int pipe,
  12226         int speed_id)
  12227 {
  12228 #if defined(BCM_TOMAHAWK_SUPPORT)
  12229     if (SOC_IS_TOMAHAWK(unit)) {
  12230         soc_th_flexport_sw_pipe_speed_group_dump(
  12231                 unit, pipe, speed_id);
  12232     }
  12233 #endif /* BCM_TOMAHAWK_SUPPORT */
  12234 }
  12235 
  12236 #endif /* BCM_SW_STATE_DUMP_DISABLE */
  12237 
  12238 static int
  12239 _bcm_esw_glp_bits_pos(int unit,
  12240                       uint8 *trunk_pos, uint8 *max_modid,
  12241                       uint8 *modid_pos, uint8 *max_port);
  12242 
  12243 #if defined(BCM_FIREBOLT_SUPPORT)
  12244 /*
  12245  * Function:
  12246  *      _bcm_port_vd_pbvl_init
  12247  * Purpose:
  12248  *      Initialization of vd_pbvl bitmap in port
  12249  * Parameters:
  12250  *      unit - StrataSwitch unit number.
  12251  * Returns:
  12252  *      BCM_E_NONE - success (or already initialized)
  12253  *      BCM_E_MEMORY - failed to allocate required memory.
  12254  */
  12255 
  12256 STATIC int
  12257 _bcm_port_vd_pbvl_init(int unit)
  12258 {
  12259     bcm_port_t port;
  12260     int idxmax;
  12261     int inds_bytes;
  12262     bcm_pbmp_t all_pbmp;
  12263 
  12264 #if defined(BCM_TOMAHAWK3_SUPPORT)
  12265     /* TH3 does not support VLAN Protocol feature. Return doing nothing */
  12266     if (SOC_IS_TOMAHAWK3(unit)) {
  12267         return BCM_E_NONE;
  12268     }
  12269 #endif
  12270 
  12271     idxmax = soc_mem_index_count(unit, VLAN_PROTOCOLm);
  12272     /* Round to the next entry */
  12273     inds_bytes =
  12274         (idxmax + (_BCM_PORT_VD_PBVL_ESIZE -  1)) / _BCM_PORT_VD_PBVL_ESIZE;
  12275 
  12276     BCM_PBMP_CLEAR(all_pbmp);
  12277     BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  12278 
  12279 #ifdef BCM_KATANA2_SUPPORT
  12280     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  12281         BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  12282     }
  12283     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  12284         soc_feature(unit, soc_feature_subtag_coe)) {
  12285         _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  12286     }
  12287 #endif
  12288 
  12289     PBMP_ITER(all_pbmp, port) {
  12290         PORT(unit, port).p_vd_pbvl = sal_alloc(inds_bytes, "vdv_info");
  12291         if (NULL == PORT(unit, port).p_vd_pbvl) {
  12292             return (BCM_E_MEMORY);
  12293         }
  12294 
  12295         sal_memset(PORT(unit, port).p_vd_pbvl, 0, inds_bytes);
  12296     }
  12297 
  12298 #ifdef BCM_WARM_BOOT_SUPPORT
  12299     if (SOC_WARM_BOOT(unit)) {
  12300         BCM_IF_ERROR_RETURN(_bcm_port_vd_pbvl_reinit(unit));
  12301     }
  12302 #endif
  12303 
  12304     return BCM_E_NONE;
  12305 }
  12306 #endif /* BCM_FIREBOLT_SUPPORT */
  12307 
  12308 /*
  12309  * Function:
  12310  *      _bcm_esw_port_software_detach
  12311  * Purpose:
  12312  *      De-initialization of software for port subsystem.
  12313  * Parameters:
  12314  *      unit - StrataSwitch unit number.
  12315  * Returns:
  12316  *      BCM_E_NONE - success (or already initialized)
  12317  *      BCM_E_INTERNAL- failed to write PTABLE entries
  12318  *      BCM_E_MEMORY - failed to allocate required memory.
  12319  */
  12320 
  12321 int
  12322 _bcm_esw_port_software_detach(int unit)
  12323 {
  12324     bcm_port_t          port;
  12325     bcm_pbmp_t all_pbmp;
  12326 
  12327     BCM_PBMP_CLEAR(all_pbmp);
  12328     BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  12329 
  12330 #ifdef BCM_KATANA2_SUPPORT
  12331     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  12332         BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  12333     }
  12334     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  12335         soc_feature(unit, soc_feature_subtag_coe)) {
  12336         _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  12337     }
  12338 #endif
  12339 
  12340     if (bcm_port_info[unit] == NULL) {
  12341          return (BCM_E_NONE);
  12342     }
  12343 
  12344     PBMP_ITER(all_pbmp, port) {
  12345         if (NULL != PORT(unit, port).p_vd_pbvl) {
  12346             sal_free(PORT(unit, port).p_vd_pbvl);
  12347             PORT(unit, port).p_vd_pbvl = NULL;
  12348         }
  12349 
  12350         if (NULL != PORT(unit, port).e2ecc_config) {
  12351             sal_free(PORT(unit, port).e2ecc_config);
  12352             PORT(unit, port).e2ecc_config = NULL;
  12353         }
  12354     }
  12355 
  12356     SOC_IF_ERROR_RETURN(soc_phy_common_detach(unit));
  12357 
  12358 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
  12359  || defined(BCM_RAVEN_SUPPORT)
  12360     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  12361         BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_detach(unit));
  12362     }
  12363 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT \
  12364           || BCM_RAPTOR_SUPPORT */
  12365 
  12366 #ifdef BCM_TRIUMPH2_SUPPORT
  12367     if (NULL != PORT_SRC_MOD_EGR_PROFILE(unit)) {
  12368         BCM_IF_ERROR_RETURN
  12369             (soc_profile_mem_destroy(unit, PORT_SRC_MOD_EGR_PROFILE(unit)));
  12370         sal_free(PORT_SRC_MOD_EGR_PROFILE(unit));
  12371         PORT_SRC_MOD_EGR_PROFILE(unit) = NULL;
  12372     }
  12373 #endif /* BCM_TRIUMPH2_SUPPORT */
  12374 #if defined(BCM_TRIDENT_SUPPORT)
  12375     if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) {
  12376         BCM_IF_ERROR_RETURN(bcm_td_port_deinit(unit));
  12377     }
  12378 #endif /* BCM_TRIDENT_SUPPORT */
  12379 
  12380     sal_free (bcm_port_info[unit]);
  12381     bcm_port_info[unit] = NULL;
  12382 
  12383     return BCM_E_NONE;
  12384 }
  12385 
  12386 /*
  12387  * Function:
  12388  *      _bcm_port_software_init
  12389  * Purpose:
  12390  *      Initialization of software for port subsystem.
  12391  * Parameters:
  12392  *      unit - StrataSwitch unit number.
  12393  * Returns:
  12394  *      BCM_E_NONE - success (or already initialized)
  12395  *      BCM_E_INTERNAL- failed to write PTABLE entries
  12396  *      BCM_E_MEMORY - failed to allocate required memory.
  12397  */
  12398 
  12399 STATIC int
  12400 _bcm_port_software_init(int unit)
  12401 {
  12402     bcm_port_t  port = 0;
  12403     int         max_num_port = 0;
  12404     bcm_pbmp_t  all_pbmp;
  12405 
  12406     BCM_PBMP_CLEAR(all_pbmp);
  12407     BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  12408     max_num_port = SOC_MAX_NUM_PORTS;
  12409 
  12410 #ifdef BCM_KATANA2_SUPPORT
  12411     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  12412         BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  12413     }
  12414     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  12415         soc_feature(unit, soc_feature_subtag_coe)) {
  12416         _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  12417         max_num_port = SOC_MAX_NUM_PP_PORTS;
  12418     }
  12419 #endif
  12420 
  12421     if (bcm_port_info[unit] != NULL) {
  12422         PBMP_ITER(all_pbmp, port) {
  12423             if (PORT(unit, port).p_vd_pbvl != NULL) {
  12424                 sal_free(PORT(unit, port).p_vd_pbvl);
  12425                 PORT(unit, port).p_vd_pbvl = NULL;
  12426             }
  12427 
  12428             if (PORT(unit, port).e2ecc_config != NULL) {
  12429                 sal_free(PORT(unit, port).e2ecc_config);
  12430                 PORT(unit, port).e2ecc_config = NULL;
  12431             }
  12432 
  12433             PORT(unit, port).flags = 0;
  12434 #ifdef BCM_TRIDENT2_SUPPORT
  12435             if (SOC_IS_TD2_TT2(unit)) {
  12436                 PORT(unit, port).enable = TRUE;
  12437             }
  12438 #endif /* BCM_TRIDENT2_SUPPORT */
  12439         }
  12440     }
  12441 
  12442     if (bcm_port_info[unit] == NULL) {
  12443         bcm_port_info[unit] = sal_alloc(sizeof(_bcm_port_info_t) * max_num_port,
  12444                                         "bcm_port_info");
  12445         if (bcm_port_info[unit] == NULL) {
  12446             return BCM_E_MEMORY;
  12447         }
  12448     }
  12449     sal_memset(bcm_port_info[unit], 0, sizeof(_bcm_port_info_t) * max_num_port);
  12450 
  12451     SOC_IF_ERROR_RETURN(soc_phy_common_init(unit));
  12452 #if defined(BCM_FIREBOLT_SUPPORT)
  12453     if (SOC_IS_FBX(unit)) {
  12454         BCM_IF_ERROR_RETURN(_bcm_port_vd_pbvl_init(unit));
  12455     }
  12456 #endif /* BCM_FIREBOLT_SUPPORT */
  12457 
  12458 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
  12459  || defined(BCM_RAVEN_SUPPORT)
  12460     if (SOC_WARM_BOOT(unit)) {
  12461 #ifdef BCM_TRIUMPH2_SUPPORT
  12462         /* Moved to here for TD3 since the warm boot function call order changed */
  12463         if (soc_feature(unit, soc_feature_lport_tab_profile)) {
  12464             BCM_IF_ERROR_RETURN(bcm_esw_port_lport_profile_recover(unit));
  12465         }
  12466         if (soc_feature(unit, soc_feature_egr_lport_tab_profile)) {
  12467             BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_profile_recover(unit));
  12468         }
  12469 #endif
  12470     }
  12471     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  12472         BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_init(unit));
  12473     }
  12474     if (soc_feature(unit, soc_feature_color_prio_map)) {
  12475         BCM_IF_ERROR_RETURN(_bcm_fb2_priority_map_init(unit));
  12476     }
  12477 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT \
  12478           || BCM_RAPTOR_SUPPORT */
  12479 
  12480 #if defined(BCM_TRX_SUPPORT)
  12481     if (SOC_IS_TRX(unit)) {
  12482         for (port = 0; port < max_num_port; port++) {
  12483             PORT(unit, port).dtag_mode = BCM_PORT_DTAG_MODE_NONE;
  12484         }
  12485     }
  12486 #endif
  12487 
  12488 #ifdef BCM_WARM_BOOT_SUPPORT
  12489     if (SOC_WARM_BOOT(unit)) {
  12490 #if defined(BCM_XGS_SWITCH_SUPPORT)
  12491         if (soc_feature(unit, soc_feature_remap_ut_prio)) {
  12492             bcm_port_cfg_t pcfg;
  12493             PBMP_ITER(all_pbmp, port) {
  12494                 SOC_IF_ERROR_RETURN
  12495                     (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port,
  12496                                                           &pcfg));
  12497                 PORT(unit, port).p_ut_prio = pcfg.pc_new_opri;
  12498             }
  12499         }
  12500 #ifdef BCM_TRIDENT2_SUPPORT
  12501         if (SOC_IS_TD2_TT2(unit)) {
  12502             PBMP_ITER(all_pbmp, port) {
  12503                 PORT(unit, port).enable = TRUE;
  12504             }
  12505         }
  12506 #endif /* BCM_TRIDENT2_SUPPORT */
  12507 #endif /* BCM_XGS_SWITCH_SUPPORT */
  12508 #if defined(BCM_TRX_SUPPORT)
  12509         if (SOC_IS_TRX(unit)) {
  12510             PBMP_ITER(all_pbmp, port) {
  12511                 /* Recover port's dtag_mode */
  12512                 PORT(unit, port).dtag_mode = BCM_PORT_DTAG_MODE_NONE;
  12513             }
  12514         }
  12515 #endif /* BCM_TRX_SUPPORT */
  12516     }
  12517 #endif /* BCM_WARM_BOOT_SUPPORT */
  12518 
  12519     return BCM_E_NONE;
  12520 }
  12521 
  12522 /*
  12523  * Function:
  12524  *      _bcm_port_settings_init
  12525  * Purpose:
  12526  *      Initialize port settings if they are to be different from the
  12527  *      default ones
  12528  * Parameters:
  12529  *      unit - StrataSwitch unit number.
  12530  *      port - port number
  12531  * Returns:
  12532  *      BCM_E_NONE - success (or already initialized)
  12533  *      BCM_E_INTERNAL- failed to write PTABLE entries
  12534  * Notes:
  12535  *      This function initializes port settings based on the folowing config
  12536  *      variables:
  12537  *           port_init_speed
  12538  *           port_init_duplex
  12539  *           port_init_adv
  12540  *           port_init_autoneg
  12541  *      If a variable is not set, then no additional initialization of the
  12542  *      corresponding parameter is done (and the defaults will normally be
  12543  *      advertize everything you can do and use autonegotiation).
  12544  *
  12545  *      A typical use would be to set:
  12546  *          port_init_adv=0
  12547  *          port_init_autoneg=1
  12548  *      to force link down in the beginning.
  12549  *
  12550  *      Another setup that makes sense is something like:
  12551  *          port_init_speed=10
  12552  *          port_init_duplex=0
  12553  *          port_init_autoneg=0
  12554  *      in order to force link into a certain mode. (It is very important to
  12555  *      disable autonegotiation in this case).
  12556  *
  12557  *      PLEASE NOTE:
  12558  *          The standard rc.soc forces autoneg=on on all the ethernet ports
  12559  *          (FE and GE). Thus, to use the second example one has to edit rc.soc
  12560  *          as well.
  12561  *
  12562  *     This function has been declared as global, but not exported. This will
  12563  *     make port initialization easier when using VxWorks shell.
  12564  */
  12565 int
  12566 bcm_port_settings_init(int unit, bcm_port_t port)
  12567 {
  12568     int             val;
  12569     bcm_port_info_t info;
  12570 
  12571     LOG_INFO(BSL_LS_BCM_PORT,
  12572              (BSL_META_U(unit,
  12573                          "bcm_port_settings_init: u=%d p=%d\n"),unit, port));
  12574 
  12575     bcm_port_info_t_init(&info);
  12576 
  12577     val = soc_property_port_get(unit, port, spn_PORT_INIT_SPEED, -1);
  12578     if (val != -1) {
  12579         info.speed = val;
  12580         info.action_mask |= BCM_PORT_ATTR_SPEED_MASK;
  12581     }
  12582 
  12583     val = soc_property_port_get(unit, port, spn_PORT_INIT_DUPLEX, -1);
  12584     if (val != -1) {
  12585         info.duplex = val;
  12586         info.action_mask |= BCM_PORT_ATTR_DUPLEX_MASK;
  12587     }
  12588 
  12589     val = soc_property_port_get(unit, port, spn_PORT_INIT_ADV, -1);
  12590     if (val != -1) {
  12591         info.local_advert = val;
  12592         info.action_mask |= BCM_PORT_ATTR_LOCAL_ADVERT_MASK;
  12593     }
  12594 
  12595     val = soc_property_port_get(unit, port, spn_PORT_INIT_AUTONEG, -1);
  12596     if (val != -1) {
  12597         info.autoneg = val;
  12598         info.action_mask |= BCM_PORT_ATTR_AUTONEG_MASK;
  12599     }
  12600     return bcm_esw_port_selective_set(unit, port, &info);
  12601 }
  12602 
  12603 #ifdef BCM_TRIUMPH2_SUPPORT
  12604 /* Helper function to program logical to physical (and reverse) port mapping */
  12605 STATIC int
  12606 _bcm_port_remap_set(int unit, bcm_port_t phys, bcm_port_t logical)
  12607 {
  12608     port_tab_entry_t ptab;
  12609     sys_portmap_entry_t sys_portmap;
  12610     uint32 regval;
  12611 
  12612     SOC_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm,
  12613                                      MEM_BLOCK_ANY, phys, &ptab));
  12614     soc_PORT_TABm_field32_set(unit, &ptab, SRC_SYS_PORT_IDf, logical);
  12615     SOC_IF_ERROR_RETURN(soc_mem_write(unit, PORT_TABm,
  12616                                       MEM_BLOCK_ALL, phys, &ptab));
  12617 
  12618     SOC_IF_ERROR_RETURN(soc_mem_read(unit, SYS_PORTMAPm,
  12619                                      MEM_BLOCK_ANY, logical, &sys_portmap));
  12620     soc_SYS_PORTMAPm_field32_set(unit, &sys_portmap, PHYS_PORT_IDf, phys);
  12621     SOC_IF_ERROR_RETURN(soc_mem_write(unit, SYS_PORTMAPm,
  12622                                       MEM_BLOCK_ALL, logical, &sys_portmap));
  12623 
  12624     /* Configure E2ECC port mapping register */
  12625     SOC_IF_ERROR_RETURN(READ_E2ECC_PORT_MAPPINGr(unit, phys, &regval));
  12626     soc_reg_field_set(unit, E2ECC_PORT_MAPPINGr, &regval, MAPPED_PORT_NUMf, logical);
  12627     SOC_IF_ERROR_RETURN(WRITE_E2ECC_PORT_MAPPINGr(unit, phys, regval));
  12628 
  12629     return BCM_E_NONE;
  12630 }
  12631 
  12632 STATIC int
  12633 _bcm_tr2_system_tpid_init(int unit)
  12634 {
  12635     int tpid_index, sys_index, rv = BCM_E_NONE;
  12636     bcm_module_t module;
  12637     bcm_port_t port;
  12638     system_config_table_entry_t systab;
  12639     uint32 tpid_enable;
  12640     uint16 tpid;
  12641 
  12642     tpid = _bcm_fb2_outer_tpid_default_get(unit);
  12643     BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_lkup(unit, tpid, &tpid_index));
  12644 
  12645     for (module = 0; module <= SOC_MODID_MAX(unit); module++) {
  12646         for (port = 0; port < 64; port++) {
  12647             sys_index = module * 64 + port;
  12648             rv = READ_SYSTEM_CONFIG_TABLEm(unit, MEM_BLOCK_ANY,
  12649                                            sys_index, &systab);
  12650             BCM_IF_ERROR_RETURN(rv);
  12651             tpid_enable = (1 << tpid_index);
  12652             soc_SYSTEM_CONFIG_TABLEm_field32_set(unit, &systab,
  12653                                                  OUTER_TPID_ENABLEf,
  12654                                                  tpid_enable);
  12655             rv = WRITE_SYSTEM_CONFIG_TABLEm(unit, MEM_BLOCK_ALL,
  12656                                             sys_index, &systab);
  12657             BCM_IF_ERROR_RETURN(rv);
  12658         }
  12659     }
  12660     return rv;
  12661 }
  12662 #endif
  12663 
  12664 /*
  12665  * Function:
  12666  *      _bcm_esw_port_deinit
  12667  * Purpose:
  12668  *      De-initialize the PORT interface layer for the specified SOC device.
  12669  * Parameters:
  12670  *      unit - StrataSwitch unit number.
  12671  * Returns:
  12672  *      BCM_E_XXX
  12673  */
  12674 int
  12675 _bcm_esw_port_deinit(int unit)
  12676 {
  12677     int  rv;
  12678 
  12679     if (NULL == bcm_port_info[unit]) {
  12680         return (BCM_E_NONE);
  12681     }
  12682 
  12683     rv = _bcm_esw_port_software_detach(unit);
  12684     BCM_IF_ERROR_RETURN(rv);
  12685 
  12686 #ifdef BCM_TRX_SUPPORT
  12687     if (soc_feature(unit, soc_feature_vlan_action) ||
  12688         soc_feature(unit,soc_feature_egr_vlan_action)) {
  12689 #ifdef BCM_TRIUMPH2_SUPPORT
  12690         if (soc_feature(unit, soc_feature_vpd_profile)) {
  12691             _bcm_tr2_port_vpd_bitmap_free(unit);
  12692         }
  12693 #endif /* BCM_TRIUMPH2_SUPPORT */
  12694 
  12695         /* Initialize the vlan action profile table */
  12696 #if defined(BCM_TOMAHAWK3_SUPPORT)
  12697         if (SOC_IS_TOMAHAWK3(unit)) {
  12698             rv = _bcm_th3_vlan_action_profile_detach(unit);
  12699         } else
  12700 #endif /* BCM_TOMAHAWK3_SUPPORT */
  12701         {
  12702             rv = _bcm_trx_vlan_action_profile_detach(unit);
  12703         }
  12704         BCM_IF_ERROR_RETURN(rv);
  12705     }
  12706 #endif /* BCM_TRX_SUPPORT */
  12707 
  12708 #ifdef BCM_TRIUMPH2_SUPPORT
  12709     if (soc_feature(unit, soc_feature_gport_service_counters)) {
  12710         rv = _bcm_esw_flex_stat_detach(unit, _bcmFlexStatTypeGport);
  12711         BCM_IF_ERROR_RETURN(rv);
  12712     }
  12713 #endif /* BCM_TRIUMPH2_SUPPORT */
  12714 
  12715 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || \
  12716     defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT)
  12717     if ((soc_feature(unit, soc_feature_timesync_v3) || SOC_IS_TRIUMPH3(unit) ||
  12718          SOC_IS_KATANAX(unit)|| SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) ||
  12719          SOC_IS_APACHE(unit)) &&
  12720         (soc_feature(unit,soc_feature_timesync_support))) {
  12721         _bcm_esw_port_timesync_profile_delete(unit);
  12722     }
  12723 #endif /* defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) ||
  12724           defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) */
  12725 
  12726 #if defined(BCM_TRIUMPH3_SUPPORT)
  12727     if (soc_feature(unit, soc_feature_epc_linkflap_recover)) {
  12728         rv = _bcm_port_force_forward_deinit(unit);
  12729         if(BCM_FAILURE(rv)) {
  12730             return rv;
  12731         }
  12732     }
  12733 #endif /*defined(BCM_TRIUMPH3_SUPPORT)*/
  12734 #if defined(BCM_TOMAHAWK_SUPPORT)
  12735     if (soc_feature(unit, soc_feature_asf_multimode)) {
  12736         /* deinit ASF (cutthrough) subsystem */
  12737         BCM_IF_ERROR_RETURN(_bcm_esw_asf_deinit(unit));
  12738     }
  12739 #endif
  12740 #ifdef BCM_TRIUMPH3_SUPPORT
  12741     if (SOC_IS_TRIUMPH3(unit)) {
  12742         _bcm_esw_ibod_sync_recovery_stop(unit);
  12743     }
  12744 #endif
  12745 #ifdef BCM_PREEMPTION_SUPPORT
  12746     if (soc_feature(unit, soc_feature_preemption)) {
  12747         bcmi_esw_preemption_cleanup(unit);
  12748     }
  12749     if (soc_feature(unit, soc_feature_preemption_cnt)) {
  12750         bcmi_esw_preemption_counter_cleanup(unit);
  12751     }
  12752 #endif /* BCM_PREEMPTION_SUPPORT */
  12753 #if defined(BCM_GREYHOUND_SUPPORT)
  12754     if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) {
  12755         BCM_IF_ERROR_RETURN(
  12756             bcmi_esw_port_treat_pktpri_as_dot1p_cleanup(unit));
  12757     }
  12758 #endif /* BCM_GREYHOUND_SUPPORT */
  12759 
  12760     return BCM_E_NONE;
  12761 }
  12762 
  12763 #ifdef BCM_TRIDENT_SUPPORT
  12764 #ifdef BCM_WARM_BOOT_SUPPORT
  12765 /*
  12766  * Function:
  12767  *      _bcm_td_phymode_reconfigure
  12768  * Purpose:
  12769  *      Reconfigure the mode of the phys during warmboot.
  12770  *      This function has code copied from _soc_trident_misc_init
  12771  *      to keep the phy modes consistent in cold and warmboot modes.
  12772  *      This is required to be called before the phy probe routines
  12773  *      in order for the mode to be configured correctly.
  12774  * Parameters:
  12775  *      unit - StrataSwitch unit number.
  12776  * Returns:
  12777  *      BCM_E_XXX
  12778  */
  12779 STATIC int
  12780 _bcm_td_phymode_reconfigure(int unit) {
  12781 
  12782     soc_info_t *si = &SOC_INFO(unit);
  12783     int port, blk, blk_port, num_lanes, phy_port, bindex;
  12784 
  12785     SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
  12786         blk_port = SOC_BLOCK_PORT(unit, blk);
  12787         if (blk_port < 0) {
  12788             continue;
  12789         }
  12790         /*
  12791          * Program XLPORT mode and default Warpcore lanes setting
  12792          * core_mode: the number of ports on the system side of XMAC
  12793          * phy_mode: the number of ports on the Warpcore side of XMAC
  12794          * num_lanes: the number of lanes on the line side of Warpcore
  12795          */
  12796         if (si->port_speed_max[blk_port] > 20000) {
  12797             num_lanes = 4;
  12798         } else if (si->port_speed_max[blk_port] > 10000) {
  12799             if (si->port_speed_max[blk_port] == 20000 &&
  12800                 si->port_num_lanes[blk_port] == 4) {
  12801                 num_lanes = 4;
  12802             } else {
  12803                 num_lanes = 2;
  12804             }
  12805         } else {
  12806             num_lanes = 1;
  12807         }
  12808 
  12809         phy_port = ((si->port_l2p_mapping[blk_port] - 1) & ~0x3) + 1;
  12810         for (bindex = 0; bindex < 4; bindex++) {
  12811             port = si->port_p2l_mapping[phy_port + bindex];
  12812             if (port == -1) {
  12813                 continue;
  12814             }
  12815             si->port_num_lanes[port] = num_lanes;
  12816         }
  12817     }
  12818     return BCM_E_NONE;
  12819 }
  12820 #endif /* BCM_WARM_BOOT_SUPPORT */
  12821 #endif /* BCM_TRIDENT_SUPPORT */
  12822 
  12823 #ifdef BCM_WARM_BOOT_SUPPORT
  12824 #ifdef BCM_TRIUMPH3_SUPPORT
  12825 STATIC int _bcm_tr3_flexport_wb_recover(int unit)
  12826 {
  12827     int rv = BCM_E_NONE;
  12828     int alloc_sz = 0;
  12829     uint8 *port_state;
  12830     uint16 recovered_ver;
  12831     bcm_port_t port;
  12832     int stable_size;
  12833     soc_scache_handle_t scache_handle;
  12834     soc_info_t *si = &SOC_INFO(unit);
  12835     int _port_lanes_valid = 0;
  12836     int _port_num_lanes[SOC_MAX_NUM_PORTS] = {0};
  12837     bcm_pbmp_t all_pbmp;
  12838 
  12839     BCM_PBMP_CLEAR(all_pbmp);
  12840     BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  12841 
  12842     /* Calculate the offset of port_num_lanes */
  12843     SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
  12844     PBMP_ITER(all_pbmp, port) {
  12845         alloc_sz += sizeof(int); /* vp count */
  12846     }
  12847     alloc_sz += sizeof(bcm_pbmp_t); /* Bitmap of dtag_mode == NONE */
  12848     PBMP_ITER(all_pbmp, port) {
  12849         if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) {
  12850             if (SOC_REG_IS_VALID(unit, COSMASKr)) {
  12851                 alloc_sz += sizeof(uint32);
  12852             } else {
  12853                 alloc_sz += sizeof(_bcm_port_metering_info_t);
  12854             }
  12855             alloc_sz += sizeof(uint8); /* flags */
  12856         }
  12857     }
  12858     alloc_sz += (SOC_MAX_NUM_PORTS * sizeof(int)); /* num lanes of port */
  12859 
  12860     /* Get port_num_lanes from scahe */
  12861     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_PORT,
  12862                           BCM_PORT_WB_SCACHE_PART_DEFAULT);
  12863     rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE,
  12864                                  alloc_sz, (uint8**)&port_state,
  12865                                  BCM_PORT_WB_DEFAULT_VERSION, &recovered_ver);
  12866     if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
  12867         return rv;
  12868     }
  12869 
  12870     port_state += (alloc_sz - (SOC_MAX_NUM_PORTS * sizeof(int)));
  12871     if (recovered_ver >= BCM_PORT_WB_VERSION_1_1) {
  12872         PBMP_ALL_ITER(unit, port) {
  12873             sal_memcpy(&_port_num_lanes[port], port_state,
  12874                        sizeof(int));
  12875             port_state += sizeof(int);
  12876             _port_lanes_valid++;
  12877         }
  12878     }
  12879 
  12880     /* Recover port_num_lanes */
  12881     if (_port_lanes_valid) {
  12882          PBMP_ALL_ITER(unit, port) {
  12883              if (soc_tr3_port_is_flex_port(unit, port) &&
  12884                  (si->port_num_lanes[port] != _port_num_lanes[port])) {
  12885                  LOG_VERBOSE(BSL_LS_BCM_PORT,
  12886                              (BSL_META_U(unit,
  12887                                          "Port %d needs flex transform !!\n"),
  12888                               port));
  12889                  if ((rv = _bcm_tr3_port_lanes_set(unit, port,
  12890                                _port_num_lanes[port])) != BCM_E_NONE) {
  12891                      LOG_ERROR(BSL_LS_BCM_PORT, \
  12892                                (BSL_META_U(unit, \
  12893                                            "Error unit %d: "\
  12894                                            "Failed port lanes set: %s\n"),
  12895                                 unit, bcm_errmsg(rv)));
  12896                      return rv;
  12897                  }
  12898              }
  12899          }
  12900          (void)soc_port_type_verify(unit);
  12901     }
  12902 
  12903     return rv;
  12904 }
  12905 
  12906 STATIC void
  12907 _bcm_tr3_port_info_reconfig(int unit)
  12908 {
  12909     soc_port_t port;
  12910 
  12911     PBMP_ALL_ITER(unit, port) {
  12912         if (IS_AXP_PORT(unit, port)) {
  12913             /* Physical port table index doesn't exist for AXP ports */
  12914             continue;
  12915         }
  12916         /* cache num of port lanes */
  12917         (void)soc_tr3_port_lanes_gen(unit, port, &SOC_INFO(unit).port_num_lanes[port], NULL);
  12918     }
  12919 
  12920     if (soc_feature(unit, soc_feature_flex_port)) {
  12921         _bcm_tr3_flexport_wb_recover(unit);
  12922     }
  12923 }
  12924 #endif /* BCM_TRIUMPH3_SUPPORT */
  12925 #endif /* BCM_WARM_BOOT_SUPPORT */
  12926 
  12927 #ifdef BCM_HIGIG2_SUPPORT
  12928 /*
  12929  * Function:
  12930  *      _bcm_esw_port_higig2_mode_set
  12931  * Purpose:
  12932  *      Set port Higig2 mode
  12933  * Parameters:
  12934  *      unit - StrataSwitch unit #
  12935  *      port - StrataSwitch port #
  12936  *      higig2_mode - Higig2 mode
  12937  * Returns:
  12938  *      BCM_E_XXX
  12939  */
  12940 int
  12941 _bcm_esw_port_higig2_mode_set(int unit, bcm_port_t port, int higig2_mode)
  12942 {
  12943     soc_reg_t egr_port_reg;
  12944     soc_mem_t egr_port_mem;
  12945 
  12946     if (SOC_USE_PORTCTRL(unit)) {
  12947         return bcmi_esw_portctrl_higig2_mode_set(unit, port, higig2_mode);
  12948     }
  12949 
  12950     if (!SOC_IS_KATANA2(unit)) {
  12951         BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
  12952                             _BCM_CPU_TABS_NONE, HIGIG2f, higig2_mode));
  12953     }
  12954     egr_port_reg = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  12955             SOC_IS_VALKYRIE2(unit) || SOC_IS_GREYHOUND(unit) ||
  12956             SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ?
  12957             EGR_PORT_64r : EGR_PORTr;
  12958     if (SOC_REG_FIELD_VALID(unit, egr_port_reg, HIGIG2f)) {
  12959         BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, egr_port_reg, port,
  12960                     HIGIG2f, higig2_mode));
  12961     } else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, HIGIG2f)) {
  12962         BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, EGR_PORTm, port,
  12963                     HIGIG2f, higig2_mode));
  12964     }
  12965 
  12966 #if defined(BCM_SABER2_SUPPORT)
  12967     if(SOC_IS_SABER2(unit)) {
  12968         /* For Saber2, configure IECELL along with XLPORT */
  12969         if (SOC_REG_PORT_VALID(unit, IECELL_CONFIGr, port)) {
  12970             BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, 
  12971                         IECELL_CONFIGr, port, HIGIG2_MODEf, higig2_mode));
  12972 
  12973         }
  12974     }
  12975 #endif
  12976 
  12977     if (IS_CL_PORT(unit, port) &&
  12978         SOC_REG_FIELD_VALID(unit, CLPORT_CONFIGr, HIGIG2_MODEf)) {
  12979         uint32 clp_hg2_mode = higig2_mode;
  12980 
  12981 #ifdef BCM_GREYHOUND2_SUPPORT
  12982         if (SOC_IS_GREYHOUND2(unit)) {
  12983             /* GH2 for CL port has PGW interface config for HG2/HG2-Lite */
  12984             BCM_IF_ERROR_RETURN(soc_greyhound2_pgw_encap_field_modify(unit,
  12985                 port, HIGIG2_MODEf, higig2_mode));
  12986 
  12987             /* GH2 sepcial design to set CLPORT_CONFIGr as IEEE encap mode for
  12988              * HG2-Lite. Thus the CLPORT_CONFIGr.HIGIG2_MODEf must be 0 here.
  12989              */
  12990             if (IS_HL_PORT(unit, port)) {
  12991                 clp_hg2_mode = 0;
  12992             }
  12993         }
  12994 #endif  /* GREYHOUND2 */
  12995         
  12996         BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, CLPORT_CONFIGr, port,
  12997                             HIGIG2_MODEf, clp_hg2_mode));
  12998     } else if (IS_C_PORT(unit, port) &&
  12999         SOC_REG_FIELD_VALID(unit, CPORT_CONFIGr, HIGIG2_MODEf)) {
  13000         BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, CPORT_CONFIGr, port,
  13001                 HIGIG2_MODEf, higig2_mode));
  13002     } else if (SOC_REG_FIELD_VALID(unit, XLPORT_CONFIGr, HIGIG2_MODEf)) {
  13003         uint32 xlp_hg2_mode = higig2_mode;
  13004 
  13005 #ifdef BCM_GREYHOUND_SUPPORT
  13006         if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  13007             SOC_IS_GREYHOUND2(unit)){
  13008             BCM_IF_ERROR_RETURN(soc_greyhound_pgw_encap_field_modify(unit,
  13009                 port, HIGIG2_MODEf, higig2_mode));
  13010 
  13011             /* GH sepcial design to set XLPORT_CONFIGr as IEEE encap mode for
  13012              * HG2-Lite. Thus the XLPORT_CONFIGr.HIGIG2_MODEf must be 0 here.
  13013              */
  13014             if (IS_HL_PORT(unit, port)) {
  13015                 xlp_hg2_mode = 0;
  13016             }
  13017         }
  13018 #endif /* BCM_GREYHOUND_SUPPORT */
  13019 
  13020         BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XLPORT_CONFIGr, port,
  13021                 HIGIG2_MODEf, xlp_hg2_mode));
  13022     } else if (SOC_REG_FIELD_VALID(unit, XPORT_CONFIGr, HIGIG2_MODEf)) {
  13023         BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XPORT_CONFIGr, port,
  13024                 HIGIG2_MODEf, higig2_mode));
  13025     } else if (SOC_REG_FIELD_VALID(unit, PORT_CONFIGr, HIGIG2_MODEf)) {
  13026         BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, PORT_CONFIGr, port,
  13027                 HIGIG2_MODEf, higig2_mode));
  13028     }
  13029     if (soc_feature(unit, soc_feature_wh2)) {
  13030         SOC_IF_ERROR_RETURN(
  13031             soc_reg_field32_modify(unit, PGW_GE_CONFIGr, port,
  13032                                    HIGIG2_MODEf, higig2_mode));
  13033     }
  13034 
  13035     egr_port_mem = SOC_IS_KATANA2(unit) ? EGR_PHYSICAL_PORTm : EGR_ING_PORTm;
  13036     if (SOC_MEM_FIELD_VALID(unit, egr_port_mem, HIGIG2f)) {
  13037         if (IS_CPU_PORT(unit, port)) {
  13038             BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, egr_port_mem,
  13039                         SOC_INFO(unit).cpu_hg_index, HIGIG2f, higig2_mode));
  13040         } else {
  13041             BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, egr_port_mem,
  13042                         port, HIGIG2f, higig2_mode));
  13043         }
  13044     }
  13045 
  13046     return BCM_E_NONE;
  13047 }
  13048 #endif /* BCM_HIGIG2_SUPPORT */
  13049 
  13050 #ifdef BCM_TRIUMPH3_SUPPORT
  13051 /*
  13052  * Function:
  13053  *      _bcm_esw_tr3_port_lanes_init
  13054  * Purpose:
  13055  *      Initialize port lanes settings for 40g port of
  13056  *      Triumph3(56541,56542, 56545 and 56546)
  13057  * Parameters:
  13058  *      unit - StrataSwitch unit number.
  13059  *      port - port number
  13060  * Returns:
  13061  *      BCM_E_NONE - success (or already initialized)
  13062  *      BCM_E_INTERNAL- failed to set lane mode
  13063  * Notes:
  13064  *      This function initializes port lanes settings based on the following config
  13065  *      variables:
  13066  *           port_max_speed
  13067  *      If a variable is not set, then no additional initialization of the
  13068  *      parameter is done.
  13069  *
  13070  *      If user want to use 100Mbps on WC ports(xe4,xe5), configuration
  13071  *      must be setted as below:
  13072  *          port_max_speed=100
  13073  */
  13074 int
  13075 _bcm_esw_tr3_port_lanes_init(int unit)
  13076 {
  13077     int rv;
  13078     int max_speed;
  13079     int old_lanes = 0, new_lanes = -1;
  13080     int enable;
  13081     bcm_port_t port;
  13082     PBMP_PORT_ITER(unit, port) {
  13083         if (port != 54 && port != 55) {
  13084             continue;
  13085         }
  13086         if (soc_property_port_get(unit, port, spn_PORT_MAX_SPEED, 0)) {
  13087             max_speed = soc_property_port_get(unit, port, spn_PORT_MAX_SPEED, 0);
  13088             if (max_speed == 100) {
  13089                 new_lanes = 1;
  13090             } else if (max_speed != 100) {
  13091                 new_lanes = 4;
  13092             }
  13093             BCM_IF_ERROR_RETURN(_bcm_tr3_port_lanes_get(unit, port, &old_lanes));
  13094             if (new_lanes > 0 && old_lanes != new_lanes) {
  13095                 /* Cache original configurations */
  13096                 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &enable));
  13097                 COUNTER_LOCK(unit);
  13098                 rv = _bcm_tr3_port_lanes_set(unit, port, new_lanes);
  13099                 COUNTER_UNLOCK(unit);
  13100                 BCM_IF_ERROR_RETURN(rv);
  13101                 bcm_port_settings_init(unit, port);
  13102                 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, port, enable));
  13103             }
  13104         }
  13105     }
  13106     return BCM_E_NONE;
  13107 }
  13108 #endif
  13109 
  13110 #if defined(BCM_TRIDENT3_SUPPORT) && defined(CANCUN_SUPPORT)
  13111 /*
  13112  * Function:
  13113  *      _bcm_esw_td3_port_cmh_ctrl_set
  13114  * Description:
  13115  *      Configure CANCUN redefined port control.
  13116  * Parameters:
  13117  *      unit - Device number
  13118  *      port - Port number
  13119  *      type - Enum value of the feature
  13120  *      value - value to be set
  13121  * Return Value:
  13122  *      BCM_E_NONE
  13123  *      BCM_E_UNAVAIL - Functionality not available
  13124  */
  13125 int
  13126 _bcm_esw_td3_port_cmh_ctrl_set(int unit, bcm_port_t port,
  13127                          bcm_port_control_t type, int value)
  13128 {
  13129     int rv = BCM_E_NONE;
  13130     uint32 entry[SOC_MAX_MEM_WORDS];
  13131     bcm_module_t my_modid = 0, modid_out;
  13132     bcm_port_t port_out;
  13133     bcm_trunk_t trunk_out;
  13134     int    src_trk_idx = 0, id_out;
  13135     soc_mem_t mem = SOURCE_TRUNK_MAP_TABLEm;
  13136 
  13137     if (BCM_GPORT_IS_SET(port)) {
  13138         BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  13139                                  &modid_out, &port_out, &trunk_out, &id_out));
  13140     } else {
  13141         port_out = port;
  13142     }
  13143 
  13144     if (!soc_cancun_cmh_check(unit, LPORT_TABm, VXLAN_SVP_ASSIGNMENT_KEY_TYPEf)) {
  13145         return rv;
  13146     }
  13147 
  13148     BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
  13149     BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, my_modid,
  13150                             port_out, &src_trk_idx));
  13151 
  13152     mem = SOURCE_TRUNK_MAP_TABLEm;
  13153     sal_memset(entry, 0, sizeof(entry));
  13154     soc_mem_lock(unit, mem);
  13155     rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, src_trk_idx, entry);
  13156     if (SOC_SUCCESS(rv)) {
  13157         soc_mem_field32_set(unit, mem, entry, CTRL_PROFILE_IDX_0f,
  13158                              value? 0x1: 0x0);
  13159         rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, src_trk_idx, entry);
  13160     }
  13161     soc_mem_unlock(unit, mem);
  13162 
  13163     return rv;
  13164 }
  13165 
  13166 #endif
  13167 
  13168 /*
  13169  * Function:
  13170  *      bcm_port_init
  13171  * Purpose:
  13172  *      Initialize the PORT interface layer for the specified SOC device.
  13173  * Parameters:
  13174  *      unit - StrataSwitch unit number.
  13175  * Returns:
  13176  *      BCM_E_NONE - success (or already initialized)
  13177  *      BCM_E_INTERNAL- failed to write PTABLE entries
  13178  *      BCM_E_MEMORY - failed to allocate required memory.
  13179  * Notes:
  13180  *      By default ports come up enabled. They can be made to come up disabled
  13181  *      at startup by a compile-time application policy flag in your Make.local
  13182  *      PTABLE initialized.
  13183  */
  13184 int
  13185 bcm_esw_port_init(int unit)
  13186 {
  13187     int                 rv, port_enable, length_check;
  13188     bcm_port_t          p;
  13189     int                 p_speed;
  13190     pbmp_t              okay_ports;
  13191     bcm_vlan_data_t     vd;
  13192     char                pfmtok[SOC_PBMP_FMT_LEN],
  13193                         pfmtall[SOC_PBMP_FMT_LEN];
  13194     bcm_pbmp_t          all_pbmp;
  13195 #ifdef BCM_TRX_SUPPORT
  13196     bcm_pbmp_t          hg_pbmp;
  13197 #endif /* BCM_TRX_SUPPORT */
  13198 #if defined(BCM_KATANA2_SUPPORT)
  13199     uint32 entry[SOC_MAX_MEM_WORDS];
  13200 #endif /* BCM_KATANA_SUPPORT */
  13201     uint32              rx_los;
  13202 #ifdef BCM_TRIDENT2_SUPPORT
  13203     int                 enable;
  13204 #endif /* BCM_TRIDENT2_SUPPORT */
  13205 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  13206     int index;
  13207     mmu_intfi_st_trans_tbl_entry_t st_trans_entry;
  13208 #endif
  13209 
  13210 
  13211     LOG_VERBOSE(BSL_LS_BCM_PORT,
  13212                 (BSL_META_U(unit,
  13213                             "bcm_port_init: unit %d\n"), unit));
  13214     assert(unit < BCM_MAX_NUM_UNITS);
  13215     if ((rv = _bcm_port_software_init(unit)) != BCM_E_NONE) {
  13216         LOG_ERROR(BSL_LS_BCM_PORT,
  13217                   (BSL_META_U(unit,
  13218                               "Error unit %d:  Failed software port init: %s\n"),
  13219                    unit, bcm_errmsg(rv)));
  13220         return rv;
  13221     }
  13222     if (SAL_BOOT_SIMULATION &&
  13223         soc_property_get(unit, "skip_port_hw_init", 0)) {
  13224         return BCM_E_NONE;
  13225     }
  13226 
  13227     /* Initialize Port Function driver */
  13228     BCM_ESW_PORT_DRV(unit) = NULL;
  13229 
  13230 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT
  13231 #if defined(BCM_KATANA2_SUPPORT)
  13232     if (SOC_IS_KATANA2(unit)) {
  13233         BCM_IF_ERROR_RETURN(bcmi_katana2_port_fn_drv_init(unit));
  13234     } else
  13235 #endif
  13236 #if defined(BCM_MONTEREY_SUPPORT)
  13237     if (SOC_IS_MONTEREY(unit)) {
  13238         BCM_IF_ERROR_RETURN(bcmi_monterey_port_fn_drv_init(unit));
  13239     } else
  13240 #endif
  13241 #if defined(BCM_APACHE_SUPPORT)
  13242     if (SOC_IS_APACHE(unit)) {
  13243         BCM_IF_ERROR_RETURN(bcmi_apache_port_fn_drv_init(unit));
  13244     } else
  13245 #endif
  13246 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  13247     if (SOC_IS_TD2P_TT2P(unit)) {
  13248         BCM_IF_ERROR_RETURN(bcmi_td2p_port_fn_drv_init(unit));
  13249     } else
  13250 #endif
  13251 #ifdef BCM_TRIDENT3_SUPPORT
  13252     if (SOC_IS_TRIDENT3(unit)) {
  13253         BCM_IF_ERROR_RETURN(bcmi_td3_port_fn_drv_init(unit));
  13254     } else
  13255 #endif
  13256 #ifdef BCM_HELIX5_SUPPORT
  13257     if (SOC_IS_HELIX5(unit)) {
  13258         BCM_IF_ERROR_RETURN(bcmi_hx5_port_fn_drv_init(unit));
  13259     } else
  13260 #endif
  13261 #ifdef BCM_MAVERICK2_SUPPORT
  13262     if (SOC_IS_MAVERICK2(unit)) {
  13263         BCM_IF_ERROR_RETURN(bcmi_mv2_port_fn_drv_init(unit));
  13264     } else
  13265 #endif
  13266 #ifdef BCM_TOMAHAWK2_SUPPORT
  13267     if (SOC_IS_TOMAHAWK2(unit)) {
  13268         BCM_IF_ERROR_RETURN(bcmi_th2_port_fn_drv_init(unit));
  13269     } else
  13270 #endif
  13271 #ifdef BCM_TOMAHAWK3_SUPPORT
  13272     if (SOC_IS_TOMAHAWK3(unit)) {
  13273         BCM_IF_ERROR_RETURN(bcmi_th3_port_fn_drv_init(unit));
  13274     } else
  13275 #endif
  13276     {
  13277     }
  13278 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT */
  13279 
  13280     SOC_PBMP_CLEAR(all_pbmp);
  13281 
  13282 #ifdef BCM_TRX_SUPPORT
  13283     SOC_PBMP_CLEAR(hg_pbmp);
  13284 
  13285     if (soc_feature(unit, soc_feature_vlan_action) ||
  13286         soc_feature(unit, soc_feature_egr_vlan_action)) {
  13287         bcm_vlan_action_set_t action;
  13288 
  13289         bcm_vlan_action_set_t_init(&action);
  13290 
  13291 #ifdef BCM_TRIUMPH2_SUPPORT
  13292         if (soc_feature(unit, soc_feature_vpd_profile)) {
  13293             BCM_IF_ERROR_RETURN(_bcm_tr2_port_vpd_bitmap_alloc(unit));
  13294         }
  13295 #endif
  13296 
  13297         BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  13298 
  13299 #ifdef BCM_KATANA2_SUPPORT
  13300         if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  13301             /* The HW defaults for EGR_VLAN_CONTROL_1.VT_MISS_UNTAG == 1, which
  13302              * causes the outer tag to be removed from packets that don't have
  13303              * a hit in the egress vlan tranlation table. Set to 0 to disable this.
  13304              */
  13305             uint32 rval = 0;
  13306             soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, VT_MISS_UNTAGf, 0);
  13307             soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, REMARK_OUTER_DOT1Pf,1);
  13308 
  13309             BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  13310             PBMP_ITER(all_pbmp, p) {
  13311                BCM_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1r(unit, p, rval));
  13312             }
  13313         }
  13314 
  13315 		if (soc_feature(unit, soc_feature_linkphy_coe) ||
  13316             soc_feature(unit, soc_feature_subtag_coe)) {
  13317             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  13318         }
  13319 #endif
  13320 
  13321 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
  13322         if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit)
  13323              || SOC_IS_TRIDENT3X(unit)) &&
  13324                 (SOC_MEM_IS_VALID(unit, VLAN_PROTOCOL_DATAm) &&
  13325                  soc_mem_index_max(unit, VLAN_PROTOCOL_DATAm) > 0)) {
  13326             vlan_protocol_data_entry_t vlan_protocol_data_entries[16];
  13327             uint32 vlan_protocol_data_index =0;
  13328             void *entries_buf[1];
  13329             int i, count = 0;
  13330                 vlan_protocol_data_entry_t vde;
  13331 
  13332             /* Create the default VLAN_PROTOCOL_DATA profile */
  13333             sal_memset(vlan_protocol_data_entries, 0,
  13334                 sizeof(vlan_protocol_data_entries));
  13335 
  13336                 entries_buf[0] = &vlan_protocol_data_entries;
  13337                 BCM_IF_ERROR_RETURN(
  13338                     _bcm_port_vlan_protocol_data_entry_add(unit, entries_buf,
  13339                          16, (uint32 *)&vlan_protocol_data_index));
  13340 
  13341             /* First 16 entries of VLAN_PROTOCOL_DATA table are used for
  13342              * default profile for Katana2 */
  13343             for (i = 0; i < soc_mem_index_count(unit, VLAN_PROTOCOLm); i++) {
  13344                     sal_memset(&vde, 0, sizeof(vlan_protocol_data_entry_t));
  13345                     soc_VLAN_PROTOCOL_DATAm_field32_set(unit, &vde,
  13346                     OVIDf, BCM_VLAN_DEFAULT);
  13347                     soc_VLAN_PROTOCOL_DATAm_field32_set(unit, &vde,
  13348                      TAG_ACTION_PROFILE_PTRf, 0);
  13349                     BCM_IF_ERROR_RETURN(WRITE_VLAN_PROTOCOL_DATAm(unit,
  13350                         MEM_BLOCK_ALL, i, &vde));
  13351             }
  13352 
  13353             count = 0;
  13354             PBMP_ITER(all_pbmp, p) {
  13355                 PORT(unit, p).vp_count = 0;
  13356                 if (!IS_LB_PORT(unit, p) && !SOC_WARM_BOOT(unit)) {
  13357 
  13358                     /* Set vlan_protocol_data_ptr profile index in port table. */
  13359                     BCM_IF_ERROR_RETURN(
  13360                     _bcm_esw_port_tab_set(unit, p, 
  13361                                          _BCM_CPU_TABS_ETHER, 
  13362                                           VLAN_PROTOCOL_DATA_INDEXf,
  13363                                           vlan_protocol_data_index / 16)); 
  13364                     PORT(unit, p).vlan_prot_ptr = vlan_protocol_data_index;
  13365                     count++;
  13366                 }
  13367             }
  13368 
  13369             /* Keep one extra reference to the default profile */
  13370             for (i = 1; i < count + 1; i++) {
  13371                 BCM_IF_ERROR_RETURN(
  13372                 _bcm_port_vlan_protocol_data_entry_reference (unit,
  13373                     vlan_protocol_data_index, 16));
  13374             }
  13375         } else
  13376 
  13377 #endif
  13378         {
  13379             PBMP_ITER(all_pbmp, p) {
  13380                 PORT(unit, p).vp_count = 0;
  13381                 if (!IS_LB_PORT(unit, p)) {
  13382                     if (!SOC_IS_TOMAHAWKX(unit) &&
  13383                         !SOC_IS_TOMAHAWK3(unit) && !SOC_IS_TRIDENT3(unit)) {
  13384                         /* there are more ports the profile */
  13385 #ifdef BCM_TRIUMPH2_SUPPORT
  13386                         if (soc_feature(unit, soc_feature_vpd_profile)) {
  13387                             BCM_IF_ERROR_RETURN
  13388                                 (_bcm_port_vlan_prot_index_alloc
  13389                                     (unit, &(PORT(unit, p).vlan_prot_ptr)));
  13390                         } else
  13391 #endif
  13392                         {
  13393                             PORT(unit, p).vlan_prot_ptr = p * soc_mem_index_count
  13394                                                           (unit, VLAN_PROTOCOLm);
  13395                         }
  13396                     }
  13397                 }
  13398             }
  13399         }
  13400 
  13401         if (!SOC_WARM_BOOT(unit)) {
  13402             /* Clear the profile ptr of source table */
  13403             PBMP_ALL_ITER(unit, p) {
  13404                 BCM_IF_ERROR_RETURN
  13405                     (_bcm_trx_vlan_port_egress_action_profile_clear(unit, p));
  13406             }
  13407         }
  13408 
  13409         /* Initialize the vlan action profile table */
  13410 #if defined(BCM_TOMAHAWK3_SUPPORT)
  13411         if (SOC_IS_TOMAHAWK3(unit)) {
  13412             BCM_IF_ERROR_RETURN (_bcm_th3_vlan_action_profile_init(unit));
  13413         } else
  13414 #endif /* BCM_TOMAHAWK3_SUPPORT */
  13415         {
  13416             BCM_IF_ERROR_RETURN (_bcm_trx_vlan_action_profile_init(unit));
  13417         }
  13418 
  13419         if (SOC_IS_KATANA2(unit)) {
  13420             SOC_PBMP_ASSIGN(hg_pbmp,PBMP_ST_ALL(unit));
  13421         } else {
  13422             SOC_PBMP_ASSIGN(hg_pbmp,PBMP_HG_ALL(unit));
  13423         }
  13424 
  13425         if (!SOC_IS_TRIDENT3X(unit)) {
  13426             PBMP_ITER(hg_pbmp, p) {
  13427                 BCM_IF_ERROR_RETURN
  13428                     (_bcm_trx_vlan_port_egress_default_action_get(unit,
  13429                                                               p, &action));
  13430                 /* Backward compatible defaults */
  13431                 action.ot_outer = bcmVlanActionDelete;
  13432                 action.dt_outer = bcmVlanActionDelete; 
  13433                 BCM_IF_ERROR_RETURN
  13434                     (_bcm_trx_vlan_port_egress_default_action_set(unit,
  13435                                                               p, &action));
  13436             }
  13437         }
  13438     }
  13439 #endif  /* BCM_TRX_SUPPORT*/
  13440 
  13441 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  13442     if (soc_feature(unit, soc_feature_higig_over_ethernet)) {
  13443 #ifdef BCM_WARM_BOOT_SUPPORT
  13444         if (SOC_WARM_BOOT(unit)) {
  13445             uint32 port_type, hg_type, update = 0;
  13446             bcm_pbmp_t e_pbm;
  13447             soc_info_t *si;
  13448             egr_port_entry_t egr_port;
  13449 
  13450             if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) {
  13451                 si = &SOC_INFO(unit);
  13452                 SOC_PBMP_ASSIGN(e_pbm, PBMP_E_ALL(unit));
  13453                 PBMP_ITER(e_pbm, p) {
  13454                     BCM_IF_ERROR_RETURN
  13455                         (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, p, &egr_port));
  13456                     port_type =
  13457                         soc_mem_field32_get(unit, EGR_PORTm, &egr_port, PORT_TYPEf);
  13458                     hg_type =
  13459                         soc_mem_field32_get(unit, EGR_PORTm, &egr_port, HG_TYPEf);
  13460                     if ((port_type == 1) &&
  13461                         (hg_type == BCM_PORT_HG_TYPE_HGOE_TRANSPORT)) {
  13462                         SOC_PBMP_PORT_ADD(si->st.bitmap, p);
  13463                         SOC_PBMP_PORT_REMOVE(si->ether.bitmap, p);
  13464                         SOC_PBMP_PORT_REMOVE(si->hg2_pbm, p);
  13465                         update = 1;
  13466                     }
  13467                 }
  13468 #define RECONFIGURE_PORT_TYPE_INFO(ptype) \
  13469                 si->ptype.num = 0; \
  13470                 si->ptype.min = si->ptype.max = -1; \
  13471                 PBMP_ITER(si->ptype.bitmap, p) { \
  13472                     si->ptype.port[si->ptype.num++] = p; \
  13473                     if (si->ptype.min < 0) { \
  13474                         si->ptype.min = p; \
  13475                     } \
  13476                     if (p > si->ptype.max) { \
  13477                         si->ptype.max = p; \
  13478                     } \
  13479                 }
  13480 
  13481                 if (update) {
  13482                     /* Recalculate port type data */
  13483                     RECONFIGURE_PORT_TYPE_INFO(ether);
  13484                     RECONFIGURE_PORT_TYPE_INFO(st);
  13485                 }
  13486 #undef  RECONFIGURE_PORT_TYPE_INFO
  13487             }
  13488         }
  13489 #endif /* BCM_WARM_BOOT_SUPPORT */
  13490     }
  13491 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  13492 
  13493 #ifdef BCM_TRIUMPH2_SUPPORT
  13494     if (soc_feature(unit, soc_feature_gport_service_counters)) {
  13495 #ifdef BCM_WARM_BOOT_SUPPORT
  13496         if (SOC_WARM_BOOT(unit)) {
  13497             port_tab_entry_t ptab;
  13498             int fs_idx;
  13499             bcm_gport_t gport;
  13500 
  13501 #ifdef BCM_TRIDENT_SUPPORT
  13502             if (SOC_IS_TD_TT(unit)) {
  13503                 BCM_IF_ERROR_RETURN(_bcm_td_phymode_reconfigure(unit));
  13504             }
  13505 #endif /* BCM_TRIDENT_SUPPORT */
  13506             PBMP_ITER(all_pbmp, p) {
  13507                 BCM_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm,
  13508                                                  MEM_BLOCK_ANY, p, &ptab));
  13509                 fs_idx =
  13510                     soc_mem_field32_get(unit, PORT_TABm, &ptab,
  13511                                         VINTF_CTR_IDXf);
  13512                 if (fs_idx) {
  13513                     BCM_IF_ERROR_RETURN
  13514                         (bcm_esw_port_gport_get(unit, p, &gport));
  13515                     _bcm_esw_flex_stat_reinit_add(unit,
  13516                              _bcmFlexStatTypeGport, fs_idx, gport);
  13517                 }
  13518             }
  13519         }
  13520 #endif /* BCM_WARM_BOOT_SUPPORT */
  13521     }
  13522 #endif /* BCM_TRIUMPH2_SUPPORT */
  13523 
  13524 #ifdef BCM_WARM_BOOT_SUPPORT
  13525 #ifdef BCM_TRIUMPH3_SUPPORT
  13526     if (SOC_IS_TRIUMPH3(unit)) {
  13527         if (SOC_WARM_BOOT(unit)) {
  13528             _bcm_tr3_port_info_reconfig(unit);
  13529         }
  13530     }
  13531 #endif /* BCM_TRIUMPH3_SUPPORT */
  13532 #endif /* BCM_WARM_BOOT_SUPPORT */
  13533     if (!SOC_WARM_BOOT(unit)) {
  13534         /*
  13535          * Write port configuration tables to contain the Initial System
  13536          * Configuration (see init.c).
  13537          */
  13538 
  13539         SOC_PBMP_CLEAR(all_pbmp);
  13540         BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  13541 
  13542 #ifdef BCM_KATANA2_SUPPORT
  13543         if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  13544             BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  13545         }
  13546 #endif
  13547 
  13548 				SOC_PBMP_REMOVE(all_pbmp, PBMP_TDM(unit));
  13549 
  13550 #ifdef BCM_KATANA2_SUPPORT
  13551         if (soc_feature(unit, soc_feature_linkphy_coe) ||
  13552             soc_feature(unit, soc_feature_subtag_coe)) {
  13553             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  13554         }
  13555 #endif
  13556 
  13557         vd.vlan_tag = BCM_VLAN_DEFAULT;
  13558         BCM_PBMP_ASSIGN(vd.port_bitmap, all_pbmp);
  13559         BCM_PBMP_ASSIGN(vd.ut_port_bitmap, all_pbmp);
  13560         BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_CMIC(unit));
  13561 
  13562         PBMP_ITER(all_pbmp, p) {
  13563             BCM_IF_ERROR_RETURN
  13564                 (mbcm_driver[unit]->mbcm_port_cfg_init(unit, p, &vd));
  13565         }
  13566 
  13567         if (SOC_IS_TRIDENT3X(unit)) {
  13568             /* Initialize inner TPID
  13569              * (WAR)Set to 0x9100 then change back to take effort
  13570              */
  13571             BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, VLAN_CTRLr,
  13572                                 REG_PORT_ANY, INNER_TPIDf, 0x9100));
  13573             BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, VLAN_CTRLr,
  13574                                 REG_PORT_ANY, INNER_TPIDf, 0x8100));
  13575 
  13576             if (SOC_REG_FIELD_VALID(unit, EGR_CONFIG_1_64r, INNER_TPIDf)) {
  13577                 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_CONFIG_1_64r,
  13578                                     REG_PORT_ANY, INNER_TPIDf, 0x9100));
  13579                 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_CONFIG_1_64r,
  13580                                 REG_PORT_ANY, INNER_TPIDf, 0x8100));
  13581         }
  13582         }
  13583 
  13584         /*
  13585          * Clear egress port blocking table
  13586          */
  13587         if (SOC_IS_XGS_SWITCH(unit)) {
  13588 #ifdef BCM_SHADOW_SUPPORT
  13589             if (!SOC_IS_SHADOW(unit)) {
  13590 #endif
  13591                 if (!SAL_BOOT_SIMULATION || SAL_BOOT_QUICKTURN) {
  13592                     SOC_IF_ERROR_RETURN
  13593                         (soc_mem_clear(unit, MAC_BLOCKm, COPYNO_ALL, TRUE));
  13594                 }
  13595 #ifdef BCM_SHADOW_SUPPORT
  13596             }
  13597 #endif
  13598         }
  13599     }
  13600 
  13601 #ifdef BCM_SHADOW_SUPPORT
  13602     if (SOC_IS_SHADOW(unit)) {
  13603         PBMP_ITER(PBMP_PORT_ALL(unit), p) {
  13604             if (BCM_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, p)) {
  13605                 SOC_PBMP_PORT_REMOVE(PBMP_PORT_ALL(unit), p);
  13606             }
  13607         }
  13608     }
  13609 #endif
  13610 #ifdef BCM_PREEMPTION_SUPPORT
  13611     if (soc_feature(unit, soc_feature_preemption)) {
  13612         BCM_IF_ERROR_RETURN(bcmi_esw_preemption_init(unit));
  13613     }
  13614 #endif
  13615 
  13616     /* Probe for ports */
  13617     SOC_PBMP_CLEAR(okay_ports);
  13618     if ((rv = bcm_esw_port_probe(unit, PBMP_PORT_ALL(unit), &okay_ports)) !=
  13619         BCM_E_NONE) {
  13620         LOG_ERROR(BSL_LS_BCM_PORT,
  13621                   (BSL_META_U(unit,
  13622                               "Error unit %d:  Failed port probe: %s\n"),
  13623                    unit, bcm_errmsg(rv)));
  13624         return rv;
  13625     }
  13626 
  13627     LOG_VERBOSE(BSL_LS_BCM_PORT,
  13628                 (BSL_META_U(unit,
  13629                             "Probed ports okay: %s of %s\n"),
  13630                  SOC_PBMP_FMT(okay_ports, pfmtok),
  13631                  SOC_PBMP_FMT(PBMP_PORT_ALL(unit), pfmtall)));
  13632     /*
  13633      * A compile-time application policy may prefer to disable ports 
  13634      * when switch boots up
  13635      */
  13636 #ifdef BCM_PORT_DEFAULT_DISABLE
  13637             port_enable = FALSE;
  13638 #else
  13639             port_enable = TRUE;
  13640 #endif  /* BCM_PORT_DEFAULT_DISABLE */
  13641 
  13642     if(SOC_IS_SABER2(unit) && (!SOC_WARM_BOOT(unit))) {
  13643         PBMP_ITER(okay_ports, p) {
  13644             if ((rv = bcm_esw_port_enable_set(unit, p, port_enable)) < 0) {
  13645                 LOG_WARN(BSL_LS_BCM_PORT,
  13646                          (BSL_META_U(unit,
  13647                                      "Warning: Unit %d Port %s: "
  13648                                      "Failed to %s port: %s\n"),
  13649                           unit, SOC_PORT_NAME(unit, p),(port_enable) ? \
  13650                           "enable" : "disable" ,bcm_errmsg(rv)));
  13651             }
  13652         }
  13653     }
  13654 
  13655 
  13656 
  13657     length_check = soc_property_get(unit, spn_MAC_LENGTH_CHECK_ENABLE, 0);
  13658 
  13659     /* Probe and initialize MAC and PHY drivers for ports that were OK */
  13660     PBMP_ITER(okay_ports, p) {
  13661         LOG_VERBOSE(BSL_LS_BCM_PORT,
  13662                     (BSL_META_U(unit,
  13663                                 "bcm_port_init: unit %d port %s\n"),
  13664                                 unit, SOC_PORT_NAME(unit, p)));
  13665 
  13666         PORT_LOCK(unit);
  13667 
  13668         
  13669         if(SOC_USE_PORTCTRL(unit)) {
  13670         } else {
  13671             if ((rv = _bcm_port_mode_setup(unit, p, TRUE)) < 0) {
  13672                 LOG_WARN(BSL_LS_BCM_PORT,
  13673                          (BSL_META_U(unit,
  13674                                      "Warning: Port %s: "
  13675                                      "Failed to set initial mode: %s\n"),
  13676                           SOC_PORT_NAME(unit, p), bcm_errmsg(rv)));
  13677             }
  13678         }
  13679         PORT_UNLOCK(unit);
  13680 
  13681 #ifdef BCM_RCPU_SUPPORT
  13682         if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, p)) {
  13683             if (SOC_USE_PORTCTRL(unit)) {
  13684                 bcmi_esw_portctrl_phy_enable_set(unit, p, TRUE);
  13685             } else {
  13686                 soc_phyctrl_enable_set(unit, p, TRUE);
  13687             }
  13688             continue;
  13689         }
  13690 #endif /* BCM_RCPU_SUPPORT */
  13691 
  13692 #ifdef BCM_WARM_BOOT_SUPPORT
  13693         if (SOC_WARM_BOOT(unit)) {
  13694             continue;
  13695         }
  13696 #endif /* BCM_WARM_BOOT_SUPPORT */
  13697         if ((rv = bcm_port_settings_init(unit, p)) < 0) {
  13698             LOG_WARN(BSL_LS_BCM_PORT,
  13699                      (BSL_META_U(unit,
  13700                                  "Warning: Port %s: "
  13701                                  "Failed to configure initial settings: %s\n"),
  13702                       SOC_PORT_NAME(unit, p), bcm_errmsg(rv)));
  13703         }
  13704 
  13705 #ifdef BCM_TRIDENT2_SUPPORT
  13706         if (soc_feature(unit, soc_feature_pgw_mac_rsv_mask_remap)) {
  13707             uint32 addr;
  13708             int block;
  13709             uint8 acc_type;
  13710             uint32 rval;
  13711 
  13712             addr = soc_reg_addr_get(unit, PGW_MAC_RSV_MASKr, p, 0,
  13713                                     SOC_REG_ADDR_OPTION_NONE, &block,
  13714                                     &acc_type);
  13715             addr &= 0xffffff00;
  13716             /* coverity[overrun-local : FALSE] */
  13717             addr |= (SOC_INFO(unit).port_l2p_mapping[p] - 1) & 0xf;
  13718             SOC_IF_ERROR_RETURN(_soc_reg32_get(unit, block, acc_type, addr,
  13719                                                &rval));
  13720             if (length_check) {
  13721                 rval |= 0x20;  /* set bit 5 to enable frame length check */
  13722             } else {
  13723                 rval &= ~0x20; /* clear bit 5 to disable frame length check */
  13724             }
  13725             rval |= 1 << 18; /* set PFC frame detected indicator */
  13726             SOC_IF_ERROR_RETURN(_soc_reg32_set(unit, block, acc_type, addr,
  13727                                                rval));
  13728         } else
  13729 #endif /* BCM_TRIDENT2_SUPPORT */
  13730         /* Control 802.3 frame length field check in MAC for
  13731          * XL, XLB0, XT, CL, CLG2, XW (helix4) or MXQ blocks */
  13732         if (IS_XL_PORT(unit, p) || IS_XLB0_PORT(unit, p) || IS_XT_PORT(unit, p) ||
  13733             IS_CL_PORT(unit, p) || IS_CLG2_PORT(unit, p) || IS_MXQ_PORT(unit,p) ||
  13734             IS_XW_PORT(unit,p) || IS_CD_PORT(unit, p)) {
  13735             uint32 rval;
  13736             soc_reg_t reg = INVALIDr;
  13737 
  13738             if ((IS_CL_PORT(unit, p) || IS_CLG2_PORT(unit, p)) &&
  13739                 SOC_REG_IS_VALID(unit, CLPORT_MAC_RSV_MASKr)) {
  13740                 reg = CLPORT_MAC_RSV_MASKr;
  13741             } else if (IS_CD_PORT(unit, p)) {
  13742                 reg = CDMAC_RSV_MASKr;
  13743             } else if (SOC_REG_IS_VALID(unit, PGW_MAC_RSV_MASKr)) {
  13744                 reg = PGW_MAC_RSV_MASKr;
  13745             } else if (SOC_IS_SABER2(unit) && SOC_REG_PORT_VALID(unit, XLPORT_MAC_RSV_MASKr, p)) {
  13746                 reg = XLPORT_MAC_RSV_MASKr;
  13747             } else if (SOC_REG_IS_VALID(unit, MAC_RSV_MASKr)) {
  13748                 reg = MAC_RSV_MASKr;
  13749             } else if (SOC_REG_IS_VALID(unit, XLPORT_MAC_RSV_MASKr)) {
  13750                 reg = XLPORT_MAC_RSV_MASKr;
  13751             }
  13752 
  13753             if (reg != INVALIDr) {
  13754                 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, p, 0, &rval));
  13755                 if (length_check) {
  13756                     rval |= 0x20;  /* set bit 5 to enable frame length check */
  13757                 } else {
  13758                     rval &= ~0x20; /* clear bit 5 to disable frame length check */
  13759                 }
  13760                 if (SOC_IS_TD2_TT2(unit)|| SOC_IS_HELIX4(unit)) {
  13761                     rval |= 1 << 18; /* set PFC frame detected indicator */
  13762                 }
  13763                 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, p, 0, rval));
  13764             }
  13765         }
  13766 
  13767         /*
  13768          * A compile-time application policy may prefer to disable ports
  13769          * when switch boots up
  13770          */
  13771 
  13772 #ifdef BCM_PORT_DEFAULT_DISABLE
  13773             port_enable = FALSE;
  13774 #else
  13775             port_enable = TRUE;
  13776 #endif  /* BCM_PORT_DEFAULT_DISABLE */
  13777 
  13778         if(!SOC_IS_SABER2(unit)) {
  13779             if ((rv = bcm_esw_port_enable_set(unit, p, port_enable)) < 0) {
  13780             LOG_WARN(BSL_LS_BCM_PORT,
  13781                      (BSL_META_U(unit,
  13782                                  "Warning: Port %s: "
  13783                                  "Failed to %s port: %s\n"),
  13784                       SOC_PORT_NAME(unit, p),(port_enable) ? \
  13785                       "enable" : "disable" ,bcm_errmsg(rv)));
  13786             }
  13787         }
  13788 
  13789         /*
  13790          *  JAM should be enabled by default
  13791          */
  13792         if (IS_E_PORT(unit, p)) {
  13793             if (soc_mem_field_valid(unit, PORT_TABm, JAM_ENf) ||
  13794                 soc_reg_field_valid(unit, GE_PORT_CONFIGr, JAM_ENf) ||
  13795                 soc_feature(unit, soc_feature_unimac)) {
  13796 
  13797 #if defined(BCM_HURRICANE_SUPPORT)
  13798                 if (SOC_IS_HURRICANEX(unit) || SOC_IS_GREYHOUND(unit) ||
  13799                     SOC_IS_GREYHOUND2(unit)) {
  13800 					rv = bcm_esw_port_jam_set(unit, p, 0);
  13801 				} else
  13802 #endif
  13803 				{
  13804 					rv = bcm_esw_port_jam_set(unit, p, 1);
  13805 				}
  13806                 if (BCM_FAILURE(rv) && (rv != BCM_E_UNAVAIL)) {
  13807                     LOG_WARN(BSL_LS_BCM_PORT,
  13808                              (BSL_META_U(unit,
  13809                                          "Warning: Port %s: "
  13810                                          "Failed to enable JAM %s\n"),
  13811                               SOC_PORT_NAME(unit, p), bcm_errmsg(rv)));
  13812                 }
  13813             }
  13814         }
  13815 #ifdef BCM_TRIUMPH2_SUPPORT
  13816         if (soc_feature(unit, soc_feature_unimac_tx_crs) && IS_XQ_PORT(unit, p)
  13817             && IS_GE_PORT(unit, p)) {
  13818             BCM_IF_ERROR_RETURN
  13819                 (soc_reg_field32_modify(unit, XPORT_CONFIGr, p,
  13820                                         UNIMAC_HD_ECO_ENABLEf, 1));
  13821         }
  13822 #endif
  13823 #ifdef BCM_RCPU_SUPPORT
  13824         if ((uint32)p == soc_property_get(unit, spn_RCPU_PORT, -1)) {
  13825             BCM_IF_ERROR_RETURN
  13826                 (bcm_esw_port_frame_max_set(unit, p, BCM_PORT_JUMBO_MAXSZ));
  13827         }
  13828 #endif /* BCM_RCPU_SUPPORT */
  13829     }
  13830 
  13831 #if defined(BCM_GREYHOUND_SUPPORT)
  13832     if (SOC_IS_GREYHOUND(unit)) {
  13833         BCM_IF_ERROR_RETURN(bcm_gh_port_init(unit));
  13834     }
  13835 #endif
  13836 
  13837 #if defined(BCM_HURRICANE3_SUPPORT)
  13838     if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  13839         BCM_IF_ERROR_RETURN(bcm_hr3_port_init(unit));
  13840     }
  13841 #endif
  13842 
  13843 #if defined(BCM_TRIDENT_SUPPORT)
  13844     if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) {
  13845         BCM_IF_ERROR_RETURN(bcm_td_port_init(unit));
  13846     }
  13847 #endif /* BCM_TRIDENT_SUPPORT */
  13848 
  13849 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \
  13850     defined(BCM_TRX_SUPPORT)
  13851     if (!SOC_WARM_BOOT(unit) && !SOC_IS_RELOADING(unit)) {
  13852         /* Enable the default outer TPID. */
  13853         if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  13854         /* if (soc_feature(unit, soc_feature_vlan_ctrl) && * SOC_IS_SHADOW(unit)) { */
  13855 
  13856         SOC_PBMP_CLEAR(all_pbmp);
  13857         SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  13858 
  13859 #ifdef BCM_KATANA2_SUPPORT
  13860         if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  13861             BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  13862         }
  13863 #endif
  13864 
  13865         SOC_PBMP_REMOVE(all_pbmp, PBMP_TDM(unit));
  13866 
  13867 #ifdef BCM_KATANA2_SUPPORT
  13868         if (soc_feature(unit, soc_feature_linkphy_coe) ||
  13869             soc_feature(unit, soc_feature_subtag_coe)) {
  13870             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  13871         }
  13872 #endif
  13873 
  13874 #if defined(BCM_SABER2_SUPPORT)
  13875         /* If OAMP is enabled by default, skip the port init for oamp port */
  13876         if(SOC_IS_SABER2(unit)) {
  13877             int oamp_enable;
  13878             (void)bcm_sb2_sat_oamp_enable_get(unit, &oamp_enable);
  13879 
  13880             if (soc_feature(unit, soc_feature_sat) &&
  13881                 ((!SOC_WARM_BOOT(unit) &&
  13882                     soc_property_get(unit, spn_SAT_ENABLE, 0)) ||
  13883                  (SOC_WARM_BOOT(unit) && (oamp_enable == TRUE)))) {
  13884                 SOC_PBMP_PORT_REMOVE(all_pbmp,
  13885                         _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER);
  13886             }
  13887         }
  13888 #endif
  13889 
  13890             PBMP_ITER(all_pbmp, p) {
  13891                 rv = bcm_esw_port_tpid_set(unit, p,
  13892                                 _bcm_fb2_outer_tpid_default_get(unit));
  13893                 if (BCM_FAILURE(rv)) {
  13894                  LOG_WARN(BSL_LS_BCM_PORT,
  13895                           (BSL_META_U(unit,
  13896                                       "Warning: "
  13897                                       "Failed to set %s port default TPID: %s\n"),
  13898                            SOC_PORT_NAME(unit, p), bcm_errmsg(rv)));
  13899                 }
  13900                 if (soc_feature(unit, soc_feature_inner_tpid_enable)) {
  13901                     /* Enable the default inner TPID. */
  13902                     rv = bcm_esw_port_inner_tpid_set(unit, p,
  13903                                     _bcm_fb2_outer_tpid_default_get(unit));
  13904                     if (BCM_FAILURE(rv)) {
  13905                      LOG_WARN(BSL_LS_BCM_PORT,
  13906                               (BSL_META_U(unit,
  13907                                           "Warning: "
  13908                                           "Failed to set %s port default inner TPID: %s\n"),
  13909                                SOC_PORT_NAME(unit, p), bcm_errmsg(rv)));
  13910                     }
  13911                 }
  13912             }
  13913         }
  13914     }
  13915 #endif
  13916 
  13917 #ifdef BCM_XGS3_FABRIC_SUPPORT
  13918     if (SOC_IS_XGS3_FABRIC(unit)) {
  13919         PBMP_ALL_ITER(unit, p) {
  13920             bcm_esw_port_learn_set(unit, p, BCM_PORT_LEARN_FWD);
  13921         }
  13922     }
  13923 #endif
  13924     if (SAL_BOOT_SIMULATION &&
  13925         soc_property_get(unit, "skip_partial_port_hw_init", 0)) {
  13926         return BCM_E_NONE;
  13927     }
  13928 #ifdef BCM_TRIUMPH2_SUPPORT
  13929     if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  13930         SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit) ||
  13931         SOC_IS_TD_TT(unit) || SOC_IS_HURRICANEX(unit) ||
  13932         SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit) ||
  13933         SOC_IS_GREYHOUND(unit) || SOC_IS_GREYHOUND2(unit)) {
  13934         uint32 regval, profile_index;
  13935         bcm_pbmp_t port_pbmp;
  13936 
  13937         /* Set the chip-wide E2ECC port mapping enable bit */
  13938         if (soc_feature(unit, soc_feature_sysport_remap)) {
  13939             SOC_IF_ERROR_RETURN(READ_E2ECC_PORT_MAPPING_CONFIGr(unit, &regval));
  13940             soc_reg_field_set(unit, E2ECC_PORT_MAPPING_CONFIGr, &regval, PORT_MAPPING_ENf, 1);
  13941             SOC_IF_ERROR_RETURN(WRITE_E2ECC_PORT_MAPPING_CONFIGr(unit, regval));
  13942         }
  13943 
  13944         SOC_PBMP_CLEAR(all_pbmp);
  13945         SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  13946         SOC_PBMP_CLEAR(port_pbmp);
  13947         SOC_PBMP_ASSIGN(port_pbmp, PBMP_PORT_ALL(unit));
  13948 
  13949 #ifdef BCM_KATANA2_SUPPORT
  13950         if (soc_feature(unit, soc_feature_linkphy_coe) ||
  13951             soc_feature(unit, soc_feature_subtag_coe)) {
  13952             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  13953             _bcm_kt2_subport_pbmp_update(unit, &port_pbmp);
  13954         }
  13955         if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  13956             BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp));
  13957             BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &port_pbmp));
  13958         }
  13959 #endif
  13960 
  13961         PBMP_ITER(all_pbmp, p) {
  13962             /* Initialize the logical to physical port mapping */
  13963             if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) &&
  13964                 !SOC_IS_TD_TT(unit) && !SOC_IS_TRIUMPH3(unit) &&
  13965                 !SOC_IS_KATANAX(unit) && !SOC_IS_GREYHOUND(unit) &&
  13966                 !SOC_IS_GREYHOUND2(unit)) {
  13967                 bcm_port_t sp = p;
  13968                 if (soc_feature(unit, soc_feature_sysport_remap)) {
  13969                     BCM_XLATE_SYSPORT_P2S(unit, &sp);
  13970                 }
  13971                 _bcm_port_remap_set(unit, p, sp);
  13972             }
  13973 
  13974             /* Initialize egress block profile pointer to invalid value */
  13975             PORT_SRC_MOD_EGR_PROF_PTR(unit, p) = -1;
  13976 
  13977             /* Program the VLAN_PROTOCOL_DATA / FP_PORT_FIELD_SEL_INDEX
  13978                / PROTOCOL_PKT_INDEX pointers */
  13979             if (!IS_LB_PORT(unit, p) && !IS_TDM_PORT(unit, p)) {
  13980                 int value = 0;
  13981                 if (SOC_MEM_IS_VALID(unit, VLAN_PROTOCOLm)) {
  13982                     value = PORT(unit, p).vlan_prot_ptr /
  13983                             soc_mem_index_count(unit, VLAN_PROTOCOLm);
  13984                 }
  13985                 if ((0 != value) &&
  13986                     (soc_mem_index_max(unit, VLAN_PROTOCOL_DATAm) > 0)) {
  13987                     BCM_IF_ERROR_RETURN(
  13988                         _bcm_esw_port_tab_set(unit, p,
  13989                                        _BCM_CPU_TABS_ETHER,
  13990                                        VLAN_PROTOCOL_DATA_INDEXf,
  13991                                        BCM_PBMP_MEMBER(port_pbmp, p) ? value : 0));
  13992                 }
  13993 
  13994                 if (soc_mem_field_valid(unit, PORT_TABm,
  13995                     FP_PORT_FIELD_SEL_INDEXf)) {
  13996                     BCM_IF_ERROR_RETURN(
  13997                         _bcm_esw_port_tab_set(unit, p, 
  13998                                    _BCM_CPU_TABS_ETHER, 
  13999                                     FP_PORT_FIELD_SEL_INDEXf, p));
  14000                 }
  14001                 if (soc_mem_field_valid(unit, PORT_TABm, PROTOCOL_PKT_INDEXf) ||
  14002                     soc_mem_field_valid(unit, LPORT_TABm,
  14003                                         PROTOCOL_PKT_INDEXf)) {
  14004                     if (SOC_REG_INFO(unit, PROTOCOL_PKT_CONTROLr).regtype ==
  14005                         soc_portreg) {
  14006                             BCM_IF_ERROR_RETURN(
  14007                                 _bcm_esw_port_tab_set(unit, p, 
  14008                                                    _BCM_CPU_TABS_ETHER, 
  14009                                                    PROTOCOL_PKT_INDEXf,
  14010                                                    p)); 
  14011                     } else {
  14012                         BCM_IF_ERROR_RETURN
  14013                             (_bcm_prot_pkt_ctrl_add(unit, 0, 0,
  14014                                                     &profile_index));
  14015                         BCM_IF_ERROR_RETURN(    
  14016                             _bcm_esw_port_tab_set(unit, p, 
  14017                                                    _BCM_CPU_TABS_ETHER, 
  14018                                                    PROTOCOL_PKT_INDEXf,
  14019                                                    profile_index)); 
  14020                     }
  14021                 }
  14022 
  14023                 if (soc_feature(unit, soc_feature_embedded_higig)
  14024                     && IS_E_PORT(unit, p)) {
  14025                     uint32 buffer[_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ];
  14026                     uint32      mask[SOC_MAX_MEM_FIELD_WORDS];
  14027 
  14028                     sal_memset(buffer, 0,
  14029                            WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ));
  14030                     sal_memset(mask, 0xFF, sizeof(mask));
  14031                     /* coverity[overrun-call : FALSE] */
  14032                     BCM_IF_ERROR_RETURN(
  14033                         _bcm_port_ehg_header_write(unit, p, buffer, buffer, mask,
  14034                                         _BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ));
  14035                 }
  14036             }
  14037         }
  14038 
  14039         if (!SOC_MEM_IS_VALID(unit, SYSTEM_CONFIG_TABLE_MODBASEm) &&
  14040             !SOC_MEM_IS_VALID(unit, SOURCE_TRUNK_MAP_MODBASEm) &&
  14041             SOC_MEM_IS_VALID(unit, SYSTEM_CONFIG_TABLEm)) {
  14042             BCM_IF_ERROR_RETURN(_bcm_tr2_system_tpid_init(unit));
  14043         }
  14044     }
  14045 #endif /* BCM_TRIUMPH2_SUPPORT */
  14046 
  14047 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || \
  14048     defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT)
  14049     if ((soc_feature(unit, soc_feature_timesync_v3) || SOC_IS_TRIUMPH3(unit) ||
  14050          SOC_IS_KATANAX(unit)|| SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) ||
  14051          SOC_IS_APACHE(unit)) &&
  14052         (soc_feature(unit,soc_feature_timesync_support))) {
  14053         _bcm_esw_port_timesync_profile_init(unit);
  14054     }
  14055 #endif /* defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) ||
  14056           defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) */
  14057 
  14058 #ifdef BCM_SHADOW_SUPPORT
  14059         /* Static port load balancing configuration for shadow */
  14060     if (SOC_IS_SHADOW(unit))  {
  14061         port_tab_entry_t ptab;
  14062 
  14063         for (p = 0; p <= 16; p++) {
  14064             /* Enable IPV4 and IPV6 */
  14065             BCM_IF_ERROR_RETURN(
  14066                 _bcm_esw_port_tab_set(unit, p, 
  14067                                      _BCM_CPU_TABS_ETHER, 
  14068                                       IPV4_ENABLEf, 1));            
  14069 
  14070             BCM_IF_ERROR_RETURN(
  14071                 _bcm_esw_port_tab_set(unit, p, 
  14072                                      _BCM_CPU_TABS_ETHER, 
  14073                                       IPV6_ENABLEf, 1));            
  14074         }
  14075 
  14076         /* For shadow-petrab mode, configure uflow_A(xe0) and uflow_b(xe1)*/
  14077         if(soc_property_get(unit, spn_BCM88732_DEVICE_MODE, 0) &&
  14078                 ((soc_property_get(unit, spn_BCM88732_2X40_1X40, 0)) ||
  14079                  (soc_property_get(unit, spn_BCM88732_2X40_2X40, 0)))) {
  14080             BCM_IF_ERROR_RETURN(
  14081                 _bcm_esw_port_tab_set(unit, 1, 
  14082                                      _BCM_CPU_TABS_ETHER, 
  14083                                       AGGREGATION_GROUP_SELECTf, 0));            
  14084 
  14085             /* port 5 (xe1) configure uflow_b for static load balancing */
  14086             BCM_IF_ERROR_RETURN(
  14087                 _bcm_esw_port_tab_set(unit, 5, 
  14088                                      _BCM_CPU_TABS_ETHER, 
  14089                                       AGGREGATION_GROUP_SELECTf, 1));            
  14090 
  14091             /* Enable SAND interop header for Interlaken ports */
  14092             for (p = 9; p <= 16; p++) {
  14093                 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, p, 
  14094                                            _BCM_CPU_TABS_ETHER, 
  14095                                             SAND_COS_ENABLEf, 1)); 
  14096             }
  14097         }
  14098         if(soc_property_get(unit, spn_BCM88732_2X40_8X10, 0))  {
  14099             sal_memset(&ptab, 0, sizeof(ptab));
  14100             /* port 1 (xe0) configure uflow_a for static load balancing */
  14101             SOC_IF_ERROR_RETURN(
  14102                     READ_PORT_TABm(unit, MEM_BLOCK_ANY, 1, &ptab));
  14103             soc_PORT_TABm_field32_set(unit, &ptab, AGGREGATION_GROUP_SELECTf, 0);
  14104             SOC_IF_ERROR_RETURN(
  14105                     WRITE_PORT_TABm(unit,MEM_BLOCK_ALL, 1, &ptab));
  14106 
  14107             /* port 5 (xe1) configure uflow_b for static load balancing */
  14108             SOC_IF_ERROR_RETURN(
  14109                     READ_PORT_TABm(unit, MEM_BLOCK_ANY, 5, &ptab));
  14110             soc_PORT_TABm_field32_set(unit, &ptab, AGGREGATION_GROUP_SELECTf, 1);
  14111             SOC_IF_ERROR_RETURN(
  14112                     WRITE_PORT_TABm(unit,MEM_BLOCK_ALL, 5, &ptab));
  14113 
  14114         }
  14115 
  14116         /* By default Disable VLAN checks and enable TPID in port table */
  14117         for (p = 0; p <= 16; p++) {
  14118             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, p, 
  14119                                 _BCM_CPU_TABS_ETHER, 
  14120                                  DISABLE_VLAN_CHECKSf, 1)); 
  14121 
  14122             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, p, 
  14123                                 _BCM_CPU_TABS_ETHER, 
  14124                                  OUTER_TPID_ENABLEf, 1)); 
  14125         }
  14126     }
  14127 #endif /* BCM_SHADOW_SUPPORT */
  14128 
  14129 #ifdef BCM_TRIDENT_SUPPORT
  14130     if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)) {
  14131         uint32 regval;
  14132         int blk;
  14133         int blk_num = -1;
  14134         int bindex = 0;
  14135         int tx_pbm = 0;
  14136         bcm_pbmp_t all_pbmp;
  14137 
  14138         if (SOC_IS_TRIUMPH3(unit)) {
  14139             /* Clear all bits for flex port considerations */
  14140             for (blk_num = 0; blk_num < 7; blk_num++) {
  14141                 SOC_IF_ERROR_RETURN
  14142                     (WRITE_E2ECC_TX_ENABLE_BMPr(unit, blk_num, 0));
  14143             }
  14144         }
  14145 
  14146         SOC_PBMP_CLEAR(all_pbmp);
  14147         SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  14148 
  14149 #ifdef BCM_KATANA2_SUPPORT
  14150         if (soc_feature(unit, soc_feature_linkphy_coe) ||
  14151             soc_feature(unit, soc_feature_subtag_coe)) {
  14152             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  14153         }
  14154 #endif
  14155 
  14156         PBMP_ITER(all_pbmp, p) {
  14157             if (!IS_LB_PORT(unit, p) && !IS_TDM_PORT(unit, p)) {
  14158                  if (soc_mem_field_valid(unit, PORT_TABm,
  14159                     FP_PORT_FIELD_SEL_INDEXf)) {
  14160                     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, p, 
  14161                                     _BCM_CPU_TABS_ETHER, 
  14162                                     FP_PORT_FIELD_SEL_INDEXf, p));
  14163                 } 
  14164             } 
  14165         }
  14166 
  14167         PBMP_ITER(PBMP_PORT_ALL(unit), p) {
  14168             /* In Trident all ports are enabled to send E2ECC messages by
  14169              * default. Disable E2ECC message TX here until congestion config
  14170              * set enables the port.
  14171              */
  14172 
  14173             if (soc_feature(unit, soc_feature_logical_port_num)) {
  14174                 /* coverity[overrun-local : FALSE] */
  14175                 blk = SOC_PORT_BLOCK(unit, SOC_INFO(unit).port_l2p_mapping[p]);
  14176                 bindex = SOC_PORT_BINDEX(unit, SOC_INFO(unit).port_l2p_mapping[p]);
  14177             } else{
  14178                 blk = SOC_PORT_BLOCK(unit, p);
  14179                 bindex = SOC_PORT_BINDEX(unit, p);
  14180             }
  14181 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
  14182            if (SOC_IS_TRIDENT2X(unit)) {
  14183                blk_num = SOC_INFO(unit).port_serdes[p];
  14184            } else
  14185 #endif
  14186            {
  14187             blk_num = SOC_BLOCK_INFO(unit, blk).number;
  14188            }
  14189             if (SOC_IS_KATANA2(unit)) {
  14190                 if (!IS_HG_PORT(unit, p)) {
  14191                     continue;
  14192                 }
  14193                 /* In KT2 E2ECC is implemented only in blocks 6..9 */
  14194                 if (blk_num >= 6) {
  14195                     blk_num -= 6;
  14196                 } else {
  14197                     continue;
  14198                 }
  14199             }
  14200             if (!SOC_IS_TRIUMPH3(unit) &&
  14201                 SOC_REG_IS_VALID(unit, E2ECC_TX_ENABLE_BMPr)) {
  14202                 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_ENABLE_BMPr(unit, blk_num,
  14203                                                               &regval));
  14204                 tx_pbm = soc_reg_field_get(unit, E2ECC_TX_ENABLE_BMPr, regval,
  14205                                            TX_ENABLE_BMPf);
  14206                 tx_pbm &= ~(1 << bindex);
  14207                 soc_reg_field_set(unit, E2ECC_TX_ENABLE_BMPr, &regval,
  14208                                   TX_ENABLE_BMPf, tx_pbm);
  14209                 SOC_IF_ERROR_RETURN(WRITE_E2ECC_TX_ENABLE_BMPr(unit,
  14210                                                                blk_num, regval));
  14211             }
  14212         }
  14213         /* Set the chip-wide E2ECC port mapping enable bit */
  14214         if (soc_feature(unit, soc_feature_sysport_remap)) {
  14215             SOC_IF_ERROR_RETURN(READ_E2ECC_PORT_MAPPING_CONFIGr(unit, &regval));
  14216             soc_reg_field_set(unit, E2ECC_PORT_MAPPING_CONFIGr, &regval,
  14217                               PORT_MAPPING_ENf, 1);
  14218             SOC_IF_ERROR_RETURN(WRITE_E2ECC_PORT_MAPPING_CONFIGr(unit, regval));
  14219         }
  14220     }
  14221 #endif
  14222 
  14223 #if defined (BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) \
  14224     || defined (BCM_HAWKEYE_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \
  14225     || defined (BCM_HURRICANE2_SUPPORT)
  14226     if (SOC_IS_HURRICANE (unit) || SOC_IS_TD_TT (unit) ||
  14227         SOC_IS_HAWKEYE (unit) || SOC_IS_SHADOW(unit) ||
  14228         SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||
  14229         SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) ||
  14230         SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  14231         if (soc_feature (unit, soc_feature_eee)) {
  14232             int mac_val = 0;
  14233             _bcm_port_info_t *port_info;
  14234             PBMP_ALL_ITER(unit, p) {
  14235                 if (!IS_LB_PORT(unit, p) && !IS_CPU_PORT (unit, p) && !IS_FAE_PORT (unit, p) &&
  14236                     !IS_TDM_PORT(unit, p) && !IS_RDB_PORT(unit,p) && !IS_MACSEC_PORT(unit,p)) {
  14237                     /* EEE standard compliance Work Around:
  14238                      * Initialize the software state of native eee in MAC
  14239                      */
  14240                     eee_cfg[unit][p] = 0;
  14241                     /* Check if MAC supports Native EEE and set the value of
  14242                      * eee_cfg by reading the EEE status from MAC*/
  14243                     if (SOC_USE_PORTCTRL(unit)) {
  14244                         rv = bcmi_esw_portctrl_eee_enable_get(unit, p,
  14245                                                               &mac_val);
  14246 
  14247                     } else {
  14248                         _bcm_port_info_access(unit, p, &port_info);
  14249                         rv = MAC_CONTROL_GET(port_info->p_mac, unit, p,
  14250                                              SOC_MAC_CONTROL_EEE_ENABLE,
  14251                                              &mac_val);
  14252                     }
  14253                     if (rv != BCM_E_UNAVAIL) {
  14254                         eee_cfg[unit][p] = mac_val;
  14255                     }
  14256                 }
  14257             }
  14258         }
  14259     }
  14260 #endif /* (BCM_HURRICANE_SUPPORT) || (BCM_TRIDENT_SUPPORT) || (BCM_HAWKEYE_SUPPORT)*/
  14261 
  14262     /*
  14263      * CES TDM Port initialization
  14264      */
  14265     /* Set Higig/Higig2 mode */
  14266     if (!SOC_WARM_BOOT(unit)) {
  14267         if (SOC_USE_PORTCTRL(unit)) {
  14268             int hg_port;
  14269             PBMP_HG_ITER(unit, hg_port) {
  14270                 BCM_IF_ERROR_RETURN
  14271                     (bcmi_esw_portctrl_higig_mode_set(unit, hg_port, TRUE));
  14272             }
  14273         } 
  14274 #ifdef BCM_HIGIG2_SUPPORT
  14275         if (soc_feature(unit, soc_feature_higig2)) {
  14276             int hg_port;
  14277 #if defined(BCM_KATANA_SUPPORT)
  14278             int hl_port;
  14279 
  14280             if (SOC_IS_KATANA(unit)) {
  14281                 PBMP_HL_ITER(unit, hl_port) {
  14282                     BCM_IF_ERROR_RETURN
  14283                         (_bcm_esw_port_higig2_mode_set(unit, hl_port, TRUE));
  14284                     SOC_HG2_ENABLED_PORT_ADD(unit, hl_port);
  14285                 }
  14286             }
  14287 #endif
  14288             PBMP_HG_ITER(unit, hg_port) {
  14289                 /*
  14290                  * Make all HG ports default to HiGig2, when
  14291                  * 1. spn_HIGIG2_HDR_MODE = 1. Or
  14292                  * 2. portmod is enabled
  14293                  */
  14294                 if (soc_property_port_get(unit, hg_port, spn_HIGIG2_HDR_MODE,
  14295                         soc_feature(unit, soc_feature_no_higig_plus) ? 1 : 0) ||
  14296                     SOC_USE_PORTCTRL(unit)) {
  14297                     BCM_IF_ERROR_RETURN
  14298                         (_bcm_esw_port_higig2_mode_set(unit, hg_port, TRUE));
  14299                     SOC_HG2_ENABLED_PORT_ADD(unit, hg_port);
  14300                 }
  14301             }
  14302         }
  14303 #endif /* BCM_HIGIG2_SUPPORT */
  14304     }
  14305 
  14306     BCM_IF_ERROR_RETURN(_bcm_esw_port_mon_start(unit));
  14307 #ifdef BCM_TRIUMPH3_SUPPORT
  14308     if (SOC_IS_TRIUMPH3(unit)) {
  14309         BCM_IF_ERROR_RETURN
  14310             (_bcm_esw_ibod_sync_recovery_start(unit,
  14311              soc_property_get(unit, spn_PORTMON_INTERVAL, IBOD_SYNC_INTERVAL_MIN)));
  14312     }
  14313 #endif /* BCM_TRIUMPH3_SUPPORT */
  14314     /* Port translation call-back function for PHY drivers */
  14315     soc_phy_cb_xlate_port_func = _bcm_phy_cb_xlate_port;
  14316 
  14317 #ifdef BCM_TRIUMPH2_SUPPORT
  14318     if (soc_feature(unit, soc_feature_src_modid_blk_profile)) {
  14319         soc_mem_t mem = SRC_MODID_EGRESSm;
  14320         int mem_words;
  14321         int rv;
  14322 
  14323         if (SOC_MEM_IS_VALID(unit, mem)) {
  14324             if (NULL == PORT_SRC_MOD_EGR_PROFILE(unit)) {
  14325                 PORT_SRC_MOD_EGR_PROFILE(unit) =
  14326                     sal_alloc(sizeof(soc_profile_mem_t),
  14327                               "SRC_MODID_EGRESS Profile Mem");
  14328                 if (NULL == PORT_SRC_MOD_EGR_PROFILE(unit)) {
  14329                     return BCM_E_MEMORY;
  14330                 }
  14331                 soc_profile_mem_t_init(PORT_SRC_MOD_EGR_PROFILE(unit));
  14332 
  14333                 mem_words = sizeof(src_modid_egress_entry_t) /
  14334                     sizeof(uint32);
  14335 
  14336                 rv = soc_profile_mem_create(unit, &mem, &mem_words, 1,
  14337                                             PORT_SRC_MOD_EGR_PROFILE(unit));
  14338                 if (rv < 0) {
  14339                     sal_free(PORT_SRC_MOD_EGR_PROFILE(unit));
  14340                     PORT_SRC_MOD_EGR_PROFILE(unit) = NULL;
  14341                     return rv;
  14342                 }
  14343             }
  14344         }
  14345     }
  14346 #endif /* BCM_TRIUMPH2_SUPPORT */
  14347 
  14348 #if defined(BCM_KATANA2_SUPPORT)
  14349     if (SOC_IS_KATANA2(unit)) {
  14350         /* Enable EGR_ENABLEm:PRT_ENABLEf for cpu port */
  14351         LOG_VERBOSE(BSL_LS_BCM_PORT,
  14352                     (BSL_META_U(unit,
  14353                                 "\nEnable EGR_ENABLEm:PRT_ENABLEf for cpu port \n")));
  14354         sal_memset(entry, 0, sizeof(egr_enable_entry_t));
  14355         soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1);
  14356         SOC_IF_ERROR_RETURN(
  14357             WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, CMIC_PORT(unit), entry));
  14358         SOC_IF_ERROR_RETURN(
  14359             WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, LB_PORT(unit), entry));
  14360     }
  14361 #endif /* BCM_KATANA_SUPPORT */
  14362 
  14363     if (!soc_feature(unit, soc_feature_no_sw_rx_los)){
  14364     /* Get Initial SW RX LOS configuration from PHY driver */
  14365     PBMP_ITER(all_pbmp, p) {
  14366         if (IS_E_PORT(unit, p)) {
  14367             rv = bcm_esw_port_phy_control_get(unit, p,
  14368                                  BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS,
  14369                                  &rx_los);
  14370             if (BCM_SUCCESS(rv)) {
  14371                 PORT(unit, p).rx_los = rx_los;
  14372             }
  14373         }
  14374     }
  14375     }
  14376 
  14377     /* set link delay offset */
  14378     PBMP_ITER(all_pbmp, p) {
  14379         PORT(unit, p).link_delay_offset = 0;
  14380         if (SOC_WARM_BOOT(unit)) {
  14381             rv = bcm_esw_port_speed_get(unit, p, &p_speed);
  14382             if (BCM_FAILURE(rv)) {
  14383                 continue;
  14384             }
  14385             BCM_IF_ERROR_RETURN(_bcm_esw_port_link_delay_recover(unit, p, p_speed));
  14386         }
  14387     }
  14388 
  14389     /* set port dscp map set to zero */
  14390     PBMP_ITER(all_pbmp, p) {
  14391         PORT(unit, p).port_dscp_map_set = 0;
  14392     }
  14393 
  14394 #ifdef BCM_TRIDENT2_SUPPORT
  14395     if (SOC_IS_TD2_TT2(unit)) {
  14396         /* Get Initial SW port enable status from HW */
  14397         PBMP_ITER(all_pbmp, p) {
  14398             if (IS_E_PORT(unit, p)) {
  14399                 rv = bcm_esw_port_enable_get(unit, p, &enable);
  14400                 if (BCM_SUCCESS(rv)) {
  14401                     PORT(unit, p).enable = enable;
  14402                 }
  14403             }
  14404         }
  14405     }
  14406 #endif /* BCM_TRIDENT2_SUPPORT */
  14407 
  14408     PBMP_PORT_ITER(unit, p) {
  14409         rv = bcm_esw_port_speed_get(unit, p, &p_speed);
  14410         if (BCM_FAILURE(rv)) {
  14411             continue;
  14412         }
  14413         _bcm_esw_port_link_delay_update(unit, p, p_speed);
  14414     }
  14415 
  14416 #if defined(BCM_TRIUMPH3_SUPPORT)
  14417     if (soc_feature(unit, soc_feature_epc_linkflap_recover)) {
  14418         rv = _bcm_port_force_forward_init(unit);
  14419         if (BCM_FAILURE(rv)) {
  14420             return rv;
  14421         }
  14422     }
  14423 #endif /*defined(BCM_TRIUMPH3_SUPPORT)*/
  14424 
  14425 #if defined(BCM_TOMAHAWK_SUPPORT)
  14426     /* TH ASF */
  14427     if (soc_feature(unit, soc_feature_asf_multimode)
  14428 #ifdef BCM_WARM_BOOT_SUPPORT
  14429         && !SOC_WARM_BOOT(unit)
  14430         /* WB recovery happens in _bcm_esw_port_wb_recover context */
  14431 #endif /* BCM_WARM_BOOT_SUPPORT */
  14432        ) {
  14433 #ifdef BCM_MAVERICK2_SUPPORT
  14434         if (SOC_IS_MAVERICK2(unit)) {
  14435             BCM_IF_ERROR_RETURN(
  14436                 _bcm_esw_mv2_asf_init(unit, _SOC_MV2_ASF_MODE_INIT));
  14437         } else
  14438 #endif
  14439 #ifdef BCM_TRIDENT3_SUPPORT
  14440         if (SOC_IS_TRIDENT3X(unit)) {
  14441             BCM_IF_ERROR_RETURN(
  14442                 _bcm_esw_td3_asf_init(unit, _SOC_TD3_ASF_MODE_INIT));
  14443         } else
  14444 #endif
  14445         {
  14446             BCM_IF_ERROR_RETURN(
  14447                 _bcm_esw_asf_init(unit, _SOC_TH_ASF_MODE_INIT));
  14448         }
  14449     }
  14450 #endif
  14451 
  14452 #if defined (BCM_EP_REDIRECT_VERSION_2)
  14453     /* Mark the RDB port as loopback mode */
  14454     if (soc_feature(unit, soc_feature_ep_redirect_v2)) {
  14455         SOC_IF_ERROR_RETURN(soc_mem_field32_modify(unit, PORT_TABm,
  14456                                        BCMI_EP_REDIRECT_PORT, PORT_TYPEf, 2));
  14457     }
  14458 #endif
  14459 
  14460 #ifdef BCM_PREEMPTION_SUPPORT
  14461     if (soc_feature(unit, soc_feature_preemption_cnt)) {
  14462         BCM_IF_ERROR_RETURN(bcmi_esw_preemption_counter_init(unit));
  14463     }
  14464 #endif
  14465 
  14466 #if defined(BCM_GREYHOUND_SUPPORT)
  14467     if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) {
  14468         /*
  14469          * The ref_cnt of system-wise treat packet priority as dot1p priority
  14470          * for different packet types or port controls.
  14471          */
  14472         BCM_IF_ERROR_RETURN(
  14473             bcmi_esw_port_treat_pktpri_as_dot1p_init(unit));
  14474     }
  14475 #endif /* BCM_GREYHOUND_SUPPORT */
  14476 
  14477     if (SOC_WARM_BOOT(unit)) {
  14478         return (_bcm_esw_port_wb_recover(unit));
  14479     }
  14480 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT) || \
  14481     defined(BCM_APACHE_SUPPORT)
  14482     else {
  14483         if(SOC_IS_KATANA2(unit) || SOC_IS_TRIDENT2(unit) || SOC_IS_APACHE(unit)) {
  14484             /*
  14485              * Hardcoding the MMU_INTFI_ST_TRANS_TBL so the
  14486              * congestion data is written as it is
  14487              * in FC_ST_TABLE, This we are doing so that
  14488              * congestion data is updated as it is how
  14489              * it recevied
  14490              */
  14491             for (index=0 ; index < soc_mem_index_count(unit,
  14492                         MMU_INTFI_ST_TRANS_TBLm); index++) {
  14493                 SOC_IF_ERROR_RETURN(READ_MMU_INTFI_ST_TRANS_TBLm(
  14494                             unit, MEM_BLOCK_ALL,index,
  14495                             &st_trans_entry));
  14496                 soc_mem_field32_set(unit, MMU_INTFI_ST_TRANS_TBLm,
  14497                         &st_trans_entry, FC_ST_XLATEf,
  14498                         index % (SOC_IS_KATANA2(unit) ? 256 : 16));
  14499                 SOC_IF_ERROR_RETURN(WRITE_MMU_INTFI_ST_TRANS_TBLm(
  14500                             unit, MEM_BLOCK_ALL, index,
  14501                             &st_trans_entry));
  14502             }
  14503         }
  14504     }
  14505 #endif
  14506 #if defined(BCM_GREYHOUND2_SUPPORT)
  14507     if (SOC_IS_GREYHOUND2(unit)) {
  14508         if (soc_feature(unit, soc_feature_e2efc)) {
  14509             bcmi_gh2_port_e2efc_remote_port_init(unit);
  14510         }
  14511     }
  14512 #endif /* BCM_GHREYHOUND2 */
  14513     return (_bcm_esw_port_wb_alloc(unit));
  14514 }
  14515 
  14516 /*
  14517  * Function:
  14518  *      bcm_port_clear
  14519  * Purpose:
  14520  *      Initialize the PORT interface layer for the specified SOC device
  14521  *      without resetting stacking ports.
  14522  * Parameters:
  14523  *      unit - StrataSwitch unit number.
  14524  * Returns:
  14525  *      BCM_E_NONE - success (or already initialized)
  14526  *      BCM_E_INTERNAL- failed to write PTABLE entries
  14527  *      BCM_E_MEMORY - failed to allocate required memory.
  14528  * Notes:
  14529  *      By default ports come up enabled. They can be made to come up disabled
  14530  *      at startup by a compile-time application policy flag in your Make.local
  14531  *      A call to bcm_port_clear should exhibit similar behavior for
  14532  *      non-stacking ethernet ports
  14533  *      PTABLE initialized.
  14534  */
  14535 
  14536 int
  14537 bcm_esw_port_clear(int unit)
  14538 {
  14539     bcm_port_config_t port_config;
  14540     bcm_pbmp_t reset_ports;
  14541     bcm_port_t port;
  14542     int rv, port_enable;
  14543 
  14544     PORT_INIT(unit);
  14545 
  14546     BCM_IF_ERROR_RETURN(bcm_esw_port_config_get(unit, &port_config));
  14547 
  14548     /* Clear all non-stacking ethernet ports */
  14549     BCM_PBMP_ASSIGN(reset_ports, port_config.e);
  14550     BCM_PBMP_REMOVE(reset_ports, SOC_PBMP_STACK_CURRENT(unit));
  14551 
  14552     PBMP_ITER(reset_ports, port) {
  14553         LOG_VERBOSE(BSL_LS_BCM_PORT,
  14554                     (BSL_META_U(unit,
  14555                                 "bcm_port_clear: unit %d port %s\n"),
  14556                      unit, SOC_PORT_NAME(unit, port)));
  14557 
  14558         PORT_LOCK(unit);
  14559         if ((rv = _bcm_port_mode_setup(unit, port, TRUE)) < 0) {
  14560             LOG_WARN(BSL_LS_BCM_PORT,
  14561                      (BSL_META_U(unit,
  14562                                  "Warning: Port %s: "
  14563                                  "Failed to set initial mode: %s\n"),
  14564                       SOC_PORT_NAME(unit, port), bcm_errmsg(rv)));
  14565         }
  14566         PORT_UNLOCK(unit);
  14567 
  14568 #ifdef BCM_RCPU_SUPPORT
  14569         if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
  14570             /* Do not enable/disable rcpu port. */
  14571             continue;
  14572         }
  14573 #endif /* BCM_RCPU_SUPPORT */
  14574 
  14575         /*
  14576          * A compile-time application policy may prefer to disable
  14577          * ports at startup. The same behavior should be observed
  14578          * when bcm_port_clear gets called.
  14579          */
  14580 
  14581 #ifdef BCM_PORT_DEFAULT_DISABLE
  14582             port_enable = FALSE;
  14583 #else
  14584             port_enable = TRUE;
  14585 #endif  /* BCM_PORT_DEFAULT_DISABLE */
  14586 
  14587 
  14588         if ((rv = bcm_esw_port_enable_set(unit, port, port_enable)) < 0) {
  14589             LOG_WARN(BSL_LS_BCM_PORT,
  14590                      (BSL_META_U(unit,
  14591                                  "Warning: Port %s: "
  14592                                  "Failed to %s port: %s\n"),
  14593                       SOC_PORT_NAME(unit, port),(port_enable) ?\
  14594                       "enable" : "disable" ,bcm_errmsg(rv)));
  14595         }
  14596 
  14597     }
  14598 
  14599     return BCM_E_NONE;
  14600 }
  14601 
  14602 /*
  14603  * Function:
  14604  *      _bcm_port_phy_probe
  14605  * Purpose:
  14606  *      Probe the phy and set up the phy of the indicated port
  14607  * Parameters:
  14608  *      unit - StrataSwitch unit number.
  14609  *      port - Port to probe
  14610  *      okay - Output parameter indicates port can be enabled.
  14611  * Returns:
  14612  *      BCM_E_NONE
  14613  *      BCM_E_INTERNAL - internal error.
  14614  * Notes:
  14615  *      If error is returned, the port should not be enabled.
  14616  */
  14617 int
  14618 _bcm_port_phy_probe(int unit, bcm_port_t port, int *okay)
  14619 {
  14620     int                 rv;
  14621     bcm_pbmp_t pbmp;
  14622     bcm_pbmp_t okay_pbmp;
  14623 
  14624     /* Check for PortMod */
  14625     if(SOC_USE_PORTCTRL(unit)) {
  14626         return BCM_E_UNAVAIL;
  14627     }
  14628 
  14629     *okay = FALSE;
  14630 
  14631     LOG_VERBOSE(BSL_LS_BCM_PORT,
  14632                 (BSL_META_U(unit,
  14633                             "Init port %d PHY...\n"), port));
  14634 
  14635     BCM_PBMP_CLEAR(okay_pbmp);
  14636     BCM_PBMP_CLEAR(pbmp);
  14637     BCM_PBMP_PORT_SET(pbmp, port);
  14638 
  14639     rv = soc_phyctrl_pbm_probe_init(unit,pbmp,&okay_pbmp);
  14640     if (rv  != BCM_E_NONE) {
  14641         LOG_ERROR(BSL_LS_BCM_PORT, \
  14642                   (BSL_META_U(unit, \
  14643                               "Error unit %d:\
  14644                               Failed port init probe: %s\n"),
  14645                    unit, bcm_errmsg(rv)));
  14646         return rv;
  14647     }
  14648 
  14649     if (!SOC_WARM_BOOT(unit)) {
  14650         /* Probe function should leave port disabled */
  14651         if ((rv = soc_phyctrl_enable_set(unit, port, 0)) < 0) {
  14652             return rv;
  14653         }
  14654     }
  14655 
  14656     *okay = TRUE;
  14657 
  14658     return BCM_E_NONE;
  14659 }
  14660 
  14661 /*
  14662  * Function:
  14663  *      _bcm_port_mac_init
  14664  * Purpose:
  14665  *      Set up the mac of the indicated port
  14666  * Parameters:
  14667  *      unit - StrataSwitch unit number.
  14668  *      port - Port to setup
  14669  *      okay - Output parameter indicates port can be enabled.
  14670  * Returns:
  14671  *      BCM_E_NONE
  14672  *      BCM_E_INTERNAL - internal error.
  14673  * Notes:
  14674  *      If error is returned, the port should not be enabled.
  14675  */
  14676 int
  14677 _bcm_port_mac_init(int unit, bcm_port_t port, int *okay)
  14678 {
  14679     int                 rv;
  14680     mac_driver_t        *macd;
  14681 
  14682     /* Check for PortMod */
  14683     if (SOC_USE_PORTCTRL(unit)) {
  14684         return BCM_E_UNAVAIL;
  14685     }
  14686 
  14687     *okay = FALSE;
  14688 
  14689     LOG_VERBOSE(BSL_LS_BCM_PORT,
  14690                 (BSL_META_U(unit,
  14691                             "Init port %d MAC...\n"), port));
  14692 
  14693     if ((rv = soc_mac_probe(unit, port, &macd)) < 0) {
  14694         LOG_WARN(BSL_LS_BCM_PORT,
  14695                  (BSL_META_U(unit,
  14696                              "Port %s: Failed to probe MAC: %s\n"),
  14697                   SOC_PORT_NAME(unit, port), soc_errmsg(rv)));
  14698         return rv;
  14699     }
  14700 
  14701     PORT(unit, port).p_mac = macd;
  14702 
  14703     if (!SOC_WARM_BOOT(unit) && !SOC_IS_RELOADING(unit)) {
  14704 
  14705 #ifdef BCM_RCPU_SUPPORT
  14706         if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
  14707             *okay = TRUE;
  14708             return BCM_E_NONE;
  14709         }
  14710 #endif /* BCM_RCPU_SUPPORT */
  14711 
  14712         if ((rv = MAC_INIT(PORT(unit, port).p_mac, unit, port)) < 0) {
  14713             LOG_WARN(BSL_LS_BCM_PORT,
  14714                      (BSL_META_U(unit,
  14715                                  "Port %s: Failed to initialize MAC: %s\n"),
  14716                       SOC_PORT_NAME(unit, port), soc_errmsg(rv)));
  14717             return rv;
  14718         }
  14719 
  14720         /* Probe function should leave port disabled */
  14721         if ((rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, 0)) < 0) {
  14722             return rv;
  14723         }
  14724     }
  14725 
  14726     *okay = TRUE;
  14727 
  14728     return BCM_E_NONE;
  14729 }
  14730 
  14731 /*
  14732  * Function:
  14733  *      _bcm_port_probe
  14734  * Purpose:
  14735  *      Probe the phy and set up the phy and mac of the indicated port
  14736  * Parameters:
  14737  *      unit - StrataSwitch unit number.
  14738  *      port - Port to probe
  14739  *      okay - Output parameter indicates port can be enabled.
  14740  * Returns:
  14741  *      BCM_E_NONE
  14742  *      BCM_E_INTERNAL - internal error.
  14743  * Notes:
  14744  *      If error is returned, the port should not be enabled.
  14745  */
  14746 
  14747 int
  14748 _bcm_port_probe(int unit, bcm_port_t port, int *okay)
  14749 {
  14750     /* Check for PortMod */
  14751     if (SOC_USE_PORTCTRL(unit)) {
  14752         return bcmi_esw_portctrl_probe(unit, port, 0, NULL, okay);
  14753     }
  14754     
  14755     BCM_IF_ERROR_RETURN(_bcm_port_phy_probe(unit, port, okay));
  14756 
  14757     /*
  14758      * Currently initializing MAC after PHY is required because of
  14759      * phy_5690_notify_init().
  14760      */
  14761     BCM_IF_ERROR_RETURN(_bcm_port_mac_init(unit, port, okay));
  14762 
  14763     return BCM_E_NONE;
  14764 }
  14765 
  14766 /*
  14767  * Function:
  14768  *      bcm_port_probe
  14769  * Purpose:
  14770  *      Probe the PHY and set up the PHY and MAC for the specified ports.
  14771  *      This is purely a discovery routine and does no configuration.
  14772  * Parameters:
  14773  *      unit - StrataSwitch unit number.
  14774  *      pbmp - Bitmap of ports to probe.
  14775  *      okay_pbmp (OUT) - Ports which were successfully probed.
  14776  * Returns:
  14777  *      BCM_E_NONE
  14778  *      BCM_E_INTERNAL - internal error.
  14779  * Notes:
  14780  *      If error is returned, the port should not be enabled.
  14781  *      Assumes port_init done.
  14782  *      Note that if a PHY is not present, the port will still probe
  14783  *      successfully.  The default driver will be installed.
  14784  */
  14785 int
  14786 bcm_esw_port_probe(int unit, pbmp_t pbmp, pbmp_t *okay_pbmp)
  14787 {
  14788     int rv = BCM_E_NONE;
  14789     bcm_port_t port;
  14790     int okay;
  14791     int skip_mac_reset = 0;
  14792     soc_persist_t      *sop;
  14793 #ifdef BCM_TRIDENT_SUPPORT
  14794     int port_speed;
  14795     soc_port_ability_t mac_ability;
  14796 #endif
  14797 
  14798     SOC_PBMP_CLEAR(*okay_pbmp);
  14799 
  14800     PORT_INIT(unit);
  14801     PORT_LOCK(unit);
  14802 #ifdef BCM_TOMAHAWK2_SUPPORT
  14803     if (SOC_IS_TOMAHAWK2(unit)) {
  14804         rv = bcmi_th2_tsc_xgxs_reset(unit, pbmp);
  14805         if (SOC_FAILURE(rv)) {
  14806             PORT_UNLOCK(unit);
  14807             return (rv);
  14808         }
  14809     } else
  14810 #endif /* BCM_TOMAHAWK2_SUPPORT */
  14811     {
  14812 #ifdef BCM_TRIDENT2_SUPPORT
  14813     if (SOC_IS_TD2_TT2(unit)) {
  14814         soc_info_t *si;
  14815         uint32 tsc_map, reset_tsc_map;
  14816         int tsc, ports[32];
  14817 
  14818         si = &SOC_INFO(unit);
  14819         /* Construct tsc_map covered by the specified pbmp */
  14820         tsc_map = 0;
  14821         PBMP_ITER(pbmp, port) {
  14822             tsc = si->port_serdes[port];
  14823             if (tsc != -1) {
  14824                 tsc_map |= 1 << tsc;
  14825             }
  14826         }
  14827 
  14828         reset_tsc_map = 0;
  14829         PBMP_PORT_ITER(unit, port) {
  14830             tsc = si->port_serdes[port];
  14831             if (tsc_map & (1 << tsc)) {
  14832                 if (PORT(unit, port).flags & _PORT_INFO_PROBE_RESET_SERDES) {
  14833                     PORT(unit, port).flags &= ~_PORT_INFO_PROBE_RESET_SERDES;
  14834                     reset_tsc_map |= 1 << tsc;
  14835                     ports[tsc] = port;
  14836                 }
  14837             }
  14838         }
  14839         for (tsc = 0; tsc < 32; tsc++) {
  14840             if (reset_tsc_map & (1 << tsc)) {
  14841                 rv = soc_tsc_xgxs_reset(unit, ports[tsc], 0);
  14842                 if (SOC_FAILURE(rv)) {
  14843                     PORT_UNLOCK(unit);
  14844                     return (rv);
  14845                 }
  14846             }
  14847         }
  14848     }
  14849 #endif /* BCM_TRIDENT2_SUPPORT */
  14850     }
  14851 #if defined(BCM_SABER2_SUPPORT)
  14852     /* If OAMP is enabled by default, skip the port init for oamp port */
  14853     if(SOC_IS_SABER2(unit)) {
  14854         int oamp_enable;
  14855         (void)bcm_sb2_sat_oamp_enable_get(unit, &oamp_enable);
  14856 
  14857         if (soc_feature(unit, soc_feature_sat) &&
  14858             ((!SOC_WARM_BOOT(unit) &&
  14859                 soc_property_get(unit, spn_SAT_ENABLE, 0)) ||
  14860              (SOC_WARM_BOOT(unit) && (oamp_enable == TRUE)))) {
  14861             SOC_PBMP_PORT_REMOVE(pbmp, _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER);
  14862             SOC_PBMP_PORT_REMOVE(*okay_pbmp,
  14863                     _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER);
  14864         }
  14865     }
  14866 #endif
  14867     /* Check for PortMod */
  14868     if (SOC_USE_PORTCTRL(unit)) {
  14869         rv = bcmi_esw_portctrl_probe_pbmp(unit, pbmp, okay_pbmp);
  14870         PORT_UNLOCK(unit);
  14871         return (rv);
  14872     }
  14873 
  14874     rv = soc_phyctrl_pbm_probe_init(unit,pbmp,okay_pbmp);
  14875     if (!SOC_WARM_BOOT(unit)) {
  14876         PBMP_ITER(*okay_pbmp, port) {
  14877             /* Probe function should leave port disabled */
  14878             if ((rv = soc_phyctrl_enable_set(unit, port, 0)) < 0) {
  14879                 break;
  14880             }
  14881         }
  14882     }
  14883     if (soc_property_get(unit, spn_SAME_SPEED_INTF_DO_NOT_OVERWRITE,
  14884                          (SAL_BOOT_BCMSIM || SAL_BOOT_XGSSIM))) {
  14885         PBMP_ITER(*okay_pbmp, port) {
  14886             if ((rv = bcm_esw_port_interface_get(unit, port, &(PORT(unit, port).intf))) < 0) {
  14887                 PORT(unit, port).intf = 0;
  14888                 continue;
  14889             }
  14890         }
  14891     }
  14892 
  14893     if (SOC_IS_GREYHOUND(unit) || SOC_IS_SABER2(unit) ||
  14894         SOC_IS_TOMAHAWKX(unit) || SOC_IS_APACHE(unit)) {
  14895         /* XLPORT_MAC_CONTROLr.XMAC0_RESETf has been toggled duirng soc_reset */
  14896         skip_mac_reset = 1;
  14897     }
  14898 
  14899     if (SOC_REG_IS_VALID(unit, GPORT_UMAC_CONTROLr)) {
  14900         int blk;
  14901         uint32 rval;
  14902         pbmp_t block_pbmp;
  14903         int port_blk_index;
  14904         int i;
  14905 
  14906         SOC_BLOCK_ITER(unit, blk, SOC_BLK_GPORT) {
  14907             rval = 0;
  14908             BCM_PBMP_ASSIGN(block_pbmp, SOC_BLOCK_BITMAP(unit, blk));
  14909             BCM_PBMP_AND(block_pbmp, pbmp);
  14910             if (BCM_PBMP_IS_NULL(block_pbmp)) {
  14911                 continue;
  14912             }
  14913 
  14914             /* get the port number */
  14915             SOC_PBMP_ITER(block_pbmp, i)
  14916             {
  14917                /* get the index of the port in blk*/
  14918                port_blk_index = SOC_PORT_BLOCK_INDEX(unit, i);
  14919                rval |= 1 << port_blk_index;
  14920             }
  14921 
  14922             port = SOC_BLOCK_PORT(unit, blk);
  14923             /* just Write.. No need for RMW as no other field is there.. */
  14924             /* (void)READ_GPORT_UMAC_CONTROLr(unit, port, &rval); */
  14925             /* Set UMAC0_RESETf..UMAC7_RESETf */
  14926 #ifdef BCM_RCPU_SUPPORT
  14927             if (SOC_IS_RCPU_ONLY(unit) &&
  14928                 SOC_PORT_VALID(unit, RCPU_PORT(unit)) &&
  14929                 BCM_PBMP_MEMBER(block_pbmp, RCPU_PORT(unit))) {
  14930                 rval &= ~ (1 << SOC_PORT_BLOCK_INDEX(unit, RCPU_PORT(unit)));
  14931             }
  14932 #endif /* BCM_RCPU_SUPPORT */
  14933             (void)WRITE_GPORT_UMAC_CONTROLr(unit, port, rval);
  14934             sal_udelay(10);
  14935             rval = 0; /* Reset UMAC0_RESETf..UMAC7_RESETf */
  14936             (void)WRITE_GPORT_UMAC_CONTROLr(unit, port, rval);
  14937         }
  14938     }
  14939 
  14940     if (SOC_REG_IS_VALID(unit, XLPORT_MAC_CONTROLr) && !skip_mac_reset) {
  14941         int blk, port;
  14942 
  14943         SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
  14944             port = SOC_BLOCK_PORT(unit, blk);
  14945             if (port == -1) {
  14946                 continue;
  14947             }
  14948 
  14949             if (SOC_INFO(unit).port_speed_max[port] >= 100000) {
  14950                 continue;
  14951             }
  14952 
  14953             /* Reset the entire block only if it is called from port init */
  14954             if (PORT(unit, port).p_mac != NULL) {
  14955                 continue;
  14956             }
  14957 
  14958 #ifdef BCM_RCPU_SUPPORT
  14959             if (SOC_IS_RCPU_ONLY(unit) &&
  14960                 SOC_PORT_VALID(unit, RCPU_PORT(unit)) &&
  14961                 BCM_PBMP_MEMBER(SOC_BLOCK_BITMAP(unit, blk), RCPU_PORT(unit))) {
  14962                 continue;
  14963             }
  14964 #endif /* BCM_RCPU_SUPPORT */
  14965 
  14966             _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  14967                 (soc_reg_field32_modify(unit, XLPORT_MAC_CONTROLr, port,
  14968                                         XMAC0_RESETf, 1));
  14969             sal_udelay(10);
  14970             _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  14971                 (soc_reg_field32_modify(unit, XLPORT_MAC_CONTROLr, port,
  14972                                         XMAC0_RESETf, 0));
  14973             if (soc_feature (unit, soc_feature_xlmac_timestamp_disable)) {
  14974                 if (soc_reg_field_valid(unit, XLPORT_MAC_CONTROLr, XLMAC_TS_DISABLEf)) {
  14975                     /* Disable MAC timestamp by default */
  14976                     _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  14977                         (soc_reg_field32_modify(unit, XLPORT_MAC_CONTROLr, port,
  14978                                                 XLMAC_TS_DISABLEf, 1));
  14979                 }
  14980             }
  14981         }
  14982     }
  14983 
  14984     if (SOC_REG_IS_VALID(unit, GPORT_UMAC_CONTROLr)) {
  14985         int blk, port;
  14986 
  14987         SOC_BLOCK_ITER(unit, blk, SOC_BLK_CPORT) {
  14988             port = SOC_BLOCK_PORT(unit, blk);
  14989             if (port == -1) {
  14990                 continue;
  14991             }
  14992 
  14993             if (SOC_INFO(unit).port_speed_max[port] < 100000) {
  14994                 continue;
  14995             }
  14996 
  14997             /* Reset the entire block only if it is called from port init */
  14998             if (PORT(unit, port).p_mac != NULL) {
  14999                 continue;
  15000             }
  15001 
  15002 #ifdef BCM_RCPU_SUPPORT
  15003             if (SOC_IS_RCPU_ONLY(unit) &&
  15004                 SOC_PORT_VALID(unit, RCPU_PORT(unit)) &&
  15005                 BCM_PBMP_MEMBER(SOC_BLOCK_BITMAP(unit, blk), RCPU_PORT(unit))) {
  15006                 continue;
  15007             }
  15008 #endif /* BCM_RCPU_SUPPORT */
  15009 
  15010             _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  15011                 (soc_reg_field32_modify(unit, CPORT_MAC_CONTROLr, port,
  15012                                         CMAC_RESETf, 1));
  15013             if (SOC_REG_IS_VALID(unit, CPORT_SOFT_RESETr)) {
  15014                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  15015                  (soc_reg_field32_modify(unit, CPORT_SOFT_RESETr, port,
  15016                                         CPORT_COREf, 1));
  15017             }
  15018             sal_udelay(10);
  15019             if (SOC_REG_IS_VALID(unit, CPORT_SOFT_RESETr)) {
  15020                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  15021                  (soc_reg_field32_modify(unit, CPORT_SOFT_RESETr, port,
  15022                                         CPORT_COREf, 0));
  15023             }
  15024             _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  15025                 (soc_reg_field32_modify(unit, CPORT_MAC_CONTROLr, port,
  15026                                         CMAC_RESETf, 0));
  15027         }
  15028     }
  15029 
  15030     if (SOC_REG_IS_VALID(unit, XLPORT_XMAC_CONTROLr)) {
  15031         int blk;
  15032         uint32 rval;
  15033         pbmp_t block_pbmp;
  15034 
  15035         SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
  15036             BCM_PBMP_ASSIGN(block_pbmp, SOC_BLOCK_BITMAP(unit, blk));
  15037             BCM_PBMP_AND(block_pbmp, pbmp);
  15038             if (BCM_PBMP_IS_NULL(block_pbmp)) {
  15039                 continue;
  15040             }
  15041 
  15042             port = SOC_BLOCK_PORT(unit, blk);
  15043 
  15044             /* Reset the entire block only if it is called from port init */
  15045             if (PORT(unit, port).p_mac != NULL) {
  15046                 continue;
  15047             }
  15048 
  15049 #ifdef BCM_RCPU_SUPPORT
  15050             if (SOC_IS_RCPU_ONLY(unit) &&
  15051                 SOC_PORT_VALID(unit, RCPU_PORT(unit)) &&
  15052                 BCM_PBMP_MEMBER(block_pbmp, RCPU_PORT(unit))) {
  15053                 continue;
  15054             }
  15055 #endif /* BCM_RCPU_SUPPORT */
  15056 
  15057             (void)READ_XLPORT_XMAC_CONTROLr(unit, port, &rval);
  15058             soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf,
  15059                               1);
  15060             (void)WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval);
  15061             sal_udelay(10);
  15062 
  15063             soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf,
  15064                               0);
  15065             (void)WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval);
  15066         }
  15067     }
  15068 #ifdef BCM_SHADOW_SUPPORT
  15069     /* Interlaken need to be taken out of reset after PHY is initialized */
  15070     if (SOC_IS_SHADOW(unit)) {
  15071         int active_il = 0;
  15072         uint32 rval;
  15073 
  15074         if (soc_property_get(unit, spn_BCM88732_2X40_1X40, 0) ||
  15075             soc_property_get(unit, spn_BCM88732_8X10_1X40, 0)) {
  15076             active_il = 1;
  15077         } else {
  15078             if (soc_property_get(unit, spn_BCM88732_1X40_4X10, 0) ||
  15079                 soc_property_get(unit, spn_BCM88732_4X10_4X10, 0) ||
  15080                 soc_property_get(unit, spn_BCM88732_2X40_2X40, 0) ||
  15081                 soc_property_get(unit, spn_BCM88732_2X40_8X12, 0) ||
  15082                 soc_property_get(unit, spn_BCM88732_8X10_8X12, 0) ||
  15083                 soc_property_get(unit, spn_BCM88732_2X40_8X10, 0) ||
  15084                 soc_property_get(unit, spn_BCM88732_8X10_8X10, 0) ||
  15085                 soc_property_get(unit, spn_BCM88732_8X10_4X12, 0) ||
  15086                 soc_property_get(unit, spn_BCM88732_8X10_2X12, 0) ||
  15087                 soc_property_get(unit, spn_BCM88732_1X40_4X10_8X12, 0) ||
  15088                 soc_property_get(unit, spn_BCM88732_4X10_1X40_8X12, 0) ||
  15089                 soc_property_get(unit, spn_BCM88732_6X10_2X12, 0)) {
  15090                 active_il = 0;
  15091             } else {
  15092                 active_il = 2;
  15093             }
  15094         }
  15095         if (active_il) {
  15096             _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  15097                 (READ_IL_GLOBAL_CONTROLr(unit, 9, &rval));
  15098             soc_reg_field_set(unit, IL_GLOBAL_CONTROLr, &rval, SOFT_RESETf, 0);
  15099             _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  15100                 (WRITE_IL_GLOBAL_CONTROLr(unit, 9, rval));
  15101         }
  15102         if (active_il == 2) {
  15103             _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  15104                 (READ_IL_GLOBAL_CONTROLr(unit, 13, &rval));
  15105             soc_reg_field_set(unit, IL_GLOBAL_CONTROLr, &rval, SOFT_RESETf, 0);
  15106             _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  15107                 (WRITE_IL_GLOBAL_CONTROLr(unit, 13, rval));
  15108         }
  15109     }
  15110 #endif /* BCM_SHADOW_SUPPORT */
  15111 
  15112     if (SOC_REG_IS_VALID(unit, XPORT_XMAC_CONTROLr)) {
  15113         int blk;
  15114         uint32 rval;
  15115         pbmp_t block_pbmp;
  15116 
  15117         SOC_BLOCK_ITER(unit, blk, SOC_BLK_MXQPORT) {
  15118             BCM_PBMP_ASSIGN(block_pbmp, SOC_BLOCK_BITMAP(unit, blk));
  15119             BCM_PBMP_AND(block_pbmp, pbmp);
  15120             if (BCM_PBMP_IS_NULL(block_pbmp)) {
  15121                 continue;
  15122             }
  15123 
  15124             port = SOC_BLOCK_PORT(unit, blk);
  15125 
  15126             /* Reset the entire block only if it is called from port init */
  15127             if (PORT(unit, port).p_mac != NULL) {
  15128                 continue;
  15129             }
  15130 
  15131 #ifdef BCM_RCPU_SUPPORT
  15132             if (SOC_IS_RCPU_ONLY(unit) &&
  15133                 SOC_PORT_VALID(unit, RCPU_PORT(unit)) &&
  15134                 BCM_PBMP_MEMBER(block_pbmp, RCPU_PORT(unit))) {
  15135                 continue;
  15136             }
  15137 #endif /* BCM_RCPU_SUPPORT */
  15138 
  15139             (void)READ_XPORT_XMAC_CONTROLr(unit, port, &rval);
  15140             soc_reg_field_set(unit, XPORT_XMAC_CONTROLr, &rval, XMAC_RESETf,
  15141                               1);
  15142             (void)WRITE_XPORT_XMAC_CONTROLr(unit, port, rval);
  15143             sal_udelay(10);
  15144 
  15145             soc_reg_field_set(unit, XPORT_XMAC_CONTROLr, &rval, XMAC_RESETf,
  15146                               0);
  15147             (void)WRITE_XPORT_XMAC_CONTROLr(unit, port, rval);
  15148         }
  15149     }
  15150 
  15151 #ifdef BCM_TRIUMPH3_SUPPORT
  15152     if (SOC_IS_TRIUMPH3(unit)) {
  15153         uint8 rev_id;
  15154         uint16 dev_id;
  15155         soc_info_t *si;
  15156         soc_port_t port;
  15157         int phy, lane, blk, block_has_ports, high_speed_port;
  15158         uint32 rval;
  15159 
  15160         si = &SOC_INFO(unit);
  15161         soc_cm_get_id(unit, &dev_id, &rev_id);
  15162         SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLPORT) {
  15163             block_has_ports = FALSE;
  15164             high_speed_port = -1;
  15165             for (phy = 0; phy < _SOC_TR3_PHY_PER_PORT_BLOCK; phy++) {
  15166                 for (lane = 0; lane < _SOC_TR3_LANES_PER_PHY; lane++) {
  15167                     port = si->port_p2l_mapping[si->blk_fpp[blk] +
  15168                                ((phy * _SOC_TR3_LANES_PER_PHY) + lane)];
  15169                     /* coverity[overrun-local : FALSE] */
  15170                     if (SOC_PORT_VALID(unit, port) &&
  15171                         si->port_speed_max[port] >= 100000) {
  15172                         /* Save the 100G+ speed port becuase we must
  15173                          * init the other two PHYs, even though they don't
  15174                          * match a valid port. */
  15175                         high_speed_port = port;
  15176                     } else if (high_speed_port >= 0) {
  15177                         port = high_speed_port;
  15178                     }
  15179                     if (SOC_PORT_VALID(unit, port)) {
  15180                         block_has_ports |= 1 << phy;
  15181                         break; /* Only need to reset PHY once */
  15182                     }
  15183                 }
  15184             }
  15185             if (!block_has_ports) {
  15186                 continue; /* All ports disabled */
  15187             }
  15188             port = SOC_BLOCK_PORT(unit, blk);
  15189 
  15190             /* Reset only when called from port init */
  15191             if (PORT(unit, port).p_mac != NULL) {
  15192                 continue;
  15193             }
  15194 
  15195             rv = READ_PORT_MAC_CONTROLr(unit, port, &rval);
  15196             if (SOC_FAILURE(rv)) {
  15197                 PORT_UNLOCK(unit);
  15198                 return (rv);
  15199             }
  15200             if ((soc_feature(unit, soc_feature_cmac)) && (high_speed_port >= 0)) {
  15201                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15202                                   CMAC_RESETf, 1);
  15203             }
  15204             if (block_has_ports & 1) {
  15205                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15206                                   XMAC0_RESETf, 1);
  15207             }
  15208             if (block_has_ports & 2) {
  15209                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15210                                   XMAC1_RESETf, 1);
  15211             }
  15212             if (block_has_ports & 4) {
  15213                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15214                                   XMAC2_RESETf, 1);
  15215             }
  15216             rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval);
  15217             if (SOC_FAILURE(rv)) {
  15218                 PORT_UNLOCK(unit);
  15219                 return (rv);
  15220             }
  15221 
  15222             sal_udelay(10);
  15223             if ((soc_feature(unit, soc_feature_cmac)) && (high_speed_port >= 0)) {
  15224                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15225                                   CMAC_RESETf, 0);
  15226             }
  15227             if (block_has_ports & 1) {
  15228                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15229                                   XMAC0_RESETf, 0);
  15230             }
  15231             if (block_has_ports & 2) {
  15232                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15233                                   XMAC1_RESETf, 0);
  15234             }
  15235             if (block_has_ports & 4) {
  15236                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15237                                   XMAC2_RESETf, 0);
  15238             }
  15239             rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval);
  15240             if (SOC_FAILURE(rv)) {
  15241                 PORT_UNLOCK(unit);
  15242                 return (rv);
  15243             }
  15244         }
  15245         SOC_BLOCK_ITER(unit, blk, SOC_BLK_XTPORT) {
  15246             block_has_ports = FALSE;
  15247             for (phy = 0; phy < _SOC_TR3_PHY_PER_PORT_BLOCK; phy++) {
  15248                 for (lane = 0; lane < _SOC_TR3_LANES_PER_PHY; lane++) {
  15249                     port = si->port_p2l_mapping[si->blk_fpp[blk] +
  15250                                ((phy * _SOC_TR3_LANES_PER_PHY) + lane)];
  15251                     if (SOC_PORT_VALID(unit, port)) {
  15252                         block_has_ports |= 1 << phy;
  15253                         break; /* Only need to reset PHY once */
  15254                     }
  15255                 }
  15256             }
  15257             if (!block_has_ports) {
  15258                 continue; /* All ports disabled */
  15259             }
  15260             port = SOC_BLOCK_PORT(unit, blk);
  15261 
  15262             /* Reset only when called from port init */
  15263             if (PORT(unit, port).p_mac != NULL) {
  15264                 continue;
  15265             }
  15266 
  15267             rv = READ_PORT_MAC_CONTROLr(unit, port, &rval);
  15268             if (SOC_FAILURE(rv)) {
  15269                 PORT_UNLOCK(unit);
  15270                 return (rv);
  15271             }
  15272             if (block_has_ports & 1) {
  15273                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15274                                   XMAC0_RESETf, 1);
  15275             }
  15276             if (block_has_ports & 2) {
  15277                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15278                                   XMAC1_RESETf, 1);
  15279             }
  15280             if (block_has_ports & 4) {
  15281                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15282                                   XMAC2_RESETf, 1);
  15283             }
  15284             rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval);
  15285             if (SOC_FAILURE(rv)) {
  15286                 PORT_UNLOCK(unit);
  15287                 return (rv);
  15288             }
  15289             sal_udelay(10);
  15290             if (block_has_ports & 1) {
  15291                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15292                                   XMAC0_RESETf, 0);
  15293             }
  15294             if (block_has_ports & 2) {
  15295                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15296                                   XMAC1_RESETf, 0);
  15297             }
  15298             if (block_has_ports & 4) {
  15299                 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15300                                   XMAC2_RESETf, 0);
  15301             }
  15302             rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval);
  15303             if (SOC_FAILURE(rv)) {
  15304                 PORT_UNLOCK(unit);
  15305                 return (rv);
  15306             }
  15307         }
  15308         SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
  15309             block_has_ports = FALSE;
  15310             /* Only one PHY per XLPORT */
  15311             for (lane = 0; lane < _SOC_TR3_LANES_PER_PHY; lane++) {
  15312                 port = si->port_p2l_mapping[si->blk_fpp[blk] + lane];
  15313                 if (SOC_PORT_VALID(unit, port)) {
  15314                     block_has_ports = TRUE;
  15315                     break;
  15316                 }
  15317             }
  15318             if (!block_has_ports) {
  15319                 continue; /* All ports disabled */
  15320             }
  15321             port = SOC_BLOCK_PORT(unit, blk);
  15322 
  15323             /* Reset only when called from port init */
  15324             if (PORT(unit, port).p_mac != NULL) {
  15325                 continue;
  15326             }
  15327 
  15328             rv = READ_PORT_MAC_CONTROLr(unit, port, &rval);
  15329             if (SOC_FAILURE(rv)) {
  15330                 PORT_UNLOCK(unit);
  15331                 return (rv);
  15332             }
  15333             soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15334                               XMAC0_RESETf, 1);
  15335             rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval);
  15336             if (SOC_FAILURE(rv)) {
  15337                 PORT_UNLOCK(unit);
  15338                 return (rv);
  15339             }
  15340             sal_udelay(10);
  15341             soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15342                               XMAC0_RESETf, 0);
  15343             rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval);
  15344             if (SOC_FAILURE(rv)) {
  15345                 PORT_UNLOCK(unit);
  15346                 return (rv);
  15347             }
  15348         }
  15349 #ifdef BCM_HELIX4_SUPPORT
  15350         SOC_BLOCK_ITER(unit, blk, SOC_BLK_XWPORT) {
  15351             block_has_ports = FALSE;
  15352             /* Only one PHY per XWPORT */
  15353             for (lane = 0; lane < _SOC_TR3_LANES_PER_PHY; lane++) {
  15354                 port = si->port_p2l_mapping[si->blk_fpp[blk] + lane];
  15355                 if (SOC_PORT_VALID(unit, port)) {
  15356                     block_has_ports = TRUE;
  15357                     break;
  15358                 }
  15359             }
  15360             if (!block_has_ports) {
  15361                 continue; /* All ports disabled */
  15362             }
  15363             port = SOC_BLOCK_PORT(unit, blk);
  15364 
  15365             /* Reset only when called from port init */
  15366             if (PORT(unit, port).p_mac != NULL) {
  15367                 continue;
  15368             }
  15369 
  15370             rv = READ_PORT_MAC_CONTROLr(unit, port, &rval);
  15371             if (SOC_FAILURE(rv)) {
  15372                 PORT_UNLOCK(unit);
  15373                 return (rv);
  15374             }
  15375             soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15376                               XMAC0_RESETf, 1);
  15377             rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval);
  15378             if (SOC_FAILURE(rv)) {
  15379                 PORT_UNLOCK(unit);
  15380                 return (rv);
  15381             }
  15382             sal_udelay(10);
  15383             soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
  15384                               XMAC0_RESETf, 0);
  15385             rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval);
  15386             if (SOC_FAILURE(rv)) {
  15387                 PORT_UNLOCK(unit);
  15388                 return (rv);
  15389             }
  15390         }
  15391 #endif /* BCM_HELIX4_SUPPORT */
  15392     }
  15393 #endif /* BCM_TRIUMPH3_SUPPORT */
  15394 
  15395     PBMP_ITER(pbmp, port) {
  15396         if (!(IS_TDM_PORT(unit, port)) &&
  15397             !SOC_USE_PORTCTRL(unit)) {
  15398     	    rv = _bcm_port_mac_init(unit, port, &okay);
  15399 
  15400     	    if (!okay) {
  15401     		SOC_PBMP_PORT_REMOVE(*okay_pbmp, port);
  15402 #if defined(BCM_ESW_SUPPORT)
  15403                 soc_counter_port_pbmp_remove(unit, port);
  15404 #endif
  15405     	    }
  15406     	    if (rv < 0) {
  15407     		LOG_WARN(BSL_LS_BCM_PORT,
  15408                          (BSL_META_U(unit,
  15409                                      "MAC init failed on port %s\n"),
  15410                           SOC_PORT_NAME(unit, port)));
  15411     		break;
  15412     	    }
  15413 
  15414 #ifdef BCM_TRIDENT_SUPPORT
  15415             if (SOC_IS_TD_TT(unit) &&
  15416                 !SOC_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, port)) {
  15417                 soc_ipg_t *si;
  15418                 int ifg, duplex;
  15419 
  15420                 rv = MAC_DUPLEX_GET(PORT(unit, port).p_mac, unit, port, &duplex);
  15421                 if (rv < 0) {
  15422                     LOG_WARN(BSL_LS_BCM_PORT,
  15423                              (BSL_META_U(unit,
  15424                                          "MAC_DUPLEX_GET failed on port %s\n"),
  15425                               SOC_PORT_NAME(unit, port)));
  15426                     break;
  15427                 }
  15428 
  15429                 si = &SOC_PERSIST(unit)->ipg[port];
  15430                 if (IS_HG_PORT(unit, port)) {
  15431                     ifg = si->fd_hg = SOC_AVERAGE_IPG_HG;
  15432                 } else {
  15433                     ifg = si->fd_xe = SOC_AVERAGE_IPG_IEEE;
  15434                 }
  15435 
  15436                 if (SOC_IS_TOMAHAWKX(unit)) {
  15437                     port_speed = (0 != SOC_INFO(unit).port_init_speed[port]) ?
  15438                                      SOC_INFO(unit).port_init_speed[port] : SOC_INFO(unit).port_speed_max[port];
  15439                 } else if (SOC_IS_TRIDENT2(unit)) {
  15440                     sal_memset(&mac_ability, 0, sizeof(soc_port_ability_t));
  15441                     rv = MAC_ABILITY_LOCAL_GET(PORT(unit, port).p_mac, unit, port,
  15442                                                &mac_ability);
  15443                     if (rv < 0) {
  15444                         LOG_WARN(BSL_LS_BCM_PORT,
  15445                                  (BSL_META_U(unit,
  15446                                              "MAC_ABILITY_LOCAL_GET failed on port %s\n"),
  15447                                   SOC_PORT_NAME(unit, port)));
  15448                         break;
  15449                     }
  15450                     port_speed = BCM_PORT_ABILITY_SPEED_MAX(mac_ability.speed_full_duplex);
  15451                 } else {
  15452                     port_speed = SOC_INFO(unit).port_speed_max[port];
  15453                 }
  15454 
  15455                 rv = MAC_IFG_SET(PORT(unit, port).p_mac, unit, port,
  15456                                  port_speed, duplex, ifg);
  15457                 if (rv < 0) {
  15458                     LOG_WARN(BSL_LS_BCM_PORT,
  15459                              (BSL_META_U(unit,
  15460                                          "MAC_IFG_SET failed on port %s\n"),
  15461                               SOC_PORT_NAME(unit, port)));
  15462                     break;
  15463                 }
  15464             }
  15465 #endif
  15466     	}
  15467 
  15468         /* This is needed for run-time probing */
  15469         sop = SOC_PERSIST(unit);
  15470         if (soc_property_port_get(unit, port, spn_FCMAP_ENABLE, 0)) {
  15471             SOC_PBMP_PORT_ADD(sop->lc_pbm_fc, port);
  15472         } else {
  15473             SOC_PBMP_PORT_REMOVE(sop->lc_pbm_fc, port);
  15474         }
  15475 
  15476         /* Check if the external phy is set in EBE/EtherRAM buffer mode */
  15477         if (soc_property_port_get(unit, port, spn_PHY_OPERATIONAL_MODE, 0) == 3) {
  15478             SOC_PBMP_PORT_ADD(sop->lc_pbm_eth_buffer_mode, port);
  15479         } else {
  15480             SOC_PBMP_PORT_REMOVE(sop->lc_pbm_eth_buffer_mode, port);
  15481         }
  15482 
  15483     }
  15484 
  15485     PORT_UNLOCK(unit);
  15486 
  15487     return rv;
  15488 }
  15489 
  15490 /*
  15491  * Function:
  15492  *      _bcm_port_detach
  15493  * Purpose:
  15494  *      Main part of bcm_port_detach
  15495  */
  15496 
  15497 int
  15498 _bcm_port_detach(int unit, pbmp_t pbmp, pbmp_t *detached)
  15499 {
  15500     bcm_port_t          port;
  15501     int                 rv;
  15502     soc_persist_t       *sop = SOC_PERSIST(unit);
  15503 
  15504     SOC_PBMP_CLEAR(*detached);
  15505 
  15506     PBMP_ITER(pbmp, port) {
  15507         BCM_IF_ERROR_RETURN(bcm_esw_port_stp_set(unit, port, BCM_STG_STP_DISABLE));
  15508         PORT_LOCK(unit);
  15509         rv = _bcm_port_mode_setup(unit, port, FALSE);
  15510         PORT_UNLOCK(unit);
  15511         BCM_IF_ERROR_RETURN(rv);
  15512         SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port));
  15513         SOC_PBMP_PORT_ADD(*detached, port);
  15514 
  15515         if (SOC_PBMP_MEMBER(sop->lc_pbm_fc, port)) {
  15516             /* Bring down the internal PHY */
  15517             rv = bcm_esw_port_update(unit, port, FALSE);
  15518             BCM_IF_ERROR_RETURN(rv);
  15519             SOC_PBMP_PORT_REMOVE(sop->lc_pbm_fc, port);
  15520         }
  15521     }
  15522 #ifdef BCM_TRIUMPH2_SUPPORT
  15523     if (soc_feature(unit, soc_feature_vpd_profile)) {
  15524         _bcm_tr2_port_vpd_bitmap_free(unit);
  15525     }
  15526 #endif
  15527     return BCM_E_NONE;
  15528 }
  15529 
  15530 /*
  15531  * Function:
  15532  *      bcm_port_detach
  15533  * Purpose:
  15534  *      Detach a port.  Set phy driver to no connection.
  15535  * Parameters:
  15536  *      unit - StrataSwitch unit number.
  15537  *      pbmp - Bitmap of ports to detach.
  15538  *      detached (OUT) - Bitmap of ports successfully detached.
  15539  * Returns:
  15540  *      BCM_E_NONE
  15541  *      BCM_E_INTERNAL - internal error.
  15542  * Notes:
  15543  *      If a port to be detached does not appear in detached, its
  15544  *      state is not defined.
  15545  */
  15546 
  15547 int
  15548 bcm_esw_port_detach(int unit, pbmp_t pbmp, pbmp_t *detached)
  15549 {
  15550     int         rv;
  15551 #ifdef  BROADCOM_DEBUG
  15552     char        pfmtp[SOC_PBMP_FMT_LEN],
  15553                 pfmtd[SOC_PBMP_FMT_LEN];
  15554 #endif  /* BROADCOM_DEBUG */
  15555 
  15556     PORT_INIT(unit);
  15557     if (SOC_USE_PORTCTRL(unit)) {
  15558         return bcmi_esw_portctrl_detach(unit, pbmp, detached);
  15559     }
  15560 
  15561     PORT_LOCK(unit);
  15562     rv = _bcm_port_detach(unit, pbmp, detached);
  15563     PORT_UNLOCK(unit);
  15564 #ifdef  BROADCOM_DEBUG
  15565     LOG_INFO(BSL_LS_BCM_PORT,
  15566              (BSL_META_U(unit,
  15567                          "bcm_port_detach: u=%d pbmp=%s det=%s rv=%d\n"),
  15568                          unit,
  15569               SOC_PBMP_FMT(pbmp, pfmtp),
  15570               SOC_PBMP_FMT(*detached, pfmtd),
  15571               rv));
  15572 #endif
  15573     return rv;
  15574 }
  15575 
  15576 /*
  15577  * Function:
  15578  *      bcm_port_config_get
  15579  * Purpose:
  15580  *      Get port configuration of a device
  15581  * Parameters:
  15582  *      unit - StrataSwitch Unit #.
  15583  *      config - (OUT) Structure returning configuration
  15584  * Returns:
  15585  *      BCM_E_XXX
  15586  */
  15587 
  15588 int
  15589 bcm_esw_port_config_get(int unit, bcm_port_config_t *config)
  15590 {
  15591     int i;
  15592 
  15593     PORT_INIT(unit);
  15594     PORT_LOCK(unit);
  15595 
  15596     config->fe          = PBMP_FE_ALL(unit);
  15597     config->ge          = PBMP_GE_ALL(unit);
  15598     config->xe          = PBMP_XE_ALL(unit);
  15599     config->ce          = PBMP_CE_ALL(unit);
  15600     config->cd          = PBMP_CDE_ALL(unit);
  15601     config->e           = PBMP_E_ALL(unit);
  15602     config->hg          = PBMP_HG_ALL(unit);
  15603     config->tdm         = PBMP_TDM_ALL(unit);
  15604     config->port        = PBMP_PORT_ALL(unit);
  15605     config->cpu         = PBMP_CMIC(unit);
  15606     config->roe         = PBMP_CPRI_ALL(unit);
  15607     config->all         = PBMP_ALL(unit);
  15608     /* Remove LB and RDB port from the PBMP_ALL bitmap for backward compatibility */
  15609     SOC_PBMP_REMOVE(config->all, PBMP_LB(unit));
  15610     SOC_PBMP_REMOVE(config->all, PBMP_RDB_ALL(unit));
  15611     SOC_PBMP_REMOVE(config->all, PBMP_FAE_ALL(unit));
  15612 #ifdef BCM_MONTEREY_SUPPORT
  15613     if (SOC_IS_MONTEREY(unit)) {
  15614         SOC_PBMP_REMOVE(config->all, PBMP_MACSEC_ALL(unit));
  15615     }
  15616 #endif
  15617     config->stack_ext   = PBMP_ST_ALL(unit);
  15618 
  15619 
  15620     BCM_PBMP_CLEAR(config->stack_int);
  15621     BCM_PBMP_CLEAR(config->sci);
  15622     BCM_PBMP_CLEAR(config->sfi);
  15623     BCM_PBMP_CLEAR(config->spi);
  15624     BCM_PBMP_CLEAR(config->spi_subport);
  15625 
  15626     for (i = 0; i < NUM_PIPE(unit); i++) {
  15627         config->per_pipe[i] = PBMP_PIPE(unit, i);
  15628         SOC_PBMP_REMOVE(config->per_pipe[i], PBMP_LB(unit));
  15629         SOC_PBMP_REMOVE(config->per_pipe[i], PBMP_RDB_ALL(unit));
  15630         SOC_PBMP_REMOVE(config->per_pipe[i], PBMP_FAE_ALL(unit));
  15631 #ifdef BCM_MONTEREY_SUPPORT
  15632         if (SOC_IS_MONTEREY(unit)) {
  15633             SOC_PBMP_REMOVE(config->per_pipe[i], PBMP_MACSEC_ALL(unit));
  15634         }
  15635 #endif
  15636     }
  15637 
  15638 #if defined(BCM_SABER2_SUPPORT)
  15639     /* Remove OAMP port from port config list */
  15640     if(SOC_IS_SABER2(unit)) {
  15641         soc_info_t *si = &SOC_INFO(unit);
  15642         bcm_port_t oamp_port = _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER;
  15643 
  15644         if(bcm_common_oamp_port_enable_get(unit, oamp_port)) {
  15645             SOC_PBMP_PORT_REMOVE(config->port, oamp_port);
  15646             SOC_PBMP_PORT_REMOVE(config->e, oamp_port);
  15647 
  15648             if(si->port_speed_max[oamp_port] < 10000) {
  15649                 SOC_PBMP_PORT_REMOVE(config->ge, oamp_port);
  15650             } else {
  15651                 SOC_PBMP_PORT_REMOVE(config->xe, oamp_port);
  15652             }
  15653         }
  15654     }
  15655 #endif
  15656 
  15657 #if defined(BCM_TRIUMPH3_SUPPORT)
  15658     if (SOC_IS_TRIUMPH3(unit)) {
  15659         config->control = soc_tr3_get_control_port_bitmap(unit);
  15660     }
  15661 #endif
  15662 
  15663 #if defined(BCM_KATANA2_SUPPORT)
  15664     if (SOC_IS_KATANA2(unit) && (soc_feature(unit, soc_feature_linkphy_coe) ||
  15665         soc_feature(unit, soc_feature_subtag_coe))) {
  15666         _bcm_kt2_subport_pbmp_update(unit, &(config->all));
  15667     }
  15668 #endif
  15669 
  15670     PORT_UNLOCK(unit);
  15671     return BCM_E_NONE;
  15672 }
  15673 
  15674 STATIC int
  15675 _bcm_td_port_mode_update(int unit, bcm_port_t port, int speed)
  15676 {
  15677     soc_info_t *si;
  15678     int enable[2], duplex[2], loopback[2], pause_tx[2], pause_rx[2];
  15679     int frame_max[2], encap[2];
  15680     sal_mac_addr_t address[2];
  15681     bcm_port_t port_list[2], phy_port, cur_port;
  15682     uint32 rval;
  15683     int core_mode, phy_mode, old_phy_mode;
  15684     int i;
  15685 
  15686     /* Get the original phy_mode */
  15687     SOC_IF_ERROR_RETURN(READ_XLPORT_MODE_REGr(unit, port, &rval));
  15688     core_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval,
  15689                                   CORE_PORT_MODEf);
  15690     old_phy_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval,
  15691                                      PHY_PORT_MODEf);
  15692 
  15693     si = &SOC_INFO(unit);
  15694     /* speed is the only factor to determine phy_mode */
  15695     if ((speed > 20000) && si->port_speed_max[port] > 20000){
  15696         phy_mode = 0;
  15697     } else if (speed > 10000) {
  15698         if ((si->port_num_lanes[port] == 1) && (speed == 11000) &&
  15699             IS_HG_PORT(unit, port)) {
  15700             phy_mode = 2;
  15701         } else {
  15702             phy_mode = 1;
  15703         }
  15704     } else {
  15705         if ((si->port_num_lanes[port] == 2) && (speed == 10000) &&
  15706             IS_HG_PORT(unit, port)) {
  15707             phy_mode = 1; /* Warpcore uses DXGXS 10.5G in HG mode */
  15708         } else if ((si->port_num_lanes[port] == 4) && (speed == 10000)) {
  15709             phy_mode = 2;
  15710             core_mode = 0;
  15711         } else {
  15712             phy_mode = 2;
  15713         }
  15714     }
  15715 
  15716     if (phy_mode == old_phy_mode) {
  15717         return BCM_E_NONE;
  15718     }
  15719 
  15720     port_list[0] = port;
  15721     port_list[1] = -1;
  15722     if (core_mode == 1) { /* dual mode */
  15723         si = &SOC_INFO(unit);
  15724         phy_port = si->port_l2p_mapping[port];
  15725         port_list[1] = si->port_p2l_mapping[((phy_port - 1) ^ 2) + 1];
  15726     }
  15727     soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, PHY_PORT_MODEf, phy_mode);
  15728     soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, CORE_PORT_MODEf, core_mode);
  15729     SOC_IF_ERROR_RETURN(WRITE_XLPORT_MODE_REGr(unit, port, rval));
  15730 
  15731     /* Retain MAC setting */
  15732     for (i = 0; i < 2; i++) {
  15733         if (port_list[i] == -1) {
  15734             continue;
  15735         }
  15736         cur_port = port_list[i];
  15737 
  15738         /* no need to save speed since speed change trigger this, in addition,
  15739          * mac may not be able to tell you exact speed in many cases */
  15740         SOC_IF_ERROR_RETURN
  15741             (MAC_DUPLEX_GET(PORT(unit, cur_port).p_mac, unit, cur_port,
  15742                             &duplex[i]));
  15743         SOC_IF_ERROR_RETURN
  15744             (MAC_PAUSE_GET(PORT(unit, cur_port).p_mac, unit, cur_port,
  15745                            &pause_tx[i], &pause_rx[i]));
  15746         SOC_IF_ERROR_RETURN
  15747             (MAC_PAUSE_ADDR_GET(PORT(unit, cur_port).p_mac, unit, cur_port,
  15748                                 address[i]));
  15749         SOC_IF_ERROR_RETURN
  15750             (MAC_FRAME_MAX_GET(PORT(unit, cur_port).p_mac, unit, cur_port,
  15751                                &frame_max[i]));
  15752         /* not saving ifg setting */
  15753         SOC_IF_ERROR_RETURN
  15754             (MAC_ENCAP_GET(PORT(unit, cur_port).p_mac, unit, cur_port,
  15755                            &encap[i]));
  15756         SOC_IF_ERROR_RETURN
  15757             (MAC_LOOPBACK_GET(PORT(unit, cur_port).p_mac, unit, cur_port,
  15758                               &loopback[i]));
  15759         SOC_IF_ERROR_RETURN
  15760             (MAC_ENABLE_GET(PORT(unit, cur_port).p_mac, unit, cur_port,
  15761                             &enable[i]));
  15762     }
  15763 
  15764     /* Do XMAC hard reset when phy_mode changed */
  15765     (void)READ_XLPORT_XMAC_CONTROLr(unit, port, &rval);
  15766     soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 1);
  15767     (void)WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval);
  15768     sal_udelay(10);
  15769     soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 0);
  15770     (void)WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval);
  15771 
  15772     for (i = 0; i < 2; i++) {
  15773         if (port_list[i] == -1) {
  15774             continue;
  15775         }
  15776         cur_port = port_list[i];
  15777 
  15778         /* mac init */
  15779         SOC_IF_ERROR_RETURN
  15780             (MAC_INIT(PORT(unit, cur_port).p_mac, unit, cur_port));
  15781 
  15782         /* Restore MAC setting */
  15783         /* no need to save speed since speed change trigger this, in addition,
  15784          * mac may not be able to tell you exact speed in many cases */
  15785         /* coverity[uninit_use_in_call] : FALSE */
  15786         SOC_IF_ERROR_RETURN
  15787             (MAC_DUPLEX_SET(PORT(unit, cur_port).p_mac, unit, cur_port,
  15788                             duplex[i]));
  15789         /* coverity[uninit_use_in_call] : FALSE */
  15790         SOC_IF_ERROR_RETURN
  15791             (MAC_PAUSE_SET(PORT(unit, cur_port).p_mac, unit, cur_port,
  15792                            pause_tx[i], pause_rx[i]));
  15793         SOC_IF_ERROR_RETURN
  15794             (MAC_PAUSE_ADDR_SET(PORT(unit, cur_port).p_mac, unit, cur_port,
  15795                                 address[i]));
  15796         /* coverity[uninit_use_in_call] : FALSE */
  15797         SOC_IF_ERROR_RETURN
  15798             (MAC_FRAME_MAX_SET(PORT(unit, cur_port).p_mac, unit, cur_port,
  15799                                frame_max[i]));
  15800         /* not saving ifg setting */
  15801         /* coverity[uninit_use_in_call] : FALSE */
  15802         SOC_IF_ERROR_RETURN
  15803             (MAC_ENCAP_SET(PORT(unit, cur_port).p_mac, unit, cur_port,
  15804                            encap[i]));
  15805         /* coverity[uninit_use_in_call] : FALSE */
  15806         SOC_IF_ERROR_RETURN
  15807             (MAC_LOOPBACK_SET(PORT(unit, cur_port).p_mac, unit, cur_port,
  15808                               loopback[i]));
  15809         /* coverity[uninit_use_in_call] : FALSE */
  15810         SOC_IF_ERROR_RETURN
  15811             (MAC_ENABLE_SET(PORT(unit, cur_port).p_mac, unit, cur_port,
  15812                             enable[i]));
  15813     }
  15814 
  15815     return BCM_E_NONE;
  15816 }
  15817 
  15818 /*
  15819  * Function:
  15820  *      _bcm_port_update
  15821  * Purpose:
  15822  *      Get port characteristics from PHY and program MAC to match.
  15823  * Parameters:
  15824  *      unit - StrataSwitch Unit #.
  15825  *      port - StrataSwitch port #.
  15826  *      link -  True if link is active, false if link is inactive.
  15827  * Returns:
  15828  *      BCM_E_NONE
  15829  *      BCM_E_XXX
  15830  */
  15831 
  15832 STATIC int
  15833 _bcm_port_update(int unit, bcm_port_t port, int link)
  15834 {
  15835     int                 rv;
  15836     int                 duplex, speed, an, an_done;
  15837     soc_port_if_t       pif;
  15838     int                 cur_mac_speed;
  15839     int                 enable;
  15840 #ifdef INCLUDE_MACSEC
  15841     int                 policy = 0;
  15842     int                 duplex_old = 0;
  15843 #endif
  15844 #ifdef INCLUDE_FCMAP
  15845     phy_ctrl_t *pc;
  15846 #endif
  15847 
  15848     /* Call Port Control module */
  15849     if (SOC_USE_PORTCTRL(unit)) {
  15850         return bcmi_esw_portctrl_update(unit, port, link);
  15851     }
  15852     if(bcm_common_oamp_port_enable_get(unit, port)) {
  15853         LOG_ERROR(BSL_LS_BCM_PORT,
  15854                   (BSL_META("Error: Not permitted on OAMP port %d.update.\n"),
  15855                    port));
  15856         return BCM_E_PARAM;
  15857     }
  15858 
  15859     if (PORT(unit, port).p_mac == NULL) {
  15860         return BCM_E_INIT;
  15861     }
  15862 
  15863     if (!link) {
  15864         /* PHY is down.  Disable the MAC. */
  15865 #ifdef SW_AUTONEG_SUPPORT
  15866         rv = _bcm_esw_port_notify_link_down_evt(unit, port);
  15867                 if (BCM_FAILURE(rv)) {
  15868                     LOG_WARN(BSL_LS_BCM_PORT,
  15869                              (BSL_META_U(unit,
  15870                                  "u=%d p=%d NOTIFY LINK DOWN EVT rv=%d\n"),
  15871                               unit, port, rv));
  15872                     return rv;
  15873                 }
  15874 #endif        
  15875 
  15876         rv = (MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, FALSE));
  15877         if (BCM_FAILURE(rv)) {
  15878             LOG_WARN(BSL_LS_BCM_PORT,
  15879                      (BSL_META_U(unit,
  15880                                  "u=%d p=%d MAC_ENABLE_SET FALSE rv=%d\n"),
  15881                       unit, port, rv));
  15882             return rv;
  15883         }
  15884         /* PHY link down event */
  15885         rv = (soc_phyctrl_linkdn_evt(unit, port));
  15886         if (BCM_FAILURE(rv) && (BCM_E_UNAVAIL != rv)) {
  15887             LOG_WARN(BSL_LS_BCM_PORT,
  15888                      (BSL_META_U(unit,
  15889                                  "u=%d p=%d soc_phyctrl_linkdn_evt rv=%d\n"),unit, port, rv));
  15890             return rv;
  15891         }
  15892         return BCM_E_NONE;
  15893     }
  15894 
  15895     /* PHY link up event may not be support by all PHY driver.
  15896      * Just ignore it if not supported */
  15897     rv = (soc_phyctrl_linkup_evt(unit, port));
  15898     if (BCM_FAILURE(rv) && (BCM_E_UNAVAIL != rv)) {
  15899         LOG_WARN(BSL_LS_BCM_PORT,
  15900                  (BSL_META_U(unit,
  15901                              "u=%d p=%d soc_phyctrl_linkup_evt rv=%d\n"),unit, port, rv));
  15902         return rv;
  15903     }
  15904 
  15905     if (soc_feature(unit, soc_feature_internal_phy_link_check)) {
  15906         int up = 0;
  15907 
  15908         SOC_IF_ERROR_RETURN
  15909             (soc_phyctrl_link_get(unit, port, &up));
  15910 
  15911         /* Wait internal PHY link when external PHY is link up */
  15912         if (up) {
  15913             (void)soc_phyctrl_notify(unit, port, phyEventLinkWait, 0);
  15914         }
  15915     }
  15916 
  15917     /*
  15918      * Set MAC speed first, since for GTH ports, this will switch
  15919      * between the 1000Mb/s or 10/100Mb/s MACs.
  15920      */
  15921 
  15922     if (!IS_HG_PORT(unit, port) || IS_GX_PORT(unit, port)) {
  15923         rv = (soc_phyctrl_speed_get(unit, port, &speed));
  15924         if (BCM_FAILURE(rv) && (BCM_E_UNAVAIL != rv)) {
  15925             LOG_WARN(BSL_LS_BCM_PORT,
  15926                      (BSL_META_U(unit,
  15927                                  "u=%d p=%d phyctrl_speed_get rv=%d\n"),unit, port, rv));
  15928             return rv;
  15929         }
  15930         if (IS_HG_PORT(unit, port) && speed < 5000) {
  15931             speed = 0;
  15932         }
  15933         LOG_INFO(BSL_LS_BCM_PORT,
  15934                  (BSL_META_U(unit,
  15935                              "u=%d p=%d phyctrl_speed_get speed=%d\n"),unit, port, speed));
  15936 
  15937         if (BCM_E_UNAVAIL == rv ) {
  15938             /* If PHY driver doesn't support speed_get, don't change
  15939              * MAC speed. E.g, Null PHY driver
  15940              */
  15941             rv = BCM_E_NONE;
  15942         } else {
  15943             if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
  15944                 BCM_IF_ERROR_RETURN
  15945                     (_bcm_td_port_mode_update(unit, port, speed));
  15946             }
  15947 #ifdef INCLUDE_FCMAP
  15948             /* FOR MONTREAL-1 ONLY
  15949              *
  15950              * In FCMAP mode, the port is operating in FC-Mode. The switch and the
  15951              * system side of the PHY operates in 10G, FullDuplex and Pause enabled
  15952              * mode
  15953              * For MT1, the phy max speed will always be 10G (never 25G which MT2 supports)
  15954              */
  15955             if (soc_property_port_get(unit, port, spn_FCMAP_ENABLE, 0)) {
  15956 
  15957                 pc = EXT_PHY_SW_STATE(unit, port);
  15958 
  15959                 if ((pc != NULL) &&  !PHY_IS_BCM8806X(pc)) {
  15960                      speed = 10000;
  15961                 }
  15962                 LOG_WARN(BSL_LS_BCM_PORT,
  15963                          (BSL_META_U(unit,
  15964                                      "u=%d p=%d speed_max=%d speed=%d\n"),unit, port,
  15965                                       pc->speed_max, speed));
  15966             }
  15967 #endif
  15968             rv =  (MAC_SPEED_GET(PORT(unit, port).p_mac, unit, port, &cur_mac_speed));
  15969             if (BCM_FAILURE(rv)) {
  15970                 LOG_WARN(BSL_LS_BCM_PORT,
  15971                          (BSL_META_U(unit,
  15972                                      "u=%d p=%d MAC_SPEED_GET rv=%d\n"),unit, port, rv));
  15973                 return rv;
  15974             }
  15975 
  15976             rv =  (MAC_ENABLE_GET(PORT(unit, port).p_mac, unit, port, &enable));
  15977             if (BCM_FAILURE(rv)) {
  15978                 LOG_WARN(BSL_LS_BCM_PORT,
  15979                             (BSL_META_U(unit,
  15980                                       "u=%d p=%d MAC_ENABLE_GET rv=%d\n"),unit, port, rv));
  15981                 return rv;
  15982             }
  15983 
  15984             /* If current MAC speed is the same as PHY speed, no need set it again */ 
  15985             if (cur_mac_speed != speed || enable != TRUE) {
  15986                  rv =  (MAC_SPEED_SET(PORT(unit, port).p_mac, unit, port, speed));
  15987             }
  15988         }
  15989         if (BCM_FAILURE(rv)) {
  15990             LOG_WARN(BSL_LS_BCM_PORT,
  15991                      (BSL_META_U(unit,
  15992                                  "u=%d p=%d MAC_SPEED_SET speed=%d rv=%d\n"),
  15993                       unit, port, speed, rv));
  15994             return rv;
  15995         }
  15996 
  15997         rv =   (soc_phyctrl_duplex_get(unit, port, &duplex));
  15998         if (BCM_FAILURE(rv)) {
  15999             LOG_WARN(BSL_LS_BCM_PORT,
  16000                      (BSL_META_U(unit,
  16001                                  "u=%d p=%d phyctrl_duplex_get rv=%d\n"),
  16002                                  unit, port, rv));
  16003             return rv;
  16004         }
  16005 
  16006 #ifdef INCLUDE_MACSEC
  16007         /* When macsec is enabled, the switch and system side of the PHY
  16008          * operate in full-duplex mode.
  16009  */
  16010         duplex_old = duplex;
  16011         if ( soc_property_port_get(unit, port, spn_MACSEC_ENABLE, 0) ) {
  16012             duplex = 1;
  16013         }
  16014 
  16015         policy = soc_property_port_get(unit, port, spn_MACSEC_SWITCH_SIDE_POLICY, 1);
  16016         if ( (policy == 2) && (! duplex_old) ) {
  16017             /* if line-side linked up at half-duplex under Duplex Gateway mode */
  16018             duplex = 1;        /* force to full-duplex */
  16019         }
  16020 #endif
  16021 
  16022 #ifdef INCLUDE_FCMAP
  16023             /*
  16024              * In FCMAP mode, the port is operating in FC-Mode. The switch and the
  16025              * system side of the PHY operates in 10G, FullDuplex and Pause enabled
  16026              * mode
  16027              */
  16028             if (soc_property_port_get(unit, port, spn_FCMAP_ENABLE, 0)) {
  16029                 duplex = 1;
  16030             }
  16031 #endif
  16032         rv = (MAC_DUPLEX_SET(PORT(unit, port).p_mac, unit, port, duplex));
  16033         if (BCM_FAILURE(rv)) {
  16034             LOG_WARN(BSL_LS_BCM_PORT,
  16035                      (BSL_META_U(unit,
  16036                                  "u=%d p=%d MAC_DUPLEX_SET %s sp=%d rv=%d\n"),
  16037                                  unit, port,
  16038                       duplex ? "FULL" : "HALF", speed, rv));
  16039             return rv;
  16040         }
  16041     } else {
  16042 
  16043         duplex = 1;
  16044     }
  16045 
  16046     rv = (soc_phyctrl_interface_get(unit, port, &pif));
  16047     if (BCM_FAILURE(rv)) {
  16048         LOG_WARN(BSL_LS_BCM_PORT,
  16049                  (BSL_META_U(unit,
  16050                              "u=%d p=%d phyctrl_interface_get rv=%d\n"),
  16051                   unit, port, rv));
  16052         return rv;
  16053     }
  16054     rv = (MAC_INTERFACE_SET(PORT(unit, port).p_mac, unit, port, pif));
  16055     if (BCM_FAILURE(rv)) {
  16056         LOG_WARN(BSL_LS_BCM_PORT,
  16057                  (BSL_META_U(unit,
  16058                              "u=%d p=%d MAC_INTERFACE_GET rv=%d\n"),
  16059                   unit, port,rv));
  16060         return rv;
  16061     }
  16062 
  16063     SOC_IF_ERROR_RETURN
  16064         (soc_phyctrl_auto_negotiate_get(unit, port, &an, &an_done));
  16065 
  16066     /*
  16067      * If autonegotiating, check the negotiated PAUSE values, and program
  16068      * MACs accordingly. Link can also be achieved thru parallel detect.
  16069      * In this case, it should be treated as in the forced mode.
  16070      */
  16071     if (an && an_done) {
  16072         bcm_port_ability_t      remote_advert, local_advert;
  16073         int                     tx_pause, rx_pause;
  16074 
  16075     sal_memset(&local_advert,  0, sizeof(bcm_port_ability_t));
  16076     sal_memset(&remote_advert, 0, sizeof(bcm_port_ability_t));
  16077 
  16078     rv = soc_phyctrl_ability_advert_get(unit, port, &local_advert);
  16079         if (BCM_FAILURE(rv)) {
  16080             LOG_WARN(BSL_LS_BCM_PORT,
  16081                      (BSL_META_U(unit,
  16082                                  "u=%d p=%d soc_phyctrl_adv_local_get rv=%d\n"),
  16083                       unit, port, rv));
  16084             return rv;
  16085         }
  16086         rv = soc_phyctrl_ability_remote_get(unit, port, &remote_advert);
  16087         if (BCM_FAILURE(rv)) {
  16088             LOG_WARN(BSL_LS_BCM_PORT,
  16089                      (BSL_META_U(unit,
  16090                                  "u=%d p=%d soc_phyctrl_adv_remote_get rv=%d\n"),
  16091                       unit, port, rv));
  16092             return rv;
  16093         }
  16094 
  16095         /*
  16096          * IEEE 802.3 Flow Control Resolution.
  16097          * Please see $SDK/doc/pause-resolution.txt for more information.
  16098          */
  16099 
  16100         if (duplex) {
  16101             tx_pause =
  16102                      ((remote_advert.pause & SOC_PA_PAUSE_RX) &&
  16103                       (local_advert.pause & SOC_PA_PAUSE_RX)) ||
  16104                      ((remote_advert.pause & SOC_PA_PAUSE_RX) &&
  16105                       !(remote_advert.pause & SOC_PA_PAUSE_TX) &&
  16106                       (local_advert.pause & SOC_PA_PAUSE_TX));
  16107 
  16108             rx_pause =
  16109                      ((remote_advert.pause & SOC_PA_PAUSE_RX) &&
  16110                       (local_advert.pause & SOC_PA_PAUSE_RX)) ||
  16111                      ((local_advert.pause & SOC_PA_PAUSE_RX) &&
  16112                       (remote_advert.pause & SOC_PA_PAUSE_TX) &&
  16113                       !(local_advert.pause & SOC_PA_PAUSE_TX));
  16114         } else {
  16115             rx_pause = tx_pause = 0;
  16116         }
  16117 #ifdef INCLUDE_MACSEC
  16118         if ( (policy == 2) && (! duplex_old) ) {
  16119             /* if line-side linked up at half-duplex under Duplex Gateway mode */
  16120             rx_pause = 1;              /* turn on flow control Rx pause frames */
  16121         }
  16122 #endif
  16123         rv = (MAC_PAUSE_SET(PORT(unit, port).p_mac,
  16124                            unit, port, tx_pause, rx_pause));
  16125         if (BCM_FAILURE(rv)) {
  16126             LOG_WARN(BSL_LS_BCM_PORT,
  16127                      (BSL_META_U(unit,
  16128                                  "u=%d p=%d MAC_PAUSE_SET rv=%d\n"),
  16129                       unit, port, rv));
  16130             return rv;
  16131         }
  16132     }
  16133 
  16134 #ifdef INCLUDE_MACSEC
  16135     {
  16136     /*
  16137      * In MACSEC based PHYs the switch side could be operating with
  16138      * different speed,duplex and pause compared to line speed, duplex and
  16139      * pause settings. The above setting will be overridden if the switch side
  16140      * of the PHY is set to operate in fixed mode
  16141      */
  16142     uint32 value;
  16143     rv = (soc_phyctrl_control_get(unit, port,
  16144                                   BCM_PORT_PHY_CONTROL_MACSEC_SWITCH_FIXED,
  16145                                   &value));
  16146 
  16147     if (BCM_E_UNAVAIL != rv) { /* Switch fixed speed is supported */
  16148 
  16149         if (value == 1) {
  16150             /* Get and Set Speed */
  16151             rv = (soc_phyctrl_control_get(unit, port,
  16152                               BCM_PORT_PHY_CONTROL_MACSEC_SWITCH_FIXED_SPEED,
  16153                               &value));
  16154             if (BCM_FAILURE(rv)) {
  16155                 LOG_WARN(BSL_LS_BCM_PORT,
  16156                          (BSL_META_U(unit,
  16157                                      "u=%d p=%d phyctrl_control_get(speed) rv=%d\n"),
  16158                           unit, port, rv));
  16159                 return rv;
  16160             }
  16161 
  16162             rv =  (MAC_SPEED_SET(PORT(unit, port).p_mac, unit, port, value));
  16163             if (BCM_FAILURE(rv)) {
  16164                 LOG_WARN(BSL_LS_BCM_PORT,
  16165                          (BSL_META_U(unit,
  16166                                      "u=%d p=%d MAC_SPEED_SET speed=%d rv=%d\n"),
  16167                           unit, port, value, rv));
  16168                 return rv;
  16169             }
  16170 
  16171             /* Get and Set Duplex */
  16172             rv = (soc_phyctrl_control_get(unit, port,
  16173                               BCM_PORT_PHY_CONTROL_MACSEC_SWITCH_FIXED_DUPLEX,
  16174                               &value));
  16175             if (BCM_FAILURE(rv)) {
  16176                 LOG_WARN(BSL_LS_BCM_PORT,
  16177                          (BSL_META_U(unit,
  16178                                      "u=%d p=%d phyctrl_control_get(duplex) rv=%d\n"),
  16179                           unit, port, rv));
  16180                 return rv;
  16181             }
  16182             rv = (MAC_DUPLEX_SET(PORT(unit, port).p_mac, unit, port, value));
  16183             if (BCM_FAILURE(rv)) {
  16184                 LOG_WARN(BSL_LS_BCM_PORT,
  16185                          (BSL_META_U(unit,
  16186                                      "u=%d p=%d MAC_DUPLEX_SET %s sp=%d rv=%d\n"),
  16187                                      unit, port,
  16188                           value ? "FULL" : "HALF", value, rv));
  16189                 return rv;
  16190             }
  16191 
  16192             /* Get and Set PAUSE */
  16193             rv = (soc_phyctrl_control_get(unit, port,
  16194                               BCM_PORT_PHY_CONTROL_MACSEC_SWITCH_FIXED_PAUSE,
  16195                               &value));
  16196             if (BCM_FAILURE(rv)) {
  16197                 LOG_WARN(BSL_LS_BCM_PORT,
  16198                          (BSL_META_U(unit,
  16199                                      "u=%d p=%d phyctrl_control_get(Pause) rv=%d\n"),
  16200                           unit, port, rv));
  16201                 return rv;
  16202             }
  16203             if (value == 1) {
  16204                 /*
  16205                  * Flow control domain is between switch MAC and PHY MAC.
  16206                  * If the flow control domain is not between switch and PHY's
  16207                  * switch MAC, then the flow control domain is extended to that
  16208                  * of GPHY.
  16209                  */
  16210                 rv = (MAC_PAUSE_SET(PORT(unit, port).p_mac,
  16211                                unit, port, value, value));
  16212                 if (BCM_FAILURE(rv)) {
  16213                     LOG_WARN(BSL_LS_BCM_PORT,
  16214                              (BSL_META_U(unit,
  16215                                          "u=%d p=%d MAC_PAUSE_SET rv=%d\n"),
  16216                               unit, port, rv));
  16217                     return rv;
  16218                 }
  16219             }
  16220 
  16221         }
  16222     }
  16223     }
  16224 #endif
  16225 
  16226     /* Enable the MAC. */
  16227     rv =  (MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, TRUE));
  16228     if (BCM_FAILURE(rv)) {
  16229         LOG_WARN(BSL_LS_BCM_PORT,
  16230                  (BSL_META_U(unit,
  16231                              "u=%d p=%d MAC_ENABLE_SET TRUE rv=%d\n"),
  16232                   unit, port, rv));
  16233         return rv;
  16234     }
  16235 
  16236 #ifdef BCM_BRADLEY_SUPPORT
  16237     /* When a link comes up, hardware will not update the
  16238      * LINK_STATUS register until software has toggled the
  16239      * the LAG_FAILOVER_CONFIG.LINK_STATUS_UP field.
  16240      * When a link goes down, hardware will update the
  16241      * LINK_STATUS register without software intervention.
  16242      */
  16243     if ((SOC_REG_IS_VALID(unit, GXPORT_LAG_FAILOVER_CONFIGr) &&
  16244          IS_GX_PORT(unit, port)) ||
  16245         (SOC_REG_IS_VALID(unit, LAG_FAILOVER_CONFIGr)) ||
  16246         (SOC_REG_IS_VALID(unit, XLPORT_LAG_FAILOVER_CONFIGr) &&
  16247          (IS_XL_PORT(unit, port) || IS_MXQ_PORT(unit, port) )) ||
  16248         (SOC_REG_IS_VALID(unit, CLPORT_LAG_FAILOVER_CONFIGr) &&
  16249           IS_CL_PORT(unit, port))) {
  16250         soc_reg_t reg;
  16251         uint32 rval;
  16252 
  16253         if (SOC_IS_SABER2(unit) && SOC_REG_PORT_VALID(unit, XLPORT_LAG_FAILOVER_CONFIGr, port)) {
  16254             reg = XLPORT_LAG_FAILOVER_CONFIGr;
  16255         } else if (SOC_REG_IS_VALID(unit, LAG_FAILOVER_CONFIGr)) {
  16256             reg = LAG_FAILOVER_CONFIGr;
  16257         } else if (SOC_REG_IS_VALID(unit, GXPORT_LAG_FAILOVER_CONFIGr)) {
  16258             reg = GXPORT_LAG_FAILOVER_CONFIGr;
  16259         } else if (SOC_REG_PORT_VALID(unit, CLPORT_LAG_FAILOVER_CONFIGr, port) && 
  16260                    (SOC_IS_TOMAHAWKX(unit) || IS_CL_PORT(unit, port))) {
  16261             reg = CLPORT_LAG_FAILOVER_CONFIGr;
  16262         } else {
  16263             reg = XLPORT_LAG_FAILOVER_CONFIGr;
  16264         }
  16265 
  16266         /* Toggle link bit to notify IPIPE on link up */
  16267         BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval));
  16268         soc_reg_field_set(unit, reg, &rval, LINK_STATUS_UPf, 1);
  16269         BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
  16270         soc_reg_field_set(unit, reg, &rval, LINK_STATUS_UPf, 0);
  16271         BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
  16272     }
  16273 #endif /* BCM_BRADLEY_SUPPORT */
  16274 
  16275     return BCM_E_NONE;
  16276 }
  16277 
  16278 
  16279 
  16280 /*
  16281  * Function:
  16282  *      bcm_port_update
  16283  * Purpose:
  16284  *      Get port characteristics from PHY and program MAC to match.
  16285  * Parameters:
  16286  *      unit - StrataSwitch Unit #.
  16287  *      port - StrataSwitch port #.
  16288  *      link - TRUE - process as link up.
  16289  *             FALSE - process as link down.
  16290  * Returns:
  16291  *      BCM_E_NONE
  16292  *      BCM_E_XXX
  16293  */
  16294 
  16295 int
  16296 bcm_esw_port_update(int unit, bcm_port_t port, int link)
  16297 {
  16298     int         rv = BCM_E_NONE;
  16299 #if defined(BCM_KATANA2_SUPPORT)
  16300     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  16301 #endif
  16302 
  16303     /* Make sure port module is initialized. */
  16304     PORT_INIT(unit);
  16305 
  16306 #if defined(BCM_KATANA2_SUPPORT)
  16307 #if defined(BCM_SABER2_SUPPORT)
  16308     if(SOC_IS_SABER2(unit)) {
  16309         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  16310     }
  16311 #endif
  16312     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  16313         (!((port >= 1) && (port <= max_phy_port)))) {
  16314          return BCM_E_PORT;
  16315     }
  16316 #endif
  16317     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  16318 
  16319 #if defined(BCM_RCPU_SUPPORT)
  16320     if (SOC_IS_RCPU_ONLY(unit) && link) {
  16321         /* Can not do this unless real phy driver is used for RCPU device. */
  16322         return BCM_E_NONE;
  16323     }
  16324 #endif /* BCM_RCPU_SUPPORT */
  16325     PORT_LOCK(unit);
  16326     rv = _bcm_port_update(unit, port, link);
  16327     if (BCM_FAILURE(rv)) {
  16328         PORT_UNLOCK(unit);
  16329         return (rv);
  16330     }
  16331 #if defined(BCM_BRADLEY_SUPPORT)
  16332     if (SOC_IS_HBX(unit) && !SOC_IS_SHADOW(unit)) {
  16333         rv = _bcm_port_mmu_update(unit, port, link);
  16334     }
  16335 #endif /* BCM_BRADLEY_SUPPORT */
  16336 
  16337 #if defined(BCM_KATANA2_SUPPORT)
  16338     if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) {
  16339         rv = soc_katana2_mmu_port_enable_set(unit, port, link);
  16340     }
  16341 #endif 
  16342 
  16343     PORT_UNLOCK(unit);
  16344 
  16345     LOG_INFO(BSL_LS_BCM_PORT,
  16346              (BSL_META_U(unit,
  16347                          "bcm_port_update: u=%d p=%d link=%d rv=%d\n"),
  16348               unit, port, link, rv));
  16349 
  16350     return(rv);
  16351 }
  16352 
  16353 /*
  16354  * Function:
  16355  *      bcm_port_stp_set
  16356  * Purpose:
  16357  *      Set the spanning tree state for a port.
  16358  *      All STGs containing all VLANs containing the port are updated.
  16359  * Parameters:
  16360  *      unit - StrataSwitch unit number.
  16361  *      port - StrataSwitch port number.
  16362  *      stp_state - State to place port in, one of BCM_PORT_STP_xxx.
  16363  * Returns:
  16364  *      BCM_E_NONE
  16365  *      BCM_E_INTERNAL
  16366  * Notes:
  16367  *      BCM_LOCK is taken so that the current list of VLANs
  16368  *      can't change during the operation.
  16369  */
  16370 
  16371 int
  16372 bcm_esw_port_stp_set(int unit, bcm_port_t port, int stp_state)
  16373 {
  16374     bcm_stg_t           *list = NULL;
  16375     int                 count = 0, i;
  16376     int                 rv = BCM_E_NONE;
  16377 
  16378     /* Make sure port module is initialized. */
  16379     PORT_INIT(unit);
  16380     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  16381 
  16382 #ifdef BCM_RCPU_SUPPORT
  16383     if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port) &&
  16384         !(stp_state == BCM_STG_STP_FORWARD)) {
  16385         return BCM_E_PORT;
  16386     }
  16387 #endif /* BCM_RCPU_SUPPORT */
  16388 
  16389     BCM_LOCK(unit);
  16390 
  16391     rv = bcm_esw_stg_list(unit, &list, &count);
  16392 
  16393     if (rv == BCM_E_UNAVAIL) {
  16394         if (stp_state == BCM_STG_STP_FORWARD) {
  16395             rv = BCM_E_NONE;
  16396         } else {
  16397             rv = BCM_E_PARAM;
  16398         }
  16399     } else if (BCM_SUCCESS(rv)) {
  16400         for (i = 0; i < count; i++) {
  16401             if ((rv = bcm_esw_stg_stp_set(unit, list[i],
  16402                                           port, stp_state)) < 0) {
  16403                 break;
  16404             }
  16405         }
  16406 
  16407         bcm_esw_stg_list_destroy(unit, list, count);
  16408     }
  16409 
  16410     BCM_UNLOCK(unit);
  16411 
  16412     LOG_INFO(BSL_LS_BCM_PORT,
  16413              (BSL_META_U(unit,
  16414                          "bcm_port_stp_set: u=%d p=%d state=%d rv=%d\n"),
  16415               unit, port, stp_state, rv));
  16416 
  16417     return rv;
  16418 }
  16419 
  16420 /*
  16421  * Function:
  16422  *      bcm_port_stp_get
  16423  * Purpose:
  16424  *      Get the spanning tree state for a port in the default STG.
  16425  * Parameters:
  16426  *      unit - StrataSwitch unit number.
  16427  *      port - StrataSwitch port number.
  16428  *      stp_state - Pointer where state stored.
  16429  * Returns:
  16430  *      BCM_E_NONE
  16431  *      BCM_E_INTERNAL
  16432  */
  16433 
  16434 int
  16435 bcm_esw_port_stp_get(int unit, bcm_port_t port, int *stp_state)
  16436 {
  16437     int                 stg_defl, rv;
  16438 
  16439     /* Make sure port module is initialized. */
  16440     PORT_INIT(unit);
  16441 
  16442     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  16443 
  16444     rv = bcm_esw_stg_default_get(unit, &stg_defl);
  16445     if (rv >= 0) {
  16446         rv = bcm_esw_stg_stp_get(unit, stg_defl, port, stp_state);
  16447     } else if (rv == BCM_E_UNAVAIL) {   /* FABRIC switches, etc */
  16448         *stp_state = BCM_STG_STP_FORWARD;
  16449         rv = BCM_E_NONE;
  16450     }
  16451 
  16452     LOG_INFO(BSL_LS_BCM_PORT,
  16453              (BSL_META_U(unit,
  16454                          "bcm_port_stp_get: u=%d p=%d state=%d rv=%d\n"),
  16455               unit, port, *stp_state, rv));
  16456 
  16457     return rv;
  16458 }
  16459 
  16460 /*
  16461  * Function:
  16462  *      bcm_port_bpdu_enable_set
  16463  * Purpose:
  16464  *      Enable/Disable BPDU reception on the specified port.
  16465  * Parameters:
  16466  *      unit - SOC unit #
  16467  *      port - Port number (0 based)
  16468  *      enable - TRUE to enable, FALSE to disable (reject bpdu).
  16469  * Returns:
  16470  *      BCM_E_NONE
  16471  *      BCM_E_INTERNAL
  16472  */
  16473 
  16474 int
  16475 bcm_esw_port_bpdu_enable_set(int unit, bcm_port_t port, int enable)
  16476 {
  16477     bcm_port_cfg_t      pcfg;
  16478     int                 rv;
  16479 
  16480     /* Make sure port module is initialized. */
  16481     PORT_INIT(unit);
  16482 
  16483     if(bcm_common_oamp_port_enable_get(unit, port)) {
  16484         LOG_ERROR(BSL_LS_BCM_PORT,
  16485                   (BSL_META("Error: Cannot enable pbdu on OAMP Port %d.\n"),
  16486                    port));
  16487         return BCM_E_PARAM;
  16488     }
  16489 
  16490     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  16491 
  16492     PORT_LOCK(unit);
  16493 
  16494     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  16495 
  16496     if (BCM_SUCCESS(rv)) {
  16497         pcfg.pc_bpdu_disable = !enable;
  16498         rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg);
  16499     }
  16500 
  16501     PORT_UNLOCK(unit);
  16502 
  16503     return rv;
  16504 }
  16505 
  16506 /*
  16507  * Function:
  16508  *      bcm_port_bpdu_enable_get
  16509  * Purpose:
  16510  *      Return whether BPDU reception is enabled on the specified port.
  16511  * Parameters:
  16512  *      unit - SOC unit #
  16513  *      port - Port number (0 based)
  16514  *      enable - (OUT) TRUE if enabled, FALSE if disabled
  16515  * Returns:
  16516  *      BCM_E_NONE
  16517  *      BCM_E_INTERNAL
  16518  */
  16519 
  16520 int
  16521 bcm_esw_port_bpdu_enable_get(int unit, bcm_port_t port, int *enable)
  16522 {
  16523     bcm_port_cfg_t      pcfg;
  16524     int                 rv;
  16525 
  16526     /* Make sure port module is initialized. */
  16527     PORT_INIT(unit);
  16528 
  16529     if(bcm_common_oamp_port_enable_get(unit, port)) {
  16530         LOG_ERROR(BSL_LS_BCM_PORT,
  16531                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  16532                    port));
  16533         return BCM_E_PARAM;
  16534     }
  16535 
  16536     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  16537 
  16538     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  16539 
  16540     if (BCM_SUCCESS(rv)) {
  16541         *enable = !pcfg.pc_bpdu_disable;
  16542     }
  16543 
  16544     return rv;
  16545 }
  16546 
  16547 /*
  16548  * Function:
  16549  *      bcm_port_l3_enable_set
  16550  * Purpose:
  16551  *      Enable/Disable L3 switching on the specified port.
  16552  * Parameters:
  16553  *      unit -          device number
  16554  *      port -          port number
  16555  *      enable -        TRUE to enable, FALSE to disable.
  16556  * Returns:
  16557  *      BCM_E_XXX
  16558  */
  16559 
  16560 int
  16561 bcm_esw_port_l3_enable_set(int unit, bcm_port_t port, int enable)
  16562 {
  16563     int  rv = BCM_E_UNAVAIL;
  16564 #if defined(INCLUDE_L3)
  16565     bcm_port_cfg_t      pcfg;
  16566 
  16567     /* Make sure port module is initialized. */
  16568     PORT_INIT(unit);
  16569 
  16570     if(bcm_common_oamp_port_enable_get(unit, port)) {
  16571         LOG_ERROR(BSL_LS_BCM_PORT,
  16572                   (BSL_META("Error: Cannot enable l3 on OAMP Port %d.\n"),
  16573                    port));
  16574         return BCM_E_PARAM;
  16575     }
  16576 
  16577     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  16578 
  16579     PORT_LOCK(unit);
  16580 
  16581     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  16582 
  16583     if (BCM_SUCCESS(rv)) {
  16584         if (enable) {
  16585             pcfg.pc_l3_flags |= (BCM_PORT_L3_V4_ENABLE | BCM_PORT_L3_V6_ENABLE);
  16586         } else {
  16587             pcfg.pc_l3_flags &=
  16588                 ~(BCM_PORT_L3_V4_ENABLE | BCM_PORT_L3_V6_ENABLE);
  16589         }
  16590         rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg);
  16591     }
  16592 
  16593     PORT_UNLOCK(unit);
  16594 #endif /* INCLUDE_L3 */
  16595     return rv;
  16596 }
  16597 
  16598 /*
  16599  * Function:
  16600  *      bcm_port_l3_enable_get
  16601  * Purpose:
  16602  *      Return whether L3 switching is enabled on the specified port.
  16603  * Parameters:
  16604  *      unit -          device number
  16605  *      port -          port number
  16606  *      enable -        (OUT) TRUE if enabled, FALSE if disabled
  16607  * Returns:
  16608  *      BCM_E_XXX
  16609  */
  16610 
  16611 int
  16612 bcm_esw_port_l3_enable_get(int unit, bcm_port_t port, int *enable)
  16613 {
  16614     int  rv = BCM_E_UNAVAIL;
  16615 #if defined(INCLUDE_L3)
  16616     bcm_port_cfg_t      pcfg;
  16617 
  16618     /* Make sure port module is initialized. */
  16619     PORT_INIT(unit);
  16620 
  16621     if(bcm_common_oamp_port_enable_get(unit, port)) {
  16622         LOG_ERROR(BSL_LS_BCM_PORT,
  16623                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  16624                    port));
  16625         return BCM_E_PARAM;
  16626     }
  16627 
  16628     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  16629 
  16630     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  16631 
  16632     if (BCM_SUCCESS(rv)) {
  16633         *enable = ((pcfg.pc_l3_flags & BCM_PORT_L3_V4_ENABLE) ||
  16634                    (pcfg.pc_l3_flags & BCM_PORT_L3_V6_ENABLE));
  16635     }
  16636 #endif /* INCLUDE_L3 */
  16637 
  16638     return rv;
  16639 }
  16640 
  16641 /*
  16642  * Function:
  16643  *      bcm_port_tgid_get
  16644  * Purpose:
  16645  *      Get the trunk group for a given port.
  16646  * Parameters:
  16647  *      unit - SOC unit #
  16648  *      port - Port number (0 based)
  16649  *      tid - trunk ID
  16650  *      psc - trunk selection criterion
  16651  * Returns:
  16652  *      BCM_E_NONE
  16653  *      BCM_E_INTERNAL
  16654  */
  16655 
  16656 int
  16657 bcm_esw_port_tgid_get(int unit, bcm_port_t port, int *tid, int *psc)
  16658 {
  16659     bcm_port_cfg_t      pcfg;
  16660     int                 rv;
  16661 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  16662     soc_field_t tgid_fld = TGIDf;
  16663     if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, SRC_TGIDf)) {
  16664         tgid_fld = SRC_TGIDf;
  16665     }
  16666 #endif
  16667 
  16668     /* Make sure port module is initialized. */
  16669     PORT_INIT(unit);
  16670 
  16671     if(bcm_common_oamp_port_enable_get(unit, port)) {
  16672         LOG_ERROR(BSL_LS_BCM_PORT,
  16673                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  16674                    port));
  16675         return BCM_E_PARAM;
  16676     }
  16677 
  16678     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  16679 
  16680 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  16681     if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, tgid_fld)) {
  16682 #if defined(BCM_KATANA2_SUPPORT)
  16683         if (SOC_IS_KATANA2(unit)) {
  16684             rv = _bcm_kt2_trunk_table_read(unit, port, tid);
  16685         } else
  16686 #endif
  16687         {
  16688             rv = _bcm_xgs3_trunk_table_read(unit, port, tid);
  16689         }
  16690         if (BCM_SUCCESS(rv)) {
  16691             *psc = 0;
  16692         }
  16693         return rv;
  16694     }
  16695 #endif /* BCM_FIREBOLT_SUPPORT */
  16696 
  16697     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  16698 
  16699     if (BCM_SUCCESS(rv)) {
  16700         *tid = pcfg.pc_tgid;
  16701         *psc = 0;
  16702     }
  16703 
  16704     return rv;
  16705 
  16706 }
  16707 
  16708 /*
  16709  * Function:
  16710  *      bcm_port_tgid_set
  16711  * Purpose:
  16712  *      Set the trunk group for a given port.
  16713  * Parameters:
  16714  *      unit - SOC unit #
  16715  *      port - Port number (0 based)
  16716  *      tid - trunk ID
  16717  *      psc - trunk selection criterion
  16718  * Returns:
  16719  *      BCM_E_NONE
  16720  *      BCM_E_INTERNAL
  16721  */
  16722 
  16723 int
  16724 bcm_esw_port_tgid_set(int unit, bcm_port_t port, int tid, int psc)
  16725 {
  16726     bcm_port_cfg_t      pcfg;
  16727     int                 rv;
  16728 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  16729     soc_field_t tgid_fld = TGIDf;
  16730     if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, SRC_TGIDf)) {
  16731         tgid_fld = SRC_TGIDf;
  16732     }
  16733 #endif
  16734 
  16735     /* Make sure port module is initialized. */
  16736     PORT_INIT(unit);
  16737 
  16738     if(bcm_common_oamp_port_enable_get(unit, port)) {
  16739         LOG_ERROR(BSL_LS_BCM_PORT,
  16740                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  16741                    port));
  16742         return BCM_E_PARAM;
  16743     }
  16744 
  16745     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  16746 
  16747 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  16748     if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, tgid_fld)) {
  16749 #if defined(BCM_KATANA2_SUPPORT)
  16750         if (SOC_IS_KATANA2(unit)) {
  16751             return _bcm_kt2_trunk_table_write(unit, port, tid);
  16752         } else
  16753 #endif
  16754         {
  16755             return _bcm_xgs3_trunk_table_write(unit, port, tid);
  16756         }
  16757     }
  16758 #endif /* BCM_FIREBOLT_SUPPORT */
  16759 
  16760     PORT_LOCK(unit);
  16761 
  16762     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  16763 
  16764     if (BCM_SUCCESS(rv)) {
  16765         if (tid != BCM_TRUNK_INVALID) {
  16766             pcfg.pc_tgid = tid;
  16767             pcfg.pc_trunk = 1;
  16768         } else {
  16769             pcfg.pc_tgid = 0;
  16770             pcfg.pc_trunk = 0;
  16771         }
  16772         rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg);
  16773     }
  16774 
  16775     PORT_UNLOCK(unit);
  16776 
  16777     return rv;
  16778 }
  16779 
  16780 /*
  16781  * Function:
  16782  *      _bcm_port_mirror_enable_get (internal)
  16783  * Purpose:
  16784  *       Return whether mirroring is enabled on the specified port.
  16785  * Parameters:
  16786  *      unit   - (IN) BCM device number.
  16787  *      port   - (IN) Port number (0 based).
  16788  *      enable - (OUT) Bitmap of ingress mirror enabled.
  16789  * Returns:
  16790  *      BCM_E_NONE
  16791  *      BCM_E_INTERNAL
  16792  */
  16793 
  16794 int
  16795 _bcm_port_mirror_enable_get(int unit, bcm_port_t port, int *enable)
  16796 {
  16797     bcm_port_cfg_t      pcfg;
  16798     int                 rv;
  16799 
  16800     /* Input parameters check. */
  16801     if (NULL == enable) {
  16802         return (BCM_E_PARAM);
  16803     }
  16804 
  16805     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  16806 
  16807     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  16808 
  16809     if (BCM_SUCCESS(rv)) {
  16810         *enable = pcfg.pc_mirror_ing;
  16811     }
  16812 
  16813     return rv;
  16814 }
  16815 
  16816 /*
  16817  * Function:
  16818  *      _bcm_port_mirror_enable_set (internal)
  16819  * Purpose:
  16820  *       Enable/Disable mirroring for a given port.
  16821  * Parameters:
  16822  *      unit -   (IN) BCM unit #
  16823  *      port -   (IN) Port number (0 based)
  16824  *      enable - (IN) Bitmap of ingress mirror enabled.
  16825  * Returns:
  16826  *      BCM_E_NONE
  16827  *      BCM_E_INTERNAL
  16828  */
  16829 
  16830 int
  16831 _bcm_port_mirror_enable_set(int unit, bcm_port_t port, int enable)
  16832 {
  16833     bcm_port_cfg_t      pcfg;
  16834     int                 rv;
  16835 
  16836     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  16837 
  16838     PORT_LOCK(unit);
  16839 
  16840     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  16841 
  16842     if (BCM_SUCCESS(rv)) {
  16843         pcfg.pc_mirror_ing = enable;
  16844         rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg);
  16845     }
  16846 
  16847     PORT_UNLOCK(unit);
  16848 
  16849     return rv;
  16850 }
  16851 
  16852 #ifdef BCM_TRIUMPH2_SUPPORT
  16853 /*
  16854  * Function:
  16855  *      _bcm_port_mirror_egress_true_enable_get (internal)
  16856  * Purpose:
  16857  *       Return whether true egress mirroring is enabled on the
  16858  *       specified port.
  16859  * Parameters:
  16860  *      unit   - (IN) BCM device number.
  16861  *      port   - (IN) Port number (0 based).
  16862  *      enable - (OUT) Bitmap of true egress mirrors enabled.
  16863  * Returns:
  16864  *      BCM_E_NONE
  16865  *      BCM_E_INTERNAL
  16866  */
  16867 
  16868 int
  16869 _bcm_port_mirror_egress_true_enable_get(int unit, bcm_port_t port,
  16870                                         int *enable)
  16871 {
  16872     int     rv;
  16873 
  16874     /* Input parameters check. */
  16875     if (NULL == enable) {
  16876         return (BCM_E_PARAM);
  16877     }
  16878 
  16879 #if defined(BCM_TRIUMPH3_SUPPORT)
  16880     if (soc_feature(unit, soc_feature_ep_redirect) ||
  16881         soc_feature(unit, soc_feature_ep_redirect_v2)) {
  16882         egr_port_entry_t egr_port_entry;
  16883         int              ep_redirect_v2 = FALSE;
  16884 
  16885         rv = READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port,
  16886                             &egr_port_entry);
  16887 
  16888         /* Check if this device supports version 2 of redirect,
  16889            based on which we will access different fields below */
  16890         ep_redirect_v2 = soc_feature(unit, soc_feature_ep_redirect_v2);
  16891 
  16892         if (BCM_SUCCESS(rv)) {
  16893             if (SOC_EPT_REDIRECT_MIRROR ==
  16894                 soc_mem_field32_get(unit, EGR_PORTm, &egr_port_entry,
  16895                                     (ep_redirect_v2 ? ER_REDIR_DEST_TYPEf :
  16896                                      REDIRECTION_TYPEf))) {
  16897                 *enable = soc_mem_field32_get(unit, EGR_PORTm,
  16898                                              &egr_port_entry,
  16899                                              (ep_redirect_v2 ? ER_REDIR_DESTINATIONf :
  16900                                              REDIRECTION_DESTINATIONf));
  16901             } else {
  16902                 *enable = 0;
  16903             }
  16904         }
  16905     } else
  16906 #endif /* BCM_TRIUMPH3_SUPPORT */
  16907 
  16908     {
  16909         uint64 egr_val64;
  16910 
  16911         rv = READ_EGR_PORT_64r(unit, port, &egr_val64);
  16912         if (BCM_SUCCESS(rv)) {
  16913             *enable = soc_reg64_field32_get(unit, EGR_PORT_64r,
  16914                                             egr_val64, MIRRORf);
  16915         }
  16916     }
  16917 
  16918     return rv;
  16919 }
  16920 
  16921 /*
  16922  * Function:
  16923  *      _bcm_port_mirror_egress_true_enable_set (internal)
  16924  * Purpose:
  16925  *       Enable/Disable true egress mirroring for a given port.
  16926  * Parameters:
  16927  *      unit -   (IN) BCM unit #
  16928  *      port -   (IN) Port number (0 based)
  16929  *      enable - (IN) Bitmap of true egress mirrors enabled.
  16930  * Returns:
  16931  *      BCM_E_NONE
  16932  *      BCM_E_INTERNAL
  16933  */
  16934 
  16935 int
  16936 _bcm_port_mirror_egress_true_enable_set(int unit, bcm_port_t port,
  16937                                         int enable)
  16938 {
  16939     int  rv = BCM_E_NONE;
  16940 
  16941     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  16942 
  16943     PORT_LOCK(unit);
  16944 
  16945 #if defined(BCM_TRIUMPH3_SUPPORT)
  16946     if (soc_feature(unit, soc_feature_ep_redirect) ||
  16947         soc_feature(unit, soc_feature_ep_redirect_v2)) {
  16948 
  16949         uint32 egr_port_vals[2];
  16950         soc_field_t egr_port_fields[2];
  16951 
  16952         /* Based on if the device support version 2 of redirect,
  16953            select the appropriate fields */
  16954         if (soc_feature(unit, soc_feature_ep_redirect_v2)) {
  16955             egr_port_fields[0] = ER_REDIR_DEST_TYPEf;
  16956             egr_port_fields[1] = ER_REDIR_DESTINATIONf;
  16957         } else {
  16958             egr_port_fields[0] = REDIRECTION_TYPEf;
  16959             egr_port_fields[1] = REDIRECTION_DESTINATIONf;
  16960         }
  16961 
  16962         egr_port_vals[0] =
  16963             (0 != enable) ? SOC_EPT_REDIRECT_MIRROR : SOC_EPT_REDIRECT_NOOP;
  16964         egr_port_vals[1] = enable;
  16965 
  16966         /* Egress port table */
  16967         rv = soc_mem_fields32_modify(unit, EGR_PORTm, port, 2,
  16968                                      egr_port_fields, egr_port_vals);
  16969 
  16970         /* If ep-redirect-v2 also set the action, always-redirect vs do-not-redirect */
  16971         if(rv == BCM_E_NONE) {
  16972             if (soc_feature(unit, soc_feature_ep_redirect_v2)) {
  16973                 rv = soc_mem_field32_modify(unit, EGR_PORTm,
  16974                        port, ER_REDIR_ACTIONf,
  16975                        (enable ? _BCM_REDIRECT_ALWAYS : _BCM_REDIRECT_NONE));
  16976             }
  16977         }
  16978 
  16979     } else
  16980 #endif /* BCM_TRIUMPH3_SUPPORT */
  16981 
  16982     {
  16983         rv = soc_reg_field32_modify(unit, EGR_PORT_64r, port,
  16984                                     MIRRORf, enable);
  16985         if (BCM_SUCCESS(rv) && IS_HG_PORT(unit, port)) {
  16986             rv = soc_reg_field32_modify(unit, IEGR_PORT_64r, port,
  16987                                         MIRRORf, enable);
  16988         }
  16989     }
  16990 
  16991     PORT_UNLOCK(unit);
  16992     return rv;
  16993 }
  16994 #endif /* BCM_TRIUMPH2_SUPPORT */
  16995 
  16996 /*
  16997  * Function:
  16998  *      bcm_port_linkscan_get
  16999  * Purpose:
  17000  *      Get the link scan state of the port
  17001  * Parameters:
  17002  *      unit - StrataSwitch Unit #.
  17003  *      port - StrataSwitch port #.
  17004  *      linkscan - (OUT) Linkscan value (None, S/W, H/W)
  17005  * Returns:
  17006  *      BCM_E_NONE
  17007  *      BCM_E_XXX
  17008  */
  17009 
  17010 int
  17011 bcm_esw_port_linkscan_get(int unit, bcm_port_t port, int *linkscan)
  17012 {
  17013     /* Make sure port module is initialized. */
  17014     PORT_INIT(unit);
  17015 
  17016     return bcm_esw_linkscan_mode_get(unit, port, linkscan);
  17017 }
  17018 
  17019 /*
  17020  * Function:
  17021  *      bcm_port_linkscan_set
  17022  * Purpose:
  17023  *      Set the linkscan state for a given port
  17024  * Parameters:
  17025  *      unit - StrataSwitch Unit #.
  17026  *      port - StrataSwitch port #.
  17027  *      linkscan - Linkscan value (None, S/W, H/W)
  17028  * Returns:
  17029  *      BCM_E_NONE
  17030  *      BCM_E_XXX
  17031  */
  17032 
  17033 int
  17034 bcm_esw_port_linkscan_set(int unit, bcm_port_t port, int linkscan)
  17035 {
  17036     /* Make sure port module is initialized. */
  17037     PORT_INIT(unit);
  17038 
  17039     if(bcm_common_oamp_port_enable_get(unit, port)) {
  17040         LOG_ERROR(BSL_LS_BCM_PORT,
  17041                   (BSL_META("Error: Cannot enable linkscan on OAMP Port %d.\n"),
  17042                    port));
  17043         return BCM_E_PARAM;
  17044     }
  17045 
  17046     return bcm_esw_linkscan_mode_set(unit, port, linkscan);
  17047 }
  17048 
  17049 /*
  17050  * Function:
  17051  *      bcm_port_autoneg_get
  17052  * Purpose:
  17053  *      Get the autonegotiation state of the port
  17054  * Parameters:
  17055  *      unit - StrataSwitch Unit #.
  17056  *      port - StrataSwitch port #.
  17057  *      autoneg - (OUT) Boolean value
  17058  * Returns:
  17059  *      BCM_E_NONE
  17060  *      BCM_E_XXX
  17061  */
  17062 
  17063 int
  17064 bcm_esw_port_autoneg_get(int unit, bcm_port_t port, int *autoneg)
  17065 {
  17066     int           done=0, rv=BCM_E_NONE;
  17067     int           phy_lane = -1;
  17068     int           phyn = 0, sys_side = 0;
  17069     bcm_port_t    local_port = -1;
  17070 #if defined(BCM_KATANA2_SUPPORT)
  17071     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  17072 #endif
  17073 
  17074     /* Make sure port module is initialized. */
  17075     PORT_INIT(unit);
  17076 
  17077     if (SOC_USE_PORTCTRL(unit)) {
  17078         return bcmi_esw_portctrl_autoneg_get(unit, port, autoneg);
  17079     }
  17080 
  17081 #if defined(BCM_KATANA2_SUPPORT)
  17082 #if defined(BCM_SABER2_SUPPORT)
  17083     if(SOC_IS_SABER2(unit)) {
  17084         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  17085     }
  17086 #endif
  17087     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  17088         (!((port >= 1) && (port <= max_phy_port)))) {
  17089          return BCM_E_PORT;
  17090     }
  17091 #endif
  17092 
  17093     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_phyn_validate(unit, port,
  17094                          &local_port, &phyn, &phy_lane, &sys_side));
  17095 
  17096     if (local_port == -1) {
  17097        BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17098     }
  17099 
  17100     PORT_LOCK(unit);
  17101     if (local_port == -1) {
  17102         rv = soc_phyctrl_auto_negotiate_get(unit, port, autoneg, &done);
  17103     } else {
  17104         rv = soc_phyctrl_redirect_auto_negotiate_get(unit, local_port, phyn,
  17105                                                      phy_lane, sys_side,
  17106                                                      autoneg, &done);
  17107     }
  17108     PORT_UNLOCK(unit);
  17109     LOG_INFO(BSL_LS_BCM_PORT,
  17110              (BSL_META_U(unit,
  17111                          "bcm_port_autoneg_get: u=%d p=%d an=%d done=%d rv=%d\n"),
  17112               unit, port, *autoneg, done, rv));
  17113 
  17114     return rv;
  17115 }
  17116 
  17117 /*
  17118  * Function:
  17119  *      bcm_port_autoneg_set
  17120  * Purpose:
  17121  *      Set the autonegotiation state for a given port
  17122  * Parameters:
  17123  *      unit - StrataSwitch Unit #.
  17124  *      port - StrataSwitch port #.
  17125  *      autoneg - Boolean value
  17126  * Returns:
  17127  *      BCM_E_NONE
  17128  *      BCM_E_XXX
  17129  */
  17130 
  17131 int
  17132 bcm_esw_port_autoneg_set(int unit, bcm_port_t port, int autoneg)
  17133 {
  17134     int           rv=BCM_E_NONE;
  17135     int           phy_lane = -1;
  17136     int           phyn = 0, sys_side = 0;
  17137     bcm_port_t    local_port = -1;
  17138    
  17139 #if defined(BCM_SABER2_SUPPORT)
  17140     int             phy_status;
  17141 #endif
  17142 #if defined(BCM_KATANA2_SUPPORT)
  17143     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  17144 #endif
  17145 
  17146     /* Make sure port module is initialized. */
  17147     PORT_INIT(unit);
  17148 
  17149     if (SOC_USE_PORTCTRL(unit)) {
  17150         return bcmi_esw_portctrl_autoneg_set(unit, port, autoneg);
  17151     }
  17152 
  17153     if(bcm_common_oamp_port_enable_get(unit, port)) {
  17154         LOG_ERROR(BSL_LS_BCM_PORT,
  17155                   (BSL_META("Error: Cannot set autoneg on OAMP Port %d.\n"),
  17156                    port));
  17157         return BCM_E_PARAM;
  17158     }
  17159 
  17160 #if defined(BCM_KATANA2_SUPPORT)
  17161 #if defined(BCM_SABER2_SUPPORT)
  17162     if(SOC_IS_SABER2(unit)) {
  17163         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  17164     }
  17165 #endif
  17166     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  17167         (!((port >= 1) && (port <= max_phy_port)))) {
  17168          return BCM_E_PORT;
  17169     }
  17170 #endif
  17171 #ifdef BCM_RCPU_SUPPORT
  17172     if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
  17173         return BCM_E_PORT;
  17174     }
  17175 #endif /* BCM_RCPU_SUPPORT */
  17176 
  17177     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_phyn_validate(unit, port,
  17178                          &local_port, &phyn, &phy_lane, &sys_side));
  17179 
  17180     if (local_port == -1) {
  17181        BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17182     }
  17183 
  17184     PORT_LOCK(unit);
  17185 
  17186 #if defined(BCM_SABER2_SUPPORT)
  17187     if(SOC_IS_SABER2(unit) && IS_XL_PORT(unit, port)) {
  17188         rv = soc_phyctrl_enable_get(unit, port, &phy_status);
  17189         if (BCM_FAILURE(rv)) {
  17190             PORT_UNLOCK(unit);
  17191             return (rv);
  17192         }
  17193         if(phy_status == TRUE) {
  17194             rv = soc_phyctrl_enable_set(unit, port, FALSE);
  17195             if (BCM_FAILURE(rv)) {
  17196                 PORT_UNLOCK(unit);
  17197                 return (rv);
  17198             }
  17199         }
  17200     }
  17201 #endif
  17202 
  17203 #ifdef SW_AUTONEG_SUPPORT
  17204     if (soc_feature(unit, soc_feature_sw_autoneg)) {
  17205 
  17206         int           an_mode = 0; 
  17207 
  17208         an_mode = soc_property_port_get(unit, port,
  17209                           spn_PHY_AN_C73, an_mode);
  17210 
  17211         /* phy_an_c73 value of 3 indicated MSA AN mode */
  17212         if ((an_mode == SW_AN_MODE_CL73_MSA) ||
  17213             (an_mode == SW_AN_MODE_MSA_ONLY)) {
  17214             if (autoneg) {
  17215                 rv = bcm_sw_an_port_register(unit, port);
  17216                 if (rv == BCM_E_NONE) {
  17217                     PORT_UNLOCK(unit);
  17218                     return rv;    
  17219                 } else if (rv == BCM_E_PORT) {
  17220                     /* when an_set is called during the init 
  17221                      * ports wouldn't have been added to SW AN
  17222                      */
  17223                     rv = BCM_E_NONE;
  17224                     PORT_UNLOCK(unit);
  17225                     return rv;
  17226                 } else {
  17227                     /* add bsl log */
  17228                     PORT_UNLOCK(unit);
  17229                     return rv;    
  17230                 }
  17231                 
  17232             } else {
  17233                 rv = bcm_sw_an_port_unregister(unit, port);
  17234                 if (rv == BCM_E_NONE) {
  17235                     PORT_UNLOCK(unit);
  17236                     return rv;    
  17237                 } else if (rv == BCM_E_PORT) {
  17238                     /* when an_set is called during the init 
  17239                      * ports wouldn't have been added to SW AN
  17240                      */
  17241                     rv = BCM_E_NONE;
  17242                     PORT_UNLOCK(unit);
  17243                     return rv;
  17244                 } else {
  17245                     /* add bsl log */
  17246                     PORT_UNLOCK(unit);
  17247                     return rv;     
  17248                 }
  17249             }
  17250         }
  17251     }
  17252 #endif  
  17253 
  17254     if (local_port == -1) {
  17255        rv = soc_phyctrl_auto_negotiate_set(unit, port, autoneg);
  17256     } else {
  17257        rv = soc_phyctrl_redirect_auto_negotiate_set(unit, local_port, phyn,
  17258                                                     phy_lane, sys_side, autoneg);
  17259     }
  17260 
  17261 #if defined(BCM_SABER2_SUPPORT)
  17262     if(SOC_IS_SABER2(unit) &&
  17263             IS_XL_PORT(unit, port) && (phy_status == TRUE)) {
  17264         /* Enable phy in tsc only if already enabled before config change */
  17265         rv = soc_phyctrl_enable_set(unit, port, TRUE);
  17266         if (BCM_FAILURE(rv)) {
  17267             PORT_UNLOCK(unit);
  17268             return (rv);
  17269         }
  17270     }
  17271 #endif
  17272 
  17273 #if defined(BCM_XMAC_SUPPORT)
  17274    if(SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) ||
  17275       SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
  17276       uint32 vco_disturbed = 0;
  17277       phy_ctrl_t *int_pc, *ext_pc;
  17278       ext_pc = EXT_PHY_SW_STATE(unit, port);
  17279        if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) ||
  17280                    IS_XE_PORT(unit, port)) && (ext_pc == NULL)) {
  17281            int_pc = INT_PHY_SW_STATE(unit, port);
  17282            rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed);
  17283            if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) {
  17284                PORT_UNLOCK(unit);
  17285                return rv;
  17286            }
  17287            if (vco_disturbed) {
  17288                rv = _mac_x_reinit(unit, port);
  17289                if (BCM_FAILURE(rv)) {
  17290                    PORT_UNLOCK(unit);
  17291                    return rv;
  17292                }
  17293            }
  17294        }
  17295    }
  17296 #endif
  17297     PORT_UNLOCK(unit);
  17298 
  17299     LOG_INFO(BSL_LS_BCM_PORT,
  17300              (BSL_META_U(unit,
  17301                          "bcm_port_autoneg_set: u=%d p=%d an=%d rv=%d\n"),
  17302               unit, port, autoneg, rv));
  17303 
  17304     return rv;
  17305 }
  17306 
  17307 /*
  17308  * Function:
  17309  *      bcm_port_speed_get
  17310  * Purpose:
  17311  *      Getting the speed of the port
  17312  * Parameters:
  17313  *      unit - StrataSwitch Unit #.
  17314  *      port - StrataSwitch port #.
  17315  *      speed - (OUT) Value in megabits/sec (10, 100, etc)
  17316  * Returns:
  17317  *      BCM_E_NONE
  17318  *      BCM_E_XXX
  17319  * Notes:
  17320  *      If port is in MAC loopback, the speed of the loopback is returned.
  17321  */
  17322 
  17323 int
  17324 bcm_esw_port_speed_get(int unit, bcm_port_t port, int *speed)
  17325 {
  17326     int         rv = BCM_E_NONE;
  17327     int         mac_lb;
  17328     int         max_speed;
  17329 #if defined(BCM_KATANA2_SUPPORT)
  17330     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  17331 #endif
  17332 
  17333     /* Make sure port module is initialized. */
  17334     PORT_INIT(unit);
  17335 
  17336     /* Check for PortMod */
  17337     if ((SOC_USE_PORTCTRL(unit)) && (port != CMIC_PORT(unit))) {
  17338         return bcmi_esw_portctrl_speed_get(unit, port, speed);
  17339     }
  17340 
  17341 #if defined(BCM_KATANA2_SUPPORT)
  17342 #if defined(BCM_SABER2_SUPPORT)
  17343     if(SOC_IS_SABER2(unit)) {
  17344         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  17345     }
  17346 #endif
  17347     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  17348         (!((port >= 1) && (port <= max_phy_port) &&
  17349          SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit),port)))) {
  17350           return BCM_E_PORT;
  17351     }
  17352 #endif
  17353 
  17354     if(bcm_common_oamp_port_enable_get(unit, port)) {
  17355         LOG_ERROR(BSL_LS_BCM_PORT,
  17356                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  17357                    port));
  17358         return BCM_E_PARAM;
  17359     }
  17360 
  17361     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17362 
  17363     PORT_LOCK(unit);
  17364 
  17365     rv = MAC_LOOPBACK_GET(PORT(unit, port).p_mac, unit, port, &mac_lb);
  17366 
  17367     if (BCM_SUCCESS(rv)) {
  17368         if (mac_lb) {
  17369             rv = MAC_SPEED_GET(PORT(unit, port).p_mac, unit, port, speed);
  17370         } else {
  17371             rv = soc_phyctrl_speed_get(unit, port, speed);
  17372 
  17373             if (BCM_E_UNAVAIL == rv) {
  17374                 /* PHY driver doesn't support speed_get. Get the speed from
  17375                  * MAC.
  17376                  */
  17377                 rv = MAC_SPEED_GET(PORT(unit, port).p_mac, unit, port, speed);
  17378             }
  17379             if ((IS_HG_PORT(unit, port) && *speed < 5000) && !(IS_HL_PORT(unit,port))) { 
  17380                 *speed = 0;
  17381             }
  17382             if (soc_feature(unit, soc_feature_port_encap_speed_max_config)) {
  17383                 rv = bcm_esw_port_speed_max(unit, port, &max_speed);
  17384                 if (BCM_FAILURE(rv)) {
  17385                     PORT_UNLOCK(unit);
  17386                     return (rv);
  17387                 }
  17388                 if (*speed > max_speed) {
  17389                     *speed = max_speed;
  17390                 }
  17391             }
  17392         }
  17393     }
  17394 
  17395     PORT_UNLOCK(unit);
  17396 
  17397     LOG_INFO(BSL_LS_BCM_PORT,
  17398              (BSL_META_U(unit,
  17399                          "bcm_port_speed_get: u=%d p=%d speed=%d rv=%d\n"),
  17400               unit, port, BCM_SUCCESS(rv) ? *speed : 0, rv));
  17401 
  17402     return rv;
  17403 }
  17404 
  17405 /*
  17406  * Function:
  17407  *      bcm_port_speed_max
  17408  * Purpose:
  17409  *      Getting the maximum speed of the port
  17410  * Parameters:
  17411  *      unit - StrataSwitch Unit #.
  17412  *      port - StrataSwitch port #.
  17413  *      speed - (OUT) Value in megabits/sec (10, 100, etc)
  17414  * Returns:
  17415  *      BCM_E_NONE
  17416  *      BCM_E_XXX
  17417  */
  17418 
  17419 int
  17420 bcm_esw_port_speed_max(int unit, bcm_port_t port, int *speed)
  17421 {
  17422     bcm_port_ability_t  ability, phy_ability;
  17423     int                 rv;
  17424     int                 phy_speed;
  17425 #if defined(BCM_KATANA2_SUPPORT)
  17426     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  17427 #endif
  17428 
  17429     if (NULL == speed) {
  17430         return (BCM_E_PARAM);
  17431     }
  17432 
  17433     /* Make sure port module is initialized. */
  17434     PORT_INIT(unit);
  17435 
  17436 
  17437     /* Check for PortMod */
  17438     if (SOC_USE_PORTCTRL(unit)) {
  17439         return bcmi_esw_portctrl_speed_max(unit, port, speed);
  17440     }
  17441 
  17442 #if defined(BCM_KATANA2_SUPPORT)
  17443 #if defined(BCM_SABER2_SUPPORT)
  17444     if(SOC_IS_SABER2(unit)) {
  17445         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  17446     }
  17447 #endif
  17448     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  17449         (!((port >= 1) && (port <= max_phy_port)))) {
  17450          return BCM_E_PORT;
  17451     }
  17452 #endif
  17453 
  17454     if(bcm_common_oamp_port_enable_get(unit, port)) {
  17455         LOG_ERROR(BSL_LS_BCM_PORT,
  17456                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  17457                    port));
  17458         return BCM_E_PARAM;
  17459     }
  17460 
  17461 
  17462     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17463     rv = bcm_esw_port_ability_local_get(unit, port, &ability);
  17464 
  17465     if (BCM_SUCCESS(rv)) {
  17466 
  17467         *speed = BCM_PORT_ABILITY_SPEED_MAX(ability.speed_full_duplex |
  17468                                             ability.speed_half_duplex);
  17469 
  17470         if (10000 == *speed) {
  17471             if (IS_HG_PORT(unit, port) && SOC_INFO(unit).port_speed_max[port]) {
  17472                 *speed = SOC_INFO(unit).port_speed_max[port];
  17473                 /* Retrieving the internal PHY ability */
  17474                 rv = soc_phyctrl_ability_local_get(unit, port, &phy_ability);
  17475                 if (BCM_SUCCESS(rv)) {
  17476                     /* considering the common supported speed among phy and mac */
  17477                     phy_speed = BCM_PORT_ABILITY_SPEED_MAX(
  17478                                              phy_ability.speed_full_duplex |
  17479                                              phy_ability.speed_half_duplex);
  17480                     *speed = (*speed > phy_speed) ? phy_speed : *speed;
  17481                 } else {
  17482                     *speed = 0;
  17483                 }
  17484             }
  17485         }
  17486     } else {
  17487         *speed = 0;
  17488     }
  17489 
  17490     LOG_INFO(BSL_LS_BCM_PORT,
  17491              (BSL_META_U(unit,
  17492                          "bcm_port_speed_max: u=%d p=%d speed=%d rv=%d\n"),
  17493               unit, port, *speed, rv));
  17494 
  17495     return rv;
  17496 }
  17497 
  17498 /*
  17499  * Function    : _bcm_port_speed_supported
  17500  * Description : Determine whether port speed is supported based on
  17501  *               number of lanes configured
  17502  * Parameters  : unit  (IN)
  17503  *               port  (IN)
  17504  *               speed (IN)
  17505  * Returns     : BCM_E_XXX
  17506  * Note        : Caller needs to ensure soc_feature_flexport_based_speed_set
  17507  *               is defined
  17508  */
  17509 STATIC bcm_error_t
  17510 _bcm_port_speed_supported(int unit, bcm_port_t port, int speed)
  17511 {
  17512 #ifdef BCM_TOMAHAWK_SUPPORT
  17513     if (SOC_IS_TOMAHAWKX(unit)) {
  17514         BCM_IF_ERROR_RETURN(_bcm_th_port_speed_supported(unit, port, speed));
  17515     }
  17516 #endif
  17517     return BCM_E_NONE;
  17518 }
  17519 
  17520 /*
  17521  * Function:
  17522  *      _bcm_port_speed_set
  17523  * Purpose:
  17524  *      Main part of bcm_port_speed_set.
  17525  */
  17526 
  17527 STATIC int
  17528 _bcm_port_speed_set(int unit, bcm_port_t port, int speed)
  17529 {
  17530     int             phy_lb, rv, enable;
  17531     int             mac_lb;
  17532     int             ignore_ability_check = FALSE;
  17533     bcm_port_ability_t mac_ability, phy_ability, requested_ability;
  17534 #if defined(BCM_SABER2_SUPPORT)
  17535     int             phy_status;
  17536 #endif
  17537 
  17538 #if defined(BCM_TOMAHAWK_SUPPORT)
  17539     int             cur_speed;
  17540 #endif
  17541 #if defined(BCM_KATANA2_SUPPORT)
  17542     bcmMxqPhyPortMode_t phy_mode = bcmMxqPhyPortModeQuad;
  17543 #endif
  17544 
  17545 
  17546     if (SOC_USE_PORTCTRL(unit)) {
  17547         return bcmi_esw_portctrl_speed_set(unit, port, speed);
  17548     }
  17549 
  17550     if(bcm_common_oamp_port_enable_get(unit, port)) {
  17551         LOG_ERROR(BSL_LS_BCM_PORT,
  17552                   (BSL_META("Error: Cannot set speed on OAMP Port %d.\n"),
  17553                    port));
  17554         return BCM_E_PARAM;
  17555     }
  17556 
  17557     sal_memset(&mac_ability, 0, sizeof(bcm_port_ability_t));
  17558     sal_memset(&phy_ability, 0, sizeof(bcm_port_ability_t));
  17559     sal_memset(&requested_ability, 0, sizeof(bcm_port_ability_t));
  17560 
  17561     /*
  17562      * If port is in MAC loopback mode, do not try setting the PHY
  17563      * speed.  This allows MAC loopback at 10/100 even if the PHY is
  17564      * 1000 only.  Loopback diagnostic tests should enable loopback
  17565      * before setting the speed, and vice versa when cleaning up.
  17566      */
  17567 
  17568     SOC_IF_ERROR_RETURN
  17569         (MAC_LOOPBACK_GET(PORT(unit, port).p_mac, unit, port, &mac_lb));
  17570 
  17571     if (speed == 0) {
  17572         /* if speed is 0, set the port speed to max */
  17573         SOC_IF_ERROR_RETURN
  17574             (bcm_esw_port_speed_max(unit, port, &speed));
  17575     }
  17576 
  17577     /* Make sure MAC can handle the requested speed. */
  17578     SOC_IF_ERROR_RETURN
  17579         (MAC_ABILITY_LOCAL_GET(PORT(unit, port).p_mac, unit, port,
  17580                                &mac_ability));
  17581     requested_ability.speed_full_duplex = SOC_PA_SPEED(speed);
  17582     requested_ability.speed_half_duplex = SOC_PA_SPEED(speed);
  17583     LOG_INFO(BSL_LS_BCM_PHY,
  17584              (BSL_META_U(unit,
  17585                          "_bcm_port_speed_set: u=%u p=%d "
  17586                          "MAC FD speed %08X MAC HD speed %08X "
  17587                          "Requested FD Speed %08X Requested HD Speed %08X\n"),
  17588               unit,
  17589               port,
  17590               mac_ability.speed_full_duplex,
  17591               mac_ability.speed_half_duplex,
  17592               requested_ability.speed_full_duplex,
  17593               requested_ability.speed_half_duplex));
  17594     /*
  17595      * On certain devices such as TH speed set is a flexport operation,
  17596      * due to changes needed to the calendar. This is not applicable to
  17597      * mgmt ports on TH as they are guranteed a fixed amount of BW in the
  17598      * calendar.
  17599      */
  17600     if ((soc_feature(unit, soc_feature_flexport_based_speed_set)) &&
  17601         !SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), port)) {
  17602             rv = _bcm_port_speed_supported(unit, port, speed);
  17603             if (BCM_SUCCESS(rv)) {
  17604                 ignore_ability_check = TRUE;
  17605             }
  17606     }
  17607 
  17608 #if defined(BCM_TOMAHAWK_SUPPORT)
  17609     if (SOC_IS_TOMAHAWK(unit)) {
  17610         int encap;
  17611         BCM_IF_ERROR_RETURN(bcm_esw_port_encap_get(unit, port, &encap));
  17612 
  17613         if (IS_HG2_SPEED(speed) && (encap == BCM_PORT_ENCAP_IEEE)) {
  17614             LOG_ERROR(BSL_LS_BCM_PORT,
  17615                   (BSL_META_U(unit,
  17616                               "Speed and encapsulation configuration unmatch "
  17617                               "for port=%d, speed=%d, encap=%d\n"),
  17618                    port, speed, encap));
  17619             return BCM_E_CONFIG;
  17620         }
  17621     }
  17622 #endif
  17623 
  17624     if (((mac_ability.speed_full_duplex &
  17625           requested_ability.speed_full_duplex) == 0) &&
  17626         ((mac_ability.speed_half_duplex &
  17627           requested_ability.speed_half_duplex) == 0) &&
  17628         !ignore_ability_check) {
  17629         LOG_ERROR(BSL_LS_BCM_PORT,
  17630                     (BSL_META_U(unit,
  17631                                 "u=%d p=%d MAC doesn't support %d Mbps speed.\n"),
  17632                      unit, port, speed));
  17633         return SOC_E_CONFIG;
  17634     }
  17635     SOC_IF_ERROR_RETURN
  17636         (soc_phyctrl_ability_local_get(unit, port, &phy_ability));
  17637 
  17638     if (((phy_ability.speed_full_duplex &
  17639           requested_ability.speed_full_duplex) == 0) &&
  17640         ((phy_ability.speed_half_duplex &
  17641           requested_ability.speed_half_duplex) == 0) &&
  17642         !ignore_ability_check) {
  17643             LOG_VERBOSE(BSL_LS_BCM_PORT,
  17644                         (BSL_META_U(unit,
  17645                                     "u=%d p=%d PHY doesn't support %d Mbps speed.\n"),
  17646                          unit, port, speed));
  17647             return SOC_E_CONFIG;
  17648     } else {
  17649 
  17650 #if defined(BCM_SABER2_SUPPORT)
  17651         if(SOC_IS_SABER2(unit) && IS_XL_PORT(unit, port)) {
  17652             BCM_IF_ERROR_RETURN(soc_phyctrl_enable_get(unit, port, &phy_status));
  17653             if(phy_status == TRUE) {
  17654                 BCM_IF_ERROR_RETURN(soc_phyctrl_enable_set(unit, port, FALSE));
  17655             }
  17656         }
  17657 #endif
  17658 
  17659 #if defined(BCM_TOMAHAWK_SUPPORT)
  17660         if (SOC_IS_TOMAHAWKX(unit)) {
  17661             SOC_IF_ERROR_RETURN
  17662                 (soc_phyctrl_speed_get(unit, port, &cur_speed));
  17663         }
  17664 #endif
  17665 #if defined(BCM_KATANA2_SUPPORT)
  17666         if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) {
  17667             SOC_IF_ERROR_RETURN
  17668                 (soc_katana2_get_phy_port_mode(unit, port, speed, &phy_mode));
  17669         }
  17670 #endif
  17671         SOC_IF_ERROR_RETURN
  17672             (soc_phyctrl_auto_negotiate_set(unit, port, FALSE));
  17673         SOC_IF_ERROR_RETURN
  17674             (soc_phyctrl_speed_set(unit, port, speed));
  17675 
  17676 #if defined(BCM_SABER2_SUPPORT)
  17677         if(SOC_IS_SABER2(unit) &&
  17678                 IS_XL_PORT(unit, port) && (phy_status == TRUE)) {
  17679             /* Enable phy in tsc only if already enabled before config change */
  17680             BCM_IF_ERROR_RETURN(soc_phyctrl_enable_set(unit, port, TRUE));
  17681         }
  17682 #endif
  17683 
  17684 #if defined(BCM_XMAC_SUPPORT)
  17685         if (SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) ||
  17686             SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
  17687             uint32 vco_disturbed = 0;
  17688             phy_ctrl_t *int_pc, *ext_pc;
  17689             ext_pc = EXT_PHY_SW_STATE(unit, port);
  17690             if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) ||
  17691                         IS_XE_PORT(unit, port)) && (ext_pc == NULL)) {
  17692 
  17693                 int_pc = INT_PHY_SW_STATE(unit, port);
  17694                 rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed);
  17695                 if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) {
  17696                     return rv;
  17697                 }
  17698                 if (vco_disturbed) {
  17699                     BCM_IF_ERROR_RETURN(_mac_x_reinit(unit, port));
  17700                 }
  17701             }
  17702         }
  17703 #endif
  17704     }
  17705 
  17706     /* TSC needs no legacy war */
  17707     if (!SOC_IS_TD2_TT2(unit)) {
  17708        /* Prevent PHY register access while resetting BigMAC and Fusion core */
  17709        if (IS_HG_PORT(unit, port)) {
  17710           soc_phyctrl_enable_get(unit, port, &enable);
  17711           soc_phyctrl_enable_set(unit, port, 0);
  17712           soc_phyctrl_loopback_get(unit, port, &phy_lb);
  17713        }
  17714     }
  17715     if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
  17716         BCM_IF_ERROR_RETURN(_bcm_td_port_mode_update(unit, port, speed));
  17717     }
  17718 
  17719 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  17720     /* Reconfigure chip(PGW/TDM/IP/EP/MMU) for speed set change */
  17721     if (BCM_ESW_PORT_DRV(unit)!= NULL) {
  17722         if (BCM_ESW_PORT_DRV(unit)->resource_speed_set != NULL) {
  17723             rv = BCM_ESW_PORT_DRV(unit)->resource_speed_set(unit, port, speed);
  17724             if (BCM_FAILURE(rv)) {
  17725                 LOG_VERBOSE(BSL_LS_BCM_PORT,
  17726                             (BSL_META_UP(unit, port,
  17727                                          "resource_speed_set failed: %s\n"),
  17728                                          bcm_errmsg(rv)));
  17729                 return rv;
  17730             }
  17731         }
  17732     }
  17733 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT*/
  17734 
  17735     rv = MAC_SPEED_SET(PORT(unit, port).p_mac, unit, port, speed);
  17736     if (BCM_FAILURE(rv)) {
  17737 #if defined(BCM_TOMAHAWK_SUPPORT)
  17738         if (SOC_IS_TOMAHAWKX(unit)) {
  17739             /* Restore phy's speed state based on what was read periously */
  17740             SOC_IF_ERROR_RETURN
  17741                 (soc_phyctrl_speed_set(unit, port, cur_speed));
  17742         }
  17743 #endif
  17744 
  17745         LOG_VERBOSE(BSL_LS_BCM_PORT,
  17746                     (BSL_META_U(unit,
  17747                                 "MAC_SPEED_SET failed: %s\n"), bcm_errmsg(rv)));
  17748     }
  17749 
  17750 if (!SOC_IS_MONTEREY(unit)) {
  17751     /* TSC needs no legacy war */
  17752     if (!SOC_IS_TD2_TT2(unit)) {
  17753        /* Restore PHY register access */
  17754        if (IS_HG_PORT(unit, port)) {
  17755           soc_phyctrl_enable_set(unit, port, enable);
  17756           soc_phyctrl_loopback_set(unit, port, phy_lb, TRUE);
  17757        }
  17758     }
  17759 }
  17760 
  17761     return rv;
  17762 }
  17763 
  17764 /*
  17765  * Function:
  17766  *      bcm_port_speed_set
  17767  * Purpose:
  17768  *      Setting the speed for a given port
  17769  * Parameters:
  17770  *      unit - StrataSwitch Unit #.
  17771  *      port - StrataSwitch port #.
  17772  *      speed - Value in megabits/sec (10, 100, etc)
  17773  * Returns:
  17774  *      BCM_E_NONE
  17775  *      BCM_E_XXX
  17776  * Notes:
  17777  *      Turns off autonegotiation.  Caller must make sure other forced
  17778  *      parameters (such as duplex) are set.
  17779  */
  17780 
  17781 int
  17782 bcm_esw_port_speed_set(int unit, bcm_port_t port, int speed)
  17783 {
  17784     int    rv=BCM_E_NONE, max_speed, enable;
  17785     pbmp_t pbm;
  17786     int    curr_speed = 0;
  17787     bcm_port_if_t curr_intf = 0;
  17788 #if defined(BCM_KATANA2_SUPPORT)
  17789     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  17790 #endif
  17791 
  17792 #if defined(BCM_PORT_SPEED_CHANGE_BENCHMARK)
  17793     sal_usecs_t time_start = 0;
  17794     sal_usecs_t time_end = 0;
  17795 #endif
  17796 
  17797     /* Make sure port module is initialized. */
  17798     PORT_INIT(unit);
  17799 
  17800 #if defined(BCM_TOMAHAWK3_SUPPORT)
  17801     /* Don't allow PM8x50 to do bcm_port_speed_set */
  17802     if (SOC_IS_TOMAHAWK3(unit) && IS_CD_PORT(unit, port)) {
  17803         return BCM_E_UNAVAIL;
  17804     }
  17805 #endif
  17806 
  17807     if(bcm_common_oamp_port_enable_get(unit, port)) {
  17808         LOG_ERROR(BSL_LS_BCM_PORT,
  17809                   (BSL_META("Error: Cannot set speed on OAMP Port %d.\n"),
  17810                    port));
  17811         return BCM_E_PARAM;
  17812     }
  17813 
  17814 #if defined(BCM_PORT_SPEED_CHANGE_BENCHMARK)
  17815     time_start = sal_time_usecs();
  17816 #endif
  17817 
  17818 #if defined(BCM_KATANA2_SUPPORT)
  17819 #if defined(BCM_SABER2_SUPPORT)
  17820     if(SOC_IS_SABER2(unit)) {
  17821         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  17822     }
  17823 #endif
  17824     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  17825         (!((port >= 1) && (port <= max_phy_port)))) {
  17826          return BCM_E_PORT;
  17827     }
  17828 #endif
  17829     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17830 
  17831     if (soc_property_get(unit, spn_SAME_SPEED_INTF_DO_NOT_OVERWRITE,
  17832                          (SAL_BOOT_BCMSIM || SAL_BOOT_XGSSIM))) {
  17833         BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &curr_speed));
  17834         BCM_IF_ERROR_RETURN(bcm_esw_port_interface_get(unit, port, &curr_intf));
  17835         if((speed == curr_speed) && (PORT(unit, port).intf == curr_intf)) {
  17836 #if defined(BCM_PORT_SPEED_CHANGE_BENCHMARK)
  17837             time_end = SAL_USECS_SUB(sal_time_usecs(), time_start);
  17838             LOG_INFO(BSL_LS_BCM_BENCHMARK,
  17839                     (BSL_META_U(unit,
  17840                                 "\nPort %d speed change to %d processing took %d usecs\n"),
  17841                                 port,
  17842                                 speed,
  17843                                 time_end));
  17844 #endif
  17845             return BCM_E_NONE;
  17846         }
  17847     }
  17848 
  17849 #ifdef BCM_RCPU_SUPPORT
  17850     if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
  17851         return BCM_E_PORT;
  17852     }
  17853 #endif /* BCM_RCPU_SUPPORT */
  17854 
  17855     /*    coverity[uninit_use_in_call : FALSE]    */
  17856     BCM_IF_ERROR_RETURN
  17857         (bcm_esw_port_speed_max(unit,port, &max_speed));
  17858 
  17859     if (IS_XL_PORT(unit,port) && (speed == 12700)) {
  17860         speed = 13000;
  17861     }
  17862 
  17863     if ((speed < 0) || (speed > max_speed)) {
  17864         if ((speed > max_speed) &&
  17865             !soc_feature(unit, soc_feature_flexport_based_speed_set))
  17866         return BCM_E_CONFIG; 
  17867     }
  17868 
  17869 #if defined(BCM_TOMAHAWK_SUPPORT)
  17870     if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3(unit)) {
  17871         int cur_speed;
  17872 
  17873         BCM_IF_ERROR_RETURN
  17874             (bcm_esw_port_speed_get(unit, port, &cur_speed));
  17875         if ((speed == 0) && (max_speed == cur_speed)) {
  17876             /* no speed set is required */
  17877             return BCM_E_NONE;
  17878         }
  17879     }
  17880 #endif /* BCM_TOMAHAWK_SUPPORT */
  17881 
  17882     /*
  17883      * When performing flexport based speed changes, disable port
  17884      * first prior to affecting speed change
  17885      */
  17886     if (soc_feature(unit, soc_feature_flexport_based_speed_set) &&
  17887         !SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), port) &&
  17888         !SOC_USE_PORTCTRL(unit)) {
  17889         BCM_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &enable));
  17890         if (TRUE == enable) {
  17891             BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, port, FALSE));
  17892         }
  17893     }
  17894 
  17895     PORT_LOCK(unit);                    /* multiple operations operation */
  17896 
  17897     rv = _bcm_port_speed_set(unit, port, speed);
  17898     PORT_UNLOCK(unit);                  /* Unlock before link call */
  17899     /*
  17900      * Restore port's enable state based on what was read prior
  17901      * to setting speed
  17902      */
  17903     if (soc_feature(unit, soc_feature_flexport_based_speed_set) &&
  17904         !SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), port) &&
  17905         !SOC_USE_PORTCTRL(unit)) {
  17906         if (TRUE == enable) {
  17907             BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, port, TRUE));
  17908         }
  17909     }
  17910 
  17911     if (BCM_SUCCESS(rv) && !SAL_BOOT_SIMULATION) {
  17912         SOC_PBMP_CLEAR(pbm);
  17913         SOC_PBMP_PORT_ADD(pbm, port);
  17914         (void)bcm_esw_link_change(unit, pbm);
  17915     }
  17916     PORT_LOCK(unit);                    /* multiple operations operation */
  17917     BCM_IF_ERROR_RETURN(_bcm_esw_port_link_delay_update(unit, port, speed));
  17918     PORT_UNLOCK(unit);                  /* Unlock before link call */
  17919 
  17920 #if defined(BCM_PORT_SPEED_CHANGE_BENCHMARK)
  17921     time_end = SAL_USECS_SUB(sal_time_usecs(), time_start);
  17922     LOG_INFO(BSL_LS_BCM_BENCHMARK,
  17923             (BSL_META_U(unit,
  17924                         "\nPort %d speed change to %d processing took %d usecs\n"),
  17925                         port,
  17926                         speed,
  17927                         time_end));
  17928 #endif
  17929 
  17930     LOG_INFO(BSL_LS_BCM_PORT,
  17931              (BSL_META_U(unit,
  17932                          "bcm_port_speed_set: u=%d p=%d speed=%d rv=%d\n"),
  17933               unit, port, speed, rv));
  17934 
  17935    return rv;
  17936 }
  17937 
  17938 /*
  17939  * Function:
  17940  *      bcm_port_master_get
  17941  * Purpose:
  17942  *      Getting the master status of the port
  17943  * Parameters:
  17944  *      unit - StrataSwitch Unit #.
  17945  *      port - StrataSwitch port #.
  17946  *      ms - (OUT) BCM_PORT_MS_*
  17947  * Returns:
  17948  *      BCM_E_NONE
  17949  *      BCM_E_XXX
  17950  * Notes:
  17951  *      WARNING: assumes BCM_PORT_MS_* matches SOC_PORT_MS_*
  17952  */
  17953 
  17954 int
  17955 bcm_esw_port_master_get(int unit, bcm_port_t port, int *ms)
  17956 {
  17957     int         rv=BCM_E_NONE;
  17958 #if defined(BCM_KATANA2_SUPPORT)
  17959     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  17960 #endif
  17961 
  17962     /* Make sure port module is initialized. */
  17963     PORT_INIT(unit);
  17964 
  17965     /* Call Port Control module */
  17966     if (SOC_USE_PORTCTRL(unit)) {
  17967         return bcmi_esw_portctrl_master_get(unit, port, ms);
  17968     }
  17969 
  17970 #if defined(BCM_KATANA2_SUPPORT)
  17971 #if defined(BCM_SABER2_SUPPORT)
  17972     if(SOC_IS_SABER2(unit)) {
  17973         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  17974     }
  17975 #endif
  17976     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  17977         (!((port >= 1) && (port <= max_phy_port)))) {
  17978          return BCM_E_PORT;
  17979     }
  17980 #endif
  17981 
  17982     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  17983     PORT_LOCK(unit);
  17984     rv = soc_phyctrl_master_get(unit, port, ms);
  17985     PORT_UNLOCK(unit);
  17986     return rv;
  17987 }
  17988 
  17989 /*
  17990  * Function:
  17991  *      bcm_port_master_set
  17992  * Purpose:
  17993  *      Setting the master status for a given port
  17994  * Parameters:
  17995  *      unit - StrataSwitch Unit #.
  17996  *      port - StrataSwitch port #.
  17997  *      ms - BCM_PORT_MS_*
  17998  * Returns:
  17999  *      BCM_E_NONE
  18000  *      BCM_E_XXX
  18001  * Notes:
  18002  *      Ignored if not supported on port.
  18003  *      WARNING: assumes BCM_PORT_MS_* matches SOC_PORT_MS_*
  18004  */
  18005 
  18006 int
  18007 bcm_esw_port_master_set(int unit, bcm_port_t port, int ms)
  18008 {
  18009     int         rv;
  18010     pbmp_t      pbm;
  18011 #if defined(BCM_KATANA2_SUPPORT)
  18012     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  18013 #endif
  18014 
  18015     /* Make sure port module is initialized. */
  18016     PORT_INIT(unit);
  18017 
  18018     /* Call Port Control module */
  18019     if (SOC_USE_PORTCTRL(unit)) {
  18020         return bcmi_esw_portctrl_master_set(unit, port, ms);
  18021     }
  18022 
  18023     if(bcm_common_oamp_port_enable_get(unit, port)) {
  18024         LOG_ERROR(BSL_LS_BCM_PORT,
  18025                   (BSL_META("Error: Cannot configure OAMP Port %d to be master.\n"),
  18026                    port));
  18027         return BCM_E_PARAM;
  18028     }
  18029 
  18030 #if defined(BCM_KATANA2_SUPPORT)
  18031 #if defined(BCM_SABER2_SUPPORT)
  18032     if(SOC_IS_SABER2(unit)) {
  18033         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  18034     }
  18035 #endif
  18036     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  18037         (!((port >= 1) && (port <= max_phy_port)))) {
  18038          return BCM_E_PORT;
  18039     }
  18040 #endif
  18041 
  18042     /* Make sure port module is initialized. */
  18043     PORT_INIT(unit);
  18044 
  18045     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  18046 
  18047 #ifdef BCM_RCPU_SUPPORT
  18048     if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
  18049         return BCM_E_PORT;
  18050     }
  18051 #endif /* BCM_RCPU_SUPPORT */
  18052 
  18053     PORT_LOCK(unit);                    /* multiple operations operation */
  18054 
  18055     rv = soc_phyctrl_master_set(unit, port, ms);
  18056     if (BCM_FAILURE(rv)) {
  18057         LOG_VERBOSE(BSL_LS_BCM_PORT,
  18058                     (BSL_META_U(unit,
  18059                                 "PHY_MASTER_SETfailed:%s\n"), bcm_errmsg(rv)));
  18060     }
  18061 
  18062 #if defined(BCM_XMAC_SUPPORT)
  18063     if(SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) ||
  18064        SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
  18065        uint32 vco_disturbed = 0;
  18066        phy_ctrl_t *int_pc, *ext_pc;
  18067        ext_pc = EXT_PHY_SW_STATE(unit, port);
  18068         if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) ||
  18069                     IS_XE_PORT(unit, port)) && (ext_pc == NULL)) {
  18070 
  18071             int_pc = INT_PHY_SW_STATE(unit, port);
  18072             rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed);
  18073             if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) {
  18074                 PORT_UNLOCK(unit);
  18075                 return rv;
  18076             }
  18077             if (vco_disturbed) {
  18078                 rv = _mac_x_reinit(unit, port);
  18079                 if (BCM_FAILURE(rv)) {
  18080                     PORT_UNLOCK(unit);
  18081                     return rv;
  18082                 }
  18083             }
  18084         }
  18085     }
  18086 #endif
  18087     PORT_UNLOCK(unit);                  /* Unlock before link call */
  18088 
  18089     if (BCM_SUCCESS(rv)) {
  18090         SOC_PBMP_CLEAR(pbm);
  18091         SOC_PBMP_PORT_ADD(pbm, port);
  18092         (void)bcm_esw_link_change(unit, pbm);
  18093     }
  18094 
  18095     return rv;
  18096 }
  18097 
  18098 /*
  18099  * Function:
  18100  *      bcm_port_interface_get
  18101  * Purpose:
  18102  *      Getting the interface type of a port
  18103  * Parameters:
  18104  *      unit - StrataSwitch Unit #.
  18105  *      port - StrataSwitch port #.
  18106  *      intf - (OUT) BCM_PORT_IF_*
  18107  * Returns:
  18108  *      BCM_E_NONE
  18109  *      BCM_E_XXX
  18110  * Notes:
  18111  *      WARNING: assumes BCM_PORT_IF_* matches SOC_PORT_IF_*
  18112  */
  18113 
  18114 int
  18115 bcm_esw_port_interface_get(int unit, bcm_port_t port, bcm_port_if_t *intf)
  18116 {
  18117     int         rv=BCM_E_NONE;
  18118 #if defined(BCM_KATANA2_SUPPORT)
  18119     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  18120 #endif
  18121 
  18122     /* Make sure port module is initialized. */
  18123     PORT_INIT(unit);
  18124 
  18125     /* Call Port Control module */
  18126     if (SOC_USE_PORTCTRL(unit)) {
  18127         return bcmi_esw_portctrl_interface_get(unit, port, intf);
  18128     }
  18129 
  18130     if(bcm_common_oamp_port_enable_get(unit, port)) {
  18131         LOG_ERROR(BSL_LS_BCM_PORT,
  18132                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  18133                    port));
  18134         return BCM_E_PARAM;
  18135     }
  18136 
  18137 #if defined(BCM_KATANA2_SUPPORT)
  18138 #if defined(BCM_SABER2_SUPPORT)
  18139     if(SOC_IS_SABER2(unit)) {
  18140         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  18141     }
  18142 #endif
  18143     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  18144         (!((port >= 1) && (port <= max_phy_port)))) {
  18145          return BCM_E_PORT;
  18146     }
  18147 #endif
  18148 
  18149     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  18150 
  18151     if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
  18152         return BCM_E_PORT;
  18153     }
  18154     PORT_LOCK(unit);
  18155     rv = soc_phyctrl_interface_get(unit, port, intf);
  18156     PORT_UNLOCK(unit);
  18157     return rv;
  18158 }
  18159 
  18160 /*
  18161  * Function:
  18162  *      bcm_port_interface_set
  18163  * Purpose:
  18164  *      Setting the interface type for a given port
  18165  * Parameters:
  18166  *      unit - StrataSwitch Unit #.
  18167  *      port - StrataSwitch port #.
  18168  *      if - BCM_PORT_IF_*
  18169  * Returns:
  18170  *      BCM_E_NONE
  18171  *      BCM_E_XXX
  18172  * Notes:
  18173  *      WARNING: assumes BCM_PORT_IF_* matches SOC_PORT_IF_*
  18174  */
  18175 
  18176 int
  18177 bcm_esw_port_interface_set(int unit, bcm_port_t port, bcm_port_if_t intf)
  18178 {
  18179     int         rv;
  18180     pbmp_t      pbm;
  18181 #if defined(BCM_KATANA2_SUPPORT)
  18182     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  18183 #endif
  18184 
  18185     /* Make sure port module is initialized. */
  18186     PORT_INIT(unit);
  18187 
  18188     /* Call Port Control module */
  18189     if (SOC_USE_PORTCTRL(unit)) {
  18190         return bcmi_esw_portctrl_interface_set(unit, port, intf);
  18191     }
  18192 
  18193     if(bcm_common_oamp_port_enable_get(unit, port)) {
  18194         LOG_ERROR(BSL_LS_BCM_PORT,
  18195                   (BSL_META(
  18196 				   		"Error: Cannot set interface type on OAMP Port %d.\n"),
  18197                    port));
  18198         return BCM_E_PARAM;
  18199     }
  18200 
  18201 #if defined(BCM_KATANA2_SUPPORT)
  18202 #if defined(BCM_SABER2_SUPPORT)
  18203     if(SOC_IS_SABER2(unit)) {
  18204         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  18205     }
  18206 #endif
  18207     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  18208         (!((port >= 1) && (port <= max_phy_port)))) {
  18209          return BCM_E_PORT;
  18210     }
  18211 #endif
  18212 
  18213     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  18214 
  18215     if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
  18216         return BCM_E_PORT;
  18217     }
  18218 
  18219 #ifdef BCM_RCPU_SUPPORT
  18220     if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
  18221         return BCM_E_PORT;
  18222     }
  18223 #endif /* BCM_RCPU_SUPPORT */
  18224 
  18225     PORT_LOCK(unit);                    /* multiple operations operation */
  18226 
  18227     rv = soc_phyctrl_interface_set(unit, port, intf);
  18228     if (BCM_FAILURE(rv)) {
  18229         LOG_VERBOSE(BSL_LS_BCM_PORT,
  18230                     (BSL_META_U(unit,
  18231                                 "PHY_INTERFACE_SETfailed:%s\n"), bcm_errmsg(rv)));
  18232     }
  18233 #if defined(BCM_XMAC_SUPPORT)
  18234     if(SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) ||
  18235        SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
  18236        uint32 vco_disturbed = 0;
  18237        phy_ctrl_t *int_pc, *ext_pc;
  18238        ext_pc = EXT_PHY_SW_STATE(unit, port);
  18239         if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) ||
  18240                     IS_XE_PORT(unit, port)) && (ext_pc == NULL)) {
  18241 
  18242             int_pc = INT_PHY_SW_STATE(unit, port);
  18243             rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed);
  18244             if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) {
  18245                 PORT_UNLOCK(unit);
  18246                 return rv;
  18247             }
  18248             if (vco_disturbed) {
  18249                 rv = _mac_x_reinit(unit, port);
  18250                 if (BCM_FAILURE(rv)) {
  18251                     PORT_UNLOCK(unit);
  18252                     return rv;
  18253                 }
  18254             }
  18255         }
  18256     }
  18257 #endif
  18258 
  18259     PORT_UNLOCK(unit);                  /* Unlock before link call */
  18260 
  18261     if (BCM_SUCCESS(rv)) {
  18262         SOC_PBMP_CLEAR(pbm);
  18263         SOC_PBMP_PORT_ADD(pbm, port);
  18264         (void)bcm_esw_link_change(unit, pbm);
  18265         PORT(unit, port).intf = intf;
  18266     }
  18267 
  18268     return rv;
  18269 }
  18270 
  18271 /*
  18272  * Function:
  18273  *      bcm_port_loopback_set
  18274  * Purpose:
  18275  *      Setting the speed for a given port
  18276  * Parameters:
  18277  *      unit - StrataSwitch Unit #.
  18278  *      port - StrataSwitch port #.
  18279  *      loopback - one of:
  18280  *              BCM_PORT_LOOPBACK_NONE
  18281  *              BCM_PORT_LOOPBACK_MAC
  18282  *              BCM_PORT_LOOPBACK_PHY
  18283  * Returns:
  18284  *      BCM_E_NONE
  18285  *      BCM_E_XXX
  18286  */
  18287 
  18288 int
  18289 bcm_esw_port_loopback_set(int unit, bcm_port_t port, int loopback)
  18290 {
  18291     int             rv, link = TRUE;
  18292     int             phy_lane = -1;
  18293     int             phyn = 0, sys_side = 0;
  18294     bcm_port_t      local_port = -1;
  18295 #if defined(BCM_TOMAHAWK_SUPPORT)
  18296     uint32          link_st = 0;
  18297     soc_timeout_t   to;
  18298     int             phy_port;
  18299 #endif
  18300     soc_persist_t   *sop = SOC_PERSIST(unit);
  18301 
  18302 #ifdef BCM_TRIDENT2_SUPPORT
  18303     int             enable;
  18304 #endif /* BCM_TRIDENT2_SUPPORT */
  18305 #if defined(BCM_KATANA2_SUPPORT)
  18306     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  18307 #endif
  18308 
  18309     /* Make sure port module is initialized. */
  18310     PORT_INIT(unit);
  18311 
  18312     if (SOC_USE_PORTCTRL(unit)) {
  18313         /* Check if port have to force-loopback */
  18314         if (BCM_ESW_PORT_DRV(unit)!= NULL) {
  18315             if (BCM_ESW_PORT_DRV(unit)->force_lb_check != NULL) {
  18316                 rv = BCM_ESW_PORT_DRV(unit)->force_lb_check(unit, port,
  18317                                                             loopback);
  18318                 if (rv != BCM_E_NONE) {
  18319                     LOG_ERROR(BSL_LS_BCM_PORT,
  18320                               (BSL_META("Error: Port %d allow PHY internal "
  18321                                         "loopback only.\n"),
  18322                                port));
  18323                     return BCM_E_PARAM;
  18324                 }
  18325             }
  18326         }
  18327 
  18328         return bcmi_esw_portctrl_loopback_set(unit, port, loopback);
  18329     }
  18330 
  18331     if(bcm_common_oamp_port_enable_get(unit, port)) {
  18332         LOG_ERROR(BSL_LS_BCM_PORT,
  18333                   (BSL_META("Error: Cannot set loopback on OAMP Port %d.\n"),
  18334                    port));
  18335         return BCM_E_PARAM;
  18336     }
  18337 
  18338 #if defined(BCM_KATANA2_SUPPORT)
  18339 #if defined(BCM_SABER2_SUPPORT)
  18340     if(SOC_IS_SABER2(unit)) {
  18341         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  18342     }
  18343 #endif
  18344     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  18345         (!((port >= 1) && (port <= max_phy_port)))) {
  18346          return BCM_E_PORT;
  18347     }
  18348 #endif
  18349 
  18350     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_phyn_validate(unit, port,
  18351                                                         &local_port, &phyn,
  18352                                                         &phy_lane, &sys_side));
  18353 
  18354     if (local_port == -1) {
  18355        BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  18356     } else {
  18357        port = local_port;
  18358     }
  18359 
  18360 #if defined(BCM_TOMAHAWK_SUPPORT)
  18361     if (SOC_IS_TOMAHAWKX(unit)) {
  18362         BCM_IF_ERROR_RETURN(bcm_th_phy_lb_check(unit, port, loopback));
  18363     }
  18364 #endif
  18365 
  18366 #ifdef BCM_RCPU_SUPPORT
  18367     if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
  18368         return BCM_E_PORT;
  18369     }
  18370 #endif /* BCM_RCPU_SUPPORT */
  18371 
  18372     PORT_LOCK(unit);
  18373     soc_phyctrl_enable_get(unit, port, &link);
  18374     PORT_UNLOCK(unit);
  18375     if (TRUE == link) {
  18376         if (SOC_PBMP_MEMBER(sop->lc_pbm_override_ports, port)) {
  18377             if(!SOC_PBMP_MEMBER(sop->lc_pbm_override_link, port)) {
  18378                 link = FALSE;
  18379             }
  18380         }
  18381     }
  18382 
  18383     rv = BCM_E_NONE;
  18384     /*
  18385      * Always force link before changing hardware to avoid
  18386      * race with the linkscan thread.
  18387      */
  18388     if (!(loopback == BCM_PORT_LOOPBACK_NONE)) {
  18389         rv = _bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, FALSE);
  18390 
  18391         if(rv == BCM_E_NONE) {
  18392             /* Force the update function to be called so the state is
  18393                updated */
  18394             if (_soc_linkscan_phy_flags_test(unit, port, PHY_FLAGS_EXTERNAL_PHY)) {
  18395                 rv = bcm_esw_port_update(unit, port, TRUE);
  18396             }
  18397         }
  18398     }
  18399 
  18400     PORT_LOCK(unit);
  18401 
  18402     if (BCM_SUCCESS(rv)) {
  18403         rv = MAC_LOOPBACK_SET(PORT(unit, port).p_mac, unit, port,
  18404                               (loopback == BCM_PORT_LOOPBACK_MAC));
  18405     }
  18406     if (BCM_SUCCESS(rv)) {
  18407         if (local_port == -1) {
  18408             if (loopback == BCM_PORT_LOOPBACK_PHY_REMOTE) {
  18409                 rv = soc_phyctrl_control_set(unit, port,
  18410                                              SOC_PHY_CONTROL_LOOPBACK_REMOTE, 1);
  18411             } else {
  18412                 if (loopback == BCM_PORT_LOOPBACK_NONE) {
  18413                     rv = soc_phyctrl_control_set(unit, port,
  18414                                              SOC_PHY_CONTROL_LOOPBACK_REMOTE, 0);
  18415                 }
  18416 
  18417                 if (rv == SOC_E_NONE || rv == SOC_E_UNAVAIL) {
  18418             rv = soc_phyctrl_loopback_set(unit, port,
  18419                                                   (loopback == BCM_PORT_LOOPBACK_PHY),
  18420                                                   TRUE);
  18421                 }
  18422             }
  18423 
  18424         } else {
  18425             rv = soc_phyctrl_redirect_loopback_set
  18426                                           (unit, port, phyn,
  18427                                            phy_lane, sys_side,
  18428                                            (loopback == BCM_PORT_LOOPBACK_PHY),
  18429                                            TRUE);
  18430         }
  18431     }
  18432     /* some mac loopback implementations require the phy to also be in loopback */
  18433     if (soc_feature(unit, soc_feature_phy_lb_needed_in_mac_lb) &&
  18434         (loopback == BCM_PORT_LOOPBACK_MAC)) {
  18435         if (local_port == -1) {
  18436             rv = soc_phyctrl_loopback_set(unit, port, 1, TRUE);
  18437         } else {
  18438             rv = soc_phyctrl_redirect_loopback_set(unit, port, phyn,
  18439                                                    phy_lane, sys_side,
  18440                                                    1, TRUE);
  18441         }
  18442      }
  18443 
  18444     PORT_UNLOCK(unit);                  /* unlock before link call */
  18445 
  18446     if ((loopback == BCM_PORT_LOOPBACK_NONE) || !BCM_SUCCESS(rv)) {
  18447         _bcm_esw_link_force(unit, 0 /*flags*/, port, FALSE, DONT_CARE);
  18448         PORT_LOCK(unit);
  18449 #ifdef BCM_TRIDENT2_SUPPORT
  18450         /* When the PHY is TSC, need to unsquelch TX LANE. */
  18451         if (SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit)){
  18452             enable = PORT(unit, port).enable;
  18453             if ((FALSE == enable) && (loopback == BCM_PORT_LOOPBACK_NONE)) {
  18454                 (void)soc_phyctrl_notify(unit, port, phyEventTxSquelch, FALSE);
  18455                 rv = soc_phyctrl_enable_set(unit, port, FALSE);
  18456                 if (SOC_FAILURE(rv)) {
  18457                     PORT_UNLOCK(unit);
  18458                     return (rv);
  18459                 }
  18460                 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, FALSE);
  18461             }
  18462         } else
  18463 #endif /* BCM_TRIDENT2_SUPPORT */
  18464         {
  18465             if ((FALSE == link) && (loopback == BCM_PORT_LOOPBACK_NONE)) {
  18466                 /* Disable MAC RX to prevent traffic going into this port */
  18467                 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  18468                                 SOC_MAC_CONTROL_RX_SET, FALSE);
  18469                 sal_udelay(100); /* Wait for 1 jumbo packet transmission time */
  18470 
  18471                 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, FALSE);
  18472             }
  18473         }
  18474         PORT_UNLOCK(unit);
  18475     } else {
  18476         /* Enable only MAC instead of calling bcm_port_enable_set so
  18477          * that this API doesn't silently enable the port if the
  18478          * port is disabled by application.
  18479          */
  18480         rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, TRUE);
  18481 
  18482 #ifdef BCM_TRIDENT2_SUPPORT
  18483         /* When the PHY is TSC, need to enable the PHY to support MAC loopback
  18484          * on a disabled port. In order to avoid link flap of link partner,
  18485          * need to squelch TX LANE before enabling PHY.
  18486          */
  18487         if (BCM_FAILURE(rv)) {
  18488             return (rv);
  18489         }
  18490         if ((SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit)) && (FALSE == link)
  18491             && (loopback == BCM_PORT_LOOPBACK_MAC)) {
  18492             PORT_LOCK(unit);
  18493             (void)soc_phyctrl_notify(unit, port, phyEventTxSquelch, TRUE);
  18494             rv = soc_phyctrl_enable_set(unit, port, TRUE);
  18495             PORT_UNLOCK(unit);
  18496             if (SOC_FAILURE(rv)) {
  18497                 return (rv);
  18498             }
  18499         }
  18500 #endif /* BCM_TRIDENT2_SUPPORT */
  18501 
  18502         if (BCM_SUCCESS(rv)) {
  18503             /* Make sure that the link status is updated only after the
  18504              * MAC is enabled so that link_mask2 is set before the
  18505              * calling thread synchronizes with linkscan thread in
  18506              * _bcm_link_force call.
  18507              * If the link is forced before MAC is enabled, there could
  18508              * be a race condition in _soc_link_update where linkscan
  18509              * may use an old view of link_mask2 and override the
  18510              * EPC_LINK_BMAP after the mac_enable_set updates
  18511              * link_mask2 and EPC_LINK_BMAP.
  18512              */
  18513             if (loopback == BCM_PORT_LOOPBACK_MAC) {
  18514                 rv = _bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, TRUE);
  18515             } else {
  18516                 rv = _bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, link);
  18517             }
  18518         }
  18519         if (BCM_FAILURE(rv)) {
  18520             return (rv);
  18521         }
  18522 
  18523 #if defined(BCM_BRADLEY_SUPPORT)
  18524         /*
  18525          * Call _bcm_port_mmu_update explicitly because linkscan
  18526          * will not call bcm_port_update when the link is forced.
  18527          */
  18528         if (SOC_IS_HBX(unit) && !SOC_IS_SHADOW(unit)) {
  18529             rv = _bcm_port_mmu_update(unit, port, 1);
  18530         }
  18531 
  18532         /* When a link comes up, hardware will not update the
  18533          * LINK_STATUS register until software has toggled the
  18534          * the LAG_FAILOVER_CONFIG.LINK_STATUS_UP field.
  18535          * Normally, this is done by bcm_port_update. But since
  18536          * linkscan will not call bcm_port_update when a link is
  18537          * forced up, the toggling of LAG_FAILOVER_CONFIG.LINK_STATUS_UP
  18538          * is done here.
  18539          */
  18540         if ((SOC_REG_IS_VALID(unit, GXPORT_LAG_FAILOVER_CONFIGr) &&
  18541              IS_GX_PORT(unit, port)) ||
  18542             (SOC_REG_IS_VALID(unit, LAG_FAILOVER_CONFIGr)) ||
  18543             (SOC_REG_IS_VALID(unit, XLPORT_LAG_FAILOVER_CONFIGr) &&
  18544               (IS_XL_PORT(unit, port) || IS_MXQ_PORT(unit, port))) ||
  18545             (SOC_REG_IS_VALID(unit, CLPORT_LAG_FAILOVER_CONFIGr) &&
  18546               IS_CL_PORT(unit, port))) {
  18547             soc_reg_t reg;
  18548             uint32 rval;
  18549 
  18550             if (SOC_IS_SABER2(unit) && SOC_REG_PORT_VALID(unit, XLPORT_LAG_FAILOVER_CONFIGr, port)) {
  18551                 reg = XLPORT_LAG_FAILOVER_CONFIGr;
  18552             } else if (SOC_REG_IS_VALID(unit, LAG_FAILOVER_CONFIGr)) {
  18553                 reg = LAG_FAILOVER_CONFIGr;
  18554             } else if (SOC_REG_IS_VALID(unit, GXPORT_LAG_FAILOVER_CONFIGr)) {
  18555                 reg = GXPORT_LAG_FAILOVER_CONFIGr;
  18556             } else if (SOC_REG_PORT_VALID(unit, CLPORT_LAG_FAILOVER_CONFIGr, port) && 
  18557                        (SOC_IS_TOMAHAWKX(unit) || IS_CL_PORT(unit, port))) {
  18558                 reg = CLPORT_LAG_FAILOVER_CONFIGr;
  18559             } else {
  18560                 reg = XLPORT_LAG_FAILOVER_CONFIGr;
  18561             }
  18562 
  18563 #if defined(BCM_TOMAHAWK_SUPPORT)
  18564            if (SOC_IS_TOMAHAWK(unit)) {
  18565                phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  18566                if((phy_port == TH_MGMT_PORT0_NUM) ||
  18567                   (phy_port == TH_MGMT_PORT1_NUM)) {
  18568                    reg = XLPORT_LAG_FAILOVER_CONFIGr;
  18569                }
  18570                /* Link status to IPIPE is updated by H/W and driven based on both the
  18571                * rising edge of XLPORT_LAG_FAILOVER_CONFIG.LINK_STATUS_UP and
  18572                * actual link up status from Serdes.
  18573                * In some loopback scenarios it may take longer time to see Serdes link up status.
  18574                */
  18575                soc_timeout_init(&to, 10000, 0);
  18576                do {
  18577                       if (((phy_port != TH_MGMT_PORT0_NUM) &&
  18578                            (phy_port != TH_MGMT_PORT1_NUM)) ||
  18579                            (loopback == BCM_PORT_LOOPBACK_NONE)) {
  18580                           break;
  18581                       }
  18582 
  18583                       switch(phy_port) {
  18584                           case TH_MGMT_PORT0_NUM:
  18585                               BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XLPORT_XGXS0_LN0_STATUS0_REGr, port, 0, &rval));
  18586                               link_st = soc_reg_field_get(unit, XLPORT_XGXS0_LN0_STATUS0_REGr, rval, LINK_STATUSf);
  18587                               break;
  18588                           case TH_MGMT_PORT1_NUM:
  18589                               BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XLPORT_XGXS0_LN2_STATUS0_REGr, port, 0, &rval));
  18590                               link_st = soc_reg_field_get(unit, XLPORT_XGXS0_LN2_STATUS0_REGr, rval, LINK_STATUSf);
  18591                               break;
  18592                       }
  18593                       if(link_st) {
  18594                           break;
  18595                       }
  18596                } while (!soc_timeout_check(&to));
  18597            }
  18598 #endif
  18599             /* Toggle link bit to notify IPIPE on link up */
  18600             BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval));
  18601             soc_reg_field_set(unit, reg, &rval, LINK_STATUS_UPf, 1);
  18602             BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
  18603             soc_reg_field_set(unit, reg, &rval, LINK_STATUS_UPf, 0);
  18604             BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
  18605         }
  18606 #endif /* BCM_BRADLEY_SUPPORT */
  18607     }
  18608 
  18609     LOG_INFO(BSL_LS_BCM_PORT,
  18610              (BSL_META_U(unit,
  18611                          "bcm_port_loopback_set: u=%d p=%d lb=%d rv=%d\n"),
  18612               unit, port, loopback, rv));
  18613 
  18614     return rv;
  18615 }
  18616 
  18617 /*
  18618  * Function:
  18619  *      bcm_port_loopback_get
  18620  * Purpose:
  18621  *      Recover the current loopback operation for the specified port.
  18622  * Parameters:
  18623  *      unit - StrataSwitch Unit #.
  18624  *      port - StrataSwitch port #.
  18625  *      loopback - (OUT) one of:
  18626  *              BCM_PORT_LOOPBACK_NONE
  18627  *              BCM_PORT_LOOPBACK_MAC
  18628  *              BCM_PORT_LOOPBACK_PHY
  18629  * Returns:
  18630  *      BCM_E_NONE
  18631  *      BCM_E_XXX
  18632  */
  18633 
  18634 int
  18635 bcm_esw_port_loopback_get(int unit, bcm_port_t port, int *loopback)
  18636 {
  18637     int         rv = BCM_E_NONE;
  18638     int         phy_lb = 0;
  18639     uint32      phy_rlb = 0;
  18640     int         mac_lb = 0;
  18641     int         phy_lane = -1;
  18642     int         phyn = 0, sys_side = 0;
  18643     bcm_port_t  local_port = -1;
  18644 #if defined(BCM_KATANA2_SUPPORT)
  18645     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  18646 #endif
  18647 
  18648     /* Make sure port module is initialized. */
  18649     PORT_INIT(unit);
  18650 
  18651     if (SOC_USE_PORTCTRL(unit)) {
  18652         return bcmi_esw_portctrl_loopback_get(unit, port, loopback);
  18653     }
  18654 
  18655     if(bcm_common_oamp_port_enable_get(unit, port)) {
  18656         LOG_ERROR(BSL_LS_BCM_PORT,
  18657                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  18658                    port));
  18659         return BCM_E_PARAM;
  18660     }
  18661 
  18662 #if defined(BCM_KATANA2_SUPPORT)
  18663 #if defined(BCM_SABER2_SUPPORT)
  18664     if(SOC_IS_SABER2(unit)) {
  18665         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  18666     }
  18667 #endif
  18668     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  18669         (!((port >= 1) && (port <= max_phy_port)))) {
  18670          return BCM_E_PORT;
  18671     }
  18672 #endif
  18673 
  18674     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_phyn_validate(unit, port,
  18675                                                         &local_port, &phyn,
  18676                                                         &phy_lane, &sys_side));
  18677 
  18678     if (local_port == -1) {
  18679        BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  18680     } else {
  18681        port = local_port;
  18682     }
  18683     PORT_LOCK(unit);                    /* multiple operations operation */
  18684 
  18685     if (local_port == -1) {
  18686         /* Most ext-phys don't support remote loopback and return SOC_E_UNAVAIL.
  18687          * When the return value is SOC_E_UNAVAIL, continue to get phy or mac
  18688          * loopback mode
  18689          */
  18690         rv = soc_phyctrl_control_get(unit, port,
  18691                                      SOC_PHY_CONTROL_LOOPBACK_REMOTE,
  18692                                      &phy_rlb);
  18693         if (rv >= 0 || rv == SOC_E_UNAVAIL) {
  18694        rv = soc_phyctrl_loopback_get(unit, port, &phy_lb);
  18695         }
  18696     } else {
  18697        rv = soc_phyctrl_redirect_loopback_get(unit, port, phyn,
  18698                                               phy_lane, sys_side,
  18699                                               &phy_lb);
  18700     }
  18701 
  18702         rv = MAC_LOOPBACK_GET(PORT(unit, port).p_mac, unit, port, &mac_lb);
  18703 
  18704     PORT_UNLOCK(unit);
  18705     if (rv >= 0) {
  18706         if (mac_lb) {
  18707             *loopback = BCM_PORT_LOOPBACK_MAC;
  18708         } else if (phy_lb) {
  18709             *loopback = BCM_PORT_LOOPBACK_PHY;
  18710         } else if (phy_rlb) {
  18711             *loopback = BCM_PORT_LOOPBACK_PHY_REMOTE;
  18712         } else {
  18713             *loopback = BCM_PORT_LOOPBACK_NONE;
  18714         }
  18715     } else {
  18716         *loopback = BCM_PORT_LOOPBACK_NONE;
  18717     }
  18718 
  18719     LOG_INFO(BSL_LS_BCM_PORT,
  18720              (BSL_META_U(unit,
  18721                          "bcm_port_loopback_get: u=%d p=%d lb=%d rv=%d\n"),
  18722               unit, port, *loopback, rv));
  18723 
  18724     return rv;
  18725 }
  18726 
  18727 /*
  18728  * Function:
  18729  *      bcm_port_duplex_get
  18730  * Purpose:
  18731  *      Get the port duplex settings
  18732  * Parameters:
  18733  *      unit - StrataSwitch Unit #.
  18734  *      port - StrataSwitch port #.
  18735  *      duplex - (OUT) Duplex setting, one of SOC_PORT_DUPLEX_xxx
  18736  * Returns:
  18737  *      BCM_E_NONE
  18738  *      BCM_E_XXX
  18739  */
  18740 
  18741 int
  18742 bcm_esw_port_duplex_get(int unit, bcm_port_t port, int *duplex)
  18743 {
  18744     int         phy_duplex;
  18745     int         rv=BCM_E_NONE;
  18746 #if defined(BCM_KATANA2_SUPPORT)
  18747     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  18748 #endif
  18749 
  18750     /* Make sure port module is initialized. */
  18751     PORT_INIT(unit);
  18752 
  18753     if (SOC_USE_PORTCTRL(unit)) {
  18754         return bcmi_esw_portctrl_duplex_get(unit, port, duplex);
  18755     }
  18756 
  18757     if(bcm_common_oamp_port_enable_get(unit, port)) {
  18758         LOG_ERROR(BSL_LS_BCM_PORT,
  18759                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  18760                    port));
  18761         return BCM_E_PARAM;
  18762     }
  18763 
  18764 #if defined(BCM_KATANA2_SUPPORT)
  18765 #if defined(BCM_SABER2_SUPPORT)
  18766     if(SOC_IS_SABER2(unit)) {
  18767         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  18768     }
  18769 #endif
  18770     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  18771         (!((port >= 1) && (port <= max_phy_port)))) {
  18772          return BCM_E_PORT;
  18773     }
  18774 #endif
  18775     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  18776     PORT_LOCK(unit);
  18777     rv = soc_phyctrl_duplex_get(unit, port, &phy_duplex);
  18778     PORT_UNLOCK(unit);
  18779 
  18780     if (BCM_SUCCESS(rv)) {
  18781         *duplex = phy_duplex ? SOC_PORT_DUPLEX_FULL : SOC_PORT_DUPLEX_HALF;
  18782     } else {
  18783         *duplex = SOC_PORT_DUPLEX_FULL;
  18784     }
  18785 
  18786     LOG_INFO(BSL_LS_BCM_PORT,
  18787              (BSL_META_U(unit,
  18788                          "bcm_port_duplex_get: u=%d p=%d dup=%d rv=%d\n"),
  18789               unit, port, *duplex, rv));
  18790 
  18791     return rv;
  18792 }
  18793 
  18794 /*
  18795  * Function:
  18796  *      _bcm_port_duplex_ability_check
  18797  * Purpose:
  18798  *      Check the port duplex ability.
  18799  * Parameters:
  18800  *      unit - StrataSwitch Unit #.
  18801  *      port - StrataSwitch port #.
  18802  *      duplex - Duplex setting, one of SOC_PORT_DUPLEX_xxx
  18803  * Returns:
  18804  *      BCM_E_NONE
  18805  *      BCM_E_XXX
  18806  */
  18807 STATIC int
  18808 _bcm_esw_port_duplex_ability_check(int unit, bcm_port_t port, int duplex)
  18809 {
  18810     bcm_port_ability_t ability_mask;
  18811     int         rv;
  18812     int         mac_lb;
  18813     int         speed = 0, full_duplex_speed, half_duplex_speed;
  18814     uint32      pa_speed = 0;
  18815     sal_memset(&ability_mask, 0, sizeof(bcm_port_ability_t));
  18816     rv = MAC_LOOPBACK_GET(PORT(unit, port).p_mac, unit, port, &mac_lb);
  18817     if (BCM_SUCCESS(rv)) {
  18818         /* If the port is in mac loopback, we get mac_ability rather than port_ability. */
  18819         if(mac_lb) {
  18820            rv = MAC_ABILITY_LOCAL_GET(PORT(unit, port).p_mac, unit,port, &ability_mask);
  18821         } else {
  18822            rv = bcm_esw_port_ability_local_get(unit, port, &ability_mask);
  18823         }
  18824         if (rv < 0) {
  18825             LOG_VERBOSE(BSL_LS_BCM_PORT,
  18826                         (BSL_META("Error: Could not get port %d ability: %s\n"),
  18827                          port, bcm_errmsg(rv)));
  18828             return rv;
  18829         }
  18830         if ((rv = bcm_esw_port_speed_get(unit, port, &speed)) < 0) {
  18831             LOG_VERBOSE(BSL_LS_BCM_PORT,
  18832                         (BSL_META("Error: Could not get port %d speed: %s\n"),
  18833                          port, bcm_errmsg(rv)));
  18834             return rv;
  18835         }
  18836         pa_speed = SOC_PA_SPEED(speed);
  18837         full_duplex_speed = ability_mask.speed_full_duplex & pa_speed;
  18838         half_duplex_speed = ability_mask.speed_half_duplex & pa_speed;
  18839         if (!soc_feature(unit, soc_feature_flexport_based_speed_set) && (speed != 0)) {
  18840             if (duplex) {
  18841                 if (!full_duplex_speed) {
  18842                     LOG_WARN(BSL_LS_BCM_PORT,
  18843                              (BSL_META_U(unit, "Warning: port %d does not support %d mbps full duplex\n"),
  18844                               port, speed));
  18845                     return BCM_E_UNAVAIL;
  18846                 }
  18847             } else {
  18848                 if (!half_duplex_speed) {
  18849                     LOG_WARN(BSL_LS_BCM_PORT,
  18850                              (BSL_META_U(unit, "Warning: port %d does not support %d mbps half duplex\n"),
  18851                               port, speed));
  18852                     return BCM_E_UNAVAIL;
  18853                 }
  18854             }
  18855         }
  18856     }
  18857     return BCM_E_NONE;
  18858 }
  18859 
  18860 /*
  18861  * Function:
  18862  *      bcm_port_duplex_set
  18863  * Purpose:
  18864  *      Set the port duplex settings.
  18865  * Parameters:
  18866  *      unit - StrataSwitch Unit #.
  18867  *      port - StrataSwitch port #.
  18868  *      duplex - Duplex setting, one of SOC_PORT_DUPLEX_xxx
  18869  * Returns:
  18870  *      BCM_E_NONE
  18871  *      BCM_E_XXX
  18872  * Notes:
  18873  *      Turns off autonegotiation.  Caller must make sure other forced
  18874  *      parameters (such as speed) are set.
  18875  */
  18876 
  18877 int
  18878 bcm_esw_port_duplex_set(int unit, bcm_port_t port, int duplex)
  18879 {
  18880     int         rv;
  18881     pbmp_t      pbm;
  18882     int         an = 0 ;
  18883     int         an_done=0;
  18884 #if defined(BCM_SABER2_SUPPORT)
  18885     int             phy_status;
  18886 #endif
  18887 #if defined(BCM_KATANA2_SUPPORT)
  18888     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  18889 #endif
  18890 
  18891     /* Make sure port module is initialized. */
  18892     PORT_INIT(unit);
  18893 
  18894     if (SOC_USE_PORTCTRL(unit)) {
  18895         return bcmi_esw_portctrl_duplex_set(unit, port, duplex);
  18896     }
  18897 
  18898     if(bcm_common_oamp_port_enable_get(unit, port)) {
  18899         LOG_ERROR(BSL_LS_BCM_PORT,
  18900                   (BSL_META("Error: Cannot set duplex mode on OAMP Port %d.\n"),
  18901                    port));
  18902         return BCM_E_PARAM;
  18903     }
  18904 
  18905 #if defined(BCM_KATANA2_SUPPORT)
  18906 #if defined(BCM_SABER2_SUPPORT)
  18907     if(SOC_IS_SABER2(unit)) {
  18908         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  18909     }
  18910 #endif
  18911     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  18912         (!((port >= 1) && (port <= max_phy_port)))) {
  18913          return BCM_E_PORT;
  18914     } else
  18915 #endif
  18916      if((!BCM_GPORT_IS_SET(port)) && (!(SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)))) {
  18917         return BCM_E_PORT;
  18918      }
  18919     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  18920 
  18921 #ifdef BCM_RCPU_SUPPORT
  18922     if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
  18923         return BCM_E_PORT;
  18924     }
  18925 #endif /* BCM_RCPU_SUPPORT */
  18926 
  18927 #if defined(BCM_TOMAHAWK_SUPPORT)
  18928     if (SOC_IS_TOMAHAWK(unit)) {
  18929         /*half-duplex is not supported at any speed Eagle & Falcon */
  18930         if (duplex == 0) {
  18931             return BCM_E_UNAVAIL;
  18932         }
  18933     }
  18934 #endif
  18935 
  18936     /* in SIMULATION, port's alility_mask may not be correct due to NULL phy */
  18937     if (!SAL_BOOT_SIMULATION) {
  18938     BCM_IF_ERROR_RETURN(_bcm_esw_port_duplex_ability_check(unit, port, duplex));
  18939     }
  18940 
  18941     PORT_LOCK(unit);
  18942 
  18943 #if defined(BCM_SABER2_SUPPORT)
  18944     if(SOC_IS_SABER2(unit) && IS_XL_PORT(unit, port)) {
  18945         rv = soc_phyctrl_enable_get(unit, port, &phy_status);
  18946         if (BCM_FAILURE(rv)) {
  18947             PORT_UNLOCK(unit);
  18948             return (rv);
  18949         }
  18950         if(phy_status == TRUE) {
  18951             rv = soc_phyctrl_enable_set(unit, port, FALSE);
  18952             if (BCM_FAILURE(rv)) {
  18953                 PORT_UNLOCK(unit);
  18954                 return (rv);
  18955             }
  18956         }
  18957     }
  18958 #endif
  18959     rv = soc_phyctrl_auto_negotiate_get(unit, port, &an, &an_done);
  18960     if (BCM_FAILURE(rv)) {
  18961         LOG_VERBOSE(BSL_LS_BCM_PORT,
  18962                     (BSL_META_U(unit,
  18963                                 "PHY_AUTONEG_GETfailed:%s\n"), bcm_errmsg(rv)));
  18964     }
  18965     if(an != FALSE)
  18966     {
  18967         rv = soc_phyctrl_auto_negotiate_set(unit, port, FALSE);
  18968         if (BCM_FAILURE(rv)) {
  18969             LOG_VERBOSE(BSL_LS_BCM_PORT,
  18970                         (BSL_META_U(unit,
  18971                                     "PHY_AUTONEG_SETfailed:%s\n"), bcm_errmsg(rv)));
  18972         }
  18973     }
  18974 
  18975 #if defined(BCM_SABER2_SUPPORT)
  18976     if(SOC_IS_SABER2(unit) &&
  18977             IS_XL_PORT(unit, port) && (phy_status == TRUE)) {
  18978         /* Enable phy in tsc only if already enabled before config change */
  18979         rv = soc_phyctrl_enable_set(unit, port, TRUE);
  18980         if (BCM_FAILURE(rv)) {
  18981             PORT_UNLOCK(unit);
  18982             return (rv);
  18983         }
  18984     }
  18985 #endif
  18986 
  18987     if (BCM_SUCCESS(rv)) {
  18988         rv = soc_phyctrl_duplex_set(unit, port, duplex);
  18989         if (BCM_FAILURE(rv)) {
  18990             LOG_VERBOSE(BSL_LS_BCM_PORT,
  18991                         (BSL_META_U(unit,
  18992                                     "PHY_DUPLEX_SETfailed:%s\n"), bcm_errmsg(rv)));
  18993         }
  18994     }
  18995 
  18996     if (BCM_SUCCESS(rv)) {
  18997         rv = MAC_DUPLEX_SET(PORT(unit, port).p_mac, unit, port, duplex);
  18998         if (BCM_FAILURE(rv)) {
  18999             LOG_VERBOSE(BSL_LS_BCM_PORT,
  19000                         (BSL_META_U(unit,
  19001                                     "MAC_DUPLEX_SETfailed:%s\n"), bcm_errmsg(rv)));
  19002         }
  19003     }
  19004 #if defined(BCM_XMAC_SUPPORT)
  19005     if(SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) ||
  19006        SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
  19007        uint32 vco_disturbed = 0;
  19008        phy_ctrl_t *int_pc, *ext_pc;
  19009        ext_pc = EXT_PHY_SW_STATE(unit, port);
  19010         if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) ||
  19011                     IS_XE_PORT(unit, port)) && (ext_pc == NULL)) {
  19012 
  19013             int_pc = INT_PHY_SW_STATE(unit, port);
  19014             rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed);
  19015             if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) {
  19016                 PORT_UNLOCK(unit);
  19017                 return rv;
  19018             }
  19019             if (vco_disturbed) {
  19020                 rv = _mac_x_reinit(unit, port);
  19021                 if (BCM_FAILURE(rv)) {
  19022                     PORT_UNLOCK(unit);
  19023                     return rv;
  19024                 }
  19025             }
  19026         }
  19027     }
  19028 #endif
  19029 
  19030     PORT_UNLOCK(unit);                  /* Unlock before link call */
  19031 
  19032     if (BCM_SUCCESS(rv) && !SAL_BOOT_SIMULATION) {
  19033         SOC_PBMP_CLEAR(pbm);
  19034         SOC_PBMP_PORT_ADD(pbm, port);
  19035         (void)bcm_esw_link_change(unit, pbm);
  19036     }
  19037 
  19038     LOG_INFO(BSL_LS_BCM_PORT,
  19039              (BSL_META_U(unit,
  19040                          "bcm_port_duplex_set: u=%d p=%d dup=%d rv=%d\n"),
  19041               unit, port, duplex, rv));
  19042 
  19043     return rv;
  19044 }
  19045 
  19046 /*
  19047  * Function:
  19048  *      bcm_port_pause_get
  19049  * Purpose:
  19050  *      Get the source address for transmitted PAUSE frames.
  19051  * Parameters:
  19052  *      unit - StrataSwitch Unit #.
  19053  *      port - StrataSwitch port #.
  19054  *      pause_tx - (OUT) Boolean value
  19055  *      pause_rx - (OUT) Boolean value
  19056  * Returns:
  19057  *      BCM_E_NONE
  19058  *      BCM_E_XXX
  19059  */
  19060 
  19061 int
  19062 bcm_esw_port_pause_get(int unit, bcm_port_t port, int *pause_tx, int *pause_rx)
  19063 {
  19064     int         rv;
  19065 #if defined(BCM_KATANA2_SUPPORT)
  19066     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  19067 #endif
  19068 
  19069     /* Make sure port module is initialized. */
  19070     PORT_INIT(unit);
  19071 
  19072     /* Call Port Control module */
  19073     if (SOC_USE_PORTCTRL(unit)) {
  19074         return bcmi_esw_portctrl_pause_get(unit, port, pause_tx, pause_rx);
  19075     }
  19076 
  19077     if(bcm_common_oamp_port_enable_get(unit, port)) {
  19078         LOG_ERROR(BSL_LS_BCM_PORT,
  19079                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  19080                    port));
  19081         return BCM_E_PARAM;
  19082     }
  19083 
  19084 #if defined(BCM_KATANA2_SUPPORT)
  19085 #if defined(BCM_SABER2_SUPPORT)
  19086     if(SOC_IS_SABER2(unit)) {
  19087         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  19088     }
  19089 #endif
  19090     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  19091         (!((port >= 1) && (port <= max_phy_port)))) {
  19092          return BCM_E_PORT;
  19093     }
  19094 #endif
  19095 
  19096     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  19097 
  19098     PORT_LOCK(unit);
  19099     rv = MAC_PAUSE_GET(PORT(unit, port).p_mac, unit, port, pause_tx, pause_rx);
  19100     PORT_UNLOCK(unit);
  19101 
  19102     return rv;
  19103 }
  19104 
  19105 /*
  19106  * Function:
  19107  *      bcm_port_pause_set
  19108  * Purpose:
  19109  *      Set the pause state for a given port
  19110  * Parameters:
  19111  *      unit - StrataSwitch Unit #.
  19112  *      port - StrataSwitch port #.
  19113  *      pause_tx - Boolean value, or -1 (don't change)
  19114  *      pause_rx - Boolean value, or -1 (don't change)
  19115  * Returns:
  19116  *      BCM_E_NONE
  19117  *      BCM_E_XXX
  19118  * Notes:
  19119  *      Symmetric pause requires the two "pause" values to be the same.
  19120  */
  19121 
  19122 int
  19123 bcm_esw_port_pause_set(int unit, bcm_port_t port, int pause_tx, int pause_rx)
  19124 {
  19125     int         rv;
  19126 #ifdef BCM_MONTEREY_SUPPORT
  19127     uint32      enable = 0;
  19128 #endif
  19129 #if defined(BCM_KATANA2_SUPPORT)
  19130     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  19131 #endif
  19132 
  19133     /* Make sure port module is initialized. */
  19134     PORT_INIT(unit);
  19135 
  19136     /* Call Port Control module */
  19137     if (SOC_USE_PORTCTRL(unit)) {
  19138 #ifdef BCM_MONTEREY_SUPPORT
  19139         if (SOC_IS_MONTEREY(unit)) {
  19140             BCM_IF_ERROR_RETURN(
  19141                 bcmi_esw_portctrl_preemption_mac_config_get(
  19142                 unit, port, bcmPortPreemptControlEnableTx, &enable));
  19143             if (enable && (pause_tx || pause_rx)) {
  19144                 return BCM_E_PARAM;
  19145             }
  19146         }
  19147 #endif
  19148         return bcmi_esw_portctrl_pause_set(unit, port, pause_tx, pause_rx);
  19149     }
  19150 
  19151     if(bcm_common_oamp_port_enable_get(unit, port)) {
  19152         LOG_ERROR(BSL_LS_BCM_PORT,
  19153                   (BSL_META("Error: Cannot set pause state on OAMP Port %d.\n"),
  19154                    port));
  19155         return BCM_E_PARAM;
  19156     }
  19157 
  19158 #if defined(BCM_KATANA2_SUPPORT)
  19159 #if defined(BCM_SABER2_SUPPORT)
  19160     if(SOC_IS_SABER2(unit)) {
  19161         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  19162     }
  19163 #endif
  19164     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  19165         (!((port >= 1) && (port <= max_phy_port)))) {
  19166          return BCM_E_PORT;
  19167     }
  19168 #endif
  19169 
  19170     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  19171 
  19172     PORT_LOCK(unit);
  19173     rv = MAC_PAUSE_SET(PORT(unit, port).p_mac, unit, port, pause_tx, pause_rx);
  19174     if (BCM_FAILURE(rv)) {
  19175         PORT_UNLOCK(unit);
  19176         return (rv);
  19177     }
  19178 
  19179 #if defined(BCM_BRADLEY_SUPPORT)
  19180     if (SOC_IS_HBX(unit)) {
  19181 #ifdef BCM_SHADOW_SUPPORT
  19182     if (!SOC_IS_SHADOW(unit)) {
  19183 #endif
  19184         rv = _bcm_port_mmu_update(unit, port, -1);
  19185 #ifdef BCM_SHADOW_SUPPORT
  19186     }
  19187 #endif
  19188     }
  19189 #endif /* BCM_BRADLEY_SUPPORT */
  19190 
  19191     PORT_UNLOCK(unit);
  19192     return rv;
  19193 }
  19194 
  19195 /*
  19196  * Function:
  19197  *      bcm_port_pause_sym_get
  19198  * Purpose:
  19199  *      Get the current pause setting for pause
  19200  * Parameters:
  19201  *      unit - StrataSwitch Unit #.
  19202  *      port - StrataSwitch port #.
  19203  *      pause - (OUT) returns a bcm_port_pause_e enum value
  19204  * Returns:
  19205  *      BCM_E_NONE
  19206  *      BCM_E_XXX
  19207  */
  19208 
  19209 int
  19210 bcm_esw_port_pause_sym_get(int unit, bcm_port_t port, int *pause)
  19211 {
  19212     int         pause_rx, pause_tx;
  19213 #if defined(BCM_KATANA2_SUPPORT)
  19214     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  19215 #endif
  19216 
  19217 #if defined(BCM_KATANA2_SUPPORT)
  19218 #if defined(BCM_SABER2_SUPPORT)
  19219     if(SOC_IS_SABER2(unit)) {
  19220         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  19221     }
  19222 #endif
  19223     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  19224         (!((port >= 1) && (port <= max_phy_port)))) {
  19225          return BCM_E_PORT;
  19226     }
  19227 #endif
  19228 
  19229     /* Make sure port module is initialized. */
  19230     PORT_INIT(unit);
  19231 
  19232     if(bcm_common_oamp_port_enable_get(unit, port)) {
  19233         LOG_ERROR(BSL_LS_BCM_PORT,
  19234                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  19235                    port));
  19236         return BCM_E_PARAM;
  19237     }
  19238 
  19239     BCM_IF_ERROR_RETURN
  19240         (bcm_esw_port_pause_get(unit, port, &pause_tx, &pause_rx));
  19241     if (pause_tx) {
  19242         if (pause_rx) {
  19243             *pause = BCM_PORT_PAUSE_SYM;
  19244         } else {
  19245             *pause = BCM_PORT_PAUSE_ASYM_TX;
  19246         }
  19247     } else if (pause_rx) {
  19248         *pause = BCM_PORT_PAUSE_ASYM_RX;
  19249     } else {
  19250         *pause = BCM_PORT_PAUSE_NONE;
  19251     }
  19252 
  19253     return BCM_E_NONE;
  19254 }
  19255 
  19256 /*
  19257  * Function:
  19258  *      bcm_port_pause_sym_set
  19259  * Purpose:
  19260  *      Set the pause values for the port using single integer
  19261  * Parameters:
  19262  *      unit - StrataSwitch Unit #.
  19263  *      port - StrataSwitch port #.
  19264  *      pause - a bcm_port_pause_e enum value
  19265  * Returns:
  19266  *      BCM_E_NONE
  19267  *      BCM_E_XXX
  19268  */
  19269 
  19270 int
  19271 bcm_esw_port_pause_sym_set(int unit, bcm_port_t port, int pause)
  19272 {
  19273     int         pause_rx, pause_tx;
  19274 #if defined(BCM_KATANA2_SUPPORT)
  19275     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  19276 #endif
  19277 
  19278 #if defined(BCM_KATANA2_SUPPORT)
  19279 #if defined(BCM_SABER2_SUPPORT)
  19280     if(SOC_IS_SABER2(unit)) {
  19281         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  19282     }
  19283 #endif
  19284     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  19285         (!((port >= 1) && (port <= max_phy_port)))) {
  19286          return BCM_E_PORT;
  19287     }
  19288 #endif
  19289     /* Make sure port module is initialized. */
  19290     PORT_INIT(unit);
  19291 
  19292     if(bcm_common_oamp_port_enable_get(unit, port)) {
  19293         LOG_ERROR(BSL_LS_BCM_PORT,
  19294                   (BSL_META("Error: Cannot set pause values on OAMP Port %d.\n"),
  19295                    port));
  19296         return BCM_E_PARAM;
  19297     }
  19298 
  19299     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  19300 
  19301     pause_tx = pause_rx = 0;
  19302 
  19303     switch (pause) {
  19304     case BCM_PORT_PAUSE_SYM:
  19305         pause_tx = pause_rx = 1;
  19306         break;
  19307     case BCM_PORT_PAUSE_ASYM_RX:
  19308         pause_rx = 1;
  19309         break;
  19310     case BCM_PORT_PAUSE_ASYM_TX:
  19311         pause_tx = 1;
  19312         break;
  19313     case BCM_PORT_PAUSE_NONE:
  19314         break;
  19315     default:
  19316         return BCM_E_PARAM;
  19317     }
  19318 
  19319     return bcm_esw_port_pause_set(unit, port, pause_tx, pause_rx);
  19320 }
  19321 
  19322 /*
  19323  * Function:
  19324  *      bcm_port_pause_addr_get
  19325  * Purpose:
  19326  *      Get the source address for transmitted PAUSE frames.
  19327  * Parameters:
  19328  *      unit - StrataSwitch Unit #.
  19329  *      port - StrataSwitch port #.
  19330  *      mac - (OUT) MAC address sent with pause frames.
  19331  * Returns:
  19332  *      BCM_E_NONE
  19333  *      BCM_E_XXX
  19334  */
  19335 
  19336 int
  19337 bcm_esw_port_pause_addr_get(int unit, bcm_port_t port, bcm_mac_t mac)
  19338 {
  19339     int         rv;
  19340 #if defined(BCM_KATANA2_SUPPORT)
  19341     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  19342 #endif
  19343 
  19344     /* Make sure port module is initialized. */
  19345     PORT_INIT(unit);
  19346 
  19347     /* Call Port Control module */
  19348     if (SOC_USE_PORTCTRL(unit)) {
  19349         return bcmi_esw_portctrl_pause_addr_get(unit, port, mac);
  19350     }
  19351 
  19352     if(bcm_common_oamp_port_enable_get(unit, port)) {
  19353         LOG_ERROR(BSL_LS_BCM_PORT,
  19354                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  19355                    port));
  19356         return BCM_E_PARAM;
  19357     }
  19358 
  19359 #if defined(BCM_KATANA2_SUPPORT)
  19360 #if defined(BCM_SABER2_SUPPORT)
  19361     if(SOC_IS_SABER2(unit)) {
  19362         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  19363     }
  19364 #endif
  19365     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  19366         (!((port >= 1) && (port <= max_phy_port)))) {
  19367          return BCM_E_PORT;
  19368     }
  19369 #endif
  19370 
  19371     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  19372 
  19373     PORT_LOCK(unit);
  19374     rv = MAC_PAUSE_ADDR_GET(PORT(unit, port).p_mac, unit, port, mac);
  19375     PORT_UNLOCK(unit);
  19376 
  19377     return rv;
  19378 }
  19379 
  19380 /*
  19381  * Function:
  19382  *      bcm_port_pause_addr_set
  19383  * Purpose:
  19384  *      Set the source address for transmitted PAUSE frames.
  19385  * Parameters:
  19386  *      unit - StrataSwitch Unit #.
  19387  *      port - StrataSwitch port #.
  19388  *      mac - station address used for pause frames.
  19389  * Returns:
  19390  *      BCM_E_NONE
  19391  *      BCM_E_XXX
  19392  * Notes:
  19393  *      Symmetric pause requires the two "pause" values to be the same.
  19394  */
  19395 
  19396 int
  19397 bcm_esw_port_pause_addr_set(int unit, bcm_port_t port, bcm_mac_t mac)
  19398 {
  19399     int         rv;
  19400 #if defined(BCM_KATANA2_SUPPORT)
  19401     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  19402 #endif
  19403 
  19404     /* Make sure port module is initialized. */
  19405     PORT_INIT(unit);
  19406 
  19407     /* Call Port Control module */
  19408     if (SOC_USE_PORTCTRL(unit)) {
  19409         return bcmi_esw_portctrl_pause_addr_set(unit, port, mac);
  19410     }
  19411 
  19412     if(bcm_common_oamp_port_enable_get(unit, port)) {
  19413         LOG_ERROR(BSL_LS_BCM_PORT,
  19414                   (BSL_META("Error: Cannot set pause addr on OAMP Port %d.\n"),
  19415                    port));
  19416         return BCM_E_PARAM;
  19417     }
  19418 
  19419 #if defined(BCM_KATANA2_SUPPORT)
  19420 #if defined(BCM_SABER2_SUPPORT)
  19421     if(SOC_IS_SABER2(unit)) {
  19422         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  19423     }
  19424 #endif
  19425     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  19426         (!((port >= 1) && (port <= max_phy_port)))) {
  19427          return BCM_E_PORT;
  19428     }
  19429 #endif
  19430 
  19431     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  19432 
  19433     PORT_LOCK(unit);
  19434     rv = MAC_PAUSE_ADDR_SET(PORT(unit, port).p_mac, unit, port, mac);
  19435     PORT_UNLOCK(unit);
  19436 
  19437     return rv;
  19438 }
  19439 
  19440 /*
  19441  * Function:
  19442  *      bcm_port_advert_get
  19443  * Purpose:
  19444  *      Retrieve the local port advertisement for autonegotiation.
  19445  * Parameters:
  19446  *      unit - StrataSwitch Unit #.
  19447  *      port - StrataSwitch port #.
  19448  *      ability_mask - (OUT) Local advertisement.
  19449  * Returns:
  19450  *      BCM_E_NONE
  19451  *      BCM_E_XXX
  19452  */
  19453 
  19454 int
  19455 bcm_esw_port_advert_get(int unit, bcm_port_t port, bcm_port_abil_t *ability_mask)
  19456 {
  19457     int                 rv;
  19458     bcm_port_ability_t  ability;
  19459 #if defined(BCM_KATANA2_SUPPORT)
  19460     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  19461 #endif
  19462 
  19463     /* Make sure port module is initialized. */
  19464     PORT_INIT(unit);
  19465 
  19466     if (SOC_USE_PORTCTRL(unit)) {
  19467         return bcmi_esw_portctrl_ability_advert_get(unit, port,
  19468                                                     &ability, ability_mask);
  19469     }
  19470     sal_memset(&ability, 0, sizeof(bcm_port_ability_t));
  19471 
  19472 #if defined(BCM_KATANA2_SUPPORT)
  19473 #if defined(BCM_SABER2_SUPPORT)
  19474     if(SOC_IS_SABER2(unit)) {
  19475         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  19476     }
  19477 #endif
  19478     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  19479         (!((port >= 1) && (port <= max_phy_port)))) {
  19480          return BCM_E_PORT;
  19481     }
  19482 #endif
  19483     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  19484 
  19485     PORT_LOCK(unit);
  19486     rv = soc_phyctrl_ability_advert_get(unit, port, &ability);
  19487     if (BCM_SUCCESS(rv)) {
  19488         rv = soc_port_ability_to_mode(&ability, ability_mask);
  19489     }
  19490     PORT_UNLOCK(unit);
  19491 
  19492 
  19493 
  19494     LOG_INFO(BSL_LS_BCM_PORT,
  19495              (BSL_META_U(unit,
  19496                          "bcm_port_advert_get: u=%d p=%d abil=0x%x rv=%d\n"),
  19497               unit, port, *ability_mask, rv));
  19498 
  19499     return rv;
  19500 }
  19501 
  19502 /*
  19503  * Function:
  19504  *      bcm_esw_port_ability_advert_get
  19505  * Purpose:
  19506  *      Retrieve the local port advertisement for autonegotiation.
  19507  * Parameters:
  19508  *      unit - StrataSwitch Unit #.
  19509  *      port - StrataSwitch port #.
  19510  *      ability_mask - (OUT) Local advertisement.
  19511  * Returns:
  19512  *      BCM_E_NONE
  19513  *      BCM_E_XXX
  19514  */
  19515 
  19516 int
  19517 bcm_esw_port_ability_advert_get(int unit, bcm_port_t port,
  19518                                 bcm_port_ability_t *ability_mask)
  19519 {
  19520     int         rv=BCM_E_NONE;
  19521 #if defined(BCM_KATANA2_SUPPORT)
  19522     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  19523 #endif
  19524 
  19525     /* Make sure port module is initialized. */
  19526     PORT_INIT(unit);
  19527 
  19528     /* Call Port Control module */
  19529     if (SOC_USE_PORTCTRL(unit)) {
  19530         return bcmi_esw_portctrl_ability_advert_get(unit, port,
  19531                                                     ability_mask, NULL);
  19532     }
  19533 
  19534     if(bcm_common_oamp_port_enable_get(unit, port)) {
  19535         LOG_ERROR(BSL_LS_BCM_PORT,
  19536                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  19537                    port));
  19538         return BCM_E_PARAM;
  19539     }
  19540 
  19541 #if defined(BCM_KATANA2_SUPPORT)
  19542 #if defined(BCM_SABER2_SUPPORT)
  19543     if(SOC_IS_SABER2(unit)) {
  19544         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  19545     }
  19546 #endif
  19547     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  19548         (!((port >= 1) && (port <= max_phy_port)))) {
  19549          return BCM_E_PORT;
  19550     }
  19551 #endif
  19552 
  19553     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  19554 
  19555     if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
  19556         return BCM_E_PORT;
  19557     }
  19558 
  19559     sal_memset(ability_mask, 0, sizeof(bcm_port_ability_t));
  19560     PORT_LOCK(unit);
  19561     rv = soc_phyctrl_ability_advert_get(unit, port, ability_mask);
  19562     PORT_UNLOCK(unit);
  19563 
  19564     LOG_INFO(BSL_LS_BCM_PORT,
  19565              (BSL_META_U(unit,
  19566                          "bcm_esw_port_ability_advert_get: u=%d p=%d rv=%d\n"),
  19567               unit, port, rv));
  19568 
  19569     return rv;
  19570 }
  19571 /*
  19572  * Function:
  19573  *      bcm_port_autoneg_ability_advert_get
  19574  * Purpose:
  19575  *      Retrieve the local port abilities.
  19576  * Parameters:
  19577  *      unit - StrataSwitch Unit #.
  19578  *      port - StrataSwitch port #.
  19579  *      max_num_ability  -- the max num of autoneg ability this port can advertise
  19580  *      ability - (OUT) values indicating the ability this port advertise
  19581  *      actual_num_ability - (OUT) the actual num of ability that this port advertise
  19582  * Returns:
  19583  *      BCM_E_NONE
  19584  *      BCM_E_XXX
  19585  */
  19586 int
  19587 bcm_esw_port_autoneg_ability_advert_get(int unit,
  19588                                      bcm_port_t port,
  19589                                      int max_num_ability,
  19590                                      bcm_port_speed_ability_t *abilities,
  19591                                      int *actual_num_ability)
  19592 {
  19593     int rv = BCM_E_UNAVAIL;
  19594 
  19595     /* Make sure port module is initialized. */
  19596     PORT_INIT(unit);
  19597 
  19598     /* Call Port Control module */
  19599     if (SOC_USE_PORTCTRL(unit)) {
  19600         rv = bcmi_esw_portctrl_autoneg_ability_advert_get(unit, port, max_num_ability,
  19601                                                           abilities, actual_num_ability);
  19602     }
  19603 
  19604     return rv;
  19605 }
  19606 
  19607 
  19608 /*
  19609  * Function:
  19610  *      bcm_port_advert_set
  19611  * Purpose:
  19612  *      Set the local port advertisement for autonegotiation.
  19613  * Parameters:
  19614  *      unit - StrataSwitch Unit #.
  19615  *      port - StrataSwitch port #.
  19616  *      ability_mask - Local advertisement.
  19617  * Returns:
  19618  *      BCM_E_NONE
  19619  *      BCM_E_XXX
  19620  * Notes:
  19621  *      This call MAY NOT restart autonegotiation (depending on the phy).
  19622  *      To do that, follow this call with bcm_port_autoneg_set(TRUE).
  19623  */
  19624 
  19625 int
  19626 bcm_esw_port_advert_set(int unit, bcm_port_t port, bcm_port_abil_t ability_mask)
  19627 {
  19628     int                 rv;
  19629     bcm_port_ability_t  given_ability, port_ability, temp_ability;
  19630 #if defined(BCM_KATANA2_SUPPORT)
  19631     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  19632 #endif
  19633 
  19634     /* Make sure port module is initialized. */
  19635     PORT_INIT(unit);
  19636 
  19637     /* Call Port Control module */
  19638     if (SOC_USE_PORTCTRL(unit)) {
  19639         return bcmi_esw_portctrl_ability_advert_set(unit, port,
  19640                                                     NULL, ability_mask);
  19641     }
  19642 
  19643     if(bcm_common_oamp_port_enable_get(unit, port)) {
  19644         LOG_ERROR(BSL_LS_BCM_PORT,
  19645                   (BSL_META("Error: Cannot set port advert on OAMP Port %d.\n"),
  19646                    port));
  19647         return BCM_E_PARAM;
  19648     }
  19649 
  19650 #if defined(BCM_KATANA2_SUPPORT)
  19651 #if defined(BCM_SABER2_SUPPORT)
  19652     if(SOC_IS_SABER2(unit)) {
  19653         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  19654     }
  19655 #endif
  19656     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  19657         (!((port >= 1) && (port <= max_phy_port)))) {
  19658          return BCM_E_PORT;
  19659     }
  19660 #endif
  19661 
  19662     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  19663 
  19664     BCM_IF_ERROR_RETURN
  19665         (bcm_esw_port_ability_local_get(unit, port, &port_ability));
  19666 
  19667     BCM_IF_ERROR_RETURN
  19668         (bcm_esw_port_ability_advert_get(unit, port, &given_ability));
  19669 
  19670     BCM_IF_ERROR_RETURN(
  19671         soc_port_mode_to_ability(ability_mask, &given_ability));
  19672 
  19673     /* temporary store ability of half duplex */
  19674     temp_ability.speed_half_duplex = given_ability.speed_half_duplex;
  19675     /* make sure that the ability advertising in PHY is supported by MAC */
  19676     soc_port_ability_mask(&given_ability, &port_ability);
  19677     /* restore half duplex ability */
  19678     given_ability.speed_half_duplex = temp_ability.speed_half_duplex;
  19679 
  19680     if (IS_HG_PORT(unit, port) && SOC_INFO(unit).port_speed_max[port]) {
  19681         if (SOC_INFO(unit).port_speed_max[port] < 16000) {
  19682             given_ability.speed_full_duplex &= ~(BCM_PORT_ABILITY_16GB);
  19683             given_ability.speed_half_duplex &= ~(BCM_PORT_ABILITY_16GB);
  19684         }
  19685 
  19686         if (SOC_INFO(unit).port_speed_max[port] < 13000) {
  19687             given_ability.speed_full_duplex &= ~(BCM_PORT_ABILITY_13GB);
  19688             given_ability.speed_half_duplex &= ~(BCM_PORT_ABILITY_13GB);
  19689         }
  19690 
  19691         if (SOC_INFO(unit).port_speed_max[port] < 12000) {
  19692             given_ability.speed_full_duplex &= ~(BCM_PORT_ABILITY_12GB);
  19693             given_ability.speed_half_duplex &= ~(BCM_PORT_ABILITY_12GB);
  19694         }
  19695 
  19696         if (IS_HL_PORT(unit, port)) {
  19697             if (!(given_ability.speed_full_duplex & BCM_PORT_ABILITY_2500MB)) {
  19698                 return BCM_E_CONFIG;
  19699             }
  19700         } else if (!(given_ability.speed_full_duplex & (BCM_PORT_ABILITY_16GB |
  19701               BCM_PORT_ABILITY_13GB | BCM_PORT_ABILITY_12GB |
  19702               BCM_PORT_ABILITY_10GB))) {
  19703             return BCM_E_CONFIG;
  19704         }
  19705     }
  19706 
  19707     PORT_LOCK(unit);
  19708     rv = soc_phyctrl_ability_advert_set(unit, port, &given_ability);
  19709     PORT_UNLOCK(unit);
  19710 
  19711     LOG_INFO(BSL_LS_BCM_PORT,
  19712              (BSL_META_U(unit,
  19713                          "bcm_port_advert_set: u=%d p=%d abil=0x%x rv=%d\n"),
  19714               unit, port, ability_mask, rv));
  19715 
  19716     return rv;
  19717 }
  19718 
  19719 /*
  19720  * Function:
  19721  *      bcm_port_ability_advert_set
  19722  * Purpose:
  19723  *      Set the local port advertisement for autonegotiation.
  19724  * Parameters:
  19725  *      unit - StrataSwitch Unit #.
  19726  *      port - StrataSwitch port #.
  19727  *      ability_mask - Local advertisement.
  19728  * Returns:
  19729  *      BCM_E_NONE
  19730  *      BCM_E_XXX
  19731  * Notes:
  19732  *      This call MAY NOT restart autonegotiation (depending on the phy).
  19733  *      To do that, follow this call with bcm_port_autoneg_set(TRUE).
  19734  */
  19735 
  19736 int
  19737 bcm_esw_port_ability_advert_set(int unit, bcm_port_t port,
  19738                                 bcm_port_ability_t *ability_mask)
  19739 {
  19740     int             rv=BCM_E_NONE;
  19741     bcm_port_ability_t port_ability, temp_ability;
  19742 #if defined(BCM_KATANA2_SUPPORT)
  19743     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  19744 #endif
  19745 
  19746     /* Make sure port module is initialized. */
  19747     PORT_INIT(unit);
  19748 
  19749     /* Call Port Control module */
  19750     if (SOC_USE_PORTCTRL(unit)) {
  19751         return bcmi_esw_portctrl_ability_advert_set(unit, port,
  19752                                                     ability_mask, 0);
  19753     }
  19754 
  19755     if(bcm_common_oamp_port_enable_get(unit, port)) {
  19756         LOG_ERROR(BSL_LS_BCM_PORT,
  19757                   (BSL_META(
  19758 						"Error: Cannot set port ability on OAMP Port %d.\n"),
  19759                    port));
  19760         return BCM_E_PARAM;
  19761     }
  19762 
  19763 #if defined(BCM_KATANA2_SUPPORT)
  19764 #if defined(BCM_SABER2_SUPPORT)
  19765     if(SOC_IS_SABER2(unit)) {
  19766         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  19767     }
  19768 #endif
  19769     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  19770         (!((port >= 1) && (port <= max_phy_port)))) {
  19771          return BCM_E_PORT;
  19772     }
  19773 #endif
  19774 
  19775     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  19776 
  19777     if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
  19778         return BCM_E_PORT;
  19779     }
  19780 
  19781     BCM_IF_ERROR_RETURN
  19782         (bcm_esw_port_ability_local_get(unit, port, &port_ability));
  19783 
  19784     /* temporary store speed_half_duplex ability */
  19785     temp_ability.speed_half_duplex = ability_mask->speed_half_duplex;
  19786     /* Make sure to advertise only abilities supported by the port */
  19787     soc_port_ability_mask(&port_ability, ability_mask);
  19788     /* restore speed_half_duplex ability even some mac don't support it */
  19789     port_ability.speed_half_duplex = temp_ability.speed_half_duplex;
  19790     PORT_LOCK(unit);
  19791     rv = soc_phyctrl_ability_advert_set(unit, port, &port_ability);
  19792     PORT_UNLOCK(unit);
  19793     LOG_INFO(BSL_LS_BCM_PORT,
  19794              (BSL_META_U(unit,
  19795                          "bcm_port_ability_advert_set: u=%d p=%d rv=%d\n"),
  19796               unit, port, rv));
  19797     LOG_VERBOSE(BSL_LS_BCM_PORT,
  19798                 (BSL_META_U(unit,
  19799                             "Speed(HD=0x%08x, FD=0x%08x) Pause=0x%08x advert_set\n"
  19800                             "Interface=0x%08x Medium=0x%08x Loopback=0x%08x Flags=0x%08x\n"),
  19801                  port_ability.speed_half_duplex,
  19802                  port_ability.speed_full_duplex,
  19803                  port_ability.pause, port_ability.interface,
  19804                  port_ability.medium, port_ability.loopback,
  19805                  port_ability.flags));
  19806 
  19807     return rv;
  19808 }
  19809 
  19810 /*
  19811  * Function:
  19812  *      bcm_port_autoneg_ability_advert_set
  19813  * Purpose:
  19814  *      Set the local port advertisement for autonegotiation.
  19815  * Parameters:
  19816  *      unit - StrataSwitch Unit #.
  19817  *      port - StrataSwitch port #.
  19818  *      num_ability - number of ability the port will advertise
  19819  *      ability - Local advertisement for each ability.
  19820  * Returns:
  19821  *      BCM_E_NONE
  19822  *      BCM_E_XXX
  19823  * Notes:
  19824  *      This call WILL NOT restart autonegotiation (depending on the phy).
  19825  *      To do that, follow this call with bcm_port_autoneg_set(TRUE).
  19826  */
  19827  
  19828 int bcm_esw_port_autoneg_ability_advert_set(int unit,
  19829                                             bcm_port_t port,
  19830                                             int num_ability,
  19831                                             bcm_port_speed_ability_t *abilities)
  19832 {
  19833     int             rv = BCM_E_UNAVAIL;
  19834 
  19835     /* Make sure port module is initialized. */
  19836     PORT_INIT(unit);
  19837 
  19838     /* Call Port Control module */
  19839     if (SOC_USE_PORTCTRL(unit)) {
  19840         rv = bcmi_esw_portctrl_autoneg_ability_advert_set(unit, port,
  19841                                                           num_ability, abilities);
  19842     }
  19843 
  19844     return rv;
  19845 }
  19846 
  19847 
  19848 /*
  19849  * Function:
  19850  *      bcm_port_advert_remote_get
  19851  * Purpose:
  19852  *      Retrieve the local port advertisement for autonegotiation.
  19853  * Parameters:
  19854  *      unit - StrataSwitch Unit #.
  19855  *      port - StrataSwitch port #.
  19856  *      ability_mask - (OUT) Remote advertisement.
  19857  * Returns:
  19858  *      BCM_E_NONE
  19859  *      BCM_E_XXX
  19860  */
  19861 
  19862 int
  19863 bcm_esw_port_advert_remote_get(int unit, bcm_port_t port,
  19864                                bcm_port_abil_t *ability_mask)
  19865 {
  19866     int                 rv;
  19867     bcm_port_ability_t  port_ability;
  19868 #if defined(BCM_KATANA2_SUPPORT)
  19869     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  19870 #endif
  19871 
  19872     /* Make sure port module is initialized. */
  19873     PORT_INIT(unit);
  19874 
  19875     /* Call Port Control module */
  19876     if (SOC_USE_PORTCTRL(unit)) {
  19877         return bcmi_esw_portctrl_ability_remote_get(unit, port,
  19878                                                     &port_ability,
  19879                                                     ability_mask);
  19880     }
  19881 
  19882     sal_memset(&port_ability, 0, sizeof(bcm_port_ability_t));
  19883 
  19884 #if defined(BCM_KATANA2_SUPPORT)
  19885 #if defined(BCM_SABER2_SUPPORT)
  19886     if(SOC_IS_SABER2(unit)) {
  19887         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  19888     }
  19889 #endif
  19890     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  19891         (!((port >= 1) && (port <= max_phy_port)))) {
  19892          return BCM_E_PORT;
  19893     }
  19894 #endif
  19895     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  19896 
  19897     PORT_LOCK(unit);
  19898     rv = _bcm_port_autoneg_advert_remote_get(unit, port, &port_ability);
  19899     if (BCM_SUCCESS(rv)) {
  19900         rv = soc_port_ability_to_mode(&port_ability, ability_mask);
  19901     }
  19902     PORT_UNLOCK(unit);
  19903 
  19904     LOG_INFO(BSL_LS_BCM_PORT,
  19905              (BSL_META_U(unit,
  19906                          "bcm_port_advert_remote_get: u=%d p=%d abil=0x%x rv=%d\n"),
  19907               unit, port, *ability_mask, rv));
  19908 
  19909     return rv;
  19910 }
  19911 
  19912 
  19913 /*
  19914  * Function:
  19915  *      bcm_port_ability_remote_get
  19916  * Purpose:
  19917  *      Retrieve the local port advertisement for autonegotiation.
  19918  * Parameters:
  19919  *      unit - StrataSwitch Unit #.
  19920  *      port - StrataSwitch port #.
  19921  *      ability_mask - (OUT) Remote advertisement.
  19922  * Returns:
  19923  *      BCM_E_NONE
  19924  *      BCM_E_XXX
  19925  */
  19926 int
  19927 bcm_esw_port_ability_remote_get(int unit, bcm_port_t port,
  19928                            bcm_port_ability_t *ability_mask)
  19929 {
  19930     int         rv;
  19931 #if defined(BCM_KATANA2_SUPPORT)
  19932     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  19933 #endif
  19934 
  19935     /* Make sure port module is initialized. */
  19936     PORT_INIT(unit);
  19937 
  19938     /* Call Port Control module */
  19939     if (SOC_USE_PORTCTRL(unit)) {
  19940         return bcmi_esw_portctrl_ability_remote_get(unit, port,
  19941                                                     ability_mask, NULL);
  19942     }
  19943 
  19944 #if defined(BCM_KATANA2_SUPPORT)
  19945 #if defined(BCM_SABER2_SUPPORT)
  19946     if(SOC_IS_SABER2(unit)) {
  19947         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  19948     }
  19949 #endif
  19950     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  19951         (!((port >= 1) && (port <= max_phy_port)))) {
  19952          return BCM_E_PORT;
  19953     }
  19954 #endif
  19955 
  19956     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  19957 
  19958     sal_memset(ability_mask, 0, sizeof(bcm_port_ability_t));
  19959     PORT_LOCK(unit);
  19960     rv = _bcm_port_autoneg_advert_remote_get(unit, port, ability_mask);
  19961     PORT_UNLOCK(unit);
  19962 
  19963     LOG_INFO(BSL_LS_BCM_PORT,
  19964              (BSL_META_U(unit,
  19965                          "bcm_port_ability_remote_get: u=%d p=%d rv=%d\n"),
  19966               unit, port, rv));
  19967     LOG_VERBOSE(BSL_LS_BCM_PORT,
  19968                 (BSL_META_U(unit,
  19969                             "Speed(HD=0x%08x, FD=0x%08x) Pause=0x%08x remote_get\n"
  19970                             "Interface=0x%08x Medium=0x%08x Loopback=0x%08x Flags=0x%08x\n"),
  19971                  ability_mask->speed_half_duplex,
  19972                  ability_mask->speed_full_duplex,
  19973                  ability_mask->pause, ability_mask->interface,
  19974                  ability_mask->medium, ability_mask->loopback,
  19975                  ability_mask->flags));
  19976 
  19977     return rv;
  19978 }
  19979 /*
  19980  * Function:
  19981  *      bcm_port_autoneg_ability_remote_get
  19982  * Purpose:
  19983  *      Retrieve the local port abilities.
  19984  * Parameters:
  19985  *      unit - StrataSwitch Unit #.
  19986  *      port - StrataSwitch port #.
  19987  *      max_num_ability  -- the max num of speed ability remote partner can advertise
  19988  *      ability - (OUT) values indicating the ability of the MAC/PHY
  19989  *      actual_num_ability - (OUT) the actual num of ability that remote partner advertise
  19990  * Returns:
  19991  *      BCM_E_NONE
  19992  *      BCM_E_XXX
  19993  */
  19994 int
  19995 bcm_esw_port_autoneg_ability_remote_get(int unit,
  19996                                      bcm_port_t port,
  19997                                      int max_num_ability,
  19998                                      bcm_port_speed_ability_t *abilities,
  19999                                      int *actual_num_ability)
  20000 {
  20001     int rv = BCM_E_UNAVAIL;
  20002 
  20003     /* Make sure port module is initialized. */
  20004     PORT_INIT(unit);
  20005 
  20006     /* Call Port Control module */
  20007     if (SOC_USE_PORTCTRL(unit)) {
  20008         rv = bcmi_esw_portctrl_autoneg_ability_remote_get(unit, port, max_num_ability,
  20009                                                           abilities, actual_num_ability);
  20010     }
  20011     return rv;
  20012 }
  20013 
  20014 
  20015 /*
  20016  * Function:
  20017  *      bcm_port_ability_get
  20018  * Purpose:
  20019  *      Retrieve the local port abilities.
  20020  * Parameters:
  20021  *      unit - StrataSwitch Unit #.
  20022  *      port - StrataSwitch port #.
  20023  *      ability_mask - (OUT) Mask of BCM_PORT_ABIL_ values indicating the
  20024  *              ability of the MAC/PHY.
  20025  * Returns:
  20026  *      BCM_E_NONE
  20027  *      BCM_E_XXX
  20028  */
  20029 
  20030 int
  20031 bcm_esw_port_ability_get(int unit, bcm_port_t port, bcm_port_abil_t *ability_mask)
  20032 {
  20033     int                 rv;
  20034     bcm_port_ability_t  port_ability;
  20035 #if defined(BCM_KATANA2_SUPPORT)
  20036     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  20037 #endif
  20038 
  20039     /* Make sure port module is initialized. */
  20040     PORT_INIT(unit);
  20041 
  20042     if (SOC_USE_PORTCTRL(unit)) {
  20043         return bcmi_esw_portctrl_ability_get(unit, port,
  20044                                              &port_ability, ability_mask);
  20045     }
  20046 
  20047     if(bcm_common_oamp_port_enable_get(unit, port)) {
  20048         LOG_ERROR(BSL_LS_BCM_PORT,
  20049                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  20050                    port));
  20051         return BCM_E_PARAM;
  20052     }
  20053 
  20054 #if defined(BCM_KATANA2_SUPPORT)
  20055 #if defined(BCM_SABER2_SUPPORT)
  20056     if(SOC_IS_SABER2(unit)) {
  20057         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  20058     }
  20059 #endif
  20060     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  20061         (!((port >= 1) && (port <= max_phy_port)))) {
  20062          return BCM_E_PORT;
  20063     }
  20064 #endif
  20065 
  20066     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  20067 
  20068     if(!(SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) {
  20069        return BCM_E_PORT;
  20070     }
  20071 
  20072     PORT_LOCK(unit);
  20073     rv = _bcm_port_ability_local_get(unit, port, &port_ability);
  20074     if (BCM_SUCCESS(rv)) {
  20075         rv = soc_port_ability_to_mode(&port_ability, ability_mask);
  20076     }
  20077     PORT_UNLOCK(unit);
  20078 
  20079     LOG_INFO(BSL_LS_BCM_PORT,
  20080              (BSL_META_U(unit,
  20081                          "bcm_port_ability_get: u=%d p=%d abil=0x%x rv=%d\n"),
  20082               unit, port, *ability_mask, rv));
  20083 
  20084     return rv;
  20085 }
  20086 
  20087 /*
  20088  * Function:
  20089  *      bcm_port_ability_local_get
  20090  * Purpose:
  20091  *      Retrieve the local port abilities.
  20092  * Parameters:
  20093  *      unit - StrataSwitch Unit #.
  20094  *      port - StrataSwitch port #.
  20095  *      ability_mask - (OUT) Mask of BCM_PORT_ABIL_ values indicating the
  20096  *              ability of the MAC/PHY.
  20097  * Returns:
  20098  *      BCM_E_NONE
  20099  *      BCM_E_XXX
  20100  */
  20101 
  20102 int
  20103 bcm_esw_port_ability_local_get(int unit, bcm_port_t port,
  20104                                bcm_port_ability_t *ability_mask)
  20105 {
  20106     int         rv;
  20107 #if defined(BCM_KATANA2_SUPPORT)
  20108     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  20109 #endif
  20110 
  20111     /* Make sure port module is initialized. */
  20112     PORT_INIT(unit);
  20113 
  20114 
  20115     /* Call Port Control module */
  20116     if (SOC_USE_PORTCTRL(unit)) {
  20117         return bcmi_esw_portctrl_ability_get(unit, port,
  20118                                              ability_mask, NULL);
  20119     }
  20120 
  20121     if(bcm_common_oamp_port_enable_get(unit, port)) {
  20122         LOG_ERROR(BSL_LS_BCM_PORT,
  20123                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  20124                    port));
  20125         return BCM_E_PARAM;
  20126     }
  20127 
  20128 #if defined(BCM_KATANA2_SUPPORT)
  20129 #if defined(BCM_SABER2_SUPPORT)
  20130     if(SOC_IS_SABER2(unit)) {
  20131         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  20132     }
  20133 #endif
  20134     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  20135         (!((port >= 1) && (port <= max_phy_port)))) {
  20136          return BCM_E_PORT;
  20137     }
  20138 #endif
  20139     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  20140 
  20141     sal_memset(ability_mask, 0, sizeof(bcm_port_ability_t));
  20142     PORT_LOCK(unit);
  20143     rv = _bcm_port_ability_local_get(unit, port, ability_mask);
  20144     PORT_UNLOCK(unit);
  20145 
  20146     LOG_INFO(BSL_LS_BCM_PORT,
  20147              (BSL_META_U(unit,
  20148                          "bcm_port_ability_local_get: u=%d p=%d rv=%d\n"),
  20149               unit, port, rv));
  20150     LOG_VERBOSE(BSL_LS_BCM_PORT,
  20151                 (BSL_META_U(unit,
  20152                             "Speed(HD=0x%08x, FD=0x%08x) Pause=0x%08x local_get\n"
  20153                             "Interface=0x%08x Medium=0x%08x EEE=0x%08x Loopback=0x%08x Flags=0x%08x\n"),
  20154                  ability_mask->speed_half_duplex,
  20155                  ability_mask->speed_full_duplex,
  20156                  ability_mask->pause, ability_mask->interface,
  20157                  ability_mask->medium, ability_mask->eee,
  20158                  ability_mask->loopback, ability_mask->flags));
  20159 
  20160     return rv;
  20161 }
  20162 /*
  20163  * Function:
  20164  *      bcm_port_speed_ability_local_get
  20165  * Purpose:
  20166  *      Retrieve the local port abilities.
  20167  * Parameters:
  20168  *      unit - StrataSwitch Unit #.
  20169  *      port - StrataSwitch port #.
  20170  *      max_num_ability  -- the max num of speed ability this port support
  20171  *      ability - (OUT) values indicating the ability of the MAC/PHY
  20172  *      actual_num_ability - (OUT) the actual num of ability that this port can support
  20173  * Returns:
  20174  *      BCM_E_NONE
  20175  *      BCM_E_XXX
  20176  */
  20177 int
  20178 bcm_esw_port_speed_ability_local_get(int unit,
  20179                                      bcm_port_t port,
  20180                                      int max_num_ability,
  20181                                      bcm_port_speed_ability_t *abilities,
  20182                                      int *actual_num_ability)
  20183 {
  20184     int rv = BCM_E_UNAVAIL;
  20185 
  20186     /* Make sure port module is initialized. */
  20187     PORT_INIT(unit);
  20188 
  20189     /* Call Port Control module */
  20190     if (SOC_USE_PORTCTRL(unit)) {
  20191         rv = bcmi_esw_portctrl_speed_ability_local_get(unit, port, max_num_ability,
  20192                                                           abilities, actual_num_ability);
  20193     }
  20194     return rv;
  20195 }
  20196 
  20197 /*
  20198  * Function:
  20199  *      bcm_port_discard_get
  20200  * Purpose:
  20201  *      Get port discard attributes for the specified port
  20202  * Parameters:
  20203  *      unit - StrataSwitch Unit #.
  20204  *      port - StrataSwitch port #.
  20205  *      mode - (OUT) Port discard mode, one of BCM_PORT_DISCARD_xxx
  20206  * Returns:
  20207  *      BCM_E_NONE
  20208  *      BCM_E_XXX
  20209  */
  20210 
  20211 int
  20212 bcm_esw_port_discard_get(int unit, bcm_port_t port, int *mode)
  20213 {
  20214     bcm_port_cfg_t pcfg;
  20215     int                 rv;
  20216 
  20217     /* Make sure port module is initialized. */
  20218     PORT_INIT(unit);
  20219 
  20220     if(bcm_common_oamp_port_enable_get(unit, port)) {
  20221         LOG_ERROR(BSL_LS_BCM_PORT,
  20222                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  20223                    port));
  20224         return BCM_E_PARAM;
  20225     }
  20226 
  20227     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  20228 
  20229     if ((rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)) ==
  20230         BCM_E_NONE) {
  20231         *mode = pcfg.pc_disc;
  20232     }
  20233 
  20234     return(rv);
  20235 }
  20236 
  20237 /*
  20238  * Function:
  20239  *      bcm_port_discard_set
  20240  * Purpose:
  20241  *      Set port discard attributes for the specified port.
  20242  * Parameters:
  20243  *      unit - StrataSwitch Unit #.
  20244  *      port - StrataSwitch port #.
  20245  *      mode - Port discard mode, one of BCM_PORT_DISCARD_xxx
  20246  * Returns:
  20247  *      BCM_E_NONE
  20248  *      BCM_E_XXX
  20249  */
  20250 
  20251 int
  20252 bcm_esw_port_discard_set(int unit, bcm_port_t port, int mode)
  20253 {
  20254     bcm_port_cfg_t      pcfg;
  20255     int                 rv;
  20256 
  20257     /* Make sure port module is initialized. */
  20258     PORT_INIT(unit);
  20259 
  20260     if(bcm_common_oamp_port_enable_get(unit, port)) {
  20261         LOG_ERROR(BSL_LS_BCM_PORT,
  20262                   (BSL_META("Error: Cannot set discard attr on OAMP Port %d.\n"),
  20263                    port));
  20264         return BCM_E_PARAM;
  20265     }
  20266 
  20267     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  20268 
  20269     switch (mode) {
  20270     case BCM_PORT_DISCARD_TAG:
  20271     case BCM_PORT_DISCARD_NONE:
  20272     case BCM_PORT_DISCARD_ALL:
  20273     case BCM_PORT_DISCARD_UNTAG:
  20274         break;
  20275     default:
  20276         return BCM_E_PARAM;
  20277     }
  20278 
  20279     PORT_LOCK(unit);
  20280 
  20281     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  20282 
  20283     if (BCM_SUCCESS(rv)) {
  20284         pcfg.pc_disc = mode;
  20285         rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg);
  20286     }
  20287 
  20288     PORT_UNLOCK(unit);
  20289 
  20290     return rv;
  20291 }
  20292 
  20293 /*
  20294  * Function:
  20295  *      _bcm_port_learn_modify
  20296  * Purpose:
  20297  *      Main part of bcm_port_learn_modify.
  20298  */
  20299 
  20300 STATIC int
  20301 _bcm_port_learn_modify(int unit, bcm_port_t port, uint32 add, uint32 remove)
  20302 {
  20303     uint32      flags;
  20304 
  20305     SOC_IF_ERROR_RETURN(bcm_esw_port_learn_get(unit, port, &flags));
  20306 
  20307     flags |= add;
  20308     flags &= ~remove;
  20309 
  20310     SOC_IF_ERROR_RETURN(bcm_esw_port_learn_set(unit, port, flags));
  20311 
  20312     return BCM_E_NONE;
  20313 }
  20314 
  20315 /*
  20316  * Function:
  20317  *      bcm_port_learn_modify
  20318  * Purpose:
  20319  *      Modify the port learn flags, adding add and removing remove flags.
  20320  * Parameters:
  20321  *      unit - StrataSwitch Unit #.
  20322  *      port - StrataSwitch port #.
  20323  *      add  - Flags to set.
  20324  *      remove - Flags to clear.
  20325  * Returns:
  20326  *      BCM_E_NONE
  20327  *      BCM_E_XXX
  20328  */
  20329 
  20330 int
  20331 bcm_esw_port_learn_modify(int unit, bcm_port_t port, uint32 add, uint32 remove)
  20332 {
  20333     int         rv;
  20334     bcm_port_t  port_out;
  20335 
  20336     /* Make sure port module is initialized. */
  20337     PORT_INIT(unit);
  20338 
  20339     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port_out));
  20340 
  20341     PORT_LOCK(unit);
  20342     rv = _bcm_port_learn_modify(unit, port, add, remove);
  20343     PORT_UNLOCK(unit);
  20344 
  20345     return rv;
  20346 }
  20347 
  20348 /*
  20349  * Function:
  20350  *      bcm_port_learn_get
  20351  * Purpose:
  20352  *      Get the ARL hardware learning options for this port.
  20353  *      This defines what the hardware will do when a packet
  20354  *      is seen with an unknown address.
  20355  * Parameters:
  20356  *      unit - StrataSwitch Unit #.
  20357  *      port - StrataSwitch port #.
  20358  *      flags - (OUT) Logical OR of BCM_PORT_LEARN_xxx flags
  20359  * Returns:
  20360  *      BCM_E_NONE
  20361  *      BCM_E_XXX
  20362  */
  20363 
  20364 int
  20365 bcm_esw_port_learn_get(int unit, bcm_port_t port, uint32 *flags)
  20366 {
  20367     bcm_port_cfg_t      pcfg;
  20368     int                 rv;
  20369 
  20370     /* Make sure port module is initialized. */
  20371     PORT_INIT(unit);
  20372 
  20373     if(bcm_common_oamp_port_enable_get(unit, port)) {
  20374         LOG_ERROR(BSL_LS_BCM_PORT,
  20375                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  20376                    port));
  20377         return BCM_E_PARAM;
  20378     }
  20379 
  20380     if (flags == NULL) {
  20381         return BCM_E_PARAM;
  20382     }
  20383 
  20384 #if defined(BCM_TRX_SUPPORT) && defined(INCLUDE_L3)
  20385     if (BCM_GPORT_IS_SUBPORT_GROUP(port)) {
  20386          if (SOC_IS_SCORPION(unit)) {
  20387              return BCM_E_UNAVAIL;
  20388          } else {
  20389              return bcm_tr_subport_learn_get(unit, (bcm_gport_t) port, flags);
  20390          }
  20391     }
  20392 #endif /* BCM_TRX_SUPPORT && INCLUDE_L3 */
  20393 #if defined(BCM_TRIUMPH_SUPPORT) && defined(BCM_MPLS_SUPPORT) && \
  20394     defined(INCLUDE_L3)
  20395     if (BCM_GPORT_IS_MPLS_PORT(port)) {
  20396         return bcm_tr_mpls_port_learn_get(unit, (bcm_gport_t) port, flags);
  20397     }
  20398 #endif
  20399 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
  20400      && defined(INCLUDE_L3))
  20401     if (BCM_GPORT_IS_MIM_PORT(port)) {
  20402         return bcm_tr2_mim_port_learn_get(unit, (bcm_gport_t) port, flags);
  20403     }
  20404     if (BCM_GPORT_IS_WLAN_PORT(port)) {
  20405 #if defined(BCM_TRIUMPH3_SUPPORT)
  20406         if (SOC_IS_TRIUMPH3(unit)) {
  20407             return bcm_tr3_wlan_port_learn_get(unit, (bcm_gport_t) port, flags);
  20408         } else
  20409 #endif /* BCM_TRIUMPH3_SUPPORT */
  20410         {
  20411             return bcm_tr2_wlan_port_learn_get(unit, (bcm_gport_t) port, flags);
  20412         }
  20413     }
  20414 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
  20415 #if defined(BCM_TRIDENT_SUPPORT)&& defined(INCLUDE_L3)
  20416     if (BCM_GPORT_IS_NIV_PORT(port)) {
  20417         return bcm_trident_niv_port_learn_get(unit, (bcm_gport_t) port, flags);
  20418     }
  20419 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  20420 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  20421     if (SOC_IS_TD2_TT2(unit)) {
  20422         if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  20423             return bcm_td2_vxlan_port_learn_get(unit, (bcm_gport_t) port, flags);
  20424         }
  20425     }
  20426 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */
  20427 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
  20428     if (BCM_GPORT_IS_L2GRE_PORT(port)){
  20429         return bcm_tr3_l2gre_port_learn_get(unit, (bcm_gport_t) port, flags);
  20430     }
  20431 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */
  20432 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
  20433     if (BCM_GPORT_IS_EXTENDER_PORT(port)){
  20434         if (soc_feature(unit, soc_feature_port_extension)) {
  20435             return bcm_tr3_extender_port_learn_get(unit, port, flags);
  20436         }
  20437     }
  20438 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */
  20439 #if defined(BCM_HGPROXY_COE_SUPPORT) && defined(INCLUDE_L3)
  20440     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 
  20441         BCM_GPORT_IS_SUBPORT_PORT(port)) {
  20442             return bcmi_xgs5_subport_port_learn_get(unit, (bcm_gport_t) port, flags);
  20443     }
  20444 #endif /* BCM_HGPROXY_COE_SUPPORT && INCLUDE_L3 */
  20445 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  20446     if (BCM_GPORT_IS_TRUNK(port)){
  20447         if (soc_feature(unit, soc_feature_vp_lag)) {
  20448             return bcm_td2_vp_lag_port_learn_get(unit,
  20449                        BCM_GPORT_TRUNK_GET(port), flags);
  20450         }
  20451     }
  20452 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */
  20453 
  20454     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  20455 
  20456     PORT_LOCK(unit);
  20457 
  20458     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  20459 
  20460     PORT_UNLOCK(unit);
  20461 
  20462     BCM_IF_ERROR_RETURN(rv);
  20463 
  20464 #ifdef BCM_TRX_SUPPORT
  20465     if (SOC_IS_TRX(unit)) {
  20466         *flags = 0;
  20467         BCM_IF_ERROR_RETURN(
  20468             _bcm_trx_port_cml_hw2flags(unit, pcfg.pc_cml, flags));
  20469     } else
  20470 #endif
  20471     {
  20472         switch (pcfg.pc_cml) {
  20473         case PVP_CML_SWITCH:
  20474             *flags = (BCM_PORT_LEARN_ARL |
  20475                       BCM_PORT_LEARN_FWD |
  20476                       (pcfg.pc_cpu ? BCM_PORT_LEARN_CPU : 0));
  20477             break;
  20478         case PVP_CML_CPU:
  20479             *flags = BCM_PORT_LEARN_CPU;
  20480             break;
  20481         case PVP_CML_FORWARD:
  20482             *flags = BCM_PORT_LEARN_FWD;
  20483             break;
  20484         case PVP_CML_DROP:
  20485             *flags = 0;
  20486             break;
  20487         case PVP_CML_CPU_SWITCH:
  20488             *flags = (BCM_PORT_LEARN_ARL |
  20489                       BCM_PORT_LEARN_CPU |
  20490                       BCM_PORT_LEARN_FWD);
  20491             break;
  20492         case PVP_CML_CPU_FORWARD:
  20493             *flags = BCM_PORT_LEARN_CPU | BCM_PORT_LEARN_FWD;
  20494             break;
  20495         default:
  20496             return BCM_E_INTERNAL;
  20497         }
  20498     }
  20499 
  20500     return BCM_E_NONE;
  20501 }
  20502 
  20503 /*
  20504  * Function:
  20505  *      bcm_port_learn_set
  20506  * Purpose:
  20507  *      Set the ARL hardware learning options for this port.
  20508  *      This defines what the hardware will do when a packet
  20509  *      is seen with an unknown address.
  20510  * Parameters:
  20511  *      unit - StrataSwitch Unit #.
  20512  *      port - StrataSwitch port #.
  20513  *      flags - Logical OR of BCM_PORT_LEARN_xxx flags
  20514  * Returns:
  20515  *      BCM_E_NONE
  20516  *      BCM_E_XXX
  20517  */
  20518 
  20519 #define Arl     BCM_PORT_LEARN_ARL
  20520 #define Cpu     BCM_PORT_LEARN_CPU
  20521 #define Fwd     BCM_PORT_LEARN_FWD
  20522 
  20523 int
  20524 bcm_esw_port_learn_set(int unit, bcm_port_t port, uint32 flags)
  20525 {
  20526     bcm_port_cfg_t      pcfg;
  20527     int                 rv;
  20528 
  20529     /* Make sure port module is initialized. */
  20530     PORT_INIT(unit);
  20531 
  20532     if(bcm_common_oamp_port_enable_get(unit, port)) {
  20533         LOG_ERROR(BSL_LS_BCM_PORT,
  20534                   (BSL_META("Error: Not permitted on OAMP Port %d.\n"),
  20535                    port));
  20536         return BCM_E_PARAM;
  20537     }
  20538 
  20539 #if defined(BCM_TRX_SUPPORT)  && defined(INCLUDE_L3)
  20540     if (BCM_GPORT_IS_SUBPORT_GROUP(port)) {
  20541         if (SOC_IS_SCORPION(unit)) {
  20542              return BCM_E_UNAVAIL;
  20543         } else {
  20544             return bcm_tr_subport_learn_set(unit, (bcm_gport_t) port, flags);
  20545         }
  20546     }
  20547 #endif /* BCM_TRX_SUPPORT && INCLUDE_L3 */
  20548 #if defined(BCM_TRIUMPH_SUPPORT) && defined(BCM_MPLS_SUPPORT) && \
  20549     defined(INCLUDE_L3)
  20550     if (BCM_GPORT_IS_MPLS_PORT(port)) {
  20551         return bcm_tr_mpls_port_learn_set(unit, (bcm_gport_t) port, flags);
  20552     }
  20553 #endif
  20554 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
  20555      && defined(INCLUDE_L3))
  20556     if (BCM_GPORT_IS_MIM_PORT(port)) {
  20557         return bcm_tr2_mim_port_learn_set(unit, (bcm_gport_t) port, flags);
  20558     }
  20559     if (BCM_GPORT_IS_VLAN_PORT(port)) {
  20560         if (soc_feature(unit, soc_feature_vlan_vp)) {
  20561             return bcm_tr2_vlan_port_learn_set(unit, (bcm_gport_t) port, flags);
  20562         }
  20563     }
  20564     if (BCM_GPORT_IS_WLAN_PORT(port)) {
  20565 #if defined(BCM_TRIUMPH3_SUPPORT)
  20566         if (SOC_IS_TRIUMPH3(unit)) {
  20567             return bcm_tr3_wlan_port_learn_set(unit, (bcm_gport_t) port, flags);
  20568         } else
  20569 #endif /* BCM_TRIUMPH3_SUPPORT */
  20570         {
  20571             return bcm_tr2_wlan_port_learn_set(unit, (bcm_gport_t) port, flags);
  20572         }
  20573     }
  20574 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
  20575 #if defined(BCM_TRIDENT_SUPPORT)&& defined(INCLUDE_L3)
  20576     if (BCM_GPORT_IS_NIV_PORT(port)) {
  20577         return bcm_trident_niv_port_learn_set(unit, (bcm_gport_t) port, flags);
  20578     }
  20579 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  20580 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  20581     if (SOC_IS_TD2_TT2(unit)) {
  20582         if (BCM_GPORT_IS_VXLAN_PORT(port)){
  20583             return bcm_td2_vxlan_port_learn_set(unit, (bcm_gport_t) port, flags);
  20584         }
  20585     }
  20586 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */
  20587 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
  20588     if (BCM_GPORT_IS_L2GRE_PORT(port)){
  20589         return bcm_tr3_l2gre_port_learn_set(unit, (bcm_gport_t) port, flags);
  20590     }
  20591 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */
  20592 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
  20593     if (BCM_GPORT_IS_EXTENDER_PORT(port)){
  20594         if (soc_feature(unit, soc_feature_port_extension)) {
  20595             return bcm_tr3_extender_port_learn_set(unit, port, flags);
  20596         }
  20597     }
  20598 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */
  20599 #if defined(BCM_HGPROXY_COE_SUPPORT) && defined(INCLUDE_L3)
  20600     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 
  20601         BCM_GPORT_IS_SUBPORT_PORT(port)) {
  20602             return bcmi_xgs5_subport_port_learn_set(unit, (bcm_gport_t) port, flags);
  20603     }
  20604 #endif /* BCM_HGPROXY_COE_SUPPORT && INCLUDE_L3 */
  20605 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  20606         if (BCM_GPORT_IS_TRUNK(port)){
  20607             if (soc_feature(unit, soc_feature_vp_lag)) {
  20608                 return bcm_td2_vp_lag_port_learn_set(unit,
  20609                            BCM_GPORT_TRUNK_GET(port), flags);
  20610             }
  20611         }
  20612 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */
  20613 
  20614     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  20615 
  20616     if (flags & BCM_PORT_LEARN_PENDING) {
  20617         if (!soc_feature(unit, soc_feature_l2_pending)) {
  20618             return BCM_E_UNAVAIL;
  20619         } else if (!IS_CPU_PORT(unit, port) & (!(flags & BCM_PORT_LEARN_ARL))) {
  20620             /* When the PENDING flag is set, the ARL must also be set */
  20621             return BCM_E_PARAM;
  20622         }
  20623     }
  20624 
  20625     PORT_LOCK(unit);
  20626 
  20627     rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg);
  20628 
  20629     pcfg.pc_cpu = ((flags & BCM_PORT_LEARN_CPU) != 0);
  20630 
  20631     /* Use shortened names to handle each flag combination individually */
  20632 
  20633 #ifdef BCM_TRX_SUPPORT
  20634     if (SOC_IS_TRX(unit)) {
  20635         pcfg.pc_cml = 0;
  20636         rv = _bcm_trx_port_cml_flags2hw(unit, flags, (uint32 *)&pcfg.pc_cml);
  20637         if (BCM_FAILURE(rv)) {
  20638             PORT_UNLOCK(unit);
  20639             return (rv);
  20640         }
  20641     } else
  20642 #endif
  20643     {
  20644         switch (flags) {
  20645         case ((!Arl) | (!Cpu) | (!Fwd)):
  20646             pcfg.pc_cml = PVP_CML_DROP;
  20647             break;
  20648         case ((!Arl) | (!Cpu) | ( Fwd)):
  20649             pcfg.pc_cml = PVP_CML_FORWARD;
  20650             break;
  20651         case ((!Arl) | ( Cpu) | (!Fwd)):
  20652             pcfg.pc_cml = PVP_CML_CPU;
  20653             break;
  20654         case ((!Arl) | ( Cpu) | ( Fwd)):
  20655             if (SOC_IS_XGS_SWITCH(unit)) {
  20656                 pcfg.pc_cml = PVP_CML_CPU_FORWARD;
  20657             } else {
  20658                 rv = BCM_E_UNAVAIL;
  20659             }
  20660             break;
  20661         case (( Arl) | (!Cpu) | (!Fwd)):
  20662             rv = BCM_E_UNAVAIL;
  20663             break;
  20664         case (( Arl) | (!Cpu) | ( Fwd)):
  20665             pcfg.pc_cml = PVP_CML_SWITCH;
  20666             break;
  20667         case (( Arl) | ( Cpu) | (!Fwd)):
  20668             rv = BCM_E_UNAVAIL;
  20669             break;
  20670         case (( Arl) | ( Cpu) | ( Fwd)):
  20671             if (SOC_IS_XGS_SWITCH(unit)) {
  20672                 pcfg.pc_cml = PVP_CML_CPU_SWITCH;
  20673             } else {
  20674                 pcfg.pc_cml = PVP_CML_SWITCH;       /* pc_cpu also being set */
  20675             }
  20676             break;
  20677         }
  20678     }
  20679 
  20680     if (BCM_SUCCESS(rv)) {
  20681         rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg);
  20682     }
  20683 
  20684     PORT_UNLOCK(unit);
  20685 
  20686     return rv;
  20687 }
  20688 
  20689 #undef Arl
  20690 #undef Cpu
  20691 #undef Fwd
  20692 
  20693 /*
  20694  * Function:
  20695  *      bcm_port_ifilter_get
  20696  * Description:
  20697  *      Return input filter mode for a port.
  20698  * Parameters:
  20699  *      unit - StrataSwitch PCI device unit number (driver internal).
  20700  *      port - Port number to operate on
  20701  *      mode - (OUT) Filter mode, 1 is enable; 0 is disable.
  20702  * Returns:
  20703  *      BCM_E_NONE              Success.
  20704  *      BCM_E_INTERNAL          Chip access failure.
  20705  * Notes:
  20706  *      This API is superseded by bcm_port_vlan_member_get.
  20707  */
  20708 
  20709 int
  20710 bcm_esw_port_ifilter_get(int unit, bcm_port_t port, int *mode)
  20711 {
  20712     int rv;
  20713     uint32 flags;
  20714 
  20715     /* Make sure port module is initialized. */
  20716     PORT_INIT(unit);
  20717 
  20718     rv = bcm_esw_port_vlan_member_get(unit, port, &flags);
  20719 
  20720     if (BCM_SUCCESS(rv)) {
  20721         *mode = (flags & BCM_PORT_VLAN_MEMBER_INGRESS) ? 1 : 0;
  20722     }
  20723 
  20724     return rv;
  20725 }
  20726 
  20727 /*
  20728  * Function:
  20729  *      bcm_port_ifilter_set
  20730  * Description:
  20731  *      Set input filter mode for a port.
  20732  * Parameters:
  20733  *      unit - StrataSwitch PCI device unit number (driver internal).
  20734  *      port - Port number to operate on
  20735  *      mode - 1 to enable, 0 to disable.
  20736  * Returns:
  20737  *      BCM_E_NONE              Success.
  20738  *      BCM_E_INTERNAL          Chip access failure.
  20739  * Notes:
  20740  *      This API is superseded by bcm_port_vlan_member_set.
  20741  *
  20742  *      When input filtering is turned on for a port, packets received
  20743  *      on the port that do not match the port's VLAN classifications
  20744  *      are discarded.
  20745  */
  20746 
  20747 int
  20748 bcm_esw_port_ifilter_set(int unit, bcm_port_t port, int mode)
  20749 {
  20750     uint32 flags;
  20751 
  20752     /* Make sure port module is initialized. */
  20753     PORT_INIT(unit);
  20754 
  20755     BCM_IF_ERROR_RETURN(bcm_esw_port_vlan_member_get(unit, port, &flags));
  20756 
  20757     if (mode) {
  20758         flags |= BCM_PORT_VLAN_MEMBER_INGRESS;
  20759     }  else {
  20760         flags &= (~BCM_PORT_VLAN_MEMBER_INGRESS);
  20761     }
  20762 
  20763     return bcm_esw_port_vlan_member_set(unit, port, flags);
  20764 }
  20765 
  20766 /*
  20767  * Function:
  20768  *      bcm_esw_port_vlan_member_get
  20769  * Description:
  20770  *      Return filter mode for a port.
  20771  * Parameters:
  20772  *      unit - StrataSwitch PCI device unit number (driver internal).
  20773  *      port - Port number to operate on
  20774  *      flags - (OUT) Filter mode, one of BCM_PORT_VLAN_MEMBER_xxx.
  20775  * Returns:
  20776  *      BCM_E_NONE              Success.
  20777  *      BCM_E_INTERNAL          Chip access failure.
  20778  */
  20779 
  20780 int
  20781 bcm_esw_port_vlan_member_get(int unit, bcm_port_t port, uint32 *flags)
  20782 {
  20783     int  rv = BCM_E_UNAVAIL;
  20784 
  20785     *flags = 0;
  20786 
  20787     /* Make sure port module is initialized. */
  20788     PORT_INIT(unit);
  20789 
  20790 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
  20791     if (BCMI_GPORT_TYPE_VALID(port)) {
  20792 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  20793         if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
  20794             return bcm_td2p_vp_vlan_member_get(unit, port, flags);
  20795         } else
  20796 #endif
  20797         {
  20798             return bcm_td_vp_vlan_member_get(unit, port, flags);
  20799         }
  20800     } else
  20801 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  20802     if (BCM_GPORT_IS_WLAN_PORT(port)) {
  20803         rv = BCM_E_NONE;
  20804     } else {
  20805         rv = _bcm_esw_port_gport_validate(unit, port, &port);
  20806     }
  20807     BCM_IF_ERROR_RETURN(rv);
  20808     rv = BCM_E_UNAVAIL;
  20809 
  20810     switch (BCM_CHIP_FAMILY(unit)) {
  20811 
  20812     case BCM_FAMILY_HERCULES:
  20813         rv = BCM_E_NONE;
  20814         break;
  20815 
  20816     case BCM_FAMILY_FIREBOLT:
  20817     case BCM_FAMILY_BRADLEY:
  20818     case BCM_FAMILY_HUMV:
  20819     case BCM_FAMILY_TRIUMPH:
  20820     case BCM_FAMILY_SCORPION:
  20821     case BCM_FAMILY_CONQUEROR:
  20822     case BCM_FAMILY_TRIUMPH2:
  20823     case BCM_FAMILY_TRIDENT:
  20824     case BCM_FAMILY_TITAN:
  20825     case BCM_FAMILY_KATANA:
  20826         if (SOC_IS_XGS12_SWITCH(unit) && IS_HG_PORT(unit, port)) {
  20827             rv = BCM_E_NONE;
  20828         } else {
  20829             uint32 ent[SOC_MAX_MEM_FIELD_WORDS];
  20830             soc_mem_t mem;
  20831             soc_field_t field = EN_EFILTERf;
  20832 
  20833 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
  20834      && defined(INCLUDE_L3))
  20835             if (BCM_GPORT_IS_WLAN_PORT(port)) {
  20836                 int value;
  20837                 if (!soc_feature(unit, soc_feature_wlan)) {
  20838                     return BCM_E_PORT;
  20839                 }
  20840 #if defined(BCM_TRIUMPH3_SUPPORT)
  20841                 if (SOC_IS_TRIUMPH3(unit)) {
  20842                     rv = bcm_tr3_wlan_lport_field_get(unit, port,
  20843                                                       EN_IFILTERf, &value);
  20844                 } else
  20845 #endif /* BCM_TRIUMPH3_SUPPORT */
  20846                 {
  20847                     rv = bcm_tr2_wlan_lport_field_get(unit, port,
  20848                                                       EN_IFILTERf, &value);
  20849                 }
  20850                 if (value) {
  20851                     *flags |= BCM_PORT_VLAN_MEMBER_INGRESS;
  20852                 }
  20853                 return rv;
  20854             }
  20855 #endif
  20856 
  20857             mem = SOC_PORT_MEM_TAB(unit, port);
  20858             if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) {
  20859 #ifdef BCM_TRIDENT3_SUPPORT
  20860                 int value;
  20861                 rv = _bcm_esw_port_tab_get(unit, port, EN_IFILTERf, &value);
  20862                 if (rv == BCM_E_NONE) {
  20863                     if(value) {
  20864                         *flags |= BCM_PORT_VLAN_MEMBER_INGRESS;
  20865                         if (value == 2) {
  20866                             *flags |= BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP;
  20867                         }
  20868                     }
  20869                 }
  20870 #endif
  20871             } else {
  20872                 uint32 value = 0;
  20873                 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY,
  20874                                   SOC_PORT_MOD_OFFSET(unit, port), &ent);
  20875 
  20876                 if (BCM_SUCCESS(rv)) {
  20877                     value = soc_PORT_TABm_field32_get(unit, &ent, EN_IFILTERf);
  20878                     if (value) {
  20879                         *flags |= BCM_PORT_VLAN_MEMBER_INGRESS;
  20880                         if (value == 2) {
  20881                             *flags |= BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP;
  20882                         }
  20883                     }
  20884                 }
  20885             }
  20886 
  20887 #ifdef BCM_TRIDENT_SUPPORT
  20888             mem = EGR_PORTm;
  20889             field = EN_EFILTERf;
  20890 #ifdef BCM_TRIDENT3_SUPPORT
  20891             if (SOC_IS_TRIDENT3X(unit)) {
  20892                 int val = 0;
  20893                 rv = _bcm_esw_egr_port_tab_get(unit, port, field, &val);
  20894                 if (BCM_SUCCESS(rv) && val != 0) {
  20895                     *flags |= BCM_PORT_VLAN_MEMBER_EGRESS;
  20896                     if(val == 2) {
  20897                         *flags |= BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP;
  20898                     }
  20899                 }
  20900             } else
  20901 #endif
  20902             if (SOC_MEM_IS_VALID(unit, mem)) {
  20903                 int val = 0;
  20904                 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, port, &ent);
  20905                 val = soc_mem_field32_get(unit, mem, &ent, field);
  20906                 if (BCM_SUCCESS(rv) && val) {
  20907                     *flags |= BCM_PORT_VLAN_MEMBER_EGRESS;
  20908                     if(val == 2) {
  20909                         *flags |= BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP;
  20910                     }
  20911                 }
  20912             } else
  20913 #endif /* BCM_TRIDENT_SUPPORT */
  20914             if (SOC_IS_XGS3_SWITCH(unit)) {
  20915                 uint32 egr_val;
  20916                 uint64 egr_val64;
  20917                 if (SOC_REG_IS_VALID(unit, EGR_PORTr)) {
  20918                     rv = READ_EGR_PORTr(unit, port, &egr_val);
  20919                 } else {
  20920                     rv = READ_EGR_PORT_64r(unit, port, &egr_val64);
  20921                 }
  20922                 if (BCM_SUCCESS(rv)) {
  20923                     if (SOC_REG_IS_VALID(unit, EGR_PORTr)) {
  20924                         if (soc_reg_field_valid(unit, EGR_PORTr, field)) {
  20925                             if (soc_reg_field_get(unit, EGR_PORTr,
  20926                                                   egr_val, field)) {
  20927                                 *flags |= BCM_PORT_VLAN_MEMBER_EGRESS;
  20928                             }
  20929                         }
  20930                     } else if (soc_reg64_field32_get(unit,
  20931                                    EGR_PORT_64r, egr_val64, field)) {
  20932                             *flags |= BCM_PORT_VLAN_MEMBER_EGRESS;
  20933                     }
  20934                 }
  20935             }
  20936         }
  20937         break;
  20938 
  20939     default:
  20940         break;
  20941     }
  20942 
  20943     return rv;
  20944 }
  20945 
  20946 /*
  20947  * Function:
  20948  *      bcm_esw_port_vlan_member_set
  20949  * Description:
  20950  *      Set ingress and egress filter mode for a port.
  20951  * Parameters:
  20952  *      unit - StrataSwitch PCI device unit number (driver internal).
  20953  *      port - Port number to operate on
  20954  *      flags - BCM_PORT_VLAN_MEMBER_xxx.
  20955  * Returns:
  20956  *      BCM_E_NONE              Success.
  20957  *      BCM_E_INTERNAL          Chip access failure.
  20958  */
  20959 
  20960 int
  20961 bcm_esw_port_vlan_member_set(int unit, bcm_port_t port, uint32 flags)
  20962 {
  20963     int       rv = BCM_E_UNAVAIL;
  20964     int fieldLen = 0;
  20965 
  20966     /* Make sure port module is initialized. */
  20967     PORT_INIT(unit);
  20968 
  20969     if(bcm_common_oamp_port_enable_get(unit, port)) {
  20970         LOG_ERROR(BSL_LS_BCM_PORT,
  20971                   (BSL_META("Error: Not permitted on OAMP Port %d.\n"),
  20972                    port));
  20973         return BCM_E_PARAM;
  20974     }
  20975 
  20976     if (BCMI_GPORT_TYPE_VALID(port)) {
  20977 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
  20978 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  20979         if (soc_feature(unit, soc_feature_vlan_vfi_membership)) {
  20980             rv = bcm_td2p_vp_vlan_member_set(unit, port, flags);
  20981         } else
  20982 #endif
  20983         {
  20984             rv = bcm_td_vp_vlan_member_set(unit, port, flags);
  20985         }
  20986 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  20987         return rv;
  20988     } else if (BCM_GPORT_IS_WLAN_PORT(port)) {
  20989         rv = BCM_E_NONE;
  20990     } else {
  20991         rv = _bcm_esw_port_gport_validate(unit, port, &port);
  20992     }
  20993     BCM_IF_ERROR_RETURN(rv);
  20994     rv = BCM_E_UNAVAIL;
  20995 
  20996     PORT_LOCK(unit);
  20997 
  20998     switch (BCM_CHIP_FAMILY(unit)) {
  20999 
  21000     case BCM_FAMILY_HERCULES:
  21001         rv = (flags & BCM_PORT_VLAN_MEMBER_INGRESS) ? BCM_E_UNAVAIL :
  21002               ((flags & BCM_PORT_VLAN_MEMBER_EGRESS) ? BCM_E_UNAVAIL : BCM_E_NONE);
  21003         break;
  21004 
  21005     case BCM_FAMILY_FIREBOLT:
  21006     case BCM_FAMILY_BRADLEY:
  21007     case BCM_FAMILY_HUMV:
  21008     case BCM_FAMILY_TRIUMPH:
  21009     case BCM_FAMILY_SCORPION:
  21010     case BCM_FAMILY_CONQUEROR:
  21011     case BCM_FAMILY_TRIUMPH2:
  21012     case BCM_FAMILY_TRIDENT:
  21013     case BCM_FAMILY_TITAN:
  21014     case BCM_FAMILY_KATANA:
  21015         if (SOC_IS_XGS12_SWITCH(unit) && IS_HG_PORT(unit, port)) {
  21016             rv = (flags & BCM_PORT_VLAN_MEMBER_INGRESS) ? BCM_E_UNAVAIL :
  21017                   ((flags & BCM_PORT_VLAN_MEMBER_EGRESS) ? BCM_E_UNAVAIL :
  21018                   BCM_E_NONE);
  21019         } else {
  21020 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
  21021      && defined(INCLUDE_L3))
  21022 
  21023             if (BCM_GPORT_IS_WLAN_PORT(port)) {
  21024                 if (!soc_feature(unit, soc_feature_wlan)) {
  21025                     PORT_UNLOCK(unit);
  21026                     return BCM_E_PORT;
  21027                 }
  21028                 if (flags & BCM_PORT_VLAN_MEMBER_INGRESS) {
  21029 #if defined(BCM_TRIUMPH3_SUPPORT)
  21030                     if (SOC_IS_TRIUMPH3(unit)) {
  21031                         rv = _bcm_tr3_wlan_port_set(unit, port, EN_IFILTERf, 1);
  21032                     } else
  21033 #endif /* BCM_TRIUMPH3_SUPPORT */
  21034                     {
  21035                         rv = _bcm_tr2_wlan_port_set(unit, port, EN_IFILTERf, 1);
  21036                     }
  21037                 } else {
  21038 #if defined(BCM_TRIUMPH3_SUPPORT)
  21039                     if (SOC_IS_TRIUMPH3(unit)) {
  21040                         rv = _bcm_tr3_wlan_port_set(unit, port, EN_IFILTERf, 0);
  21041                     } else
  21042 #endif /* BCM_TRIUMPH3_SUPPORT */
  21043                     {
  21044                         rv = _bcm_tr2_wlan_port_set(unit, port, EN_IFILTERf, 0);
  21045                     }
  21046                 }
  21047                 PORT_UNLOCK(unit);
  21048                 return rv;
  21049             }
  21050 #endif
  21051             if (SOC_MEM_IS_VALID(unit, PORT_TABm) &&
  21052                 SOC_MEM_FIELD_VALID(unit, PORT_TABm, EN_IFILTERf)) {
  21053                 fieldLen = soc_mem_field_length(unit, PORT_TABm, EN_IFILTERf);
  21054             } else if (SOC_MEM_IS_VALID(unit, LPORT_TABm) &&
  21055                 SOC_MEM_FIELD_VALID(unit, LPORT_TABm, EN_IFILTERf)) {
  21056                 fieldLen = soc_mem_field_length(unit, LPORT_TABm, EN_IFILTERf);
  21057             }
  21058             if (fieldLen > 0) {
  21059                 /* value = 2 requires EN_IFILTERf to have 2 bits. In some
  21060                  * chips the field only has 1 bit */
  21061                 if ((flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP) &&
  21062                         fieldLen == 1) {
  21063                     PORT_UNLOCK(unit);
  21064                     return BCM_E_PARAM;
  21065                 }
  21066             }
  21067 
  21068             if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) {
  21069                 int value = (flags & BCM_PORT_VLAN_MEMBER_INGRESS) ? 1 : 0;
  21070                 if (soc_feature(unit, soc_feature_vlan_vfi_membership) &&
  21071                     (flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) {
  21072                     if (value == 1) {
  21073                         value = 2;
  21074                     }
  21075                 }
  21076                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  21077                                            EN_IFILTERf, value);
  21078             } else {
  21079                 int value = (flags & BCM_PORT_VLAN_MEMBER_INGRESS) ? 1 : 0;
  21080                 if (soc_feature(unit, soc_feature_vlan_vfi_membership) &&
  21081                     (flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) {
  21082                     if (value == 1) {
  21083                         value = 2;
  21084                     }
  21085                 }
  21086                 rv = _bcm_esw_port_tab_set(unit, port, 0, EN_IFILTERf, value);
  21087             }
  21088 
  21089 #ifdef BCM_TRIDENT_SUPPORT
  21090             if (SOC_MEM_IS_VALID(unit, ING_EN_EFILTER_BITMAPm)) {
  21091                 uint32 efilter;
  21092                 ing_en_efilter_bitmap_entry_t entry;
  21093                 pbmp_t pbmp;
  21094 
  21095                 if (SOC_MEM_IS_VALID(unit, EGR_PORTm) &&
  21096                     SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EN_EFILTERf)) {
  21097                     fieldLen = soc_mem_field_length(unit, EGR_PORTm, EN_EFILTERf);
  21098                 } else if (SOC_MEM_IS_VALID(unit, EGR_LPORT_PROFILEm) &&
  21099                     SOC_MEM_FIELD_VALID(unit, EGR_LPORT_PROFILEm, EN_EFILTERf)) {
  21100                     fieldLen = soc_mem_field_length(unit, EGR_LPORT_PROFILEm, EN_EFILTERf);
  21101                 }
  21102                 if (fieldLen > 0) {
  21103                     /* value = 2 requires EN_EFILTERf to have 2 bits. In some
  21104                      * chips the field only has 1 bit */
  21105                     if ((flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP) &&
  21106                             fieldLen == 1) {
  21107                         PORT_UNLOCK(unit);
  21108                         return BCM_E_PARAM;
  21109                     }
  21110                 }
  21111 
  21112                 efilter = flags & BCM_PORT_VLAN_MEMBER_EGRESS ? 1 : 0;
  21113                 if((efilter == 1) && (flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) {
  21114                     efilter = 2;
  21115                 }
  21116                 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EGR_LPORT_PROFILE_IDXf)) {
  21117                     rv = _bcm_esw_egr_port_tab_set(unit, port, EN_EFILTERf,
  21118                                                    efilter);
  21119                 } else {
  21120                 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, EN_EFILTERf,
  21121                                             efilter);
  21122                 }
  21123                 if (BCM_SUCCESS(rv)) {
  21124                     rv = soc_mem_read(unit, ING_EN_EFILTER_BITMAPm,
  21125                                       MEM_BLOCK_ANY, 0, &entry);
  21126                 }
  21127                 if (BCM_SUCCESS(rv)) {
  21128                     soc_mem_pbmp_field_get(unit, ING_EN_EFILTER_BITMAPm,
  21129                                            &entry, BITMAPf, &pbmp);
  21130                     if (efilter && PORT(unit, port).vp_count == 0) {
  21131                         SOC_PBMP_PORT_ADD(pbmp, port);
  21132                     } else {
  21133                         SOC_PBMP_PORT_REMOVE(pbmp, port);
  21134                     }
  21135                     soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm,
  21136                                            &entry, BITMAPf, &pbmp);
  21137                     rv = soc_mem_write(unit, ING_EN_EFILTER_BITMAPm,
  21138                                        MEM_BLOCK_ANY, 0, &entry);
  21139                 }
  21140             } else
  21141 #endif /* BCM_TRIDENT_SUPPORT */
  21142             if (SOC_IS_XGS3_SWITCH(unit)) {
  21143                 soc_reg_t egr_port_reg;
  21144                 egr_port_reg = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  21145                                 SOC_IS_VALKYRIE2(unit) || SOC_IS_GREYHOUND(unit) ||
  21146                                 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ?
  21147                                 EGR_PORT_64r : EGR_PORTr;
  21148                 rv = soc_reg_field32_modify(unit, egr_port_reg, port, EN_EFILTERf,
  21149                                           (flags & BCM_PORT_VLAN_MEMBER_EGRESS) ? 1 : 0);
  21150                 if (BCM_SUCCESS(rv)) {
  21151 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \
  21152         defined(BCM_SCORPION_SUPPORT)
  21153                     if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) ||
  21154                         SOC_IS_SC_CQ(unit) || SOC_IS_HAWKEYE(unit)) {
  21155                         uint32 egr_val;
  21156                         pbmp_t pbmp;
  21157                         uint32 bitmap, pbmp32;
  21158 
  21159                         rv = READ_ING_EN_EFILTER_BITMAPr(unit, &egr_val);
  21160                         if (BCM_SUCCESS(rv)) {
  21161                             SOC_PBMP_PORT_SET(pbmp, port);
  21162                             pbmp32 = SOC_PBMP_WORD_GET(pbmp, 0);
  21163                             bitmap =
  21164                                 soc_reg_field_get(unit,
  21165                                                   ING_EN_EFILTER_BITMAPr,
  21166                                                   egr_val, BITMAPf);
  21167                             if (flags & BCM_PORT_VLAN_MEMBER_EGRESS) {
  21168                                 bitmap |= pbmp32;
  21169                             } else {
  21170                                 bitmap &= ~pbmp32;
  21171                             }
  21172                             soc_reg_field_set(unit, ING_EN_EFILTER_BITMAPr,
  21173                                               &egr_val, BITMAPf, bitmap);
  21174                             rv = WRITE_ING_EN_EFILTER_BITMAPr(unit, egr_val);
  21175                         }
  21176                     }
  21177 #endif /* BCM_FIREBOLT_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */
  21178 #if defined(BCM_TRIUMPH_SUPPORT)
  21179                     /* Do this only if there is no VP on this port */
  21180                     if (soc_feature (unit, soc_feature_high_portcount_register)) {
  21181                         /* 
  21182                         *  pbmp reg split to multiple reg due to high port count 
  21183                         *  Note :
  21184                         *   - ING_EN_EFILTER_BITMAP_64r here is split to 
  21185                         *      {ING_EN_EFILTER_BITMAP_LOr + ING_EN_EFILTER_BITMAP_HIr}
  21186                         */
  21187                         uint64      fval64, rval64;
  21188                         uint32      t_port;
  21189                         soc_reg_t   reg;
  21190                         pbmp_t      curr_pbmp;
  21191 
  21192                         BCM_PBMP_CLEAR(curr_pbmp);
  21193                         COMPILER_64_ZERO(fval64);
  21194                         COMPILER_64_ZERO(rval64);
  21195                         
  21196                         if (port < 64) {
  21197                             reg = ING_EN_EFILTER_BITMAP_LOr;
  21198                             t_port = port;
  21199                         } else {
  21200                             reg = ING_EN_EFILTER_BITMAP_HIr;
  21201                             t_port = port - 64;
  21202                         }
  21203                         rv = soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64);
  21204                         if (BCM_SUCCESS(rv)) {
  21205                             fval64 = soc_reg64_field_get(unit, reg, 
  21206                                                          rval64, BITMAPf);
  21207                             SOC_PBMP_WORD_SET(curr_pbmp, 0, 
  21208                                               COMPILER_64_LO(fval64));
  21209                             SOC_PBMP_WORD_SET(curr_pbmp, 1, 
  21210                                               COMPILER_64_HI(fval64));
  21211 
  21212                             if ((flags & BCM_PORT_VLAN_MEMBER_EGRESS)){
  21213                                 SOC_PBMP_PORT_ADD(curr_pbmp, t_port);
  21214                             } else {
  21215                                 SOC_PBMP_PORT_REMOVE(curr_pbmp, t_port);
  21216                             }
  21217                                 
  21218                             COMPILER_64_SET(fval64,
  21219                                             SOC_PBMP_WORD_GET(curr_pbmp, 1),
  21220                                             SOC_PBMP_WORD_GET(curr_pbmp, 0));
  21221                             soc_reg64_field_set(unit, reg, &rval64, 
  21222                                                 BITMAPf, fval64);
  21223                             rv = soc_reg_set(unit, reg, 
  21224                                              REG_PORT_ANY, 0, rval64);
  21225                         }
  21226                     } else if (SOC_IS_TR_VL(unit)) {
  21227                         uint64 egr_val_64;
  21228                         pbmp_t pbmp;
  21229                         uint32 bitmap, pbmp32;
  21230 
  21231                         rv = READ_ING_EN_EFILTER_BITMAP_64r(unit, &egr_val_64);
  21232                         if (BCM_SUCCESS(rv)) {
  21233                             SOC_PBMP_PORT_SET(pbmp, port);
  21234                             /* Low bitmap */
  21235                             bitmap =
  21236                                 soc_reg64_field32_get(unit,
  21237                                                       ING_EN_EFILTER_BITMAP_64r,
  21238                                                       egr_val_64, BITMAP_LOf);
  21239                             pbmp32 = SOC_PBMP_WORD_GET(pbmp, 0);
  21240                             if ((flags & BCM_PORT_VLAN_MEMBER_EGRESS)  &&
  21241                                 (PORT(unit, port).vp_count == 0)) {
  21242                                 bitmap |= pbmp32;
  21243                             } else {
  21244                                 bitmap &= ~pbmp32;
  21245                             }
  21246                             soc_reg64_field32_set(unit, ING_EN_EFILTER_BITMAP_64r,
  21247                                                   &egr_val_64, BITMAP_LOf, bitmap);
  21248 
  21249                             if(!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) &&
  21250                                     !SOC_IS_GREYHOUND(unit)) {
  21251                                     /* High bitmap */
  21252                                     bitmap =
  21253                                         soc_reg64_field32_get(unit,
  21254                                                               ING_EN_EFILTER_BITMAP_64r,
  21255                                                               egr_val_64, BITMAP_HIf);
  21256                                     pbmp32 = SOC_PBMP_WORD_GET(pbmp, 1);
  21257                                     if ((flags & BCM_PORT_VLAN_MEMBER_EGRESS)  &&
  21258                                         (PORT(unit, port).vp_count == 0)) {
  21259                                         bitmap |= pbmp32;
  21260                                     } else {
  21261                                         bitmap &= ~pbmp32;
  21262                                     }
  21263                                     soc_reg64_field32_set(unit, ING_EN_EFILTER_BITMAP_64r,
  21264                                                           &egr_val_64, BITMAP_HIf, bitmap);
  21265                             }
  21266 
  21267                             rv = WRITE_ING_EN_EFILTER_BITMAP_64r(unit, egr_val_64);
  21268                         }
  21269                     }
  21270 #endif
  21271                 }
  21272             }
  21273         }
  21274         break;
  21275 
  21276     default:
  21277         break;
  21278     }
  21279 
  21280     PORT_UNLOCK(unit);
  21281 
  21282     return rv;
  21283 }
  21284 
  21285 /*
  21286  * Function:
  21287  *      _bcm_port_link_get
  21288  * Purpose:
  21289  *      Return current PHY up/down status
  21290  * Parameters:
  21291  *      unit - StrataSwitch Unit #.
  21292  *      port - StrataSwitch port #.
  21293  *      hw - If TRUE, assume hardware linkscan is active and use it
  21294  *              to reduce PHY reads.
  21295  *           If FALSE, do not use information from hardware linkscan.
  21296  *      up - (OUT) TRUE for link up, FALSE for link down.
  21297  * Returns:
  21298  *      BCM_E_NONE
  21299  *      BCM_E_XXX
  21300  */
  21301 
  21302 int
  21303 _bcm_port_link_get(int unit, bcm_port_t port, int hw, int *up)
  21304 {
  21305     int     rv = 0;
  21306 #if defined(BCM_KATANA2_SUPPORT)
  21307     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  21308 #endif
  21309 
  21310     if (SOC_USE_PORTCTRL(unit)) {
  21311         return bcmi_esw_portctrl_link_get(unit, port, hw, up);
  21312     }
  21313 
  21314 #if defined(BCM_KATANA2_SUPPORT)
  21315 #if defined(BCM_SABER2_SUPPORT)
  21316     if(SOC_IS_SABER2(unit)) {
  21317         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  21318     }
  21319 #endif
  21320     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  21321         (!((port >= 1) && (port <= max_phy_port)))) {
  21322          return BCM_E_PORT;
  21323     }
  21324 #endif
  21325     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  21326 
  21327     PORT_LOCK(unit);
  21328 
  21329     if (hw) {
  21330         pbmp_t hw_linkstat;
  21331 
  21332         rv = soc_linkscan_hw_link_get(unit, &hw_linkstat);
  21333 
  21334         *up = PBMP_MEMBER(hw_linkstat, port);
  21335 
  21336         /*
  21337          * We need to confirm link down because we may receive false link
  21338          * change interrupts when hardware and software linkscan are mixed.
  21339          * Processing a false link down event is known to cause packet
  21340          * loss, which is obviously unacceptable.
  21341          */
  21342         if(!(*up)) {
  21343             rv = soc_phyctrl_link_get(unit, port, up);
  21344         }
  21345     } else {
  21346         if (SOC_IS_RCPU_ONLY(unit)) {
  21347             rv = MAC_ENABLE_GET(PORT(unit, port).p_mac, unit, port, up);
  21348         } else {
  21349             rv = soc_phyctrl_link_get(unit, port, up);
  21350         }
  21351     }
  21352 
  21353     if (BCM_SUCCESS(rv)) {
  21354         if (PHY_FLAGS_TST(unit, port, PHY_FLAGS_MEDIUM_CHANGE)) {
  21355             soc_port_medium_t  medium;
  21356             soc_phyctrl_medium_get(unit, port, &medium);
  21357             soc_phy_medium_status_notify(unit, port, medium);
  21358         }
  21359     }
  21360     PORT_UNLOCK(unit);
  21361 
  21362     LOG_VERBOSE(BSL_LS_BCM_PORT,
  21363                 (BSL_META_U(unit,
  21364                             "_bcm_port_link_get: u=%d p=%d hw=%d up=%d rv=%d\n"),
  21365                  unit, port, hw, *up, rv));
  21366 
  21367     return rv;
  21368 }
  21369 
  21370 /*
  21371  * Function:
  21372  *      bcm_port_link_status_get
  21373  * Purpose:
  21374  *      Return current Link up/down status, queries linkscan, if unable to
  21375  *      retrieve status queries the PHY.
  21376  * Parameters:
  21377  *      unit - StrataSwitch Unit #.
  21378  *      port - StrataSwitch port #.
  21379  *      up - (OUT) Boolean value, FALSE for link down and TRUE for link up
  21380  * Returns:
  21381  *      BCM_E_NONE
  21382  *      BCM_E_XXX
  21383  */
  21384 
  21385 int
  21386 bcm_esw_port_link_status_get(int unit, bcm_port_t port, int *up)
  21387 {
  21388     int                 rv;
  21389 #if defined(BCM_KATANA2_SUPPORT)
  21390     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  21391 #endif
  21392 
  21393     /* Make sure port module is initialized. */
  21394     PORT_INIT(unit);
  21395 
  21396     if(bcm_common_oamp_port_enable_get(unit, port)) {
  21397         LOG_ERROR(BSL_LS_BCM_PORT,
  21398                   (BSL_META("Error: Not permitted on OAMP port %d.\n"),
  21399                    port));
  21400         return BCM_E_PARAM;
  21401     }
  21402 
  21403 #if defined(BCM_KATANA2_SUPPORT)
  21404 #if defined(BCM_SABER2_SUPPORT)
  21405     if(SOC_IS_SABER2(unit)) {
  21406         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  21407     }
  21408 #endif
  21409     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  21410         (!((port >= 1) && (port <= max_phy_port)))) {
  21411          return BCM_E_PORT;
  21412     }
  21413 #endif
  21414     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  21415 
  21416     rv = _bcm_esw_link_get(unit, port, up);
  21417 
  21418     if (rv == BCM_E_DISABLED) {
  21419         int mode;
  21420         mode = BCM_LINKSCAN_MODE_NONE;
  21421 
  21422         rv = bcm_esw_linkscan_mode_get(unit, port, &mode);
  21423 
  21424 #if defined(BCM_KATANA2_SUPPORT)
  21425         /*
  21426          * Check added for invalid ports where the port number
  21427          * lies between the maximum and minimum port values.
  21428          */
  21429         if (SOC_IS_KATANA2(unit) && rv == BCM_E_PORT) {
  21430             return rv;
  21431         }
  21432 #endif
  21433         if (mode == BCM_LINKSCAN_MODE_HW) {
  21434             rv = _bcm_port_link_get(unit, port, 1, up);
  21435         } else {
  21436             rv = _bcm_port_link_get(unit, port, 0, up);
  21437         }
  21438     }
  21439 
  21440 
  21441     return rv;
  21442 }
  21443 
  21444 /*
  21445  * Function:
  21446  *      bcm_esw_port_link_failed_clear
  21447  * Purpose:
  21448  *      Clear failed link status from a port which has undergone
  21449  *      LAG failover.
  21450  * Parameters:
  21451  *      unit - StrataSwitch Unit #.
  21452  *      port - StrataSwitch port #.
  21453  * Notes:
  21454  *      The port is moved to down status.  The application is responsible
  21455  *      for removing the port from all trunk memberships before calling this
  21456  *      function.
  21457  * Returns:
  21458  *      BCM_E_NONE
  21459  *      BCM_E_XXX
  21460  */
  21461 
  21462 int
  21463 bcm_esw_port_link_failed_clear(int unit, bcm_port_t port)
  21464 {
  21465     /* Make sure port module is initialized. */
  21466     PORT_INIT(unit);
  21467 
  21468     return _bcm_esw_link_failed_clear(unit, port);
  21469 }
  21470 
  21471 /*
  21472  * Function:
  21473  *      _bcm_port_pfm_set
  21474  * Purpose:
  21475  *      Main part of function bcm_port_pfm_set
  21476  */
  21477 
  21478 STATIC int
  21479 _bcm_port_pfm_set(int unit, bcm_port_t port, int mode)
  21480 {
  21481     int                 rv = BCM_E_NONE;
  21482 
  21483     /*
  21484      * The filter mode for the first 16 ports is in one register
  21485      * and for the rest in another
  21486      */
  21487     switch (BCM_CHIP_FAMILY(unit)) {
  21488 
  21489 #ifdef BCM_XGS12_FABRIC_SUPPORT
  21490     case BCM_FAMILY_HERCULES:
  21491         /* See remarks under bcm_port_pfm_get below */
  21492         break;
  21493 #endif
  21494 
  21495 #ifdef BCM_XGS3_SWITCH_SUPPORT
  21496     case BCM_FAMILY_FIREBOLT:
  21497     case BCM_FAMILY_BRADLEY:
  21498     case BCM_FAMILY_HUMV:
  21499     case BCM_FAMILY_TRIUMPH:
  21500     case BCM_FAMILY_SCORPION:
  21501     case BCM_FAMILY_CONQUEROR:
  21502     case BCM_FAMILY_TRIUMPH2:
  21503     case BCM_FAMILY_TRIDENT:
  21504     case BCM_FAMILY_TITAN:
  21505     case BCM_FAMILY_KATANA:
  21506         /*
  21507          * PFM is a per VLAN attribute. It is not a per port attribute
  21508          * on XGS3
  21509          */
  21510         return BCM_E_UNAVAIL;
  21511 #endif
  21512 
  21513     default:
  21514         return BCM_E_UNAVAIL;
  21515         break;
  21516     }
  21517 
  21518     return rv;
  21519 }
  21520 
  21521 /*
  21522  * Function:
  21523  *      bcm_port_pfm_set
  21524  * Purpose:
  21525  *      Set current port filtering mode (see port.h)
  21526  * Parameters:
  21527  *      unit - StrataSwitch Unit #.
  21528  *      port - StrataSwitch port #.
  21529  *      mode - mode for PFM bits (see port.h)
  21530  * Returns:
  21531  *      BCM_E_NONE
  21532  *      BCM_E_XXX
  21533  */
  21534 
  21535 int
  21536 bcm_esw_port_pfm_set(int unit, bcm_port_t port, int mode)
  21537 {
  21538     int                 rv;
  21539 
  21540     /* Make sure port module is initialized. */
  21541     PORT_INIT(unit);
  21542 
  21543     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  21544     if (!IS_PORT(unit, port)) {
  21545         return BCM_E_PORT;
  21546     }
  21547 
  21548     PORT_LOCK(unit);
  21549     rv = _bcm_port_pfm_set(unit, port, mode);
  21550     PORT_UNLOCK(unit);
  21551 
  21552     return rv;
  21553 }
  21554 
  21555 /*
  21556  * Function:
  21557  *      bcm_port_pfm_get
  21558  * Purpose:
  21559  *      Return current port filtering mode (see port.h)
  21560  * Parameters:
  21561  *      unit - StrataSwitch Unit #.
  21562  *      port - StrataSwitch port #.
  21563  *      mode - (OUT) mode read from StrataSwitch for PFM bits (see port.h)
  21564  * Returns:
  21565  *      BCM_E_NONE
  21566  *      BCM_E_XXX
  21567  * Notes:
  21568  *      This function not supported on 5670.
  21569  */
  21570 
  21571 int
  21572 bcm_esw_port_pfm_get(int unit, bcm_port_t port, int *mode)
  21573 {
  21574     /* Make sure port module is initialized. */
  21575     PORT_INIT(unit);
  21576 
  21577     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  21578     if (!IS_PORT(unit, port)) {
  21579         return BCM_E_PORT;
  21580     }
  21581 
  21582     switch (BCM_CHIP_FAMILY(unit)) {
  21583 
  21584 #ifdef BCM_HERCULES_SUPPORT
  21585     case BCM_FAMILY_HERCULES:
  21586         /*
  21587          * Packets marked as multicast prompt a lookup in the
  21588          * MC table in 567x.  There is no notion of missing a multicast
  21589          * address.
  21590          *
  21591          * Alternatively, we can mess with the MC/IPMC table
  21592          * entries to support the different modes.  This is
  21593          * probably not worth the trouble when we look at how
  21594          * 567x is meant to fit into the system.
  21595          */
  21596         *mode = BCM_PORT_PFM_MODEC;
  21597         break;
  21598 #endif
  21599 
  21600 #ifdef BCM_XGS3_SWITCH_SUPPORT
  21601     case BCM_FAMILY_FIREBOLT:
  21602     case BCM_FAMILY_BRADLEY:
  21603     case BCM_FAMILY_HUMV:
  21604     case BCM_FAMILY_TRIUMPH:
  21605     case BCM_FAMILY_SCORPION:
  21606     case BCM_FAMILY_CONQUEROR:
  21607     case BCM_FAMILY_TRIUMPH2:
  21608     case BCM_FAMILY_TRIDENT:
  21609     case BCM_FAMILY_TITAN:
  21610     case BCM_FAMILY_KATANA:
  21611         /*
  21612          * PFM is a per VLAN attribute. It is not a per port attribute
  21613          * on XGS3
  21614          */
  21615         *mode = BCM_PORT_PFM_MODEC;
  21616         return BCM_E_UNAVAIL;
  21617 #endif
  21618 
  21619     default:
  21620         return BCM_E_UNAVAIL;
  21621         break;
  21622     }
  21623 
  21624     return BCM_E_NONE;
  21625 }
  21626 
  21627 /*
  21628  * Function:
  21629  *      _bcm_port_untagged_priority_set
  21630  * Purpose:
  21631  *      Main part of bcm_port_untagged_priority_set.
  21632  */
  21633 
  21634 STATIC int
  21635 _bcm_port_untagged_priority_set(int unit, bcm_port_t port, int priority)
  21636 {
  21637     if (priority > 7) {
  21638         return BCM_E_PARAM;
  21639     }
  21640 
  21641     if(bcm_common_oamp_port_enable_get(unit, port)) {
  21642         LOG_ERROR(BSL_LS_BCM_PORT,
  21643                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  21644                    port));
  21645         return BCM_E_PARAM;
  21646     }
  21647 
  21648 #if defined(BCM_XGS_SWITCH_SUPPORT)
  21649     if (soc_feature(unit, soc_feature_remap_ut_prio) && (priority >= 0)) {
  21650         bcm_port_cfg_t pcfg;
  21651         SOC_IF_ERROR_RETURN(
  21652             mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg));
  21653         pcfg.pc_remap_pri_en = 1;
  21654             pcfg.pc_new_opri = priority;
  21655         SOC_IF_ERROR_RETURN(
  21656             mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg));
  21657         PORT(unit, port).p_ut_prio = pcfg.pc_new_opri;
  21658         return SOC_E_NONE;
  21659     }
  21660 #endif /* BCM_XGS_SWITCH_SUPPORT */
  21661 
  21662     if (priority < 0) {
  21663         return BCM_E_PARAM;
  21664     }
  21665 
  21666     return BCM_E_UNAVAIL;
  21667 }
  21668 
  21669 /*
  21670  * Function:
  21671  *      bcm_port_untagged_priority_set
  21672  * Purpose:
  21673  *      Set the 802.1P priority for untagged packets coming in on a
  21674  *      port.  This value will be written into the priority field of the
  21675  *      tag that is added at the ingress.
  21676  * Parameters:
  21677  *      unit      - StrataSwitch Unit #.
  21678  *      port      - StrataSwitch port #.
  21679  *      priority  - Priority to be set in 802.1p priority tag, from 0 to 7.
  21680  *                  A negative priority leaves the ingress port priority as
  21681  *                  is, but disables it from overriding ARL-based priorities.
  21682  *                  (on those devices that support ARL-based priority).
  21683  * Returns:
  21684  *      BCM_E_NONE
  21685  *      BCM_E_XXX
  21686  */
  21687 
  21688 int
  21689 bcm_esw_port_untagged_priority_set(int unit, bcm_port_t port, int priority)
  21690 {
  21691     int         rv;
  21692 
  21693     /* Make sure port module is initialized. */
  21694     PORT_INIT(unit);
  21695 
  21696     if(bcm_common_oamp_port_enable_get(unit, port)) {
  21697         LOG_ERROR(BSL_LS_BCM_PORT,
  21698                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  21699                    port));
  21700         return BCM_E_PARAM;
  21701     }
  21702 
  21703 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
  21704      && defined(INCLUDE_L3))
  21705     if (BCM_GPORT_IS_WLAN_PORT(port)) {
  21706 #if defined(BCM_TRIUMPH3_SUPPORT)
  21707         if (SOC_IS_TRIUMPH3(unit)) {
  21708             return bcm_tr3_wlan_port_untagged_prio_set(unit, port, priority);
  21709         } else
  21710 #endif /* BCM_TRIUMPH3_SUPPORT */
  21711         {
  21712             return bcm_tr2_wlan_port_untagged_prio_set(unit, port, priority);
  21713         }
  21714     }
  21715 #endif
  21716     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  21717 
  21718     PORT_LOCK(unit);
  21719     rv = _bcm_port_untagged_priority_set(unit, port, priority);
  21720     PORT_UNLOCK(unit);
  21721 
  21722     LOG_INFO(BSL_LS_BCM_PORT,
  21723              (BSL_META_U(unit,
  21724                          "bcm_port_ut_priority_set: u=%d p=%d pri=%d rv=%d\n"),
  21725               unit, port, priority, rv));
  21726 
  21727     return rv;
  21728 }
  21729 
  21730 /*
  21731  * Function:
  21732  *      bcm_port_untagged_priority_get
  21733  * Purpose:
  21734  *      Returns priority being assigned to untagged receive packets
  21735  * Parameters:
  21736  *      unit      - StrataSwitch Unit #.
  21737  *      port      - StrataSwitch port #.
  21738  *      priority  - Pointer to an int in which priority value is returned.
  21739  * Returns:
  21740  *      BCM_E_NONE
  21741  *      BCM_E_XXX
  21742  */
  21743 
  21744 int
  21745 bcm_esw_port_untagged_priority_get(int unit, bcm_port_t port, int *priority)
  21746 {
  21747     /* Make sure port module is initialized. */
  21748     PORT_INIT(unit);
  21749 
  21750     if(bcm_common_oamp_port_enable_get(unit, port)) {
  21751         LOG_ERROR(BSL_LS_BCM_PORT,
  21752                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  21753                    port));
  21754         return BCM_E_PARAM;
  21755     }
  21756 
  21757 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
  21758      && defined(INCLUDE_L3))
  21759     if (BCM_GPORT_IS_WLAN_PORT(port)) {
  21760 #if defined(BCM_TRIUMPH3_SUPPORT)
  21761         if (SOC_IS_TRIUMPH3(unit)) {
  21762             return bcm_tr3_wlan_port_untagged_prio_get(unit, port, priority);
  21763         } else
  21764 #endif /* BCM_TRIUMPH3_SUPPORT */
  21765         {
  21766             return bcm_tr2_wlan_port_untagged_prio_get(unit, port, priority);
  21767         }
  21768     }
  21769 #endif
  21770     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  21771 
  21772     if (priority != NULL) {
  21773         *priority = PORT(unit, port).p_ut_prio;
  21774         LOG_INFO(BSL_LS_BCM_PORT,
  21775                  (BSL_META_U(unit,
  21776                              "bcm_port_ut_priority_get: u=%d p=%d pri=%d\n"),
  21777                   unit, port, *priority));
  21778     }
  21779 
  21780     return BCM_E_NONE;
  21781 }
  21782 
  21783 /*
  21784  * Function:
  21785  *      bcm_port_selective_get
  21786  * Purpose:
  21787  *      Get requested port parameters
  21788  * Parameters:
  21789  *      unit - switch Unit
  21790  *      port - switch port
  21791  *      info - (IN/OUT) port information structure
  21792  * Returns:
  21793  *      BCM_E_XXX
  21794  * Notes:
  21795  *      The action_mask field of the info argument is used as an input
  21796  */
  21797 
  21798 int
  21799 bcm_esw_port_selective_get(int unit, bcm_port_t port, bcm_port_info_t *info)
  21800 {
  21801     int                 r;
  21802     uint32              mask;
  21803 
  21804     /* Make sure port module is initialized. */
  21805     PORT_INIT(unit);
  21806     if (!BCM_GPORT_IS_SET(port)) {
  21807         if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit),port)) {
  21808             return BCM_E_PORT;
  21809         }
  21810     }
  21811 
  21812     if(bcm_common_oamp_port_enable_get(unit, port)) {
  21813         LOG_ERROR(BSL_LS_BCM_PORT,
  21814                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  21815                    port));
  21816         return BCM_E_PARAM;
  21817     }
  21818 
  21819     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  21820 
  21821     mask = info->action_mask;
  21822 
  21823     /* PM8x50 does not support these things, so do not try to fetch them */
  21824     if (IS_CD_PORT(unit, port)) {
  21825         mask &= ~BCM_PORT_ATTR_ABILITY_MASK;
  21826         mask &= ~BCM_PORT_ATTR_LOCAL_ADVERT_MASK;
  21827         mask &= ~BCM_PORT_ATTR_INTERFACE_MASK;
  21828     }
  21829 
  21830     if (IS_QSGMII_PORT(unit, port)) {
  21831         mask &= ~BCM_PORT_ATTR_FAULT_MASK;
  21832     }
  21833 
  21834     if (mask & BCM_PORT_ATTR_ENCAP_MASK) {
  21835         r = bcm_esw_port_encap_get(unit, port, &info->encap_mode);
  21836         if (BCM_FAILURE(r)) {
  21837             LOG_VERBOSE(BSL_LS_BCM_PORT,
  21838                         (BSL_META_U(unit,
  21839                                     "bcm_port_encap_getfailed:%s\n"), bcm_errmsg(r)));
  21840         }
  21841         BCM_IF_ERROR_RETURN(r);
  21842     }
  21843 
  21844     if (mask & BCM_PORT_ATTR_ENABLE_MASK) {
  21845         r = bcm_esw_port_enable_get(unit, port, &info->enable);
  21846         if (BCM_FAILURE(r)) {
  21847             LOG_VERBOSE(BSL_LS_BCM_PORT,
  21848                         (BSL_META_U(unit,
  21849                                     "bcm_port_enable_getfailed:%s\n"), bcm_errmsg(r)));
  21850         }
  21851         BCM_IF_ERROR_RETURN(r);
  21852     }
  21853 
  21854     if (mask & BCM_PORT_ATTR_LINKSTAT_MASK) {
  21855         r = bcm_esw_port_link_status_get(unit, port, &info->linkstatus);
  21856         if (BCM_FAILURE(r)) {
  21857             /* LOG_VERBOSE(BSL_LS_BCM_PORT,
  21858                         (BSL_META_U(unit,
  21859                                     "bcm_port_link_status_getfailed:%s\n"), bcm_errmsg(r))); */
  21860         }
  21861         BCM_IF_ERROR_RETURN(r);
  21862     }
  21863 
  21864     if (mask & BCM_PORT_ATTR_AUTONEG_MASK) {
  21865         r = bcm_esw_port_autoneg_get(unit, port, &info->autoneg);
  21866         if (BCM_FAILURE(r)) {
  21867             LOG_VERBOSE(BSL_LS_BCM_PORT,
  21868                         (BSL_META_U(unit,
  21869                                     "bcm_port_autoneg_getfailed:%s\n"), bcm_errmsg(r)));
  21870         }
  21871         BCM_IF_ERROR_RETURN(r);
  21872     }
  21873 
  21874     if (mask & BCM_PORT_ATTR_LOCAL_ADVERT_MASK) {
  21875         r = bcm_esw_port_ability_advert_get(unit, port,
  21876                                             &info->local_ability);
  21877         if (BCM_FAILURE(r)) {
  21878             LOG_VERBOSE(BSL_LS_BCM_PORT,
  21879                         (BSL_META_U(unit,
  21880                                     "bcm_port_ability_advert_getfailed:%s\n"),
  21881                          bcm_errmsg(r)));
  21882         }
  21883         BCM_IF_ERROR_RETURN(r);
  21884         r = soc_port_ability_to_mode(&info->local_ability,
  21885                                      &info->local_advert);
  21886         BCM_IF_ERROR_RETURN(r);
  21887     }
  21888 
  21889     if (mask & BCM_PORT_ATTR_REMOTE_ADVERT_MASK) {
  21890 
  21891         if ((r = bcm_esw_port_ability_remote_get(unit, port,
  21892                                                  &info->remote_ability)) < 0) {
  21893             info->remote_advert = 0;
  21894             info->remote_advert_valid = FALSE;
  21895         } else {
  21896             r = soc_port_ability_to_mode(&info->remote_ability,
  21897                                          &info->remote_advert);
  21898             BCM_IF_ERROR_RETURN(r);
  21899             info->remote_advert_valid = TRUE;
  21900         }
  21901     }
  21902 
  21903     if (mask & BCM_PORT_ATTR_SPEED_MASK) {
  21904         if ((r = bcm_esw_port_speed_get(unit, port, &info->speed)) < 0) {
  21905             if (r != BCM_E_BUSY) {
  21906                 LOG_VERBOSE(BSL_LS_BCM_PORT,
  21907                             (BSL_META_U(unit,
  21908                                         "bcm_port_speed_get failed: %s\n"), bcm_errmsg(r)));
  21909                 return(r);
  21910             } else {
  21911                 info->speed = 0;
  21912             }
  21913         }
  21914     }
  21915 
  21916     if (mask & BCM_PORT_ATTR_DUPLEX_MASK) {
  21917         if ((r = bcm_esw_port_duplex_get(unit, port, &info->duplex)) < 0) {
  21918             if (r != BCM_E_BUSY) {
  21919                 LOG_VERBOSE(BSL_LS_BCM_PORT,
  21920                             (BSL_META_U(unit,
  21921                                         "bcm_port_duplex_get failed: %s\n"), bcm_errmsg(r)));
  21922                 return r;
  21923             } else {
  21924                 info->duplex = 0;
  21925             }
  21926         }
  21927     }
  21928 
  21929     /* get both if either mask bit set */
  21930     if (mask & (BCM_PORT_ATTR_PAUSE_TX_MASK |
  21931                 BCM_PORT_ATTR_PAUSE_RX_MASK)) {
  21932         r = bcm_esw_port_pause_get(unit, port,
  21933                                    &info->pause_tx, &info->pause_rx);
  21934         if (BCM_FAILURE(r)) {
  21935             LOG_VERBOSE(BSL_LS_BCM_PORT,
  21936                         (BSL_META_U(unit,
  21937                                     "bcm_port_pause_get failed:%s\n"), bcm_errmsg(r)));
  21938         }
  21939         BCM_IF_ERROR_RETURN(r);
  21940     }
  21941 
  21942     if (mask & BCM_PORT_ATTR_PAUSE_MAC_MASK) {
  21943         r = bcm_esw_port_pause_addr_get(unit, port, info->pause_mac);
  21944         if (BCM_FAILURE(r)) {
  21945             LOG_VERBOSE(BSL_LS_BCM_PORT,
  21946                         (BSL_META_U(unit,
  21947                                     "bcm_port_pause_addr_get failed:%s\n"), bcm_errmsg(r)));
  21948         }
  21949         BCM_IF_ERROR_RETURN(r);
  21950     }
  21951 
  21952     if (mask & BCM_PORT_ATTR_LINKSCAN_MASK) {
  21953         r = bcm_esw_port_linkscan_get(unit, port, &info->linkscan);
  21954         if (BCM_FAILURE(r)) {
  21955             LOG_VERBOSE(BSL_LS_BCM_PORT,
  21956                         (BSL_META_U(unit,
  21957                                     "bcm_port_linkscan_get failed:%s\n"), bcm_errmsg(r)));
  21958         }
  21959         BCM_IF_ERROR_RETURN(r);
  21960     }
  21961 
  21962     if (mask & BCM_PORT_ATTR_LEARN_MASK) {
  21963         r = bcm_esw_port_learn_get(unit, port, &info->learn);
  21964         if (BCM_FAILURE(r)) {
  21965             LOG_VERBOSE(BSL_LS_BCM_PORT,
  21966                         (BSL_META_U(unit,
  21967                                     "bcm_port_learn_getfailed:%s\n"), bcm_errmsg(r)));
  21968         }
  21969         BCM_IF_ERROR_RETURN(r);
  21970     }
  21971 
  21972     if (mask & BCM_PORT_ATTR_DISCARD_MASK) {
  21973         r = bcm_esw_port_discard_get(unit, port, &info->discard);
  21974         if (BCM_FAILURE(r)) {
  21975             LOG_VERBOSE(BSL_LS_BCM_PORT,
  21976                         (BSL_META_U(unit,
  21977                                     "bcm_port_discard_get failed:%s\n"), bcm_errmsg(r)));
  21978         }
  21979         BCM_IF_ERROR_RETURN(r);
  21980     }
  21981 
  21982     if (mask & BCM_PORT_ATTR_VLANFILTER_MASK) {
  21983         r = bcm_esw_port_vlan_member_get(unit, port, &info->vlanfilter);
  21984         if (BCM_FAILURE(r)) {
  21985             LOG_VERBOSE(BSL_LS_BCM_PORT,
  21986                         (BSL_META_U(unit,
  21987                                     "bcm_esw_port_vlan_member_get failed:%s\n"),
  21988                          bcm_errmsg(r)));
  21989         }
  21990         BCM_IF_ERROR_RETURN(r);
  21991     }
  21992 
  21993     if (mask & BCM_PORT_ATTR_UNTAG_PRI_MASK) {
  21994         r = bcm_esw_port_untagged_priority_get(unit, port,
  21995                                                &info->untagged_priority);
  21996         if (BCM_FAILURE(r)) {
  21997             LOG_VERBOSE(BSL_LS_BCM_PORT,
  21998                         (BSL_META_U(unit,
  21999                                     "bcm_port_untagged_priority_get failed:%s\n"),
  22000                          bcm_errmsg(r)));
  22001         }
  22002         BCM_IF_ERROR_RETURN(r);
  22003     }
  22004 
  22005     if (mask & BCM_PORT_ATTR_UNTAG_VLAN_MASK) {
  22006         r = bcm_esw_port_untagged_vlan_get(unit, port,
  22007                                            &info->untagged_vlan);
  22008         if (BCM_FAILURE(r)) {
  22009             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22010                         (BSL_META_U(unit,
  22011                                     "bcm_port_untagged_vlan_get failed:%s\n"),
  22012                          bcm_errmsg(r)));
  22013         }
  22014         BCM_IF_ERROR_RETURN(r);
  22015     }
  22016 
  22017     if (mask & BCM_PORT_ATTR_STP_STATE_MASK) {
  22018         r = bcm_esw_port_stp_get(unit, port, &info->stp_state);
  22019         if (BCM_FAILURE(r)) {
  22020             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22021                         (BSL_META_U(unit,
  22022                                     "bcm_port_stp_get failed:%s\n"), bcm_errmsg(r)));
  22023         }
  22024         BCM_IF_ERROR_RETURN(r);
  22025     }
  22026 
  22027     if (mask & BCM_PORT_ATTR_PFM_MASK) {
  22028         r = bcm_esw_port_pfm_get(unit, port, &info->pfm);
  22029         if (r != BCM_E_UNAVAIL) {
  22030             if (BCM_FAILURE(r)) {
  22031                 LOG_VERBOSE(BSL_LS_BCM_PORT,
  22032                             (BSL_META_U(unit,
  22033                                         "bcm_port_pfm_get failed:%s\n"), bcm_errmsg(r)));
  22034             }
  22035         }
  22036         BCM_IF_ERROR_NOT_UNAVAIL_RETURN(r);
  22037     }
  22038 
  22039     if (mask & BCM_PORT_ATTR_LOOPBACK_MASK) {
  22040         r = bcm_esw_port_loopback_get(unit, port, &info->loopback);
  22041         if (BCM_FAILURE(r)) {
  22042             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22043                         (BSL_META_U(unit,
  22044                                     "bcm_port_loopback_get failed:%s\n"), bcm_errmsg(r)));
  22045         }
  22046         BCM_IF_ERROR_RETURN(r);
  22047     }
  22048 
  22049     if (mask & BCM_PORT_ATTR_PHY_MASTER_MASK) {
  22050         r = bcm_esw_port_master_get(unit, port, &info->phy_master);
  22051         if (BCM_FAILURE(r)) {
  22052             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22053                         (BSL_META_U(unit,
  22054                                     "bcm_port_master_get failed:%s\n"), bcm_errmsg(r)));
  22055         }
  22056         BCM_IF_ERROR_RETURN(r);
  22057     }
  22058 
  22059     if (mask & BCM_PORT_ATTR_INTERFACE_MASK) {
  22060         r = bcm_esw_port_interface_get(unit, port, &info->interface);
  22061         if (BCM_FAILURE(r)) {
  22062             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22063                         (BSL_META_U(unit,
  22064                                     "bcm_port_interface_get failed:%s\n"), bcm_errmsg(r)));
  22065         }
  22066         BCM_IF_ERROR_RETURN(r);
  22067     }
  22068 
  22069     if (mask & BCM_PORT_ATTR_RATE_MCAST_MASK) {
  22070         r = bcm_esw_rate_mcast_get(unit, &info->mcast_limit,
  22071                                    &info->mcast_limit_enable, port);
  22072         if (r == BCM_E_UNAVAIL) {
  22073             r = BCM_E_NONE;     /* Ignore if not supported on chip */
  22074         }
  22075         if (BCM_FAILURE(r)) {
  22076             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22077                         (BSL_META_U(unit,
  22078                                     "bcm_rate_mcast_get failed:%s\n"), bcm_errmsg(r)));
  22079         }
  22080         BCM_IF_ERROR_RETURN(r);
  22081     }
  22082 
  22083     if (mask & BCM_PORT_ATTR_RATE_BCAST_MASK) {
  22084         r = bcm_esw_rate_bcast_get(unit, &info->bcast_limit,
  22085                                    &info->bcast_limit_enable, port);
  22086         if (r == BCM_E_UNAVAIL) {
  22087             r = BCM_E_NONE;     /* Ignore if not supported on chip */
  22088         }
  22089         if (BCM_FAILURE(r)) {
  22090             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22091                         (BSL_META_U(unit,
  22092                                     "bcm_rate_bcast_get failed:%s\n"), bcm_errmsg(r)));
  22093         }
  22094         BCM_IF_ERROR_RETURN(r);
  22095     }
  22096 
  22097     if (mask & BCM_PORT_ATTR_RATE_DLFBC_MASK) {
  22098         r = bcm_esw_rate_dlfbc_get(unit, &info->dlfbc_limit,
  22099                                    &info->dlfbc_limit_enable, port);
  22100         if (r == BCM_E_UNAVAIL) {
  22101             r = BCM_E_NONE;     /* Ignore if not supported on chip */
  22102         }
  22103         if (BCM_FAILURE(r)) {
  22104             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22105                         (BSL_META_U(unit,
  22106                                     "bcm_rate_dlfbc_get failed:%s\n"), bcm_errmsg(r)));
  22107         }
  22108         BCM_IF_ERROR_RETURN(r);
  22109     }
  22110 
  22111     if (mask & BCM_PORT_ATTR_SPEED_MAX_MASK) {
  22112         r = bcm_esw_port_speed_max(unit, port, &info->speed_max);
  22113         if (BCM_FAILURE(r)) {
  22114             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22115                         (BSL_META_U(unit,
  22116                                     "bcm_port_speed_max failed:%s\n"), bcm_errmsg(r)));
  22117         }
  22118         BCM_IF_ERROR_RETURN(r);
  22119     }
  22120 
  22121     if (mask & BCM_PORT_ATTR_ABILITY_MASK) {
  22122         r = bcm_esw_port_ability_local_get(unit, port, &info->port_ability);
  22123         if (BCM_FAILURE(r)) {
  22124             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22125                         (BSL_META_U(unit,
  22126                                     "bcm_port_ability_get failed:%s\n"), bcm_errmsg(r)));
  22127         }
  22128         BCM_IF_ERROR_RETURN(r);
  22129         r = soc_port_ability_to_mode(&info->port_ability,
  22130                                      &info->ability);
  22131         BCM_IF_ERROR_RETURN(r);
  22132     }
  22133 
  22134     if (mask & BCM_PORT_ATTR_FRAME_MAX_MASK) {
  22135         r = bcm_esw_port_frame_max_get(unit, port, &info->frame_max);
  22136         if (BCM_FAILURE(r)) {
  22137             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22138                         (BSL_META_U(unit,
  22139                                     "bcm_port_frame_max_get failed:%s\n"), bcm_errmsg(r)));
  22140         }
  22141         BCM_IF_ERROR_RETURN(r);
  22142     }
  22143 
  22144     if (mask & BCM_PORT_ATTR_MDIX_MASK) {
  22145         r = bcm_esw_port_mdix_get(unit, port, &info->mdix);
  22146         if (BCM_FAILURE(r)) {
  22147             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22148                         (BSL_META_U(unit,
  22149                                     "bcm_port_mdix_get failed:%s\n"), bcm_errmsg(r)));
  22150         }
  22151         BCM_IF_ERROR_RETURN(r);
  22152     }
  22153 
  22154     if (mask & BCM_PORT_ATTR_MDIX_STATUS_MASK) {
  22155         r = bcm_esw_port_mdix_status_get(unit, port, &info->mdix_status);
  22156         if (BCM_FAILURE(r)) {
  22157             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22158                         (BSL_META_U(unit,
  22159                                     "bcm_port_mdix_status_get failed:%s\n"), bcm_errmsg(r)));
  22160         }
  22161         BCM_IF_ERROR_RETURN(r);
  22162     }
  22163 
  22164     if (mask & BCM_PORT_ATTR_MEDIUM_MASK) {
  22165         r = bcm_esw_port_medium_get(unit, port, &info->medium);
  22166         if (BCM_FAILURE(r)) {
  22167             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22168                         (BSL_META_U(unit,
  22169                                     "bcm_port_medium_get failed:%s\n"), bcm_errmsg(r)));
  22170         }
  22171         BCM_IF_ERROR_RETURN(r);
  22172     }
  22173 
  22174     if (mask & BCM_PORT_ATTR_FAULT_MASK) {
  22175         r = bcm_esw_port_fault_get(unit, port, &info->fault);
  22176         if (r == BCM_E_PORT) {
  22177             r = BCM_E_NONE;     /* Ignore if not supported on chip/port */
  22178         }
  22179         if (BCM_FAILURE(r)) {
  22180             LOG_VERBOSE(BSL_LS_BCM_PORT,
  22181                         (BSL_META_U(unit,
  22182                                     "bcm_port_fault_get failed:%s\n"), bcm_errmsg(r)));
  22183         }
  22184         BCM_IF_ERROR_RETURN(r);
  22185     }
  22186 
  22187     return BCM_E_NONE;
  22188 }
  22189 
  22190 /*
  22191  * Function:
  22192  *      bcm_port_selective_set
  22193  * Purpose:
  22194  *      Set requested port parameters
  22195  * Parameters:
  22196  *      unit - switch unit
  22197  *      port - switch port
  22198  *      info - port information structure
  22199  * Returns:
  22200  *      BCM_E_NONE
  22201  *      BCM_E_XXX
  22202  * Notes:
  22203  *      Does not set spanning tree state.
  22204  */
  22205 
  22206 int
  22207 bcm_esw_port_selective_set(int unit, bcm_port_t port, bcm_port_info_t *info)
  22208 {
  22209     int                 r;
  22210     uint32              mask;
  22211     int                 flags = 0;
  22212     soc_info_t          *si;
  22213 
  22214     if (!(si = &SOC_INFO(unit))) {
  22215         return SOC_E_INTERNAL;
  22216     }
  22217 
  22218     LOG_INFO(BSL_LS_BCM_PORT,
  22219              (BSL_META_U(unit,
  22220                          "bcm_port_selective_set: u=%d p=%d\n"), unit, port));
  22221 
  22222     /* Make sure port module is initialized. */
  22223     PORT_INIT(unit);
  22224     if (!BCM_GPORT_IS_SET(port)) {
  22225         if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit),port)) {
  22226             return BCM_E_PORT;
  22227         }
  22228     }
  22229 
  22230     if(bcm_common_oamp_port_enable_get(unit, port)) {
  22231         LOG_ERROR(BSL_LS_BCM_PORT,
  22232                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  22233                    port));
  22234         return BCM_E_PARAM;
  22235     }
  22236 
  22237     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  22238 
  22239     mask = info->action_mask;
  22240 
  22241     /* PM8x50 does not support these things, so do not try to fetch them */
  22242     if (IS_CD_PORT(unit, port)) {
  22243         mask &= ~BCM_PORT_ATTR_ABILITY_MASK;
  22244         mask &= ~BCM_PORT_ATTR_LOCAL_ADVERT_MASK;
  22245         mask &= ~BCM_PORT_ATTR_INTERFACE_MASK;
  22246     }
  22247 
  22248     if (mask & BCM_PORT_ATTR_ENCAP_MASK) {
  22249         if (info->encap_mode == BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET) {
  22250             /* HGOE mode valid only for TD3 fabric */
  22251 #ifdef BCM_TRIDENT3_SUPPORT
  22252             if (SOC_IS_TRIDENT3X(unit) &&
  22253                  soc_feature(unit, soc_feature_higig_over_ethernet)) {
  22254                 bcm_port_encap_config_t config;
  22255                 config.encap = info->encap_mode;
  22256                 BCM_IF_ERROR_RETURN(
  22257                     bcm_esw_port_encap_config_set(unit, port, &config));
  22258             } else
  22259 #endif
  22260             {
  22261                 return BCM_E_PARAM;
  22262             }
  22263         } else {
  22264 
  22265             BCM_IF_ERROR_RETURN
  22266                 (bcmi_esw_port_encap_validate(unit, port, info->encap_mode,
  22267                             ((mask & BCM_PORT_ATTR_SPEED_MASK) ? info->speed : 0)));
  22268             r = _bcm_esw_port_encap_set(unit, port, info->encap_mode);
  22269             if (BCM_FAILURE(r)) {
  22270                 LOG_ERROR(BSL_LS_BCM_PORT,
  22271                             (BSL_META_U(unit,
  22272                                         "bcm_port_encap_set failed:%s\n"), bcm_errmsg(r)));
  22273             }
  22274             BCM_IF_ERROR_RETURN(r);
  22275         }
  22276     }
  22277 
  22278     if (mask & BCM_PORT_ATTR_ENABLE_MASK) {
  22279         r = bcm_esw_port_enable_set(unit, port, info->enable);
  22280         if (BCM_FAILURE(r)) {
  22281             LOG_ERROR(BSL_LS_BCM_PORT,
  22282                         (BSL_META_U(unit,
  22283                                     "bcm_port_enable_set failed:%s\n"), bcm_errmsg(r)));
  22284         }
  22285         BCM_IF_ERROR_RETURN(r);
  22286     }
  22287 
  22288     if (mask & BCM_PORT_ATTR_PAUSE_MAC_MASK) {
  22289         r = bcm_esw_port_pause_addr_set(unit, port, info->pause_mac);
  22290         if (BCM_FAILURE(r)) {
  22291             LOG_ERROR(BSL_LS_BCM_PORT,
  22292                         (BSL_META_U(unit,
  22293                                     "bcm_port_pause_addr_set failed:%s\n"), bcm_errmsg(r)));
  22294         }
  22295         BCM_IF_ERROR_RETURN(r);
  22296     }
  22297 
  22298     if (mask & BCM_PORT_ATTR_INTERFACE_MASK) {
  22299         r = bcm_esw_port_interface_set(unit, port, info->interface);
  22300         if (BCM_FAILURE(r)) {
  22301             LOG_ERROR(BSL_LS_BCM_PORT,
  22302                         (BSL_META_U(unit,
  22303                                     "bcm_port_interface_set failed:%s\n"), bcm_errmsg(r)));
  22304         }
  22305         BCM_IF_ERROR_RETURN(r);
  22306     }
  22307 
  22308     if (mask & BCM_PORT_ATTR_PHY_MASTER_MASK) {
  22309         r = bcm_esw_port_master_set(unit, port, info->phy_master);
  22310         if (r != BCM_E_UNAVAIL) {
  22311             if (BCM_FAILURE(r)) {
  22312                 LOG_VERBOSE(BSL_LS_BCM_PORT,
  22313                             (BSL_META_U(unit,
  22314                                         "bcm_port_master_set failed:%s\n"), bcm_errmsg(r)));
  22315             }
  22316         }
  22317         BCM_IF_ERROR_NOT_UNAVAIL_RETURN(r);
  22318     }
  22319 
  22320     if (mask & BCM_PORT_ATTR_LINKSCAN_MASK) {
  22321         r = bcm_esw_port_linkscan_set(unit, port, info->linkscan);
  22322         if (BCM_FAILURE(r)) {
  22323             LOG_ERROR(BSL_LS_BCM_PORT,
  22324                         (BSL_META_U(unit,
  22325                                     "bcm_port_linkscan_set failed:%s\n"), bcm_errmsg(r)));
  22326         }
  22327         BCM_IF_ERROR_RETURN(r);
  22328     }
  22329 
  22330     if (mask & BCM_PORT_ATTR_LEARN_MASK) {
  22331         r = bcm_esw_port_learn_set(unit, port, info->learn);
  22332         if (BCM_FAILURE(r)) {
  22333             LOG_ERROR(BSL_LS_BCM_PORT,
  22334                         (BSL_META_U(unit,
  22335                                     "bcm_port_learn_set failed:%s\n"), bcm_errmsg(r)));
  22336         }
  22337         BCM_IF_ERROR_RETURN(r);
  22338     }
  22339 
  22340     if (mask & BCM_PORT_ATTR_DISCARD_MASK) {
  22341         r = bcm_esw_port_discard_set(unit, port, info->discard);
  22342         if (BCM_FAILURE(r)) {
  22343             LOG_ERROR(BSL_LS_BCM_PORT,
  22344                         (BSL_META_U(unit,
  22345                                     "bcm_port_discard_set failed:%s\n"), bcm_errmsg(r)));
  22346         }
  22347         BCM_IF_ERROR_RETURN(r);
  22348     }
  22349 
  22350     if (mask & BCM_PORT_ATTR_VLANFILTER_MASK) {
  22351         r = bcm_esw_port_vlan_member_set(unit, port, info->vlanfilter);
  22352         if (BCM_FAILURE(r)) {
  22353             LOG_ERROR(BSL_LS_BCM_PORT,
  22354                         (BSL_META_U(unit,
  22355                                     "bcm_esw_port_vlan_member_set failed:%s\n"),
  22356                          bcm_errmsg(r)));
  22357         }
  22358         BCM_IF_ERROR_RETURN(r);
  22359     }
  22360 
  22361     if (mask & BCM_PORT_ATTR_UNTAG_PRI_MASK) {
  22362         r = bcm_esw_port_untagged_priority_set(unit, port,
  22363                                                info->untagged_priority);
  22364         if (BCM_FAILURE(r)) {
  22365             LOG_ERROR(BSL_LS_BCM_PORT,
  22366                         (BSL_META_U(unit,
  22367                                     "bcm_port_untagged_priority_set failed:%s\n"),
  22368                          bcm_errmsg(r)));
  22369         }
  22370         BCM_IF_ERROR_RETURN(r);
  22371     }
  22372 
  22373     if (mask & BCM_PORT_ATTR_UNTAG_VLAN_MASK) {
  22374         r = bcm_esw_port_untagged_vlan_set(unit, port, info->untagged_vlan);
  22375         if (BCM_FAILURE(r)) {
  22376             LOG_ERROR(BSL_LS_BCM_PORT,
  22377                         (BSL_META_U(unit,
  22378                                     "bcm_port_untagged_vlan_set (%d) failed: %s\n"),
  22379                          info->untagged_vlan, bcm_errmsg(r)));
  22380         }
  22381         BCM_IF_ERROR_RETURN(r);
  22382     }
  22383 
  22384     if (mask & BCM_PORT_ATTR_PFM_MASK) {
  22385         r = bcm_esw_port_pfm_set(unit, port, info->pfm);
  22386         if (r != BCM_E_UNAVAIL) {
  22387             if (BCM_FAILURE(r)) {
  22388                 LOG_ERROR(BSL_LS_BCM_PORT,
  22389                             (BSL_META_U(unit,
  22390                                         "bcm_port_pfm_set failed:%s\n"), bcm_errmsg(r)));
  22391             }
  22392         }
  22393         BCM_IF_ERROR_NOT_UNAVAIL_RETURN(r);
  22394     }
  22395 
  22396     /*
  22397      * Set loopback mode before setting the speed/duplex, since it may
  22398      * affect the allowable values for speed/duplex.
  22399      */
  22400 
  22401     if (mask & BCM_PORT_ATTR_LOOPBACK_MASK) {
  22402         r = bcm_esw_port_loopback_set(unit, port, info->loopback);
  22403         if (BCM_FAILURE(r)) {
  22404             LOG_ERROR(BSL_LS_BCM_PORT,
  22405                         (BSL_META_U(unit,
  22406                                     "bcm_port_loopback_set failed:%s\n"), bcm_errmsg(r)));
  22407         }
  22408         BCM_IF_ERROR_RETURN(r);
  22409     }
  22410 
  22411     if (mask & BCM_PORT_ATTR_LOCAL_ADVERT_MASK) {
  22412         if (info->action_mask2 & BCM_PORT_ATTR2_PORT_ABILITY) {
  22413             r = bcm_esw_port_ability_advert_set(unit, port,
  22414                                                 &(info->local_ability));
  22415             if (BCM_FAILURE(r)) {
  22416                 LOG_ERROR(BSL_LS_BCM_PORT,
  22417                             (BSL_META_U(unit,
  22418                                         "bcm_port_ability_advert_set failed: %s\n"),
  22419                              bcm_errmsg(r)));
  22420             }
  22421             BCM_IF_ERROR_RETURN(r);
  22422         } else {
  22423             r = bcm_esw_port_advert_set(unit, port, info->local_advert);
  22424             if (BCM_FAILURE(r)) {
  22425                 LOG_ERROR(BSL_LS_BCM_PORT,
  22426                             (BSL_META_U(unit,
  22427                                         "bcm_port_advert_set failed: (0x%x): %s\n"),
  22428                              info->local_advert, bcm_errmsg(r)));
  22429             }
  22430             BCM_IF_ERROR_RETURN(r);
  22431         }
  22432     }
  22433 
  22434     if (mask & BCM_PORT_ATTR_AUTONEG_MASK) {
  22435 #if defined(BCM_TOMAHAWK_SUPPORT)
  22436         if ((SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3(unit)) && IS_CL_PORT(unit, port)) {
  22437             int speed = si->port_init_speed[port];
  22438             if (1000 == speed) {    /* 1G ports do not support autoneg, force off */
  22439                 info->autoneg = 0;
  22440             }
  22441         }
  22442 #endif
  22443         r = bcm_esw_port_autoneg_set(unit, port, info->autoneg);
  22444         if (BCM_FAILURE(r)) {
  22445             LOG_ERROR(BSL_LS_BCM_PORT,
  22446                         (BSL_META_U(unit,
  22447                                     "bcm_port_autoneg_set failed:%s\n"), bcm_errmsg(r)));
  22448         }
  22449         BCM_IF_ERROR_RETURN(r);
  22450     }
  22451 
  22452     if (mask & BCM_PORT_ATTR_SPEED_MASK) {
  22453         /*When AN=on, speed will be auto-detected. Hence don't set*/
  22454         if ((mask & BCM_PORT_ATTR_AUTONEG_MASK) && info->autoneg) {
  22455             r = BCM_E_PARAM;
  22456             if (BCM_FAILURE(r)) {
  22457                 LOG_ERROR(BSL_LS_BCM_PORT,
  22458                          (BSL_META_U(unit,
  22459                           "Autoneg:On. SPEED will be " 
  22460                            "auto-detected :%s\n"), bcm_errmsg(r)));
  22461             }
  22462             BCM_IF_ERROR_RETURN(r);
  22463         }
  22464 #ifdef BCM_TOMAHAWK3_SUPPORT
  22465         if (SOC_IS_TOMAHAWK3(unit) && IS_CD_PORT(unit, port)) {
  22466             bcm_port_resource_t pr;
  22467             r = bcm_esw_port_resource_get(unit, port, &pr);
  22468             BCM_IF_ERROR_RETURN(r);
  22469             if (pr.speed != info->speed) {
  22470                 LOG_INFO(BSL_LS_BCM_PORT,
  22471                          (BSL_META_U(unit,
  22472                           "Warning: bcm_port_info speed (%d) does NOT match "
  22473                           " current speed (%d). May have fec/link training/"
  22474                           "phy lane config mismatches!\n"),
  22475                           pr.speed, info->speed));
  22476             }
  22477             pr.speed = info->speed;
  22478             r = bcm_esw_port_resource_speed_set(unit, port, &pr);
  22479             BCM_IF_ERROR_RETURN(r);
  22480         } else
  22481 #endif
  22482         {
  22483         r = bcm_esw_port_speed_set(unit, port, info->speed);
  22484         }
  22485         if (BCM_FAILURE(r)) {
  22486             LOG_ERROR(BSL_LS_BCM_PORT,
  22487                         (BSL_META_U(unit,
  22488                                     "bcm_port_speed_set failed:%s\n"), bcm_errmsg(r)));
  22489         }
  22490         BCM_IF_ERROR_RETURN(r);
  22491     }
  22492 
  22493     if (mask & BCM_PORT_ATTR_DUPLEX_MASK) {
  22494         /*When AN=on, then duplex method will be auto-detected, hence don't set*/
  22495         if ((mask & BCM_PORT_ATTR_AUTONEG_MASK) && info->autoneg) {
  22496             r = BCM_E_PARAM;
  22497             if (BCM_FAILURE(r)) {
  22498                 LOG_ERROR(BSL_LS_BCM_PORT,
  22499                          (BSL_META_U(unit,
  22500                           "Autoneg:On. DUPLEX should be " 
  22501                            "auto-detected :%s\n"), bcm_errmsg(r)));
  22502             }
  22503             BCM_IF_ERROR_RETURN(r);
  22504         }
  22505         r = bcm_esw_port_duplex_set(unit, port, info->duplex);
  22506         if (BCM_FAILURE(r)) {
  22507             LOG_ERROR(BSL_LS_BCM_PORT,
  22508                         (BSL_META_U(unit,
  22509                                     "bcm_port_duplex_set failed:%s\n"), bcm_errmsg(r)));
  22510         }
  22511         BCM_IF_ERROR_RETURN(r);
  22512     }
  22513 
  22514     if (mask & (BCM_PORT_ATTR_PAUSE_TX_MASK |
  22515                 BCM_PORT_ATTR_PAUSE_RX_MASK)) {
  22516         int     tpause, rpause;
  22517 
  22518         tpause = rpause = -1;
  22519         if (mask & BCM_PORT_ATTR_PAUSE_TX_MASK) {
  22520             tpause = info->pause_tx;
  22521         }
  22522         if (mask & BCM_PORT_ATTR_PAUSE_RX_MASK) {
  22523             rpause = info->pause_rx;
  22524         }
  22525         r = bcm_esw_port_pause_set(unit, port, tpause, rpause);
  22526         if (BCM_FAILURE(r)) {
  22527             LOG_ERROR(BSL_LS_BCM_PORT,
  22528                         (BSL_META_U(unit,
  22529                                     "bcm_port_pause_set failed:%s\n"), bcm_errmsg(r)));
  22530         }
  22531         BCM_IF_ERROR_RETURN(r);
  22532     }
  22533 
  22534     if (mask & BCM_PORT_ATTR_RATE_MCAST_MASK) {
  22535         flags = (info->mcast_limit_enable) ? BCM_RATE_MCAST : 0;
  22536         r = bcm_esw_rate_mcast_set(unit, info->mcast_limit, flags, port);
  22537         if (r == BCM_E_UNAVAIL) {
  22538             r = BCM_E_NONE;     /* Ignore if not supported on chip */
  22539         }
  22540         if (BCM_FAILURE(r)) {
  22541             LOG_ERROR(BSL_LS_BCM_PORT,
  22542                         (BSL_META_U(unit,
  22543                                     "bcm_rate_mcast_port_set failed:%s\n"), bcm_errmsg(r)));
  22544         }
  22545         BCM_IF_ERROR_RETURN(r);
  22546     }
  22547 
  22548     if (mask & BCM_PORT_ATTR_RATE_BCAST_MASK) {
  22549         flags = (info->bcast_limit_enable) ? BCM_RATE_BCAST : 0;
  22550         r = bcm_esw_rate_bcast_set(unit, info->bcast_limit, flags, port);
  22551         if (r == BCM_E_UNAVAIL) {
  22552             r = BCM_E_NONE;     /* Ignore if not supported on chip */
  22553         }
  22554         if (BCM_FAILURE(r)) {
  22555             LOG_ERROR(BSL_LS_BCM_PORT,
  22556                         (BSL_META_U(unit,
  22557                                     "bcm_rate_bcast_port_set failed:%s\n"), bcm_errmsg(r)));
  22558         }
  22559         BCM_IF_ERROR_RETURN(r);
  22560     }
  22561 
  22562     if (mask & BCM_PORT_ATTR_RATE_DLFBC_MASK) {
  22563         flags = (info->dlfbc_limit_enable) ? BCM_RATE_DLF : 0;
  22564         r = bcm_esw_rate_dlfbc_set(unit, info->dlfbc_limit, flags, port);
  22565         if (r == BCM_E_UNAVAIL) {
  22566             r = BCM_E_NONE;     /* Ignore if not supported on chip */
  22567         }
  22568         if (BCM_FAILURE(r)) {
  22569             LOG_ERROR(BSL_LS_BCM_PORT,
  22570                         (BSL_META_U(unit,
  22571                                     "bcm_rate_dlfbcast_port_set failed:%s\n"),
  22572                          bcm_errmsg(r)));
  22573         }
  22574         BCM_IF_ERROR_RETURN(r);
  22575     }
  22576 
  22577     if (mask & BCM_PORT_ATTR_STP_STATE_MASK) {
  22578         r = bcm_esw_port_stp_set(unit, port, info->stp_state);
  22579         if (BCM_FAILURE(r)) {
  22580             LOG_ERROR(BSL_LS_BCM_PORT,
  22581                         (BSL_META_U(unit,
  22582                                     "bcm_port_stp_set failed:%s\n"), bcm_errmsg(r)));
  22583         }
  22584         BCM_IF_ERROR_RETURN(r);
  22585     }
  22586 
  22587     if (mask & BCM_PORT_ATTR_FRAME_MAX_MASK) {
  22588         r = bcm_esw_port_frame_max_set(unit, port, info->frame_max);
  22589         if (BCM_FAILURE(r)) {
  22590             LOG_ERROR(BSL_LS_BCM_PORT,
  22591                         (BSL_META_U(unit,
  22592                                     "bcm_port_frame_max_set failed:%s\n"), bcm_errmsg(r)));
  22593         }
  22594         BCM_IF_ERROR_RETURN(r);
  22595     }
  22596 
  22597     if (mask & BCM_PORT_ATTR_MDIX_MASK) {
  22598         r = bcm_esw_port_mdix_set(unit, port, info->mdix);
  22599         if (BCM_FAILURE(r)) {
  22600             LOG_ERROR(BSL_LS_BCM_PORT,
  22601                         (BSL_META_U(unit,
  22602                                     "bcm_port_mdix_set failed:%s\n"), bcm_errmsg(r)));
  22603         }
  22604         BCM_IF_ERROR_RETURN(r);
  22605     }
  22606 
  22607     return BCM_E_NONE;
  22608 }
  22609 
  22610 /*
  22611  * Function:
  22612  *      bcm_port_info_get
  22613  * Purpose:
  22614  *      Get all information on the port
  22615  * Parameters:
  22616  *      unit - StrataSwitch unit #
  22617  *      port - StrataSwitch port #
  22618  *      info - Pointer to structure in which to save values
  22619  * Returns:
  22620  *      BCM_E_XXX
  22621  */
  22622 
  22623 int
  22624 bcm_esw_port_info_get(int unit, bcm_port_t port, bcm_port_info_t *info)
  22625 {
  22626     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  22627 
  22628     /* Make sure port module is initialized. */
  22629     PORT_INIT(unit);
  22630 
  22631     bcm_port_info_t_init(info);
  22632 
  22633     if (IS_ST_PORT(unit, port)) {
  22634         info->action_mask = BCM_PORT_HERC_ATTRS;
  22635         if (SOC_IS_XGS_SWITCH(unit)) {
  22636             info->action_mask |= BCM_PORT_ATTR_STP_STATE_MASK |
  22637                                  BCM_PORT_ATTR_DISCARD_MASK |
  22638                                  BCM_PORT_ATTR_LEARN_MASK;
  22639         }
  22640     } else {
  22641         info->action_mask = BCM_PORT_ATTR_ALL_MASK;
  22642     }
  22643 
  22644     return bcm_esw_port_selective_get(unit, port, info);
  22645 }
  22646 
  22647 /*
  22648  * Function:
  22649  *      bcm_port_info_set
  22650  * Purpose:
  22651  *      Set all information on the port
  22652  * Parameters:
  22653  *      unit - StrataSwitch unit #
  22654  *      port - StrataSwitch port #
  22655  *      info - Pointer to structure in which to save values
  22656  * Returns:
  22657  *      BCM_E_XXX
  22658  * Notes:
  22659  *      Checks if AN is on, and if so, clears the
  22660  *      proper bits in the action mask.
  22661  */
  22662 
  22663 int
  22664 bcm_esw_port_info_set(int unit, bcm_port_t port, bcm_port_info_t *info)
  22665 {
  22666     /* Make sure port module is initialized. */
  22667     PORT_INIT(unit);
  22668 
  22669     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  22670 
  22671     if (IS_ST_PORT(unit, port)) {
  22672         info->action_mask = BCM_PORT_HERC_ATTRS;
  22673         if (SOC_IS_XGS_SWITCH(unit)) {
  22674             info->action_mask |= BCM_PORT_ATTR_STP_STATE_MASK |
  22675                                  BCM_PORT_ATTR_DISCARD_MASK |
  22676                                  BCM_PORT_ATTR_LEARN_MASK;
  22677         }
  22678     } else {
  22679         info->action_mask = BCM_PORT_ATTR_ALL_MASK;
  22680     }
  22681 
  22682     /* If autoneg is set, remove those attributes controlled by it */
  22683     if (info->autoneg) {
  22684         info->action_mask &= ~BCM_PORT_AN_ATTRS;
  22685     }
  22686 
  22687     return bcm_esw_port_selective_set(unit, port, info);
  22688 }
  22689 
  22690 /*
  22691  * Function:
  22692  *      bcm_port_info_save
  22693  * Purpose:
  22694  *      Save the current settings of a port
  22695  * Parameters:
  22696  *      unit - StrataSwitch unit #
  22697  *      port - StrataSwitch port #
  22698  *      info - Pointer to structure in which to save values
  22699  * Returns:
  22700  *      BCM_E_XXX
  22701  * Notes:
  22702  *      The action_mask will be adjusted so that the
  22703  *      proper values will be set when a restore is made.
  22704  *      This mask should not be altered between these calls.
  22705  */
  22706 
  22707 int
  22708 bcm_esw_port_info_save(int unit, bcm_port_t port, bcm_port_info_t *info)
  22709 {
  22710     /* Make sure port module is initialized. */
  22711     PORT_INIT(unit);
  22712 
  22713     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  22714 
  22715     if (IS_ST_PORT(unit, port)) {
  22716         info->action_mask = BCM_PORT_HERC_ATTRS;
  22717         if (SOC_IS_XGS_SWITCH(unit)) {
  22718             info->action_mask |= BCM_PORT_ATTR_STP_STATE_MASK;
  22719         }
  22720 #ifdef BCM_GXPORT_SUPPORT
  22721         if (IS_GX_PORT(unit, port)) {
  22722             info->action_mask |= BCM_PORT_ATTR_AUTONEG_MASK;
  22723         }
  22724 #endif
  22725     } else {
  22726         info->action_mask = BCM_PORT_ATTR_ALL_MASK;
  22727     }
  22728     info->action_mask2 = BCM_PORT_ATTR2_PORT_ABILITY;
  22729 
  22730     BCM_IF_ERROR_RETURN(bcm_esw_port_selective_get(unit, port, info));
  22731 
  22732     if (info->autoneg) {
  22733         info->action_mask &= ~BCM_PORT_AN_ATTRS;
  22734     }
  22735 
  22736     return BCM_E_NONE;
  22737 }
  22738 
  22739 /*
  22740  * Function:
  22741  *      bcm_port_info_restore
  22742  * Purpose:
  22743  *      Restore port settings saved by info_save
  22744  * Parameters:
  22745  *      unit - StrataSwitch unit #
  22746  *      port - StrataSwitch port #
  22747  *      info - Pointer to structure with info from port_info_save
  22748  * Returns:
  22749  *      BCM_E_XXX
  22750  * Notes:
  22751  *      bcm_port_info_save has done all the work.
  22752  *      We just call port_selective_set.
  22753  */
  22754 
  22755 int
  22756 bcm_esw_port_info_restore(int unit, bcm_port_t port, bcm_port_info_t *info)
  22757 {
  22758     /* Make sure port module is initialized. */
  22759     PORT_INIT(unit);
  22760 
  22761     return bcm_esw_port_selective_set(unit, port, info);
  22762 }
  22763 
  22764 /*
  22765  * Function:
  22766  *      bcm_port_phy_drv_name_get
  22767  * Purpose:
  22768  *      Return the name of the PHY driver being used on a port.
  22769  * Parameters:
  22770  *      unit - StrataSwitch unit #
  22771  *      port - StrataSwitch port #
  22772  * Returns:
  22773  *      Pointer to static string
  22774  */
  22775 int
  22776 bcm_esw_port_phy_drv_name_get(int unit, bcm_port_t port, char *name, int len)
  22777 {
  22778     int str_len;
  22779 
  22780     /* Make sure port module is initialized. */
  22781     PORT_INIT(unit);
  22782 
  22783     if(bcm_common_oamp_port_enable_get(unit, port)) {
  22784         LOG_ERROR(BSL_LS_BCM_PORT,
  22785                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  22786                    port));
  22787         return BCM_E_PARAM;
  22788     }
  22789 
  22790     /* Call Port Control module */
  22791     if (SOC_USE_PORTCTRL(unit)) {
  22792         return bcmi_esw_portctrl_phy_drv_name_get(unit, port, name, len);
  22793     }
  22794 
  22795     if (bcm_port_info[unit] == NULL) {
  22796         str_len = sal_strlen("driver not initialized");
  22797         if (str_len <= len) {
  22798             sal_strncpy(name, "driver not initialized", len);
  22799         }
  22800         return BCM_E_INIT;
  22801     }
  22802     if (!SOC_PORT_VALID(unit, port)) {
  22803         str_len = sal_strlen("invalid port");
  22804         if (str_len <= len) {
  22805             sal_strncpy(name, "invalid port", len);
  22806         }
  22807         return BCM_E_PORT;
  22808     }
  22809     return (soc_phyctrl_drv_name_get(unit, port, name, len));
  22810 }
  22811 
  22812 /*
  22813  * Function:
  22814  *      _bcm_port_encap_xport_set
  22815  * Purpose:
  22816  *      Convert 10G Ether port to Higig port, or reverse
  22817  * Notes;
  22818  *      Must be called with PORT_LOCK held.
  22819  */
  22820 
  22821 int
  22822 _bcm_port_encap_xport_set(int unit, bcm_port_t port, int mode,
  22823                           int update_port_mode)
  22824 {
  22825 #ifdef BCM_FIREBOLT_SUPPORT
  22826     bcm_stg_t        stg;
  22827     int              to_higig;
  22828     soc_field_t      port_type_field;
  22829     soc_reg_t        egr_port_reg;
  22830     soc_port_ability_t ability;
  22831     soc_port_mode_t  non_ieee_speed;
  22832     int              an, an_done, force_speed, port_type;
  22833     uint32           entry[SOC_MAX_MEM_WORDS];
  22834 #ifdef BCM_TRIDENT2_SUPPORT
  22835     int              config_speed = 0;
  22836 #endif
  22837 #if defined(BCM_KATANA2_SUPPORT)
  22838     int speed = 0;
  22839     bcmMxqPhyPortMode_t phy_mode;
  22840 #endif
  22841 int              enable = 0;
  22842 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  22843     uint32 rval = 0;
  22844     uint32 mtu = 0;
  22845     soc_info_t       *si = &SOC_INFO(unit);
  22846 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  22847 
  22848     if (SOC_USE_PORTCTRL(unit)) {
  22849         return bcmi_esw_portctrl_encap_xport_set(unit, port, mode);
  22850     }
  22851 
  22852     to_higig = (mode != BCM_PORT_ENCAP_IEEE);
  22853     port_type_field = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  22854                        SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit) ||
  22855                        SOC_IS_HURRICANEX(unit) || SOC_IS_TD_TT(unit) ||
  22856                        SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)||
  22857                        SOC_IS_GREYHOUND(unit) || SOC_IS_GREYHOUND2(unit)) ? 
  22858                        PORT_TYPEf : HIGIG_PACKETf;
  22859     egr_port_reg = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  22860                     SOC_IS_VALKYRIE2(unit) || SOC_IS_GREYHOUND(unit) ||
  22861                     SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ?
  22862                     EGR_PORT_64r : EGR_PORTr;
  22863 
  22864 #if defined(BCM_KATANA2_SUPPORT)
  22865     if (to_higig && SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit) &&
  22866             update_port_mode) {
  22867         /*
  22868          * Updating the phy_mode according to the port encap type.
  22869          * Using 13G as default speed for higig since the underlying routine
  22870          * do not differentiate on higig speeds.
  22871          */
  22872         SOC_IF_ERROR_RETURN
  22873             (soc_katana2_get_phy_port_mode(unit, port, 13000, &phy_mode));
  22874     }
  22875 #endif
  22876     SOC_IF_ERROR_RETURN
  22877         (MAC_ENCAP_SET(PORT(unit, port).p_mac, unit, port, mode));
  22878 
  22879     if ((SOC_IS_SABER2(unit) || SOC_IS_HURRICANE2(unit)) && IS_XL_PORT(unit, port)) {
  22880         if (mode == BCM_PORT_ENCAP_HIGIG2_LITE) {
  22881             SOC_PBMP_PORT_ADD(SOC_INFO(unit).hl.bitmap, port);
  22882         } else {
  22883             SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).hl.bitmap, port);
  22884         }
  22885     }
  22886     if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) { 
  22887         if ((mode == BCM_PORT_ENCAP_HIGIG2_LITE) && IS_ST_PORT(unit, port)) {
  22888             /*KT2: HL port is treated as GE port too*/ 
  22889             SOC_PBMP_PORT_ADD(SOC_INFO(unit).hl.bitmap, port);
  22890             SOC_PBMP_PORT_ADD(SOC_INFO(unit).ge.bitmap, port);
  22891         } else if ((mode == BCM_PORT_ENCAP_IEEE) && IS_XE_PORT(unit,port)) {
  22892             SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).hl.bitmap, port);
  22893             SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).ge.bitmap, port);
  22894         }
  22895         soc_dport_map_update(unit);
  22896     }
  22897     /*
  22898      * MAC_ENCAP_SET() would change the ING_MTU to defalut value.
  22899      * So also change EGR_MTU to default value manually.
  22900      */
  22901 #ifdef BCM_SHADOW_SUPPORT
  22902     if (SOC_IS_SHADOW(unit)) {
  22903         mtu = (1 << soc_reg_field_length(unit, EGR_L2_MTUr, VALUEf)) - 1;
  22904         soc_reg_field_set(unit, EGR_L2_MTUr, &rval,
  22905                           VALUEf, mtu);
  22906         SOC_IF_ERROR_RETURN(WRITE_EGR_L2_MTUr(unit, port, rval));
  22907     } else
  22908 #endif /* BCM_SHADOW_SUPPORT */
  22909 
  22910 #ifdef BCM_XGS3_SWITCH_SUPPORT
  22911     if (SOC_IS_XGS3_SWITCH(unit)) {
  22912         soc_reg_t reg;
  22913         soc_mem_t mem;
  22914         uint32 field_val_clear = 0;
  22915 
  22916         if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) {
  22917             mem = EGR_MTUm;
  22918             mtu = si->max_mtu;
  22919             if (soc_feature(unit, soc_feature_egr_all_profile)) {
  22920                 BCM_IF_ERROR_RETURN(
  22921                     bcm_esw_port_egr_lport_field_set(unit, port, mem,
  22922                     MTU_SIZEf, mtu));
  22923             } else {
  22924             SOC_IF_ERROR_RETURN(
  22925                           soc_mem_read(unit, mem, MEM_BLOCK_ANY, port, entry));
  22926             soc_mem_field_set(unit, mem, entry, MTU_SIZEf, &mtu);
  22927             if (soc_mem_field_valid(unit, mem, MTU_ENABLEf)) {
  22928                 soc_mem_field_set(unit, mem, entry, MTU_ENABLEf,
  22929                                   &field_val_clear);
  22930             }
  22931             SOC_IF_ERROR_RETURN(
  22932                           soc_mem_write(unit, mem, MEM_BLOCK_ANY, port, entry));
  22933             }
  22934         } else {
  22935             reg = SOC_REG_IS_VALID(unit, EGR_MTUr) ? EGR_MTUr : EGR_MTU_SIZEr;
  22936             mtu = si->max_mtu;
  22937             soc_reg_field_set(unit, reg, &rval, MTU_SIZEf, mtu);
  22938             if (soc_reg_field_valid(unit, reg, MTU_ENABLEf)) {
  22939                 soc_reg_field_set(unit, reg, &rval, MTU_ENABLEf, 0);
  22940             }
  22941             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
  22942         }
  22943     }
  22944 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  22945 
  22946     if (!to_higig) {
  22947         SOC_IF_ERROR_RETURN
  22948             (MAC_INTERFACE_SET(PORT(unit, port).p_mac,
  22949                                unit, port, SOC_PORT_IF_XGMII));
  22950     }
  22951 
  22952     /* Sepcific for GH on avoiding port speed change */
  22953     if (!soc_feature(unit, soc_feature_hg_no_speed_change)) {
  22954         BCM_IF_ERROR_RETURN
  22955                 (bcm_esw_port_ability_local_get(unit, port, &ability));
  22956 
  22957         non_ieee_speed = ability.speed_full_duplex &
  22958                 ~(SOC_PA_SPEED_100GB | SOC_PA_SPEED_40GB | SOC_PA_SPEED_10GB |
  22959                   SOC_PA_SPEED_2500MB | SOC_PA_SPEED_1000MB | SOC_PA_SPEED_100MB |
  22960                   SOC_PA_SPEED_10MB);
  22961 
  22962         BCM_IF_ERROR_RETURN
  22963                 (bcm_esw_port_ability_advert_get(unit, port, &ability));
  22964         if (to_higig) {
  22965             ability.speed_full_duplex |= non_ieee_speed;
  22966             ability.pause &= ~(SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM);
  22967             /* Retrieving the max speed */
  22968             BCM_IF_ERROR_RETURN(bcm_esw_port_speed_max(unit, port, &force_speed));
  22969             force_speed = force_speed == 0 ?
  22970                     SOC_CONTROL(unit)->info.port_speed_max[port] : force_speed;
  22971 
  22972 #ifdef BCM_TRIDENT2_SUPPORT
  22973             if (SOC_IS_TRIDENT2(unit) && 
  22974                 soc_property_port_get(unit, port, spn_PORT_MAX_SPEED, 0) &&
  22975                 (si->port_num_lanes[port] != 4)) {
  22976                 config_speed = soc_property_port_get(unit, port, spn_PORT_MAX_SPEED, force_speed);
  22977                 force_speed = (force_speed > config_speed) ? config_speed : force_speed;
  22978             }
  22979 #endif
  22980             
  22981             ability.speed_full_duplex |= SOC_PA_SPEED(force_speed);
  22982         } else {
  22983             ability.speed_full_duplex &= ~non_ieee_speed;
  22984             force_speed = IS_GE_PORT(unit , port) ? 1000 : IS_CE_PORT(unit , port) ?
  22985                 100000 : SOC_CONTROL(unit)->info.port_speed_max[port] >= 40000 ?
  22986                 40000 :  SOC_CONTROL(unit)->info.port_speed_max[port] >= 10000 ?
  22987                 10000 : 1000;
  22988 #if defined(BCM_KATANA2_SUPPORT)
  22989             /* For Katana2 Warpcore the xlport_mode_reg. The phy_port_mode value
  22990             * differs when speed is 1000 vs 2500.
  22991             * GE port does not necessarily have 1000 speed always.
  22992             * The VCO frequency can change ased on phy_port_mode, 
  22993             * core_port_mode and number of lanes on Warpcore.
  22994             * The lower layer Warpcore driver relies on these values.
  22995             * So we need to set the correct forced speed for the port */
  22996             if ((SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) && force_speed == 1000) {
  22997                 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed));
  22998                 force_speed = (speed == 2500) ? speed : force_speed;
  22999             }
  23000 #endif
  23001         }
  23002 
  23003     BCM_IF_ERROR_RETURN
  23004         (bcm_esw_port_ability_advert_set(unit, port, &ability));
  23005 
  23006 #ifdef BCM_KATANA2_SUPPORT
  23007 #ifdef BCM_METROLITE_SUPPORT
  23008     if (SOC_IS_METROLITE(unit)) {
  23009        BCM_IF_ERROR_RETURN
  23010               (_bcm_ml_update_port_mode(unit, port, force_speed));
  23011 
  23012         if (IS_XL_PORT(unit,port) &&
  23013             ((mode == BCM_PORT_ENCAP_HIGIG2) || (mode == BCM_PORT_ENCAP_HIGIG))) {
  23014             SOC_IF_ERROR_RETURN(soc_phyctrl_speed_set(unit, port, force_speed));
  23015             SOC_IF_ERROR_RETURN(MAC_SPEED_SET(PORT(unit, port).p_mac, 
  23016                                   unit, port, force_speed));
  23017         }
  23018     } else 
  23019 #endif
  23020 
  23021 #ifdef BCM_SABER2_SUPPORT
  23022     if (SOC_IS_SABER2(unit)) {
  23023        BCM_IF_ERROR_RETURN
  23024               (_bcm_sb2_update_port_mode(unit, port, force_speed));
  23025 
  23026         if (IS_XL_PORT(unit,port) &&
  23027             ((mode == BCM_PORT_ENCAP_HIGIG2) || (mode == BCM_PORT_ENCAP_HIGIG))) {
  23028             SOC_IF_ERROR_RETURN(soc_phyctrl_speed_set(unit, port, force_speed));
  23029             SOC_IF_ERROR_RETURN(MAC_SPEED_SET(PORT(unit, port).p_mac, 
  23030                                   unit, port, force_speed));
  23031         }
  23032     } else 
  23033 #endif
  23034         if(SOC_IS_KATANA2(unit) && update_port_mode) {
  23035             BCM_IF_ERROR_RETURN
  23036                 (_bcm_kt2_update_port_mode(unit, port, force_speed));
  23037         }
  23038 #endif
  23039         SOC_IF_ERROR_RETURN
  23040                 (soc_phyctrl_auto_negotiate_get(unit, port, &an, &an_done));
  23041         /* some phy driver will enable the port no matter previous port 
  23042          * state while executing speed_set or autoneg_set. So we need to 
  23043          * get the port state before speed_set or autoneg_set, and set it
  23044          * back after speed_set or autoneg_set. So that it can keep the 
  23045          * same port state before after speed_set or autoneg_set*/
  23046         BCM_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &enable));
  23047         
  23048         /* Some mac driver re-init phy while executing MAC_ENCAP_SET, in that case
  23049          * autoneg is probably always true here */
  23050         if (an) {
  23051             SOC_IF_ERROR_RETURN(bcm_esw_port_autoneg_set(unit, port, TRUE));
  23052         } else {
  23053             SOC_IF_ERROR_RETURN(soc_phyctrl_speed_set(unit, port, force_speed));
  23054         }
  23055         BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, port, enable));
  23056     }
  23057 
  23058     /* Now we propagate the changes */
  23059     port_type = to_higig ? 1 : 0;
  23060     if (soc_mem_field_valid(unit, PORT_TABm, port_type_field)) {
  23061         SOC_IF_ERROR_RETURN(soc_mem_field32_modify(
  23062                             unit, PORT_TABm, port, port_type_field, port_type));
  23063     }
  23064     if (SOC_MEM_IS_VALID(unit, EGR_PORTm)) {
  23065         if (soc_mem_field_valid(unit, EGR_PORTm, port_type_field)) {
  23066             SOC_IF_ERROR_RETURN
  23067                 (soc_mem_field32_modify(unit, EGR_PORTm, port, port_type_field,
  23068                                         port_type));
  23069         }
  23070     } else {
  23071         SOC_IF_ERROR_RETURN
  23072             (soc_reg_field32_modify(unit, egr_port_reg, port, port_type_field,
  23073                                     port_type));
  23074     }
  23075 
  23076     if (SOC_MEM_IS_VALID(unit, EGR_ING_PORTm)) {
  23077         if (!IS_CPU_PORT(unit, port) && !IS_LB_PORT(unit, port)) {
  23078             SOC_IF_ERROR_RETURN
  23079                 (soc_mem_field32_modify(unit, EGR_ING_PORTm, port, PORT_TYPEf,
  23080                                         mode == BCM_PORT_ENCAP_IEEE ? 0 : 1));
  23081         }
  23082     }
  23083 
  23084     
  23085     if (SOC_MEM_IS_VALID(unit, ICONTROL_OPCODE_BITMAPm)) {
  23086         icontrol_opcode_bitmap_entry_t entry;
  23087         soc_pbmp_t pbmp;
  23088 
  23089         SOC_IF_ERROR_RETURN
  23090             (READ_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry));
  23091         SOC_PBMP_CLEAR(pbmp);
  23092         if (to_higig) {
  23093             SOC_PBMP_PORT_SET(pbmp, CMIC_PORT(unit));
  23094         }
  23095         soc_mem_pbmp_field_set(unit, ICONTROL_OPCODE_BITMAPm, &entry,
  23096                                BITMAPf, &pbmp);
  23097         SOC_IF_ERROR_RETURN
  23098             (WRITE_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry));
  23099     } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  23100         SOC_IS_VALKYRIE2(unit)) {
  23101         uint64 cpu_pbm64;
  23102         uint64 rval64;      /* Current 64 bit register data.  */
  23103         COMPILER_64_ZERO(cpu_pbm64);
  23104         COMPILER_64_SET(cpu_pbm64, 0, to_higig ? 1 : 0);
  23105         SOC_IF_ERROR_RETURN(READ_ICONTROL_OPCODE_BITMAP_64r(unit, port,
  23106                                                             &rval64));
  23107         soc_reg64_field_set(unit, ICONTROL_OPCODE_BITMAP_64r, &rval64,
  23108                             BITMAPf, cpu_pbm64);
  23109         SOC_IF_ERROR_RETURN(WRITE_ICONTROL_OPCODE_BITMAP_64r(unit, port,
  23110                                                              rval64));
  23111     } else if (SOC_REG_IS_VALID(unit,ICONTROL_OPCODE_BITMAP_LOr) && 
  23112                 SOC_REG_IS_VALID(unit,ICONTROL_OPCODE_BITMAP_HIr)) {
  23113         uint64      fval64, rval64;
  23114         uint32      t_port;
  23115         pbmp_t      curr_pbmp;
  23116         soc_reg_t   reg;
  23117 
  23118         BCM_PBMP_CLEAR(curr_pbmp);
  23119         COMPILER_64_ZERO(fval64);
  23120 
  23121         /* Set HG ingress CPU Opcode map to the CPU */
  23122         if (CMIC_PORT(unit) < 64) {
  23123             reg = ICONTROL_OPCODE_BITMAP_LOr;
  23124             t_port = CMIC_PORT(unit);
  23125     } else {
  23126             reg = ICONTROL_OPCODE_BITMAP_HIr;
  23127             t_port = CMIC_PORT(unit) - 64;
  23128         }
  23129 
  23130 
  23131         if (to_higig) {
  23132             SOC_PBMP_PORT_ADD(curr_pbmp, t_port);
  23133         }
  23134 
  23135         BCM_IF_ERROR_RETURN(soc_reg_get(unit, 
  23136                             reg, port, 0, &rval64));
  23137         COMPILER_64_SET(fval64,
  23138                         SOC_PBMP_WORD_GET(curr_pbmp, 1),
  23139                         SOC_PBMP_WORD_GET(curr_pbmp, 0));
  23140 
  23141         soc_reg64_field_set(unit, 
  23142                 reg, &rval64, BITMAPf, fval64);
  23143         BCM_IF_ERROR_RETURN(soc_reg_set(unit, 
  23144                 reg, port, 0, rval64));
  23145 
  23146     } else if (SOC_REG_IS_VALID(unit,ICONTROL_OPCODE_BITMAPr)) {
  23147 
  23148         /* Set HG ingress CPU Opcode map to the CPU */
  23149         int pbm_len;
  23150         uint32 cpu_pbm = 0;
  23151 
  23152         if (to_higig) {
  23153             if (SOC_IS_TR_VL(unit)) {
  23154                 soc_xgs3_port_to_higig_bitmap(unit, CMIC_PORT(unit),
  23155                                               &cpu_pbm);
  23156             } else if (CMIC_PORT(unit)) {
  23157                 pbm_len = soc_reg_field_length(unit, ICONTROL_OPCODE_BITMAPr,
  23158                                                BITMAPf);
  23159                 cpu_pbm = 1 << (pbm_len - 1);
  23160             } else {
  23161                 cpu_pbm = 1;
  23162             }
  23163         } /* else, cpu_pbm = 0 */
  23164 
  23165         SOC_IF_ERROR_RETURN
  23166             (soc_reg_field32_modify(unit, ICONTROL_OPCODE_BITMAPr,
  23167                                     port, BITMAPf, cpu_pbm));
  23168     }
  23169 
  23170     if (to_higig) {
  23171         /* HG ports to forwarding */
  23172         BCM_IF_ERROR_RETURN(bcm_esw_port_stp_set(unit, port,
  23173                                                  BCM_STG_STP_FORWARD));
  23174     }  
  23175 
  23176 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  23177     /*
  23178      * Higig ports need the MIRROR_CONTROL.M_ENABLE=1 in order to respond to
  23179      * the mirror bit in the Higig headers.
  23180      */
  23181     if (to_higig) {
  23182         BCM_IF_ERROR_RETURN(_bcm_esw_mirror_enable_set(unit, port, TRUE));
  23183     }
  23184 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  23185 
  23186     /* Clear mirror enable settings */
  23187     /* coverity[stack_use_callee] */
  23188     /* coverity[stack_use_overflow] */
  23189     BCM_IF_ERROR_RETURN(bcm_esw_mirror_port_set(unit, port, -1, -1, 0));
  23190 
  23191     /* Set untagged state in default VLAN properly */
  23192     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_untag_update(unit, port, to_higig));
  23193 
  23194     /* Resolve STG 0 */
  23195     BCM_IF_ERROR_RETURN(bcm_esw_stg_default_get(unit, &stg));
  23196     BCM_IF_ERROR_RETURN
  23197         (bcm_esw_stg_stp_set(unit, 0, port,
  23198                              to_higig ? BCM_STG_STP_FORWARD : BCM_STG_STP_DISABLE));
  23199 
  23200 #ifdef BCM_TRX_SUPPORT
  23201     /* Reset the vlan default action */
  23202     if (SOC_IS_TRX(unit) && 
  23203         (soc_feature(unit, soc_feature_vlan_action) ||
  23204          soc_feature(unit, soc_feature_egr_vlan_action))) {
  23205         bcm_vlan_action_set_t action;
  23206 
  23207         BCM_IF_ERROR_RETURN
  23208             (_bcm_trx_vlan_port_egress_default_action_get(unit,
  23209                                                          port, &action));
  23210         /* Backward compatible defaults */
  23211         if (to_higig && (!SOC_IS_TRIDENT3X(unit))) {
  23212             action.ot_outer = bcmVlanActionDelete;
  23213             action.dt_outer = bcmVlanActionDelete;
  23214         } else {
  23215             action.ot_outer = bcmVlanActionNone;
  23216             action.dt_outer = bcmVlanActionNone;
  23217         }
  23218         BCM_IF_ERROR_RETURN
  23219             (_bcm_trx_vlan_port_egress_default_action_set(unit,
  23220                                                          port, &action));
  23221     }
  23222 #endif
  23223 
  23224 #ifdef INCLUDE_L3
  23225     if (soc_feature(unit, soc_feature_ip_mcast)) {
  23226         BCM_IF_ERROR_RETURN(bcm_esw_ipmc_egress_port_set(unit, port, 
  23227                 to_higig ? _soc_mac_all_ones :_soc_mac_all_zeroes, 
  23228                 0, 0, 0));
  23229     }
  23230 #endif /* INCLUDE_L3 */
  23231 
  23232     return BCM_E_NONE;
  23233 #else
  23234     return BCM_E_PARAM;
  23235 #endif
  23236 }
  23237 
  23238 /*
  23239  * Function:
  23240  *      _bcm_port_encap_stport_set
  23241  * Purpose:
  23242  *      Convert 2.5G Higig 2 port to Ether port, or reverse
  23243  */
  23244 int
  23245 _bcm_port_encap_stport_set(int unit, bcm_port_t port, int mode)
  23246 {
  23247 #if defined(BCM_RAVEN_SUPPORT) || defined (BCM_TRIUMPH2_SUPPORT) || \
  23248     defined(BCM_KATANA_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  23249     uint32           rval;
  23250     bcm_stg_t        stg;
  23251     int              to_higig = 0, max_mtu = 0;
  23252     uint32           tab_higig_type;
  23253     soc_info_t       *si = &SOC_INFO(unit);
  23254     soc_field_t      hg_en[6] = {-1, HGIG2_EN_S0f, HGIG2_EN_S1f, -1,
  23255                                  HGIG2_EN_S3f, HGIG2_EN_S4f};
  23256     soc_field_t      port_type;
  23257     soc_reg_t        egr_port;
  23258 
  23259     if (mode == BCM_PORT_ENCAP_HIGIG2 || mode == BCM_PORT_ENCAP_HIGIG2_LITE
  23260         || mode == BCM_PORT_ENCAP_HIGIG || mode == BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET) {
  23261         to_higig = TRUE;
  23262     }
  23263 
  23264     if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  23265         SOC_IS_GREYHOUND2(unit)) {
  23266         if (!soc_feature(unit, soc_feature_wh2)) {
  23267             return BCM_E_INTERNAL;
  23268         }
  23269     }
  23270 
  23271     /* This check is not correct for devices supporting embedded higig */
  23272     if (!soc_feature(unit, soc_feature_embedded_higig) &&
  23273         !soc_feature(unit, soc_feature_higig_over_ethernet)) {
  23274         if (SOC_IS_ENDURO(unit) || SOC_IS_HURRICANE(unit)) {
  23275             if ((port != 26) && (port != 27) && (port != 28) && (port != 29)) {
  23276                 return BCM_E_PORT;
  23277             }
  23278             SOC_IF_ERROR_RETURN
  23279                 (soc_reg_field32_modify(unit, EHG_RX_CONTROLr, port, MODEf,
  23280                                         to_higig ? 2 : 0));
  23281         } else if (SOC_IS_HURRICANE2(unit)) {
  23282             if ((port < 26) || (port > 29)) {
  23283                 return BCM_E_PORT;
  23284             }
  23285         } else if (SOC_IS_KATANA(unit)) {
  23286             /* Only ports 25..34 are HGL capable */
  23287             if ((port < 25) || (port > 34)) {
  23288                 return BCM_E_PORT;
  23289             }
  23290         } else if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) {
  23291             /* Only ports 25..40 are HGL capable */
  23292             if ((port < 25) || (port > 40)) {
  23293                 return BCM_E_PORT;
  23294             }
  23295         } else if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_TOMAHAWKX(unit) ||
  23296                    SOC_IS_TRIDENT3X(unit)) {
  23297             /* Need to check what is the right condition for Embedded Higig */
  23298         } else if (soc_feature(unit, soc_feature_wh2)) {
  23299             /* All ports are HGL capable */
  23300         } else {
  23301             if ((port != 1) && (port != 2) && (port != 4) && (port != 5)) {
  23302                 return BCM_E_PORT;
  23303             }
  23304         }
  23305     }
  23306 
  23307 #if defined(BCM_KATANA2_SUPPORT)
  23308     if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) {
  23309         SOC_IF_ERROR_RETURN(MAC_ENCAP_SET(PORT(unit, port).p_mac, 
  23310                                                unit, port, mode));
  23311     } else 
  23312 #endif
  23313     {
  23314         port_type = SOC_MEM_FIELD_VALID(unit, 
  23315                              SOC_PORT_MEM_TAB(unit, port),
  23316                              HIGIG_PACKETf) ?
  23317                              HIGIG_PACKETf : PORT_TYPEf;
  23318 
  23319         BCM_IF_ERROR_RETURN
  23320              (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE,
  23321                                     port_type, to_higig));
  23322 
  23323         if (to_higig == 1) {
  23324             if (mode == BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET) {
  23325                 tab_higig_type = BCM_PORT_HG_TYPE_HGOE_TRANSPORT;
  23326             } else if (mode == BCM_PORT_ENCAP_HIGIG) {
  23327                 tab_higig_type = BCM_PORT_HG_TYPE_HIGIGPLUS;
  23328             } else {
  23329                 tab_higig_type = BCM_PORT_HG_TYPE_HIGIG2_NORMAL;
  23330             }
  23331         } else {
  23332             tab_higig_type = 0; 
  23333         }
  23334 
  23335         if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, HG_TYPEf)) {
  23336             SOC_IF_ERROR_RETURN
  23337                 (soc_mem_field32_modify(unit, EGR_ING_PORTm, port,
  23338                  HG_TYPEf, tab_higig_type));
  23339         }
  23340 
  23341         if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, HG_TYPEf)) {
  23342             SOC_IF_ERROR_RETURN
  23343                 (soc_mem_field32_modify(unit, EGR_PORTm, port,
  23344                  HG_TYPEf, tab_higig_type));
  23345         }
  23346 
  23347         if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, PORT_TYPEf)) {
  23348             SOC_IF_ERROR_RETURN
  23349                 (soc_mem_field32_modify(unit, EGR_PORTm, port,
  23350                              PORT_TYPEf, to_higig));
  23351         } else {
  23352             if (SOC_REG_IS_VALID(unit, EGR_PORT_64r)) {
  23353                 egr_port = EGR_PORT_64r;
  23354             } else {
  23355                 egr_port = EGR_PORTr;
  23356             }
  23357             SOC_IF_ERROR_RETURN
  23358                 (soc_reg_field32_modify(unit, egr_port, port,
  23359                                         port_type, to_higig));
  23360        }
  23361 
  23362        /* The port number check is for Coverity.  No port > 6 will
  23363         * reach this logic on Raven. */
  23364         if (SOC_IS_RAVEN(unit) && (port < 6)) {
  23365             SOC_IF_ERROR_RETURN
  23366                 (soc_reg_field32_modify(unit, GPORT_CONFIGr, port,
  23367                                         hg_en[port], to_higig));
  23368         }
  23369     }
  23370 
  23371     if (to_higig) {
  23372         BCM_IF_ERROR_RETURN(bcm_esw_port_pause_set(unit, port, 0, 0));
  23373         /* For encap to hg/st port, SOC_PORT_MIN need to update or
  23374            cannot do SOC_PBMP_PORT_ADD if the port is lower than
  23375            SOC_PORT_MIN
  23376         */
  23377         if ((port < SOC_PORT_MIN(unit,st)) || (SOC_PORT_MIN(unit,st) == -1)) {
  23378             SOC_PORT_MIN(unit,st) = port;
  23379         }
  23380         if (port > SOC_PORT_MAX(unit,st)) {
  23381             SOC_PORT_MAX(unit,st) = port;
  23382         }
  23383 
  23384         SOC_PBMP_PORT_ADD(si->st.bitmap, port);
  23385         SOC_PBMP_PORT_ADD(si->hl.bitmap, port);
  23386         SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port);
  23387         SOC_PBMP_PORT_REMOVE(si->ether.bitmap, port);
  23388 
  23389         SOC_PBMP_PORT_INFO_UPDATE(si->xe);
  23390 
  23391         max_mtu = SOC_INFO(unit).max_mtu;
  23392         BCM_IF_ERROR_RETURN(bcm_esw_port_frame_max_set(unit, port, max_mtu));
  23393     } else {
  23394         SOC_PBMP_PORT_REMOVE(si->st.bitmap, port);
  23395         SOC_PBMP_PORT_REMOVE(si->hl.bitmap, port);
  23396         SOC_PBMP_PORT_ADD(si->ether.bitmap, port);
  23397 
  23398         /* Set pause and frame - other abilities depend on the board and
  23399          * the application needs to call other APIs appropriately */
  23400         BCM_IF_ERROR_RETURN(bcm_esw_port_pause_set(unit, port, 1, 1));
  23401         max_mtu = SOC_INFO(unit).max_mtu - 4;
  23402         BCM_IF_ERROR_RETURN(bcm_esw_port_frame_max_set(unit, port, max_mtu));
  23403     }
  23404     SOC_PBMP_PORT_INFO_UPDATE(si->ether);
  23405     SOC_PBMP_PORT_INFO_UPDATE(si->st);
  23406     SOC_PBMP_PORT_INFO_UPDATE(si->hl);
  23407 
  23408     /* Set HG ingress CPU Opcode map to the CPU */
  23409     if (SOC_MEM_IS_VALID(unit, ICONTROL_OPCODE_BITMAPm)) {
  23410         icontrol_opcode_bitmap_entry_t entry;
  23411         soc_pbmp_t pbmp;
  23412 
  23413         SOC_IF_ERROR_RETURN
  23414             (READ_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry));
  23415         SOC_PBMP_CLEAR(pbmp);
  23416         if (to_higig) {
  23417             SOC_PBMP_PORT_SET(pbmp, CMIC_PORT(unit));
  23418         }
  23419         soc_mem_pbmp_field_set(unit, ICONTROL_OPCODE_BITMAPm, &entry,
  23420                                BITMAPf, &pbmp);
  23421         SOC_IF_ERROR_RETURN
  23422             (WRITE_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry));
  23423     } else if (SOC_REG_IS_VALID(unit, ICONTROL_OPCODE_BITMAP_64r)) {
  23424         uint64 cpu_pbm64;
  23425         uint64 rval64;      /* Current 64 bit register data.  */
  23426         COMPILER_64_ZERO(cpu_pbm64);
  23427         COMPILER_64_SET(cpu_pbm64, 0, to_higig ? 1 : 0);
  23428         SOC_IF_ERROR_RETURN(
  23429             READ_ICONTROL_OPCODE_BITMAP_64r(unit, port,&rval64));
  23430 
  23431         soc_reg64_field_set(unit, ICONTROL_OPCODE_BITMAP_64r, &rval64,
  23432                             BITMAPf, cpu_pbm64);
  23433 
  23434         SOC_IF_ERROR_RETURN(
  23435             WRITE_ICONTROL_OPCODE_BITMAP_64r(unit, port, rval64));
  23436     } else {
  23437         uint32 cpu_pbm;
  23438 
  23439         if(SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit)) {
  23440             if(to_higig) {
  23441                 SOC_IF_ERROR_RETURN
  23442                         (soc_xgs3_port_to_higig_bitmap(unit, CMIC_PORT(unit),
  23443                                            &cpu_pbm));
  23444             } else {
  23445                 cpu_pbm = 0;
  23446             }
  23447         } else {
  23448             cpu_pbm = to_higig ? 1 : 0;
  23449         }
  23450         SOC_IF_ERROR_RETURN(
  23451             READ_ICONTROL_OPCODE_BITMAPr(unit, port,&rval));
  23452 
  23453         soc_reg_field_set(unit, ICONTROL_OPCODE_BITMAPr,
  23454                           &rval, BITMAPf, cpu_pbm);
  23455 
  23456         SOC_IF_ERROR_RETURN(
  23457             WRITE_ICONTROL_OPCODE_BITMAPr(unit, port, rval));
  23458     }
  23459 
  23460     /* HG ports to forwarding */
  23461     BCM_IF_ERROR_RETURN(
  23462         bcm_esw_port_stp_set(unit, port, BCM_STG_STP_FORWARD));
  23463 
  23464     /* Set untagged state in default VLAN properly */
  23465     BCM_IF_ERROR_RETURN(_bcm_esw_vlan_untag_update(unit, port, to_higig));
  23466 
  23467     /* Resolve STG 0 */
  23468     BCM_IF_ERROR_RETURN(bcm_esw_stg_default_get(unit, &stg));
  23469     BCM_IF_ERROR_RETURN(
  23470         bcm_esw_stg_stp_set(unit, stg, port, BCM_STG_STP_FORWARD));
  23471 
  23472 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  23473     /* Reset the vlan default action */
  23474     if ((SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit) ||
  23475          SOC_IS_KATANA2(unit)) &&
  23476             soc_feature(unit, soc_feature_vlan_action)) {
  23477         bcm_vlan_action_set_t action;
  23478 
  23479         BCM_IF_ERROR_RETURN
  23480             (_bcm_trx_vlan_port_egress_default_action_get(unit,
  23481                                                          port, &action));
  23482         if (to_higig) {
  23483             action.ot_outer = bcmVlanActionDelete;
  23484             action.dt_outer = bcmVlanActionDelete;
  23485         } else {
  23486             action.ot_outer = bcmVlanActionNone;
  23487             action.dt_outer = bcmVlanActionNone;
  23488         }
  23489         BCM_IF_ERROR_RETURN
  23490             (_bcm_trx_vlan_port_egress_default_action_set(unit,
  23491                                                          port, &action));
  23492     }
  23493 #endif /* BCM_ENDURO_SUPPORT */
  23494 
  23495     return BCM_E_NONE;
  23496 #else
  23497     return BCM_E_PARAM;
  23498 #endif
  23499 }
  23500 
  23501 /*
  23502  * Function:
  23503  *      _bcm_port_ehg_header_mem_get
  23504  * Purpose:
  23505  *      Calculates the correct memories for a given port
  23506  * Parameters:
  23507  *      unit            - (IN) device id
  23508  *      port            - (IN) Physical port
  23509  *      tx_mem          - (OUT) tx memory for EHG heade
  23510  *      rx_mem          - (OUT) rx memory for EHG heade
  23511  *      rx_mask_mem     - (OUT) rx mask memory for EHG heade
  23512  * Returns:
  23513  *      BCM_E_XXX
  23514  */
  23515 STATIC int
  23516 _bcm_port_ehg_header_mem_get(int unit, bcm_port_t port, soc_mem_t *tx_mem,
  23517                              soc_mem_t *rx_mem, soc_mem_t *rx_mask_mem)
  23518 {
  23519     int phy_port;
  23520 
  23521     if (NULL == tx_mem || NULL == rx_mem || NULL == rx_mask_mem) {
  23522         return BCM_E_PARAM;
  23523     }
  23524 
  23525     if (soc_feature(unit, soc_feature_logical_port_num)) {
  23526         /* coverity[overrun-local : FALSE] */
  23527         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  23528     } else {
  23529         phy_port = port;
  23530     }
  23531     switch (SOC_PORT_BLOCK_TYPE(unit, phy_port)) {
  23532         case SOC_BLK_GXPORT:
  23533             *tx_mem = XPORT_EHG_TX_TUNNEL_DATAm;
  23534             *rx_mem = XPORT_EHG_RX_TUNNEL_DATAm;
  23535             *rx_mask_mem = XPORT_EHG_RX_TUNNEL_MASKm;
  23536             break;
  23537         case SOC_BLK_GPORT:
  23538             *tx_mem = GPORT_EHG_TX_TUNNEL_DATAm;
  23539             *rx_mem = GPORT_EHG_RX_TUNNEL_DATAm;
  23540             *rx_mask_mem = GPORT_EHG_RX_TUNNEL_MASKm;
  23541             break;
  23542         case SOC_BLK_SPORT:
  23543             *tx_mem = SPORT_EHG_TX_TUNNEL_DATAm;
  23544             *rx_mem = SPORT_EHG_RX_TUNNEL_DATAm;
  23545             *rx_mask_mem = SPORT_EHG_RX_TUNNEL_MASKm;
  23546             break;
  23547         case SOC_BLK_XQPORT:
  23548             *tx_mem = XQPORT_EHG_TX_TUNNEL_DATAm;
  23549             *rx_mem = XQPORT_EHG_RX_TUNNEL_DATAm;
  23550             *rx_mask_mem = XQPORT_EHG_RX_TUNNEL_MASKm;
  23551             break;
  23552         case SOC_BLK_CLPORT:
  23553         case SOC_BLK_XLPORT:
  23554         case SOC_BLK_XTPORT:
  23555         case SOC_BLK_XWPORT:
  23556             *tx_mem = PORT_EHG_TX_TUNNEL_DATAm;
  23557             *rx_mem = PORT_EHG_RX_TUNNEL_DATAm;
  23558             *rx_mask_mem = PORT_EHG_RX_TUNNEL_MASKm;
  23559             break;
  23560         default:
  23561             *tx_mem = *rx_mem = *rx_mask_mem = INVALIDm;
  23562     }
  23563 
  23564     return BCM_E_NONE;
  23565 }
  23566 
  23567 /*
  23568  * Function:
  23569  *      _bcm_port_ehg_header_read
  23570  * Purpose:
  23571  *      Reads EHG header from the HW tables
  23572  * Parameters:
  23573  *      unit            - (IN) device id
  23574  *      port            - (IN) Physical port
  23575  *      buffer          - (OUT) Pointer to the buffer to contain header
  23576  * Returns:
  23577  *      BCM_E_XXX
  23578  */
  23579 
  23580 STATIC int
  23581 _bcm_port_ehg_header_read(int unit, bcm_port_t port, uint32 *buffer)
  23582 {
  23583     soc_mem_t   tx_mem, rx_mem, rx_mask_mem;
  23584     int         tbl_idx_start, tbl_idx_end, idx;
  23585     xqport_ehg_rx_tunnel_data_entry_t      entry;
  23586     int         phy_port;
  23587 
  23588     BCM_IF_ERROR_RETURN
  23589         (_bcm_port_ehg_header_mem_get(unit, port, &tx_mem, &rx_mem,
  23590                                       &rx_mask_mem));
  23591 
  23592     if (INVALIDm == tx_mem) {
  23593         return (BCM_E_PORT);
  23594     }
  23595 
  23596     if (soc_feature(unit, soc_feature_logical_port_num)) {
  23597         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  23598     } else {
  23599         phy_port = port;
  23600     }
  23601 
  23602     tbl_idx_start = SOC_PORT_BINDEX(unit, phy_port) * 4;
  23603     tbl_idx_end = tbl_idx_start + 3;
  23604 
  23605     for (idx = 0 ; idx <= (tbl_idx_end - tbl_idx_start); idx ++) {
  23606         BCM_IF_ERROR_RETURN
  23607             (soc_mem_read(unit, tx_mem, SOC_PORT_BLOCK(unit, phy_port),
  23608                           (idx + tbl_idx_start), (void *)&entry));
  23609         soc_mem_field_get(unit, tx_mem, (void *)&entry, TUNNEL_DATAf,
  23610                           (buffer + ((tbl_idx_end - tbl_idx_start - idx) * 4)));
  23611     }
  23612 
  23613     return (BCM_E_NONE);
  23614 }
  23615 
  23616 /*
  23617  * Function:
  23618  *      _bcm_port_ehg_header_write
  23619  * Purpose:
  23620  *      Writes EHG header into the HW tables
  23621  * Parameters:
  23622  *      unit            - (IN) device id
  23623  *      port            - (IN) Physical port
  23624  *      tx_buff         - (IN) Pointer to the tx header
  23625  *      rx_buff         - (IN) Pointer to the rx header
  23626  *      mask            - (IN) Pointer to the mask header
  23627  *      len             - (IN) Header length
  23628  * Returns:
  23629  *      BCM_E_XXX
  23630  */
  23631 int
  23632 _bcm_port_ehg_header_write(int unit, bcm_port_t port, uint32 *tx_buf,
  23633                            uint32 *rx_buf, uint32 *mask, int len)
  23634 {
  23635     soc_mem_t   tx_mem, rx_mem, rx_mask_mem;
  23636     int         tbl_idx_start, tbl_idx_end, idx;
  23637     xqport_ehg_rx_tunnel_data_entry_t data_entry;
  23638     xqport_ehg_rx_tunnel_mask_entry_t mask_entry;
  23639     int         phy_port;
  23640 
  23641     BCM_IF_ERROR_RETURN
  23642         (_bcm_port_ehg_header_mem_get(unit, port, &tx_mem, &rx_mem,
  23643                                       &rx_mask_mem));
  23644 
  23645     if (INVALIDm == tx_mem) {
  23646         return (BCM_E_PORT);
  23647     }
  23648 
  23649     if (soc_feature(unit, soc_feature_logical_port_num)) {
  23650         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  23651     } else {
  23652         phy_port = port;
  23653     }
  23654 
  23655     tbl_idx_start = SOC_PORT_BINDEX(unit, phy_port) * 4;
  23656     tbl_idx_end = tbl_idx_start + (len / 4) - 1;
  23657 
  23658     for (idx = 0; idx <= (tbl_idx_end - tbl_idx_start); idx ++) {
  23659         /* Reset hw buffer. */
  23660         sal_memset(&data_entry, 0, sizeof(xqport_ehg_rx_tunnel_data_entry_t));
  23661         soc_mem_field_set(unit, tx_mem, (uint32 *)&data_entry, TUNNEL_DATAf,
  23662                           (tx_buf + ((tbl_idx_end - tbl_idx_start - idx) * 4)));
  23663         BCM_IF_ERROR_RETURN
  23664             (soc_mem_write(unit, tx_mem, SOC_PORT_BLOCK(unit, phy_port),
  23665                            (idx + tbl_idx_start), &data_entry));
  23666 
  23667         /* Reset hw buffer. */
  23668         sal_memset(&data_entry, 0, sizeof(xqport_ehg_rx_tunnel_data_entry_t));
  23669         soc_mem_field_set(unit, rx_mem, (uint32 *)&data_entry, TUNNEL_DATAf,
  23670                           (rx_buf + ((tbl_idx_end - tbl_idx_start - idx) * 4)));
  23671         BCM_IF_ERROR_RETURN
  23672             (soc_mem_write(unit, rx_mem, SOC_PORT_BLOCK(unit, phy_port),
  23673                            (idx + tbl_idx_start), &data_entry));
  23674 
  23675         /* Reset hw buffer. */
  23676         sal_memset(&mask_entry, 0, sizeof(xqport_ehg_rx_tunnel_mask_entry_t));
  23677         soc_mem_field_set(unit, rx_mask_mem, (uint32 *)&mask_entry, TUNNEL_MASKf,
  23678                           (mask + ((tbl_idx_end - tbl_idx_start - idx)* 4)));
  23679         BCM_IF_ERROR_RETURN
  23680             (soc_mem_write(unit, rx_mask_mem, SOC_PORT_BLOCK(unit, phy_port),
  23681                            (idx + tbl_idx_start), &mask_entry));
  23682     }
  23683 
  23684     return (BCM_E_NONE);
  23685 }
  23686 
  23687 
  23688 /*
  23689  * Function:
  23690  *      _bcm_port_ehg_setup_txrx_ethernet_hdr
  23691  * Purpose:
  23692  *      Prepares SRC and DEST MAC addresses into rx and tx buffers on a given index
  23693  * Parameters:
  23694  *      tx_buffer       -(IN/OUT) - tx buffer to fill
  23695  *      rx_buffer       -(IN/OUT) - rx buffer to fill
  23696  *      index           -(IN/OUT) - index to the right location in buffer
  23697  *      encap_config    - (IN) structure describes port encapsulation configuration
  23698  * Returns:
  23699  *      BCM_E_XXX
  23700  */
  23701 
  23702 STATIC void
  23703 _bcm_port_ehg_setup_txrx_ethernet_hdr(uint32 *tx_buffer, uint32 *rx_buffer,
  23704                                       int *index,
  23705                                       bcm_port_encap_config_t *encap_config)
  23706 {
  23707     int idx = *index;
  23708 
  23709     /* Destination mac address. */
  23710     tx_buffer[idx] = (((uint32)(encap_config->dst_mac)[0]) << 24 | \
  23711                       ((uint32)(encap_config->dst_mac)[1]) << 16 | \
  23712                       ((uint32)(encap_config->dst_mac)[2]) << 8  | \
  23713                       ((uint32)(encap_config->dst_mac)[3]));
  23714     /* TX dest MAC is RX src MAC */
  23715     rx_buffer[idx] = (((uint32)(encap_config->src_mac)[0]) << 24 | \
  23716                       ((uint32)(encap_config->src_mac)[1]) << 16 | \
  23717                       ((uint32)(encap_config->src_mac)[2]) << 8  | \
  23718                       ((uint32)(encap_config->src_mac)[3]));
  23719     idx--;
  23720 
  23721     tx_buffer[idx] = (((uint32)(encap_config->dst_mac)[4]) << 24 | \
  23722                       ((uint32)(encap_config->dst_mac)[5]) << 16 | \
  23723                       ((uint32)(encap_config->src_mac)[0]) << 8  | \
  23724                       ((uint32)(encap_config->src_mac)[1]));
  23725     /* TX dest MAC is RX src MAC */
  23726     rx_buffer[idx] = (((uint32)(encap_config->src_mac)[4]) << 24 | \
  23727                       ((uint32)(encap_config->src_mac)[5]) << 16 | \
  23728                       ((uint32)(encap_config->dst_mac)[0]) << 8  | \
  23729                       ((uint32)(encap_config->dst_mac)[1]));
  23730     idx--;
  23731     /* Source mac address. */
  23732     tx_buffer[idx] = (((uint32)(encap_config->src_mac)[2]) << 24 | \
  23733                       ((uint32)(encap_config->src_mac)[3]) << 16 | \
  23734                       ((uint32)(encap_config->src_mac)[4]) << 8  | \
  23735                       ((uint32)(encap_config->src_mac)[5]));
  23736     /* TX src MAC is RX dest MAC */
  23737     rx_buffer[idx] = (((uint32)(encap_config->dst_mac)[2]) << 24 | \
  23738                       ((uint32)(encap_config->dst_mac)[3]) << 16 | \
  23739                       ((uint32)(encap_config->dst_mac)[4]) << 8  | \
  23740                       ((uint32)(encap_config->dst_mac)[5]));
  23741     idx--;
  23742 
  23743     *index = idx;
  23744     return;
  23745 }
  23746 
  23747 /* Embedded Higig register access macros */
  23748 #define EHG_TX_REG(unit) \
  23749         (SOC_IS_TRIUMPH3(unit) ? PORT_EHG_TX_CONTROLr : EHG_TX_CONTROLr)
  23750 #define EHG_RX_REG(unit) \
  23751         (SOC_IS_TRIUMPH3(unit) ? PORT_EHG_RX_CONTROLr : EHG_RX_CONTROLr)
  23752 #define EHG_TPID_REG(unit) \
  23753         (SOC_IS_TRIUMPH3(unit) ? PORT_EHG_TPIDr : EHG_TPIDr)
  23754 
  23755 /*
  23756  * Function:
  23757  *      _bcm_port_ehg_ethernet_header_parse
  23758  * Purpose:
  23759  *      Parses Ethernet header from EHG header
  23760  * Parameters:
  23761  *      unit            - (IN) device id
  23762  *      port            - (IN) Physical port
  23763  *      header          - (IN) pointer to the EHG header buffer
  23764  *      encap_config    - (IN/OUT) structure describes port encapsulation configuration
  23765  *      index           - (IN/OUT) index to the right location in buffer
  23766  * Returns:
  23767  *      BCM_E_XXX
  23768  */
  23769 STATIC int
  23770 _bcm_port_ehg_ethernet_header_parse(int unit, bcm_port_t port, uint32 *header,
  23771                                     bcm_port_encap_config_t *encap_config, int *index)
  23772 {
  23773     uint32  val;
  23774     int     idx = *index;
  23775     soc_reg_t ehg_tx_reg = EHG_TX_REG(unit);
  23776 
  23777     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tx_reg, port, 0, &val));
  23778     encap_config->dst_mac[0] = (uint8)(header[idx] >> 24);
  23779     encap_config->dst_mac[1] = (uint8)(header[idx] >> 16);
  23780     encap_config->dst_mac[2] = (uint8)(header[idx] >> 8);
  23781     encap_config->dst_mac[3] = (uint8)(header[idx]);
  23782     idx--;
  23783     encap_config->dst_mac[4] = (uint8)(header[idx] >> 24);
  23784     encap_config->dst_mac[5] = (uint8)(header[idx] >> 16);
  23785     encap_config->src_mac[0] = (uint8)(header[idx] >> 8);
  23786     encap_config->src_mac[1] = (uint8)(header[idx]);
  23787     idx--;
  23788     encap_config->src_mac[2] = (uint8)(header[idx] >> 24);
  23789     encap_config->src_mac[3] = (uint8)(header[idx] >> 16);
  23790     encap_config->src_mac[4] = (uint8)(header[idx] >> 8);
  23791     encap_config->src_mac[5] = (uint8)(header[idx]);
  23792     idx--;
  23793 
  23794     if (soc_reg_field_get(unit, ehg_tx_reg, val, VLAN_TAG_CONTROLf)) {
  23795         encap_config->tpid = (uint16)(header[idx] >> 16);
  23796         encap_config->vlan = (uint16)(header[idx]);
  23797         idx--;
  23798     } else {
  23799         encap_config->vlan = BCM_VLAN_NONE;
  23800         encap_config->tpid = BCM_VLAN_NONE;
  23801     }
  23802 
  23803     *index = idx;
  23804     return BCM_E_NONE;
  23805 }
  23806 /*
  23807  * Function:
  23808  *      _bcm_port_ip4_tunnel_header_set
  23809  * Purpose:
  23810  *      Prepares and sets IP GRE tunnel header for Embedded higig
  23811  * Parameters:
  23812  *      unit            - (IN) device id
  23813  *      port            - (IN) Physical port
  23814  *      encap_config    - (IN) structure describes port encapsulation configuration
  23815  * Returns:
  23816  *      BCM_E_XXX
  23817  */
  23818 STATIC int
  23819 _bcm_port_ip4_tunnel_header_set(int unit, bcm_port_t port,
  23820                                bcm_port_encap_config_t *encap_config)
  23821 {
  23822     /*SW tunnel tx encap buffer.*/
  23823     uint32 tx_buffer[_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ];
  23824     /*SW tunnel rx encap buffer.*/
  23825     uint32 rx_buffer[_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ];
  23826     uint32      mask[_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ];
  23827     int    idx;  /* Headers offset iterator.*/
  23828     int    adjust_rx_offset = 0;
  23829 
  23830     sal_memset(tx_buffer, 0, WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ));
  23831     sal_memset(rx_buffer, 0, WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ));
  23832     sal_memset(mask, 0, WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ));
  23833 
  23834     idx = _BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ - 1;
  23835 
  23836     _bcm_port_ehg_setup_txrx_ethernet_hdr(tx_buffer, rx_buffer, &idx,
  23837                                           encap_config);
  23838 
  23839     /* Set tpid & vlan id. */
  23840     if (BCM_VLAN_VALID(encap_config->vlan)) {
  23841         /* Tpid. Priority,  Cfi, Vlan id. */
  23842         tx_buffer[idx] |= (((uint32)(encap_config->tpid)) << 16 | \
  23843                            ((uint32)(encap_config->vlan)));
  23844         /*rx_buffer should not have the VLAN and TPID included*/
  23845         idx--;
  23846         adjust_rx_offset = 1;
  23847     }
  23848 
  23849     /*
  23850      *   IPv4 header.
  23851      */
  23852     /* Set ether type to ip. 0x800  */
  23853     /* Version + 5 word no options length.  + Tos */
  23854     /* Length, Id, Flags, Fragmentation offset. */
  23855     tx_buffer[idx] |= (((uint32)(0x0800) << 16) | \
  23856                        ((uint32)(0x45) << 8) | \
  23857                        ((uint32)(encap_config->tos)));
  23858     rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx];
  23859     idx--;
  23860     idx--;
  23861 
  23862     /* Ttl */
  23863     /* Protocol (GRE 0x2f) */
  23864     tx_buffer[idx] = (((uint32)(encap_config->ttl) << 8) | \
  23865                       ((uint32)(0x2f)));
  23866     rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx];
  23867     idx--;
  23868 
  23869     /* TX Src Ip. */
  23870     tx_buffer[idx] |= ((uint32)(encap_config->src_addr) >> 16);
  23871 
  23872     /* RX Dst Ip. */
  23873     rx_buffer[idx + adjust_rx_offset] |= ((uint32)(encap_config->dst_addr) >> 16);
  23874     idx--;
  23875 
  23876     /* TX Src Ip. */
  23877     tx_buffer[idx] |= ((uint32)(encap_config->src_addr) << 16);
  23878 
  23879     /* RX Dst Ip. */
  23880     rx_buffer[idx + adjust_rx_offset] |= ((uint32)(encap_config->dst_addr) << 16);
  23881 
  23882     /* TX Dst Ip. */
  23883     tx_buffer[idx] |= ((uint32)(encap_config->dst_addr) >> 16);
  23884 
  23885     /* RX Src Ip */
  23886     rx_buffer[idx + adjust_rx_offset] |= ((uint32)(encap_config->src_addr) >> 16);
  23887     idx--;
  23888 
  23889 
  23890     /* TX Dst Ip. */
  23891     tx_buffer[idx] |= ((uint32)(encap_config->dst_addr) << 16);
  23892 
  23893     /* RX Src Ip */
  23894     rx_buffer[idx + adjust_rx_offset] |= ((uint32)(encap_config->src_addr) << 16);
  23895     idx--;
  23896 
  23897     /* Gre header */
  23898     /* Set protocol type in GRE header to ether type specified by user */
  23899     tx_buffer[idx] |= (((uint32)(encap_config->higig_ethertype) << 16) | \
  23900                        ((uint32)(encap_config->oui)[0]) << 8 | \
  23901                        ((uint32)(encap_config->oui)[1]));
  23902     rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx];
  23903     mask[idx + adjust_rx_offset]=0x0000FFFF;/*TUNNEL_TYPE=1:The first 38 bytes will be compared against the rx table data*/
  23904     sal_memset(mask, 0xFF, WORDS2BYTES(idx + adjust_rx_offset));
  23905     idx--;
  23906 
  23907     /* Set TX OUI and OUI Ethertype*/
  23908     tx_buffer[idx] |= (((uint32)(encap_config->oui)[2]) << 24 | \
  23909                        ((uint32)(encap_config->oui_ethertype)) << 8);
  23910     rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx];
  23911 
  23912     return _bcm_port_ehg_header_write(unit, port, tx_buffer, rx_buffer, mask,
  23913                                       _BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ);
  23914 }
  23915 
  23916 /*
  23917  * Function:
  23918  *      _bcm_port_ipv4_tunnel_header_parse
  23919  * Purpose:
  23920  *      Parse IPv4 GRE tunnel header for Embedded higig and updates encap_config
  23921  *      structure accordingly
  23922  * Parameters:
  23923  *      unit            - (IN) device id
  23924  *      port            - (IN) Physical port
  23925  *      header          - (IN) Buffer contains EHG header to parse
  23926  *      encap_config    - (OUT) structure describes port encapsulation configuration
  23927  * Returns:
  23928  *      BCM_E_XXX
  23929  */
  23930 STATIC int
  23931 _bcm_port_ipv4_tunnel_header_parse(int unit, bcm_port_t port, uint32 *header,
  23932                                    bcm_port_encap_config_t *encap_config)
  23933 {
  23934     /* Headers offset iterator, begins at end of header */
  23935     int  idx = 4 * BYTES2WORDS(sizeof(xport_ehg_tx_tunnel_data_entry_t)) - 1;
  23936 
  23937     BCM_IF_ERROR_RETURN(
  23938     _bcm_port_ehg_ethernet_header_parse(unit, port, header, encap_config,
  23939                                             &idx));
  23940 
  23941     encap_config->tos = (uint8)(header[idx]);
  23942     idx--;
  23943     idx--;
  23944     encap_config->ttl = (uint8)(header[idx] >> 8);
  23945     idx--;
  23946     encap_config->src_addr = ((uint16)(header[idx])) << 16;
  23947     idx--;
  23948     encap_config->src_addr |=(uint16)(header[idx] >> 16);
  23949     encap_config->dst_addr = ((uint16)(header[idx])) << 16;
  23950     idx--;
  23951     encap_config->dst_addr |=(uint16)(header[idx] >> 16);
  23952     idx--;
  23953     encap_config->higig_ethertype = (uint16)(header[idx] >> 16);
  23954     encap_config->oui[0] = (uint8)(header[idx] >> 8);
  23955     encap_config->oui[1] = (uint8)(header[idx]);
  23956     idx--;
  23957     encap_config->oui[2] = (uint8)(header[idx] >> 24);
  23958     encap_config->oui_ethertype = (uint16)(header[idx] >> 8);
  23959 
  23960     return BCM_E_NONE;
  23961 }
  23962 
  23963 /*
  23964  * Function:
  23965  *      _bcm_port_l2_tunnel_header_set
  23966  * Purpose:
  23967  *      Prepares and sets L2 tunnel header for Embedded higig
  23968  * Parameters:
  23969  *      unit            - (IN) device id
  23970  *      port            - (IN) Physical port
  23971  *      encap_config    - (IN) structure describes port encapsulation configuration
  23972  * Returns:
  23973  *      BCM_E_XXX
  23974  */
  23975 STATIC int
  23976 _bcm_port_l2_tunnel_header_set(int unit, bcm_port_t port,
  23977                                bcm_port_encap_config_t *encap_config)
  23978 {
  23979     /*SW tunnel tx encap buffer.*/
  23980     uint32 tx_buffer[_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ];
  23981     /*SW tunnel rx encap buffer.*/
  23982     uint32 rx_buffer[_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ];
  23983     uint32      mask[_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ];
  23984     int     idx;  /* Headers offset iterator.*/
  23985     int     adjust_rx_offset = 0;
  23986 
  23987     sal_memset(tx_buffer, 0, WORDS2BYTES(_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ));
  23988     sal_memset(rx_buffer, 0, WORDS2BYTES(_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ));
  23989     sal_memset(mask, 0, WORDS2BYTES(_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ));
  23990 
  23991     idx = _BCM_PORT_EHG_L2_HEADER_BUFFER_SZ - 1;
  23992 
  23993     _bcm_port_ehg_setup_txrx_ethernet_hdr(tx_buffer, rx_buffer, &idx,
  23994                                           encap_config);
  23995 
  23996     /* Set tpid & vlan id. */
  23997     if (BCM_VLAN_VALID(encap_config->vlan)) {
  23998         /* Tpid. Priority,  Cfi, Vlan id. */
  23999         tx_buffer[idx] |= (((uint32)(encap_config->tpid)) << 16 | \
  24000                            ((uint32)(encap_config->vlan)));
  24001         /*rx_buffer should not have the VLAN and TPID included*/
  24002         idx--;
  24003         adjust_rx_offset = 1;
  24004     }
  24005 
  24006     /* Set ether type to OUI and TX OUI */
  24007     tx_buffer[idx] |= (((uint32)(encap_config->higig_ethertype)) << 16 | \
  24008                        ((uint32)(encap_config->oui)[0]) << 8 | \
  24009                        ((uint32)(encap_config->oui)[1]));
  24010     rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx];
  24011     mask[idx + adjust_rx_offset] = 0x0000FFFF; /*TUNNEL_TYPE=0:The first 14 bytes will be compared against the rx table data*/
  24012     sal_memset(mask, 0xFF, WORDS2BYTES(idx + adjust_rx_offset));
  24013     idx--;
  24014     /* Set TX OUI and HG ether type */
  24015     tx_buffer[idx] |= (((uint32)(encap_config->oui)[2]) << 24 | \
  24016                        ((uint32)(encap_config->oui_ethertype)) << 8);
  24017     rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx];
  24018 
  24019     return _bcm_port_ehg_header_write(unit, port, tx_buffer, rx_buffer, mask,
  24020                                        _BCM_PORT_EHG_L2_HEADER_BUFFER_SZ);
  24021 }
  24022 
  24023 
  24024 /*
  24025  * Function:
  24026  *      _bcm_port_l2_tunnel_header_parse
  24027  * Purpose:
  24028  *      Parse L2 tunnel header for Embedded higig and updates encap_config
  24029  *      structure accordingly
  24030  * Parameters:
  24031  *      unit            - (IN) device id
  24032  *      port            - (IN) Physical port
  24033  *      header          - (IN) Buffer contains EHG header to parse
  24034  *      encap_config    - (OUT) structure describes port encapsulation configuration
  24035  * Returns:
  24036  *      BCM_E_XXX
  24037  */
  24038 STATIC int
  24039 _bcm_port_l2_tunnel_header_parse(int unit, bcm_port_t port, uint32 *header,
  24040                                  bcm_port_encap_config_t *encap_config)
  24041 {
  24042     /* Headers offset iterator, begins at end of header */
  24043     int  idx = 4 * BYTES2WORDS(sizeof(xport_ehg_tx_tunnel_data_entry_t)) - 1;
  24044 
  24045     BCM_IF_ERROR_RETURN
  24046         (_bcm_port_ehg_ethernet_header_parse(unit, port, header,
  24047                                              encap_config, &idx));
  24048 
  24049     encap_config->higig_ethertype = (uint16)(header[idx] >> 16);
  24050     encap_config->oui[0] = (uint8)(header[idx] >> 8);
  24051     encap_config->oui[1] = (uint8)(header[idx]);
  24052     idx--;
  24053     encap_config->oui[2] = (uint8)(header[idx] >> 24);
  24054     encap_config->oui_ethertype = (uint16)(header[idx] >> 8);
  24055 
  24056     return BCM_E_NONE;
  24057 }
  24058 
  24059 /*
  24060  * Function:
  24061  *      _bcm_port_encap_ehg_xport_update
  24062  * Purpose:
  24063  *      Updates XPORT higig config for EHG
  24064  * Parameters:
  24065  *      unit            - (IN) device id
  24066  *      port            - (IN) Physical port
  24067  * Returns:
  24068  */
  24069 STATIC int
  24070 _bcm_port_encap_ehg_xport_update(int unit, bcm_port_t port)
  24071 {
  24072 #if defined(BCM_TRIUMPH3_SUPPORT)
  24073     if (SOC_IS_TRIUMPH3(unit)) {
  24074         
  24075         soc_field_t ept_fields[2] = { HIGIG2f, PORT_TYPEf };
  24076         uint32 ept_vals[2] = { BCM_EGR_PORT_HIGIG2, BCM_EGR_PORT_TYPE_EHG };
  24077 
  24078         /* Ingress port table */
  24079         BCM_IF_ERROR_RETURN
  24080             (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE,
  24081                                    HIGIG2f, 1));
  24082         BCM_IF_ERROR_RETURN
  24083             (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE,
  24084                                    PORT_TYPEf, BCM_EGR_PORT_TYPE_EHG));
  24085 
  24086         /* Egress port table */
  24087         BCM_IF_ERROR_RETURN
  24088             (soc_mem_fields32_modify(unit, EGR_PORTm, port, 2,
  24089                                      ept_fields, ept_vals));
  24090 
  24091         /* Egress ingress port table */
  24092         BCM_IF_ERROR_RETURN
  24093             (soc_mem_fields32_modify(unit, EGR_ING_PORTm, port, 2,
  24094                                      ept_fields, ept_vals));
  24095 
  24096         BCM_IF_ERROR_RETURN
  24097             (soc_reg_field32_modify(unit, PORT_CONFIGr, port,
  24098                                     HIGIG2_MODEf, 1));
  24099 
  24100         if (SOC_MEM_IS_VALID(unit, ICONTROL_OPCODE_BITMAPm)) {
  24101             icontrol_opcode_bitmap_entry_t entry;
  24102             soc_pbmp_t pbmp;
  24103 
  24104             BCM_IF_ERROR_RETURN
  24105                 (READ_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry));
  24106 
  24107             SOC_PBMP_CLEAR(pbmp);
  24108 
  24109             SOC_PBMP_PORT_SET(pbmp, CMIC_PORT(unit));
  24110 
  24111             soc_mem_pbmp_field_set(unit, ICONTROL_OPCODE_BITMAPm, &entry,
  24112                     BITMAPf, &pbmp);
  24113 
  24114             BCM_IF_ERROR_RETURN
  24115                 (WRITE_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry));
  24116         }
  24117 
  24118         return (BCM_E_NONE);
  24119     }
  24120 #endif /* BCM_TRIUMPH3_SUPPORT  */
  24121 
  24122 #ifdef BCM_GXPORT_SUPPORT
  24123     {
  24124         soc_reg_t   egr_port_reg;
  24125 
  24126         if (IS_GX_PORT(unit, port) || IS_XQ_PORT(unit,port)) {
  24127 
  24128             egr_port_reg =
  24129                 (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  24130                  SOC_IS_VALKYRIE2(unit)|| SOC_IS_GREYHOUND(unit) ||
  24131                  SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ?
  24132                  EGR_PORT_64r : EGR_PORTr;
  24133 
  24134             BCM_IF_ERROR_RETURN
  24135                 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE,
  24136                                        HIGIG2f, 1));
  24137 
  24138             BCM_IF_ERROR_RETURN
  24139                 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE,
  24140                                        PORT_TYPEf, BCM_EGR_PORT_TYPE_EHG));
  24141             BCM_IF_ERROR_RETURN
  24142                 (soc_reg_field32_modify(unit, egr_port_reg, port, HIGIG2f,
  24143                                         BCM_EGR_PORT_HIGIG2));
  24144             BCM_IF_ERROR_RETURN
  24145                 (soc_reg_field32_modify(unit, egr_port_reg, port,
  24146                                         PORT_TYPEf, BCM_EGR_PORT_TYPE_EHG));
  24147 
  24148             if(SOC_REG_IS_VALID(unit, XPORT_CONFIGr)) {
  24149                 BCM_IF_ERROR_RETURN
  24150                     (soc_reg_field32_modify(unit, XPORT_CONFIGr, port,
  24151                                             HIGIG2_MODEf, 1));
  24152             }
  24153         }
  24154     }
  24155 #endif /* BCM_GXPORT_SUPPORT */
  24156     return (BCM_E_NONE);
  24157 }
  24158 
  24159 /*
  24160  * Function:
  24161  *      _bcm_port_ehg_transport_mode_set
  24162  * Purpose:
  24163  *      Set the port into embedded higig transport mode
  24164  * Parameters:
  24165  *      unit            - (IN) device id
  24166  *      port            - (IN) Physical port
  24167  *      encap_config    - (IN) structure describes port encapsulation configuration
  24168  * Returns:
  24169  *      BCM_E_XXX
  24170  */
  24171 STATIC int
  24172 _bcm_port_ehg_transport_mode_set(int unit, bcm_port_t port,
  24173                                  bcm_port_encap_config_t *encap_config)
  24174 {
  24175     int         vlan_valid;
  24176     uint32      val;
  24177     soc_reg_t   ehg_tx_reg = EHG_TX_REG(unit);
  24178     soc_reg_t   ehg_rx_reg = EHG_RX_REG(unit);
  24179     soc_reg_t   ehg_tpid_reg = EHG_TPID_REG(unit);
  24180 
  24181     if (IS_HG_PORT(unit, port)) {
  24182         return BCM_E_CONFIG;
  24183     }
  24184 
  24185     BCM_IF_ERROR_RETURN
  24186         (_bcm_port_encap_ehg_xport_update(unit, port));
  24187 
  24188     vlan_valid = BCM_VLAN_VALID(encap_config->vlan);
  24189 
  24190     /* Configure TX control */
  24191     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tx_reg, port, 0, &val));
  24192     soc_reg_field_set(unit, ehg_tx_reg, &val, ENABLEf, 1);
  24193     soc_reg_field_set(unit, ehg_tx_reg, &val, TUNNEL_TYPEf, 0);
  24194     soc_reg_field_set(unit, ehg_tx_reg, &val, VLAN_TAG_CONTROLf,
  24195                       vlan_valid);
  24196     soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_VLAN_PRI_CFIf,
  24197                       vlan_valid);
  24198     soc_reg_field_set(unit, ehg_tx_reg, &val, PAYLOAD_LENGTH_ADJUSTMENTf,
  24199                       0);
  24200     soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_DSCPf, 0);
  24201     soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_IPf, 0);
  24202     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_tx_reg, port, 0, val));
  24203 
  24204     /* Configure RX control */
  24205     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_rx_reg, port, 0, &val));
  24206     soc_reg_field_set(unit, ehg_rx_reg, &val, TUNNEL_TYPEf, 0);
  24207     soc_reg_field_set(unit, ehg_rx_reg, &val, MODEf, 1);
  24208     soc_reg_field_set(unit, ehg_rx_reg, &val, VLAN_TAG_CONTROLf,
  24209                       vlan_valid);
  24210     soc_reg_field_set(unit, ehg_rx_reg, &val, COMPARE_VLANf,
  24211                       vlan_valid);
  24212     soc_reg_field_set(unit, ehg_rx_reg, &val, VLANf,
  24213                       (vlan_valid) ? encap_config->vlan : 0);
  24214     soc_reg_field_set(unit, ehg_rx_reg, &val, IPV4_CHKSUM_ENABLEf, 0);
  24215     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_rx_reg, port, 0, val));
  24216 
  24217     /* Configure EHG-tpid */
  24218     if (vlan_valid) {
  24219         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tpid_reg, port, 0, &val));
  24220         soc_reg_field_set(unit, ehg_tpid_reg, &val, TPIDf,
  24221                           encap_config->tpid);
  24222         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_tpid_reg, port, 0, val));
  24223     }
  24224 
  24225     return _bcm_port_l2_tunnel_header_set(unit, port, encap_config);
  24226 }
  24227 
  24228 /*
  24229  * Function:
  24230  *      _bcm_port_ehg_tunnel_mode_set
  24231  * Purpose:
  24232  *      Set the port into embedded higig tunnel mode
  24233  * Parameters:
  24234  *      unit            - (IN) device id
  24235  *      port            - (IN) Physical port
  24236  *      encap_config    - (IN) structure describes port encapsulation configuration
  24237  * Returns:
  24238  *      BCM_E_XXX
  24239  */
  24240 STATIC int
  24241 _bcm_port_ehg_tunnel_mode_set(int unit, bcm_port_t port,
  24242                                  bcm_port_encap_config_t *encap_config)
  24243 {
  24244     int         vlan_valid;
  24245     uint32      val;
  24246     soc_reg_t   ehg_tx_reg = EHG_TX_REG(unit);
  24247     soc_reg_t   ehg_rx_reg = EHG_RX_REG(unit);
  24248     soc_reg_t   ehg_tpid_reg = EHG_TPID_REG(unit);
  24249 
  24250     if (IS_HG_PORT(unit, port)) {
  24251         return BCM_E_CONFIG;
  24252     }
  24253 
  24254     BCM_IF_ERROR_RETURN
  24255         (_bcm_port_encap_ehg_xport_update(unit, port));
  24256 
  24257     vlan_valid = BCM_VLAN_VALID(encap_config->vlan);
  24258 
  24259     /* Configure TX control */
  24260     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tx_reg, port, 0, &val));
  24261     soc_reg_field_set(unit, ehg_tx_reg, &val, ENABLEf, 1);
  24262     soc_reg_field_set(unit, ehg_tx_reg, &val, TUNNEL_TYPEf, 1);
  24263     soc_reg_field_set(unit, ehg_tx_reg, &val, VLAN_TAG_CONTROLf,
  24264                       vlan_valid);
  24265     soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_VLAN_PRI_CFIf,
  24266                       vlan_valid);
  24267     soc_reg_field_set(unit, ehg_tx_reg, &val, PAYLOAD_LENGTH_ADJUSTMENTf,
  24268          vlan_valid ? (WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ) - 1):
  24269                  (WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ - 1) - 1));
  24270     soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_DSCPf, 1);
  24271     soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_IPf, 1);
  24272     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_tx_reg, port, 0, val));
  24273 
  24274     /* Configure RX control */
  24275     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_rx_reg, port, 0, &val));
  24276     soc_reg_field_set(unit, ehg_rx_reg, &val, MODEf, 1);
  24277     soc_reg_field_set(unit, ehg_rx_reg, &val, TUNNEL_TYPEf, 1);
  24278     soc_reg_field_set(unit, ehg_rx_reg, &val, VLAN_TAG_CONTROLf,
  24279                       vlan_valid);
  24280     soc_reg_field_set(unit, ehg_rx_reg, &val, COMPARE_VLANf,
  24281                       vlan_valid);
  24282     soc_reg_field_set(unit, ehg_rx_reg, &val, VLANf,
  24283                       (vlan_valid) ? encap_config->vlan : 0);
  24284     soc_reg_field_set(unit, ehg_rx_reg, &val, IPV4_CHKSUM_ENABLEf, 1);
  24285     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_rx_reg, port, 0, val));
  24286 
  24287     /* Configure EHG-tpid */
  24288     if (vlan_valid) {
  24289         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tpid_reg, port, 0, &val));
  24290         soc_reg_field_set(unit, ehg_tpid_reg, &val, TPIDf,
  24291                           encap_config->tpid);
  24292         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_tpid_reg, port, 0, val));
  24293     }
  24294 
  24295     return _bcm_port_ip4_tunnel_header_set(unit, port, encap_config);
  24296 }
  24297 
  24298 /*
  24299  * Function:
  24300  *      _bcm_port_hgoe_transport_mode_set
  24301  * Purpose:
  24302  *      Set the port into Higig over Ethernet transport mode
  24303  * Parameters:
  24304  *      unit            - (IN) device id
  24305  *      port            - (IN) Physical port
  24306  *      encap_config    - (IN) structure describes port encapsulation configuration
  24307  * Returns:
  24308  *      BCM_E_XXX
  24309  */
  24310 STATIC int
  24311 _bcm_port_hgoe_transport_mode_set(int unit, bcm_port_t port,
  24312                                  bcm_port_encap_config_t *encap_config)
  24313 {
  24314     uint64 val64;
  24315     uint32 val;
  24316 
  24317 
  24318     if (IS_HG_PORT(unit, port)) {
  24319         return BCM_E_CONFIG;
  24320     }
  24321 #if defined(BCM_TRIDENT3_SUPPORT)
  24322     if (SOC_IS_TRIDENT3X(unit)) {
  24323         if (BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET == encap_config->encap) {
  24324             return bcm_td3_port_hgoe_mode_set(unit, port);
  24325         } else {
  24326             return BCM_E_UNAVAIL;
  24327         }
  24328     }
  24329 #endif
  24330     /* Configure HGoE TX control */
  24331     if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, HG_TYPEf)) {
  24332         BCM_IF_ERROR_RETURN
  24333             (soc_mem_field32_modify(unit, EGR_PORTm, port, PORT_TYPEf,
  24334                                     encap_config->encap ==
  24335                                     BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET?
  24336                                     1 : 0));
  24337         BCM_IF_ERROR_RETURN
  24338             (soc_mem_field32_modify(unit, EGR_PORTm, port, HG_TYPEf,
  24339                                     BCM_PORT_HG_TYPE_HGOE_TRANSPORT));
  24340     }
  24341 
  24342     if (SOC_REG_IS_VALID(unit, EGR_EHG_ETHERTYPEr)) {
  24343         BCM_IF_ERROR_RETURN
  24344             (soc_reg32_get(unit, EGR_EHG_ETHERTYPEr, port, 0, &val));
  24345         soc_reg_field_set(unit, EGR_EHG_ETHERTYPEr,
  24346                           &val, ETHERTYPEf, encap_config->higig_ethertype);
  24347         BCM_IF_ERROR_RETURN
  24348             (soc_reg32_set(unit, EGR_EHG_ETHERTYPEr, port, 0, val));
  24349     }
  24350 
  24351     if (SOC_REG_IS_VALID(unit, EGR_EHG_HEADER_CONTROLr)) {
  24352         BCM_IF_ERROR_RETURN
  24353             (soc_reg32_get(unit, EGR_EHG_HEADER_CONTROLr, port, 0, &val));
  24354         soc_reg_field_set(unit, EGR_EHG_HEADER_CONTROLr,
  24355                           &val, EHG_RESERVEDf, encap_config->hgoe_reserved);
  24356         BCM_IF_ERROR_RETURN
  24357             (soc_reg32_set(unit, EGR_EHG_HEADER_CONTROLr, port, 0, val));
  24358     }
  24359 
  24360     /* Configure HGoE RX control */
  24361     if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, HG_TYPEf)) {
  24362         BCM_IF_ERROR_RETURN
  24363             (_bcm_esw_port_tab_set(unit, port,
  24364                                    _BCM_CPU_TABS_NONE, PORT_TYPEf,
  24365                                    encap_config->encap ==
  24366                                    BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET?
  24367                                    1 : 0));
  24368 
  24369         BCM_IF_ERROR_RETURN
  24370             (_bcm_esw_port_tab_set(unit, port,
  24371                                    _BCM_CPU_TABS_NONE, HG_TYPEf,
  24372                                    BCM_PORT_HG_TYPE_HGOE_TRANSPORT));
  24373     }
  24374 
  24375     if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, HG_TYPEf)) {
  24376         BCM_IF_ERROR_RETURN
  24377             (soc_mem_field32_modify(unit, EGR_ING_PORTm, port, PORT_TYPEf,
  24378                                     encap_config->encap ==
  24379                                     BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET?
  24380                                     1 : 0));
  24381         BCM_IF_ERROR_RETURN
  24382             (soc_mem_field32_modify(unit, EGR_ING_PORTm, port, HG_TYPEf,
  24383                                     BCM_PORT_HG_TYPE_HGOE_TRANSPORT));
  24384     }
  24385 
  24386     if (SOC_REG_IS_VALID(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr)) {
  24387         uint64 v64;
  24388         COMPILER_64_SET(v64, 0, encap_config->higig_ethertype);
  24389         BCM_IF_ERROR_RETURN
  24390             (soc_reg_get(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr, port, 0,
  24391                          &val64));
  24392         soc_reg64_field_set(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr,
  24393                             &val64, ETHERTYPEf, v64);
  24394         BCM_IF_ERROR_RETURN
  24395             (soc_reg_set(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr, port, 0,
  24396                          val64));
  24397     }
  24398 
  24399     /* Enable HGoE */
  24400     if (SOC_REG_IS_VALID(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r)) {
  24401         uint64 one = COMPILER_64_INIT(0, 1);
  24402         BCM_IF_ERROR_RETURN
  24403             (soc_reg_get(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r, port, 0,
  24404                          &val64));
  24405         soc_reg64_field_set(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r,
  24406                             &val64, TRANSPORT_ENf, one);
  24407         BCM_IF_ERROR_RETURN
  24408             (soc_reg_set(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r, port, 0,
  24409                          val64));
  24410     }
  24411 #ifdef BCM_TRX_SUPPORT
  24412     /* Set the vlan default action */
  24413     if (soc_feature(unit, soc_feature_vlan_action) &&
  24414         (!SOC_IS_TRIDENT3X(unit))) {
  24415         bcm_vlan_action_set_t action;
  24416 
  24417         BCM_IF_ERROR_RETURN
  24418             (_bcm_trx_vlan_port_egress_default_action_get(unit,
  24419                                                         port, &action));
  24420         /* Backward compatible defaults */
  24421         action.ot_outer = bcmVlanActionDelete;
  24422         action.dt_outer = bcmVlanActionDelete;
  24423         BCM_IF_ERROR_RETURN
  24424             (_bcm_trx_vlan_port_egress_default_action_set(unit,
  24425                                                         port, &action));
  24426     }
  24427 #endif
  24428 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(BCM_TX_HGOE_LIMITED_SOLUTION)
  24429     if (SOC_IS_TRIDENT2PLUS(unit)
  24430         && SOC_MEM_IS_VALID(unit, ICONTROL_OPCODE_BITMAPm)) {
  24431         icontrol_opcode_bitmap_entry_t entry;
  24432         soc_pbmp_t pbmp;
  24433 
  24434         SOC_IF_ERROR_RETURN
  24435             (READ_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry));
  24436         SOC_PBMP_CLEAR(pbmp);
  24437         SOC_PBMP_PORT_SET(pbmp, CMIC_PORT(unit));
  24438         soc_mem_pbmp_field_set(unit,
  24439                             ICONTROL_OPCODE_BITMAPm, &entry, BITMAPf, &pbmp);
  24440         SOC_IF_ERROR_RETURN
  24441             (WRITE_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry));
  24442     }
  24443 #endif /* BCM_TRIDENT2PLUS_SUPPORT && BCM_TX_HGOE_LIMITED_SOLUTION */
  24444 
  24445     return BCM_E_NONE;
  24446 }
  24447 
  24448 
  24449 /*
  24450  * Function:
  24451  *      _bcm_esw_port_encap_higig_lite_set
  24452  * Purpose:
  24453  *      Helper function to force a port into HIGIG2_LITE mode
  24454  * Parameters:
  24455  *      unit            - (IN) device id
  24456  *      port            - (IN) port number
  24457  * Returns:
  24458  *      BCM_E_XXX
  24459  */
  24460 STATIC int
  24461 _bcm_esw_port_encap_higig_lite_set(int unit, bcm_port_t port)
  24462 {
  24463     soc_port_ability_t  ability;
  24464     int                 an, an_done;
  24465     int rv = BCM_E_CONFIG;
  24466 
  24467     if (SOC_USE_PORTCTRL(unit)) {
  24468         return bcmi_esw_portctrl_encap_higig_lite_set(unit, port);
  24469     }
  24470 
  24471     sal_memset(&ability, 0, sizeof(soc_port_ability_t));
  24472 
  24473     if (soc_feature(unit, soc_feature_hg_no_speed_change)) {
  24474         /* HG-Lite process without 2.5G speed setting can calls to
  24475             * _bcm_port_encap_xport_set() directly.
  24476             */
  24477         return _bcm_port_encap_xport_set(unit, port,
  24478                                          BCM_PORT_ENCAP_HIGIG2_LITE, TRUE);
  24479     } else {
  24480         if (IS_XE_PORT(unit, port) || IS_HG_PORT(unit, port)) {
  24481             /* Restrict the speed to <= 2.5G and set the encap to HG2 */
  24482             if ((SOC_IS_SABER2(unit) || SOC_IS_HURRICANE2(unit)) && IS_XL_PORT(unit, port)) {
  24483                 rv = _bcm_port_encap_xport_set(unit, port,
  24484                                                BCM_PORT_ENCAP_HIGIG2_LITE,
  24485                                                TRUE);
  24486                 if (rv != BCM_E_NONE) {
  24487                     return rv;
  24488                 }
  24489                 SOC_IF_ERROR_RETURN
  24490                          (MAC_SPEED_SET(PORT(unit, port).p_mac, unit, port, 2500));
  24491             } 
  24492             if((SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) && IS_XE_PORT(unit, port)) {
  24493                /*Restrict the speed to <= 2.5G and set the encap to HG_LITE*/
  24494                 rv = _bcm_port_encap_xport_set(unit, port,
  24495                                                BCM_PORT_ENCAP_HIGIG2_LITE,
  24496                                                TRUE);
  24497                 if (rv != BCM_E_NONE) {
  24498                     return rv;
  24499                 }
  24500                 SOC_IF_ERROR_RETURN
  24501                          (MAC_SPEED_SET(PORT(unit, port).p_mac, unit, port, 2500));
  24502             }
  24503             BCM_IF_ERROR_RETURN(
  24504                 soc_phyctrl_ability_local_get(unit, port, &ability));
  24505 
  24506             ability.speed_full_duplex &= ~(SOC_PA_SPEED_10GB |
  24507                     SOC_PA_SPEED_12GB | SOC_PA_SPEED_13GB | SOC_PA_SPEED_15GB |
  24508                     SOC_PA_SPEED_16GB | SOC_PA_SPEED_20GB | SOC_PA_SPEED_21GB |
  24509                     SOC_PA_SPEED_25GB | SOC_PA_SPEED_30GB | SOC_PA_SPEED_40GB);
  24510 
  24511             BCM_IF_ERROR_RETURN(
  24512                 soc_phyctrl_ability_advert_set(unit, port, &ability));
  24513             BCM_IF_ERROR_RETURN(
  24514                 soc_phyctrl_auto_negotiate_get(unit, port, &an, &an_done));
  24515             if (!an) {
  24516                 BCM_IF_ERROR_RETURN(
  24517                     soc_phyctrl_speed_set(unit, port, 2500));
  24518             }
  24519             if (!SOC_IS_SABER2(unit) && !SOC_IS_KATANA2(unit) && !SOC_IS_HURRICANE2(unit)) {
  24520                 return _bcm_port_encap_xport_set(unit, port,
  24521                                                  BCM_PORT_ENCAP_HIGIG2, TRUE);
  24522             }
  24523         } else if (IS_ST_PORT(unit, port) || IS_E_PORT(unit, port)) {
  24524             return _bcm_port_encap_stport_set(unit, port, BCM_PORT_ENCAP_HIGIG2);
  24525         }
  24526     } /* if soc_feature(soc_feature_hg_no_speed_change) */
  24527 
  24528     return rv;
  24529 }
  24530 
  24531 
  24532 /*
  24533  * Function:
  24534  *      bcm_esw_port_encap_config_set
  24535  * Purpose:
  24536  *      Set the port encapsulation
  24537  * Parameters:
  24538  *      unit            - (IN) device id
  24539  *      gport           - (IN) Generic port
  24540  *      encap_config    - (IN) structure describes port encapsulation configuration
  24541  * Returns:
  24542  *      BCM_E_XXX
  24543  */
  24544 int
  24545 bcm_esw_port_encap_config_set(int unit, bcm_gport_t gport,
  24546                                   bcm_port_encap_config_t *encap_config)
  24547 {
  24548     bcm_port_t  port;
  24549     int         rv = BCM_E_UNAVAIL, curr_mode=0; 
  24550     soc_info_t  *si = &SOC_INFO(unit);
  24551     bcm_stg_t        stg = 0;
  24552 
  24553     if (NULL == encap_config) {
  24554         return BCM_E_PARAM;
  24555     }
  24556     /* Make sure port module is initialized. */
  24557     PORT_INIT(unit);
  24558 
  24559     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, gport, &port));
  24560     if(bcm_common_oamp_port_enable_get(unit, port)) {
  24561         LOG_ERROR(BSL_LS_BCM_PORT,
  24562                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  24563                    port));
  24564         return BCM_E_PARAM;
  24565     }
  24566 
  24567 
  24568     if (encap_config->encap != BCM_PORT_ENCAP_HIGIG2_L2 &&
  24569         encap_config->encap != BCM_PORT_ENCAP_HIGIG2_LITE &&
  24570         encap_config->encap != BCM_PORT_ENCAP_HIGIG2_IP_GRE &&
  24571         encap_config->encap != BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET) {
  24572         return bcm_esw_port_encap_set(unit, port, encap_config->encap);
  24573     }
  24574 
  24575     if (encap_config->encap == BCM_PORT_ENCAP_HIGIG2_LITE &&
  24576         (SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit) || SOC_IS_RAVEN(unit)
  24577         || SOC_IS_GREYHOUND(unit) || SOC_IS_GREYHOUND2(unit))) {
  24578         return bcm_esw_port_encap_set(unit, port, encap_config->encap);
  24579     }
  24580 
  24581     if (!soc_feature(unit, soc_feature_embedded_higig) &&
  24582         !soc_feature(unit, soc_feature_higig_over_ethernet)) {
  24583         return (BCM_E_UNAVAIL);
  24584     }
  24585 
  24586 #if defined(BCM_SABER2_SUPPORT)
  24587     if (SOC_IS_SABER2(unit) && (!BCM_GPORT_IS_SET(port))) {
  24588         if(!IS_XL_PORT(unit, port)) {
  24589             /* On saber2 non XL port, shouldn't have reached till here */
  24590             return BCM_E_UNAVAIL;
  24591         }
  24592     }
  24593 #endif
  24594 #if defined(BCM_TRIDENT3_SUPPORT)
  24595     if (SOC_IS_TRIDENT3X(unit)
  24596         && encap_config->encap == BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET) {
  24597 
  24598         if (!soc_feature(unit, soc_feature_higig_over_ethernet)) {
  24599             return BCM_E_UNAVAIL;
  24600         }
  24601     }
  24602 #endif
  24603     PORT_LOCK(unit);
  24604 
  24605     if (encap_config->encap == BCM_PORT_ENCAP_HIGIG2_LITE) {
  24606         rv = _bcm_esw_port_encap_higig_lite_set(unit, port);
  24607     } else {
  24608         if ((IS_XE_PORT(unit, port) || IS_HG_PORT(unit, port))) {
  24609             if (BCM_PORT_ENCAP_HIGIG2_L2 == encap_config->encap) {
  24610                 rv = BCM_E_NONE;
  24611                 rv = bcm_esw_port_encap_get(unit, port, &curr_mode);
  24612                 if ((BCM_SUCCESS(rv)) && (curr_mode != BCM_PORT_ENCAP_IEEE)) {
  24613                     rv = _bcm_port_encap_xport_set(unit, port,
  24614                                                    BCM_PORT_ENCAP_IEEE, TRUE);
  24615                 }
  24616             } else {
  24617                 rv = _bcm_port_encap_xport_set(unit, port,
  24618                                                BCM_PORT_ENCAP_IEEE, TRUE);
  24619             }
  24620             /* Update soc_info_t after changing port to ethernet */
  24621             soc_xport_type_update(unit, port, 0);
  24622         } else if (IS_ST_PORT(unit, port) || IS_E_PORT(unit, port)) {
  24623             rv = _bcm_port_encap_stport_set(unit, port, BCM_PORT_ENCAP_IEEE);
  24624         }
  24625     }
  24626 
  24627     if (BCM_SUCCESS(rv)) {
  24628         if (BCM_PORT_ENCAP_HIGIG2_L2 == encap_config->encap) {
  24629             rv = _bcm_port_ehg_transport_mode_set(unit, port, encap_config);
  24630         } else if (BCM_PORT_ENCAP_HIGIG2_IP_GRE == encap_config->encap){
  24631             rv = _bcm_port_ehg_tunnel_mode_set(unit, port, encap_config);
  24632         } else if (BCM_PORT_ENCAP_HIGIG2_LITE == encap_config->encap){
  24633             rv = soc_reg_field32_modify(unit, EHG_RX_REG(unit),
  24634                                         port, MODEf, 2);
  24635         } else if (BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET == encap_config->encap){
  24636             rv = _bcm_port_hgoe_transport_mode_set(unit, port, encap_config);
  24637         }
  24638     }
  24639 
  24640     /* Embedded Higig ports should be configured and marked as ST ports */
  24641     if (BCM_SUCCESS(rv)) {
  24642         rv = bcm_esw_port_pause_set(unit, port, 0, 0);
  24643     }
  24644     if (BCM_SUCCESS(rv)) {
  24645         /* Stack ports to forwarding */
  24646         rv = bcm_esw_port_stp_set(unit, port, BCM_STG_STP_FORWARD);
  24647     }
  24648     if (BCM_SUCCESS(rv)) {
  24649         /* Set untagged state in default VLAN properly */
  24650         rv = _bcm_esw_vlan_untag_update(unit, port, TRUE);
  24651     }
  24652     if (BCM_SUCCESS(rv)) {
  24653         /* Resolve STG 0 */
  24654         rv = bcm_esw_stg_default_get(unit, &stg);
  24655     }
  24656     if (BCM_SUCCESS(rv)) {
  24657         rv = bcm_esw_stg_stp_set(unit, stg, port, BCM_STG_STP_FORWARD);
  24658     }
  24659     if (BCM_SUCCESS(rv)) {
  24660         SOC_PBMP_PORT_ADD(si->st.bitmap, port);
  24661         SOC_PBMP_PORT_REMOVE(si->ether.bitmap, port);
  24662         SOC_PBMP_PORT_REMOVE(si->hg2_pbm, port);
  24663     }
  24664 
  24665     PORT_UNLOCK(unit);
  24666 
  24667     return (rv);
  24668 }
  24669 
  24670 /*
  24671  * Function:
  24672  *      bcm_esw_port_encap_config_get
  24673  * Purpose:
  24674  *      Get the port encapsulation
  24675  * Parameters:
  24676  *      unit            - (IN) device id
  24677  *      gport           - (IN) Generic port
  24678  *      encap_config    - (OUT) structure describes port encapsulation configuration
  24679  * Returns:
  24680  *      BCM_E_XXX
  24681  */
  24682 int
  24683 bcm_esw_port_encap_config_get(int unit, bcm_gport_t gport,
  24684                                   bcm_port_encap_config_t *encap_config)
  24685 {
  24686     bcm_port_t      port;
  24687     uint32          val, buffer[16];   /* 64 bytes max EHG header size */
  24688     uint64          val64;
  24689     int             rv = BCM_E_NONE, mode = 0;
  24690     soc_reg_t       ehg_tx_reg = EHG_TX_REG(unit);
  24691     soc_reg_t       ehg_rx_reg = EHG_RX_REG(unit);
  24692 
  24693     if (NULL == encap_config) {
  24694         return (BCM_E_PARAM);
  24695     }
  24696     /* Make sure port module is initialized. */
  24697     PORT_INIT(unit);
  24698 
  24699     sal_memset(encap_config, 0, sizeof(bcm_port_encap_config_t));
  24700 
  24701     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, gport, &port));
  24702     if(bcm_common_oamp_port_enable_get(unit, port)) {
  24703         LOG_ERROR(BSL_LS_BCM_PORT,
  24704                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  24705                    port));
  24706         return BCM_E_PARAM;
  24707     }
  24708 
  24709     if (!soc_feature(unit, soc_feature_embedded_higig) &&
  24710         !soc_feature(unit, soc_feature_higig_over_ethernet)) {
  24711 
  24712         rv = bcm_esw_port_encap_get(unit, port, &mode);
  24713         if (BCM_SUCCESS(rv)) {
  24714             encap_config->encap = (bcm_port_encap_t)mode;
  24715         }
  24716         return rv;
  24717     }
  24718 
  24719     if (soc_feature(unit, soc_feature_embedded_higig)) {
  24720         /* Check for Raptor-style stacking */
  24721         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_rx_reg, port, 0, &val));
  24722         if (soc_reg_field_get(unit, ehg_rx_reg, val, MODEf) == 2) {
  24723             encap_config->encap = BCM_PORT_ENCAP_HIGIG2_LITE;
  24724             return rv;
  24725         }
  24726 
  24727         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tx_reg, port, 0, &val));
  24728         /* If no EHG was programmed the just read port encapsulation */
  24729         if (!soc_reg_field_get(unit, ehg_tx_reg, val, ENABLEf)) {
  24730             rv = bcm_esw_port_encap_get(unit, port, &mode);
  24731             if (BCM_SUCCESS(rv)) {
  24732                 encap_config->encap = (bcm_port_encap_t)mode;
  24733             }
  24734             return rv;
  24735         }
  24736 
  24737         /* EHG is enabled. */
  24738         if (!IS_ST_PORT(unit, port)) {
  24739             return (BCM_E_CONFIG);
  24740         }
  24741 
  24742         BCM_IF_ERROR_RETURN(_bcm_port_ehg_header_read(unit, port, buffer));
  24743 
  24744         if (!soc_reg_field_get(unit, ehg_tx_reg, val, TUNNEL_TYPEf)) {
  24745             encap_config->encap = BCM_PORT_ENCAP_HIGIG2_L2;
  24746             rv = _bcm_port_l2_tunnel_header_parse(unit, port, buffer,
  24747                                                   encap_config);
  24748         } else {
  24749             encap_config->encap = BCM_PORT_ENCAP_HIGIG2_IP_GRE;
  24750             rv = _bcm_port_ipv4_tunnel_header_parse(unit, port, buffer,
  24751                                                     encap_config);
  24752         }
  24753     } else if(soc_feature(unit, soc_feature_higig_over_ethernet)) {
  24754         uint64 v64 = COMPILER_64_INIT(0, 0);
  24755         uint32 v32=0;
  24756 
  24757         /* If HGoE disabled and then just read port encapsulation */
  24758         if (SOC_REG_IS_VALID(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r)) {
  24759             BCM_IF_ERROR_RETURN
  24760              (soc_reg_get(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r, port, 0,
  24761                     &val64));
  24762             v64 = soc_reg64_field_get(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r,
  24763                                     val64, TRANSPORT_ENf);
  24764         }
  24765 #ifdef BCM_TRIDENT3_SUPPORT
  24766         if (SOC_IS_TRIDENT3X(unit)) {
  24767             uint8 is_hgoe = 0;
  24768             BCM_IF_ERROR_RETURN(bcm_td3_port_hgoe_mode_get(
  24769                         unit, port, &is_hgoe));
  24770             if (is_hgoe) {
  24771                 encap_config->encap = BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET;
  24772                 encap_config->higig_ethertype = BCM_TD3_HGOE_HDR_TYPE;
  24773                 return BCM_E_NONE;
  24774             } else {
  24775                 rv = bcm_esw_port_encap_get(unit, port, &mode);
  24776                 if (BCM_SUCCESS(rv)) {
  24777                     encap_config->encap = (bcm_port_encap_t)mode;
  24778                 }
  24779                 return rv;
  24780             }
  24781         } else
  24782 #endif
  24783         if (COMPILER_64_IS_ZERO(v64)) {
  24784             rv = bcm_esw_port_encap_get(unit, port, &mode);
  24785             if (BCM_SUCCESS(rv)) {
  24786                 encap_config->encap = (bcm_port_encap_t)mode;
  24787             }
  24788             return rv;
  24789         }
  24790 
  24791         if (!IS_ST_PORT(unit, port)) {
  24792             return (BCM_E_CONFIG);
  24793         }
  24794 
  24795         sal_memset(encap_config, 0, sizeof(bcm_port_encap_config_t));
  24796         encap_config->encap = BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET;
  24797 
  24798         if (SOC_REG_IS_VALID(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr)) {
  24799             BCM_IF_ERROR_RETURN
  24800                 (soc_reg_get(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr, port,
  24801                     0, &val64));
  24802             v64 = soc_reg64_field_get(unit,
  24803                    PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr, val64, ETHERTYPEf);
  24804             encap_config->higig_ethertype = (uint16) COMPILER_64_LO(v64);
  24805         }
  24806 
  24807         if (SOC_REG_IS_VALID(unit, EGR_EHG_HEADER_CONTROLr)) {
  24808             BCM_IF_ERROR_RETURN
  24809                 (soc_reg_get(unit, EGR_EHG_HEADER_CONTROLr, port, 0, &val64));
  24810             v32 = COMPILER_64_LO(val64);
  24811             encap_config->hgoe_reserved = soc_reg_field_get(unit,
  24812                                 EGR_EHG_HEADER_CONTROLr, v32, EHG_RESERVEDf);
  24813         }
  24814     }
  24815 
  24816     return (rv);
  24817 }
  24818 
  24819 /*
  24820  * Function:
  24821  *      _bcm_esw_port_mirror_lock
  24822  * Purpose:
  24823  *      Take the mirror and port mutexes
  24824  * Parameters:
  24825  *      unit - unit #
  24826  * Returns:
  24827  *      None
  24828  */
  24829 void
  24830 _bcm_esw_port_mirror_lock(int unit) {
  24831     bcm_esw_mirror_lock(unit);
  24832     PORT_LOCK(unit);
  24833 }
  24834 
  24835 /*
  24836  * Function:
  24837  *      _bcm_esw_port_mirror_unlock
  24838  * Purpose:
  24839  *      Give up the mirror and port mutexes
  24840  * Parameters:
  24841  *      unit - unit #
  24842  * Returns:
  24843  *      None
  24844  */
  24845 void
  24846 _bcm_esw_port_mirror_unlock(int unit) {
  24847     PORT_UNLOCK(unit);
  24848     bcm_esw_mirror_unlock(unit);
  24849 }
  24850 
  24851 /*
  24852  * Function:
  24853  *      bcmi_esw_port_encap_set
  24854  * Purpose:
  24855  *      Set the port encapsulation mode
  24856  * Parameters:
  24857  *      unit - StrataSwitch unit #
  24858  *      port - StrataSwitch port #
  24859  *      mode - One of BCM_PORT_ENCAP_xxx (see port.h)
  24860  * Returns:
  24861  *      BCM_E_XXX
  24862  */
  24863 int
  24864 bcmi_esw_port_encap_set(int unit, bcm_port_t port, int mode)
  24865 {
  24866     int         rv=BCM_E_NONE, xport_swap = FALSE;
  24867     int         stport_swap = FALSE;
  24868 #if defined(BCM_KATANA2_SUPPORT)
  24869     uint64      rval64;
  24870     ing_physical_port_table_entry_t ing_entry={{0}};
  24871     ing_physical_port_table_entry_t ing_entry_dup={{0}};
  24872     egr_physical_port_entry_t       egr_entry={{0}};
  24873     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  24874 #endif
  24875 #ifdef BCM_HELIX4_SUPPORT
  24876     uint16 dev_id = 0;
  24877     uint8 rev_id = 0;
  24878 #endif
  24879     /* Make sure port module is initialized. */
  24880     PORT_INIT(unit);
  24881 
  24882     if(bcm_common_oamp_port_enable_get(unit, port)) {
  24883         LOG_ERROR(BSL_LS_BCM_PORT,
  24884                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  24885                    port));
  24886         return BCM_E_PARAM;
  24887     }
  24888 
  24889 #ifdef BCM_HELIX4_SUPPORT
  24890     soc_cm_get_id(unit, &dev_id, &rev_id);
  24891     if ((BCM56548H_DEVICE_ID == dev_id) &&
  24892         (mode == BCM_PORT_ENCAP_IEEE) && ((port >= 46) && (port <= 53))) {
  24893         /* IEEE encap mode shouldn't be supported on WC1 and WC2 for BCM56548H*/
  24894         return BCM_E_UNAVAIL;
  24895     }
  24896 #endif
  24897 
  24898 #if defined(BCM_KATANA2_SUPPORT)
  24899 #if defined(BCM_SABER2_SUPPORT)
  24900     if(SOC_IS_SABER2(unit)) {
  24901         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  24902     }
  24903 #endif
  24904     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  24905         (!((port >= 1) && (port <= max_phy_port)))) {
  24906          return BCM_E_PORT;
  24907     }
  24908 #endif
  24909 
  24910     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  24911     LOG_INFO(BSL_LS_BCM_PORT,
  24912              (BSL_META_U(unit,
  24913                          "bcm_esw_port_encap_set: u=%d p=%d mode=%d\n"),
  24914               unit, port, mode));
  24915 #if defined(BCM_METROLITE_SUPPORT)
  24916     if (SOC_IS_METROLITE(unit)){
  24917     if (!BCM_GPORT_IS_SET(port)) {
  24918         if(!IS_XL_PORT(unit, port) && (mode != BCM_PORT_ENCAP_IEEE)) {
  24919             return BCM_E_UNAVAIL;
  24920 	}
  24921         if((0 == SOC_PORT_BLOCK_NUMBER(unit, port)) && 
  24922             (mode != BCM_PORT_ENCAP_IEEE)) {
  24923             return BCM_E_UNAVAIL;
  24924         }
  24925     }
  24926 }else
  24927 #endif
  24928 #if defined(BCM_SABER2_SUPPORT)
  24929     if (SOC_IS_SABER2(unit) && (!BCM_GPORT_IS_SET(port))) {
  24930         if(!IS_XL_PORT(unit, port) && (mode != BCM_PORT_ENCAP_IEEE)) {
  24931             return BCM_E_UNAVAIL;
  24932         }
  24933     }
  24934 #endif
  24935 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) ||\
  24936     defined (BCM_SABER2_SUPPORT)
  24937     if (SOC_IS_GREYHOUND(unit) || SOC_IS_TOMAHAWKX(unit) || 
  24938         SOC_IS_HURRICANE3(unit) || SOC_IS_SABER2(unit) ||
  24939         SOC_IS_TRIDENT3X(unit) || SOC_IS_GREYHOUND2(unit)) {
  24940         int encap_mode;
  24941         BCM_IF_ERROR_RETURN(bcm_esw_port_encap_get(unit, port, &encap_mode));
  24942         if (encap_mode == mode) {
  24943             /* no encap set is required */
  24944             return BCM_E_NONE;
  24945         }
  24946     }
  24947 #endif /* BCM_GREYHOUND_SUPPORT || BCM_TOMAHAWK_SUPPORT || BCM_SABER2_SUPPORT */
  24948 
  24949 #if defined(BCM_HURRICANE3_SUPPORT)
  24950     if (soc_feature(unit, soc_feature_wh2)){
  24951         return bcmi_wh2_port_encap_set(unit, port, mode);
  24952     }
  24953 #endif /* BCM_HURRICANE3_SUPPORT */
  24954     _bcm_esw_port_mirror_lock(unit);
  24955 
  24956     if ((IS_HG_PORT(unit,port) && (mode == BCM_PORT_ENCAP_IEEE)) ||
  24957         ((IS_XE_PORT(unit,port) || IS_CE_PORT(unit,port)) &&
  24958          (mode != BCM_PORT_ENCAP_IEEE))) {
  24959         if (soc_feature(unit, soc_feature_xport_convertible)) {
  24960             xport_swap =  TRUE;
  24961         } else {
  24962             /* Ether <=> Higig not allowed on all systems */
  24963             _bcm_esw_port_mirror_unlock(unit);
  24964             return BCM_E_UNAVAIL;
  24965         }
  24966     }
  24967 #if defined(BCM_GREYHOUND_SUPPORT)
  24968     if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  24969         SOC_IS_GREYHOUND2(unit)) {
  24970         if ((IS_HG_PORT(unit, port) && (mode != BCM_PORT_ENCAP_IEEE)) ||
  24971                 (IS_HL_PORT(unit, port) && (mode == BCM_PORT_ENCAP_IEEE))) {
  24972             /* HG port encap swap between HG/HG2/HG-Lite and
  24973              * HG-Lite encap swap to IEEE.
  24974              */
  24975             xport_swap = TRUE;
  24976         } else if (IS_GE_PORT(unit, port)) {
  24977             if ((IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) && 
  24978                     (mode == BCM_PORT_ENCAP_IEEE || 
  24979                     mode == BCM_PORT_ENCAP_HIGIG2_LITE)){
  24980                 /* GE+XL/CL port encap set between IEEE/HG-Lite */
  24981                 xport_swap = TRUE;
  24982             } else {
  24983                 /* unavail encap configuration :
  24984                  *  1. QSGMII port for HG/HG2/HG2-Lite related encap
  24985                  *  2. GE(+XL) port for HG/HG2
  24986                  */
  24987                 _bcm_esw_port_mirror_unlock(unit);
  24988                 return BCM_E_UNAVAIL;
  24989             }
  24990         }
  24991     }
  24992 #endif  /* BCM_GREYHOUND_SUPPORT */
  24993 #if defined(BCM_KATANA_SUPPORT)
  24994     if (SOC_IS_KATANA(unit) && IS_MXQ_PORT(unit,port) &&
  24995                                 IS_GE_PORT(unit,port)) {
  24996         if ((IS_ST_PORT(unit,port) && (mode == BCM_PORT_ENCAP_IEEE)) ||
  24997             (IS_E_PORT(unit,port) && (mode == BCM_PORT_ENCAP_HIGIG2 ||
  24998                                       mode == BCM_PORT_ENCAP_HIGIG2_LITE))) {
  24999             stport_swap =  TRUE;
  25000         }
  25001     }
  25002 #endif
  25003 #if defined(BCM_KATANA2_SUPPORT)
  25004     if ((SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) && 
  25005                                  (port >= 25 && port <= 40)) {
  25006         if ((IS_ST_PORT(unit,port) && (mode == BCM_PORT_ENCAP_IEEE)) ||
  25007             (IS_E_PORT(unit,port) && (mode == BCM_PORT_ENCAP_HIGIG2 ||
  25008                                       mode == BCM_PORT_ENCAP_HIGIG2_LITE))) {
  25009              stport_swap =  TRUE;
  25010         }
  25011     }
  25012 #endif
  25013 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT)
  25014     /* There could be hg to hg (hg2 -> hg2 lite) which require special processing */
  25015     if ((SOC_IS_SABER2(unit) || SOC_IS_HURRICANE2(unit)) && IS_XL_PORT(unit, port)) {
  25016         xport_swap = TRUE;
  25017     }
  25018 #endif
  25019     if (SOC_IS_RAVEN(unit) || SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit)) {
  25020         if ((IS_ST_PORT(unit,port) && (mode == BCM_PORT_ENCAP_IEEE)) ||
  25021             (IS_E_PORT(unit,port) && (mode == BCM_PORT_ENCAP_HIGIG2 ||
  25022                                       mode == BCM_PORT_ENCAP_HIGIG2_LITE))) {
  25023                 stport_swap =  TRUE;
  25024         }
  25025     }
  25026 #ifdef BCM_TRIUMPH3_SUPPORT
  25027     if (SOC_IS_TRIUMPH3(unit) && IS_XT_PORT(unit,port) &&
  25028         !((mode == BCM_PORT_ENCAP_IEEE) || (mode == BCM_PORT_ENCAP_HIGIG2_L2))) {
  25029         /* Ether => Higig not allowed on XT ports */
  25030             _bcm_esw_port_mirror_unlock(unit);
  25031             return BCM_E_UNAVAIL;
  25032     }
  25033     if (SOC_IS_TRIUMPH3(unit) && (mode != BCM_PORT_ENCAP_IEEE) &&
  25034         !IS_HG_PORT(unit, port)) {
  25035         int hp, hgc = 0;
  25036 
  25037         PBMP_HG_ITER(unit, hp) {
  25038             if (!SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit, port), hp)) {
  25039                 hgc++;
  25040             }
  25041         }
  25042         if (hgc+1 > _SOC_TR3_MAX_HG_PORT_COUNT) {
  25043             LOG_ERROR(BSL_LS_BCM_PORT, \
  25044                       (BSL_META_U(unit, \
  25045                                   "Error: Port %d config error "\
  25046                                   "(Higig port count(%d) exceeded) !!\n"),
  25047                        port, hgc));
  25048             _bcm_esw_port_mirror_unlock(unit);
  25049             return BCM_E_RESOURCE;
  25050         }
  25051     }
  25052 #endif /* BCM_TRIUMPH3_SUPPORT */
  25053 
  25054     if (xport_swap) {
  25055         COUNTER_LOCK(unit);
  25056         if ((BCM_PORT_ENCAP_HIGIG2_LITE == mode)) {
  25057             rv = _bcm_esw_port_encap_higig_lite_set(unit, port);
  25058         } else {
  25059             rv = _bcm_port_encap_xport_set(unit, port, mode, TRUE);
  25060         }
  25061 
  25062         COUNTER_UNLOCK(unit);
  25063     } else if (stport_swap) {
  25064         rv = _bcm_port_encap_stport_set(unit, port, mode);
  25065     } else if (IS_HG_PORT(unit, port)) {
  25066         rv = MAC_ENCAP_SET(PORT(unit, port).p_mac, unit, port, mode);
  25067     } else if (IS_GE_PORT(unit, port) && IS_ST_PORT(unit, port)) {
  25068         if (mode == BCM_PORT_ENCAP_IEEE) {
  25069             bcm_port_encap_config_t encap_config;
  25070 
  25071             rv = bcm_esw_port_encap_config_get(unit, port,
  25072                                                &encap_config);
  25073             if (BCM_SUCCESS(rv)) {
  25074                 if ((BCM_PORT_ENCAP_HIGIG2_L2 == encap_config.encap) ||
  25075                     (BCM_PORT_ENCAP_HIGIG2_IP_GRE == encap_config.encap) ||
  25076                     (BCM_PORT_ENCAP_HIGIG2_LITE == encap_config.encap) ||
  25077                     (BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET == encap_config.encap)) {
  25078                     rv = _bcm_port_encap_stport_set(unit, port,
  25079                                                     BCM_PORT_ENCAP_IEEE);
  25080                 } else {
  25081                     rv = BCM_E_UNAVAIL;
  25082                 }
  25083             }
  25084         } else {
  25085             if ((mode == BCM_PORT_ENCAP_HIGIG2) ||
  25086                 (mode == BCM_PORT_ENCAP_HIGIG2_LITE &&
  25087                  (SOC_IS_RAVEN(unit) || SOC_IS_ENDURO(unit) ||
  25088                   SOC_IS_HURRICANEX( unit) || SOC_IS_GREYHOUND(unit) ||
  25089                   SOC_IS_GREYHOUND2(unit)))) {
  25090                 rv = BCM_E_NONE;
  25091             } else {
  25092                 rv = BCM_E_UNAVAIL;
  25093             }
  25094         }
  25095 #if defined(BCM_TRIUMPH3_SUPPORT)
  25096      } else if (IS_CE_PORT(unit, port))  {
  25097          if ((mode == BCM_PORT_ENCAP_HIGIG2) || (mode == BCM_PORT_ENCAP_HIGIG)
  25098                || (mode == BCM_PORT_ENCAP_IEEE)) {
  25099                     rv = _bcm_port_encap_stport_set(unit, port, mode);
  25100          } else {
  25101              rv = BCM_E_UNAVAIL;
  25102          }
  25103 #endif
  25104     } else if (mode == BCM_PORT_ENCAP_IEEE) {
  25105         rv = BCM_E_NONE;
  25106     } else {
  25107         rv = BCM_E_UNAVAIL;
  25108     }
  25109 
  25110 #ifdef BCM_GXPORT_SUPPORT
  25111     if ( IS_GX_PORT(unit, port)
  25112       || IS_XG_PORT(unit,port)
  25113       || (IS_XQ_PORT(unit, port) &&
  25114          (SOC_IS_ENDURO(unit) || SOC_IS_HURRICANE(unit)))
  25115       || (IS_XL_PORT(unit, port) &&
  25116          (SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) ||
  25117           (SOC_IS_SABER2(unit) || SOC_IS_HURRICANE3(unit)) ||
  25118            SOC_IS_GREYHOUND2(unit)))
  25119       || (IS_CL_PORT(unit, port) && (SOC_IS_GREYHOUND2(unit)))
  25120       || (IS_MXQ_PORT(unit, port) && (SOC_IS_KATANAX(unit) && !SOC_IS_SABER2(unit)))
  25121       || ((IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port) ||
  25122            IS_CE_PORT(unit, port)) &&
  25123           (SOC_IS_TRIUMPH3(unit)
  25124            || (SOC_IS_TRIDENT2X(unit) || SOC_IS_TITAN2PLUS(unit)) ||
  25125            SOC_IS_TOMAHAWKX(unit))) ) {
  25126         int hg2 = FALSE;
  25127         soc_reg_t port_config_reg;
  25128         uint32 regval, new_hg_pbm;
  25129         int blk, blk_num, bindex;
  25130 
  25131         if (mode == BCM_PORT_ENCAP_HIGIG2 || mode == BCM_PORT_ENCAP_HIGIG2_LITE) {
  25132             hg2 = TRUE;
  25133         }
  25134         if (BCM_SUCCESS(rv)) {
  25135             rv = _bcm_esw_port_higig2_mode_set(unit, port, hg2);
  25136         }
  25137 
  25138         if (IS_CL_PORT(unit, port) &&
  25139             SOC_REG_IS_VALID(unit, CLPORT_CONFIGr)) {
  25140             port_config_reg = CLPORT_CONFIGr;
  25141         } else if (IS_C_PORT(unit, port) &&
  25142             SOC_REG_IS_VALID(unit, CPORT_CONFIGr)) {
  25143             port_config_reg = CPORT_CONFIGr;
  25144         } else if (SOC_REG_IS_VALID(unit, XLPORT_CONFIGr)) {
  25145             port_config_reg = XLPORT_CONFIGr;
  25146         } else if (SOC_REG_IS_VALID(unit, PORT_CONFIGr)) {
  25147             port_config_reg = PORT_CONFIGr;
  25148         } else {
  25149             port_config_reg = XPORT_CONFIGr;
  25150         }
  25151         if (BCM_SUCCESS(rv)) {
  25152 #if defined(BCM_GREYHOUND_SUPPORT)||defined(BCM_GREYHOUND2_SUPPORT) 
  25153             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  25154                 SOC_IS_GREYHOUND2(unit)){
  25155                 uint32  port_hg_mode;
  25156 
  25157                 /* XLPORT/CLPORT and PGW register for HIGIG_MODEf is confirmed
  25158                     *  will be '1' for HG/HG+ setting only and '0' for other
  25159                     *  encap mode{IEEE/HG2/HG2-LITE}
  25160                     */
  25161                 port_hg_mode = (mode == BCM_PORT_ENCAP_HIGIG) ? 1 : 0;
  25162                 rv = soc_reg_field32_modify(unit, port_config_reg, port,
  25163                         HIGIG_MODEf, port_hg_mode);
  25164                 if (BCM_FAILURE(rv)) {
  25165                     _bcm_esw_port_mirror_unlock(unit);
  25166                     return rv;
  25167                 }
  25168 
  25169                 /* only port available for HG2 configuration allows PGW encap
  25170                 * setting below
  25171                 */
  25172 #if defined(BCM_GREYHOUND2_SUPPORT)
  25173                 if (SOC_IS_GREYHOUND2(unit)) {
  25174                     rv = soc_greyhound2_pgw_encap_field_modify(unit, 
  25175                             port, HIGIG_MODEf, port_hg_mode);
  25176                 } else 
  25177 #endif /* BCM_GREYHOUND2_SUPPORT */
  25178                 {
  25179                 rv = soc_greyhound_pgw_encap_field_modify(unit, 
  25180                             port, HIGIG_MODEf, port_hg_mode);
  25181                 }
  25182                 if (BCM_FAILURE(rv)) {
  25183                     _bcm_esw_port_mirror_unlock(unit);
  25184                     return rv;
  25185                 }
  25186             } else
  25187 #endif /* BCM_GREYHOUND_SUPPORT||BCM_GREYHOUND2_SUPPORT */
  25188             {
  25189 #if defined(BCM_SABER2_SUPPORT)
  25190                 if(SOC_IS_SABER2(unit)) {
  25191                     /* For Saber2, configure IECELL along with XLPORT */
  25192                     if (SOC_REG_PORT_VALID(unit, IECELL_CONFIGr, port)) {
  25193                         if ((mode == BCM_PORT_ENCAP_HIGIG2) || 
  25194                                 (mode == BCM_PORT_ENCAP_HIGIG2_LITE) ||
  25195                                 (mode == BCM_PORT_ENCAP_HIGIG)) {
  25196                             rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port,
  25197                                     HIGIG_MODEf, mode == BCM_PORT_ENCAP_HIGIG ?
  25198                                     1 : 0);
  25199                             rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port,
  25200                                     HIGIG2_MODEf, mode == BCM_PORT_ENCAP_HIGIG ?
  25201                                     0 : 1);
  25202                         } else {
  25203                             rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port,
  25204                                     HIGIG2_MODEf, 0);
  25205                             rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port,
  25206                                     HIGIG_MODEf, 0);
  25207                         } 
  25208                     }
  25209                 }
  25210 #endif
  25211 #ifdef BCM_KATANA2_SUPPORT
  25212                 if (SOC_IS_KATANA2(unit)) {
  25213                     if (SOC_REG_FIELD_VALID(unit, port_config_reg, HIGIG_MODEf)) {
  25214                         if ((mode == BCM_PORT_ENCAP_HIGIG2) || 
  25215                                 (mode == BCM_PORT_ENCAP_HIGIG2_LITE) ||
  25216                                 (mode == BCM_PORT_ENCAP_HIGIG)) {
  25217 
  25218                             rv = soc_reg_field32_modify(unit, port_config_reg, port,
  25219                                     HIGIG_MODEf, mode == BCM_PORT_ENCAP_HIGIG ?
  25220                                     1 : 0);
  25221                             rv = soc_reg_field32_modify(unit, port_config_reg, port,
  25222                                     HIGIG2_MODEf, mode == BCM_PORT_ENCAP_HIGIG ?
  25223                                     0 : 1);
  25224                         } else {
  25225                             rv = soc_reg_field32_modify(unit, port_config_reg, port,
  25226                                     HIGIG2_MODEf, 0);
  25227                             rv = soc_reg_field32_modify(unit, port_config_reg, port,
  25228                                     HIGIG_MODEf, 0);
  25229                         }
  25230                     }
  25231                 } else
  25232 #endif 
  25233                 {
  25234                     if (SOC_REG_FIELD_VALID(unit, port_config_reg, HIGIG_MODEf)) {
  25235                         rv = soc_reg_field32_modify(unit, port_config_reg, port,
  25236                                         HIGIG_MODEf, mode == BCM_PORT_ENCAP_IEEE ?
  25237                                         0 : 1);
  25238                     }
  25239                     if (SOC_IS_TOMAHAWKX(unit)) {
  25240                         if (IS_CL_PORT(unit, port) &&
  25241                             (mode == BCM_PORT_ENCAP_HIGIG)) {
  25242                             if (SOC_REG_FIELD_VALID(unit, port_config_reg,
  25243                                 HIGIG2_MODEf)) {
  25244                                 rv = soc_reg_field32_modify(unit,
  25245                                         port_config_reg, port, HIGIG2_MODEf, 1);
  25246                             }
  25247                         }
  25248                     }
  25249                 }
  25250             }
  25251         }
  25252         if (BCM_SUCCESS(rv)) {
  25253             if (SOC_MEM_IS_VALID(unit, EGR_PORTm) && 
  25254                     soc_mem_field_valid(unit, EGR_PORTm, PORT_TYPEf)) {
  25255                 rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  25256                                             PORT_TYPEf, mode == BCM_PORT_ENCAP_IEEE ?
  25257                                             0 : 1);
  25258             }
  25259         }
  25260         if (SOC_IS_TRIUMPH3(unit) && (mode == BCM_PORT_ENCAP_IEEE)) {
  25261             /* Disable E2ECC */
  25262             if (soc_feature(unit, soc_feature_logical_port_num)) {
  25263                 blk = SOC_PORT_BLOCK(unit, SOC_INFO(unit).port_l2p_mapping[port]);
  25264                 bindex = SOC_PORT_BINDEX(unit, SOC_INFO(unit).port_l2p_mapping[port]);
  25265             } else{
  25266                 blk = SOC_PORT_BLOCK(unit, port);
  25267                 bindex = SOC_PORT_BINDEX(unit, port);
  25268             }
  25269             blk_num = SOC_BLOCK_INFO(unit, blk).number;
  25270             /* In TR3 E2ECC is implemented only in blocks CL, XL1 */
  25271             if (IS_CL_PORT(unit, port) || (blk == 13)) {
  25272                 if (IS_CL_PORT(unit, port)) {
  25273                     blk_num = (blk_num ?  4 + bindex/4 : bindex/4);
  25274                     bindex = bindex%4;
  25275                 } else {
  25276                     blk_num = 3;
  25277                 }
  25278 #if defined(BCM_KATANA2_SUPPORT)
  25279                 if (SOC_IS_KATANA2(unit)) {
  25280                     /* In KT2 E2ECC is implemented only in blocks 6..9 */
  25281                     blk_num = (blk_num >= 6) ? (blk_num - 6) : blk_num ;
  25282                 }
  25283 #endif
  25284                 rv = READ_E2ECC_TX_ENABLE_BMPr(unit, blk_num, &regval);
  25285                 if (BCM_FAILURE(rv)) {
  25286                     _bcm_esw_port_mirror_unlock(unit);
  25287                     return rv;
  25288                 }
  25289                 if (regval & (1 << bindex)) {
  25290                     new_hg_pbm = soc_reg_field_get(unit, E2ECC_TX_ENABLE_BMPr, regval,
  25291                                                    TX_ENABLE_BMPf);
  25292                     new_hg_pbm &= ~(1 << bindex);
  25293                     soc_reg_field_set(unit, E2ECC_TX_ENABLE_BMPr, &regval,
  25294                                       TX_ENABLE_BMPf, new_hg_pbm);
  25295                     rv = WRITE_E2ECC_TX_ENABLE_BMPr(unit, blk_num, regval);
  25296                 }
  25297             }
  25298         }
  25299     }
  25300 #endif /* BCM_GXPORT_SUPPORT */
  25301 
  25302     if (soc_feature(unit, soc_feature_embedded_higig)) {
  25303         /* Clear embedded Higig regs, if present */
  25304         soc_reg_t   ehg_tx_reg = EHG_TX_REG(unit);
  25305         soc_reg_t   ehg_rx_reg = EHG_RX_REG(unit);
  25306 
  25307         if (BCM_SUCCESS(rv) && SOC_REG_IS_VALID(unit, ehg_tx_reg)) {
  25308             rv = soc_reg32_set(unit, ehg_tx_reg, port, 0, 0);
  25309         }
  25310         if (BCM_SUCCESS(rv) && SOC_REG_IS_VALID(unit, ehg_rx_reg)) {
  25311             rv = soc_reg32_set(unit, ehg_rx_reg, port, 0, 0);
  25312         }
  25313     }
  25314 
  25315 #ifdef BCM_HIGIG2_SUPPORT
  25316     /* Update cached version of HiGig2 encapsulation */
  25317     if (BCM_SUCCESS(rv)) {
  25318         if (mode == BCM_PORT_ENCAP_HIGIG2 || mode == BCM_PORT_ENCAP_HIGIG2_LITE) {
  25319             SOC_HG2_ENABLED_PORT_ADD(unit, port);
  25320 
  25321             if(SOC_IS_SABER2(unit)){ 
  25322                 if(mode == BCM_PORT_ENCAP_HIGIG2_LITE) {
  25323                     SOC_PBMP_PORT_ADD(SOC_INFO(unit).hl.bitmap, port);
  25324                 } else {
  25325                     SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).hl.bitmap, port);
  25326                 }
  25327             }
  25328         } else {
  25329             SOC_HG2_ENABLED_PORT_REMOVE(unit, port);
  25330             if(SOC_IS_SABER2(unit) && IS_XL_PORT(unit, port)) {
  25331                 SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).hl.bitmap, port);
  25332             }
  25333         }
  25334     }
  25335 #endif /* BCM_HIGIG2_SUPPORT */
  25336 
  25337 #ifdef BCM_KATANA2_SUPPORT
  25338     if (BCM_SUCCESS(rv)) {
  25339         if (SOC_IS_KATANA2(unit)) {
  25340             int hdr_mode = 0;
  25341 
  25342             do {
  25343                 rv = soc_mem_read(unit, ING_PHYSICAL_PORT_TABLEm,
  25344                                   MEM_BLOCK_ANY, port, &ing_entry);
  25345                 sal_memcpy(&ing_entry_dup,&ing_entry,
  25346                            sizeof(ing_physical_port_table_entry_t));
  25347                 if (BCM_FAILURE(rv)) {
  25348                     LOG_ERROR(BSL_LS_BCM_PORT,
  25349                               (BSL_META_U(unit,
  25350                                           "Error: Encap Set: "
  25351                                           "ING_PHYSICAL_PORT_TABLEm read failure")));
  25352                     break;
  25353                 }
  25354                 rv = soc_mem_read(unit, EGR_PHYSICAL_PORTm,
  25355                                   MEM_BLOCK_ANY, port, &egr_entry);
  25356                 if (BCM_FAILURE(rv)) {
  25357                     LOG_ERROR(BSL_LS_BCM_PORT,
  25358                               (BSL_META_U(unit,
  25359                                           "Error: Encap Set: "
  25360                                           "EGR_PHYSICAL_PORTm read failure")));
  25361                     break;
  25362                 }
  25363                 /* Initialize */
  25364                 soc_mem_field32_set(unit, ING_PHYSICAL_PORT_TABLEm,
  25365                                     &ing_entry, PORT_TYPEf, 0);
  25366                 soc_mem_field32_set(unit, ING_PHYSICAL_PORT_TABLEm,
  25367                                     &ing_entry, HIGIG2f, 0);
  25368                 soc_mem_field32_set(unit, EGR_PHYSICAL_PORTm,
  25369                                     &egr_entry, PORT_TYPEf, 0);
  25370                 soc_mem_field32_set(unit, EGR_PHYSICAL_PORTm,
  25371                                     &egr_entry, HIGIG2f, 0);
  25372                 if ((mode == BCM_PORT_ENCAP_HIGIG) ||
  25373                     (mode == BCM_PORT_ENCAP_HIGIG2) ||
  25374                     (mode == BCM_PORT_ENCAP_HIGIG2_LITE)) {
  25375                      if (((mode == BCM_PORT_ENCAP_HIGIG2) || 
  25376                           (mode == BCM_PORT_ENCAP_HIGIG2_LITE)) && 
  25377                            soc_feature(unit, soc_feature_higig2)) {
  25378                          if (mode == BCM_PORT_ENCAP_HIGIG2_LITE) {
  25379                              hdr_mode = 0; /* Ieee mode */
  25380                          } else {
  25381                              hdr_mode = 2; /* Higig2 */
  25382                          }
  25383                          soc_mem_field32_set(unit,
  25384                                              ING_PHYSICAL_PORT_TABLEm,
  25385                                              &ing_entry, HIGIG2f, 1);
  25386                          soc_mem_field32_set(unit, EGR_PHYSICAL_PORTm,
  25387                                              &egr_entry, HIGIG2f, 1);
  25388                     } else {
  25389                         hdr_mode = 1; /* HG, hg+ */
  25390                     }
  25391                     soc_mem_field32_set(unit, ING_PHYSICAL_PORT_TABLEm,
  25392                             &ing_entry, PORT_TYPEf, 1);
  25393                     soc_mem_field32_set(unit, EGR_PHYSICAL_PORTm,
  25394                             &egr_entry, PORT_TYPEf, 1);
  25395                 } else {
  25396                     hdr_mode = 0; /* Ieee mode */
  25397                 }
  25398                 if (SOC_REG_IS_VALID(unit, XMAC_MODEr)) {
  25399                     SOC_IF_ERROR_RETURN(READ_XMAC_MODEr(unit,port, &rval64));
  25400                     soc_reg64_field32_set(unit, XMAC_MODEr, &rval64,HDR_MODEf, hdr_mode);
  25401                     SOC_IF_ERROR_RETURN(WRITE_XMAC_MODEr(unit, port, rval64));
  25402                 }
  25403                 if (SOC_REG_IS_VALID(unit, XLMAC_MODEr)) {
  25404                     SOC_IF_ERROR_RETURN(READ_XLMAC_MODEr(unit,port, &rval64));
  25405                     soc_reg64_field32_set(unit, XLMAC_MODEr, &rval64,HDR_MODEf, hdr_mode);
  25406                     SOC_IF_ERROR_RETURN(WRITE_XLMAC_MODEr(unit, port, rval64));
  25407                 }
  25408 
  25409                 if (sal_memcmp(&ing_entry_dup,&ing_entry,
  25410                                sizeof(ing_physical_port_table_entry_t)) == 0) {
  25411                     LOG_VERBOSE(BSL_LS_BCM_PORT,
  25412                                 (BSL_META_U(unit,
  25413                                             "##No Change in  entry so skipping write##\n")));
  25414                     rv = BCM_E_NONE;
  25415                 } else {
  25416                     LOG_ERROR(BSL_LS_BCM_PORT,
  25417                               (BSL_META_U(unit,
  25418                                           "##Change in  entry so Need to update##\n")));
  25419                     rv = soc_mem_write(unit, ING_PHYSICAL_PORT_TABLEm,
  25420                                        MEM_BLOCK_ALL, port, &ing_entry);
  25421                 }
  25422                 if (BCM_FAILURE(rv)) {
  25423                     LOG_ERROR(BSL_LS_BCM_PORT,
  25424                               (BSL_META_U(unit,
  25425                                           "Error: Encap Set: "
  25426                                           "ING_PHYSICAL_PORT_TABLEm write failure")));
  25427                     break;
  25428                 }
  25429                 rv = soc_mem_write(unit, EGR_PHYSICAL_PORTm,
  25430                                    MEM_BLOCK_ALL, port, &egr_entry);
  25431                 if (BCM_FAILURE(rv)) {
  25432                     LOG_ERROR(BSL_LS_BCM_PORT,
  25433                               (BSL_META_U(unit,
  25434                                           "Error: Encap Set: "
  25435                                           "EGR_PHYSICAL_PORTm write failure")));
  25436                     break;
  25437                 }
  25438 
  25439 #ifdef BCM_KATANA2_SUPPORT
  25440                 if (SOC_IS_KATANA2(unit )) {
  25441                     rv =  _bcm_kt2_cosq_dynamic_port_encap_change(unit,port); 
  25442                     if (BCM_FAILURE(rv)) {
  25443                     LOG_ERROR(BSL_LS_BCM_PORT,
  25444                               (BSL_META_U(unit,
  25445                                  "Error: Encap Set: "
  25446                                  "MMU config failure")));
  25447                         break;
  25448                     }
  25449                 }
  25450 #endif 
  25451 
  25452             }while (0);
  25453         }
  25454     }
  25455 #endif
  25456 
  25457 #if defined(BCM_XMAC_SUPPORT)
  25458    if(SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) ||
  25459       SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
  25460        uint32          vco_disturbed = 0;
  25461        phy_ctrl_t      *int_pc, *ext_pc;
  25462        ext_pc = EXT_PHY_SW_STATE(unit, port);
  25463        if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) ||
  25464                    IS_XE_PORT(unit, port)) && (ext_pc == NULL)) {
  25465 
  25466            int_pc = INT_PHY_SW_STATE(unit, port);
  25467            rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed);
  25468            if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) {
  25469                _bcm_esw_port_mirror_unlock(unit);
  25470                return rv;
  25471            }
  25472            if (vco_disturbed) {
  25473                rv = _mac_x_reinit(unit, port);
  25474                if (BCM_FAILURE(rv)) {
  25475                    _bcm_esw_port_mirror_unlock(unit);
  25476                    return rv;
  25477                }
  25478            }
  25479        }
  25480    }
  25481 #endif
  25482     _bcm_esw_port_mirror_unlock(unit);
  25483 
  25484     return rv;
  25485 }
  25486 
  25487 
  25488 /*
  25489  * Function:
  25490  *      bcmi_esw_port_encap_validate
  25491  * Purpose:
  25492  *      Check if the encap change for this port can be acceptable or not.
  25493  * Parameters:
  25494  *      unit     - (IN) Unit number
  25495  *      port     - (IN) Logical port number
  25496  *      encap    - (IN) encap mode
  25497  *      speed    - (IN) speed
  25498  * Returns:
  25499  *      BCM_E_NONE
  25500  *      BCM_E_XXX
  25501  * Notes:
  25502  */
  25503 STATIC int
  25504 bcmi_esw_port_encap_validate(int unit, bcm_port_t port, int mode, int speed)
  25505 {
  25506 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT
  25507     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  25508 
  25509     if (BCM_ESW_PORT_DRV(unit)!= NULL) {
  25510         if (BCM_ESW_PORT_DRV(unit)->encap_speed_check != NULL) {
  25511             BCM_IF_ERROR_RETURN
  25512                 (BCM_ESW_PORT_DRV(unit)->encap_speed_check(unit, port,
  25513                                                            mode, speed));
  25514         }
  25515     }
  25516     return BCM_E_NONE;
  25517 #else
  25518     return BCM_E_NONE;
  25519 #endif
  25520 }
  25521 
  25522 STATIC int
  25523 _bcm_esw_port_encap_set(int unit, bcm_port_t port, int mode)
  25524 {
  25525     int rv;
  25526 #if defined(BCM_TOMAHAWK2_SUPPORT)
  25527     int asf_mode;
  25528 #endif /* BCM_TOMAHAWK2_SUPPORT */
  25529 
  25530 
  25531 #if defined(BCM_TOMAHAWK3_SUPPORT)
  25532     if (SOC_IS_TOMAHAWK3(unit)) {
  25533         return BCM_E_NONE;
  25534     }
  25535 #endif /* BCM_TOMAHAWK3_SUPPORT */
  25536 
  25537 #if defined(BCM_TOMAHAWK2_SUPPORT)
  25538     if (SOC_IS_TOMAHAWK2(unit)) {
  25539         BCM_IF_ERROR_RETURN(bcm_esw_port_asf_mode_get(unit, port, &asf_mode));
  25540         if (asf_mode != _SOC_TH_ASF_MODE_SAF) {
  25541             BCM_IF_ERROR_RETURN
  25542                 (bcm_esw_port_asf_mode_set(unit, port, _SOC_TH_ASF_MODE_SAF));
  25543         }
  25544     }
  25545 #endif /* BCM_TOMAHAWK2_SUPPORT */
  25546 
  25547     /* Call Port Control module */
  25548     if (SOC_USE_PORTCTRL(unit)) {
  25549         rv = bcmi_esw_portctrl_encap_set(unit, port, mode, FALSE);
  25550     } else {
  25551         rv = bcmi_esw_port_encap_set(unit, port, mode);
  25552     }
  25553 
  25554 #if defined(BCM_TOMAHAWK2_SUPPORT)
  25555     if (SOC_IS_TOMAHAWK2(unit)) {
  25556         if (asf_mode != _SOC_TH_ASF_MODE_SAF) {
  25557             BCM_IF_ERROR_RETURN
  25558                 (bcm_esw_port_asf_mode_set(unit, port, asf_mode));
  25559         }
  25560     }
  25561 #endif /* BCM_TOMAHAWK2_SUPPORT */
  25562 
  25563     return rv;
  25564 }
  25565 
  25566 /*
  25567  * Function:
  25568  *      bcm_port_encap_set
  25569  * Purpose:
  25570  *      Set the port encapsulation mode
  25571  * Parameters:
  25572  *      unit - StrataSwitch unit #
  25573  *      port - StrataSwitch port #
  25574  *      mode - One of BCM_PORT_ENCAP_xxx (see port.h)
  25575  * Returns:
  25576  *      BCM_E_XXX
  25577  */
  25578 int
  25579 bcm_esw_port_encap_set(int unit, bcm_port_t port, int mode)
  25580 {
  25581     /* Make sure port module is initialized. */
  25582     PORT_INIT(unit);
  25583 
  25584     BCM_IF_ERROR_RETURN(bcmi_esw_port_encap_validate(unit, port, mode, 0));
  25585     BCM_IF_ERROR_RETURN(_bcm_esw_port_encap_set(unit, port, mode));
  25586 
  25587     return BCM_E_NONE;
  25588 }
  25589 
  25590 /*
  25591  * Function:
  25592  *      bcm_port_encap_get
  25593  * Purpose:
  25594  *      Get the port encapsulation mode
  25595  * Parameters:
  25596  *      unit - StrataSwitch unit #
  25597  *      port - StrataSwitch port #
  25598  *      mode (OUT) - One of BCM_PORT_ENCAP_xxx (see port.h)
  25599  * Returns:
  25600  *      BCM_E_XXX
  25601  */
  25602 
  25603 int
  25604 bcm_esw_port_encap_get(int unit, bcm_port_t port, int *mode)
  25605 {
  25606 
  25607 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_KATANA_SUPPORT)
  25608    int speed_mode = 0;
  25609    uint64 rval64;
  25610 #endif
  25611 
  25612 #if defined(BCM_KATANA2_SUPPORT)
  25613    int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  25614 #endif
  25615 
  25616     *mode = -1;
  25617 
  25618     /* Make sure port module is initialized. */
  25619     PORT_INIT(unit);
  25620 
  25621     /* Call Port Control module */
  25622     if (SOC_USE_PORTCTRL(unit)) {
  25623         return (bcmi_esw_portctrl_encap_get(unit, port, mode));
  25624     }
  25625     if(bcm_common_oamp_port_enable_get(unit, port)) {
  25626         LOG_ERROR(BSL_LS_BCM_PORT,
  25627                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  25628                    port));
  25629         return BCM_E_PARAM;
  25630     }
  25631 
  25632 
  25633 #if defined(BCM_KATANA2_SUPPORT)
  25634 #if defined(BCM_SABER2_SUPPORT)
  25635    if(SOC_IS_SABER2(unit)) {
  25636        max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  25637    }
  25638 #endif
  25639     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) &&
  25640         (!((port >= 1) && (port <= max_phy_port)))) {
  25641          return BCM_E_PORT;
  25642     }
  25643 #endif
  25644 
  25645     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  25646 
  25647 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_KATANA_SUPPORT)
  25648     if (SOC_IS_ENDURO(unit) || SOC_IS_KATANAX(unit) ||
  25649         SOC_IS_HURRICANE(unit) || SOC_IS_HURRICANE2(unit)) {
  25650         if (IS_HL_PORT(unit, port)) {
  25651             *mode = BCM_PORT_ENCAP_HIGIG2;
  25652 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  25653             if (SOC_IS_KATANAX(unit)) {
  25654                 if (SOC_REG_PORT_VALID(unit, XMAC_MODEr, port)) {
  25655                     SOC_IF_ERROR_RETURN(READ_XMAC_MODEr(unit, port, &rval64));
  25656                     speed_mode = soc_reg64_field32_get(unit, XMAC_MODEr, rval64,
  25657                                                        SPEED_MODEf);
  25658 
  25659                 } else if (SOC_REG_PORT_VALID(unit, XLMAC_MODEr, port)) {
  25660 
  25661                     SOC_IF_ERROR_RETURN(READ_XLMAC_MODEr(unit, port, &rval64));
  25662                     speed_mode = soc_reg64_field32_get(unit, XLMAC_MODEr, rval64,
  25663                                                        SPEED_MODEf);
  25664                 }
  25665 #if defined(BCM_METROLITE_SUPPORT)
  25666                 if (SOC_IS_METROLITE(unit)) {
  25667                     /* 2.5G and 1G speed in HIGIG2_LITE */
  25668                     if ((speed_mode == 3)||(speed_mode == 2)) {
  25669                         *mode = BCM_PORT_ENCAP_HIGIG2_LITE;
  25670                     }
  25671                 } else
  25672 #endif
  25673                 if (speed_mode == 3) {
  25674                     *mode = BCM_PORT_ENCAP_HIGIG2_LITE;
  25675                  }
  25676              }
  25677 #endif
  25678         } else {
  25679             SOC_IF_ERROR_RETURN
  25680                 (MAC_ENCAP_GET(PORT(unit, port).p_mac, unit, port, mode));
  25681         }
  25682     } else
  25683 #endif  /* BCM_ENDURO_SUPPORT */
  25684 #ifdef BCM_GREYHOUND_SUPPORT
  25685     if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  25686         SOC_IS_GREYHOUND2(unit)) {
  25687         int     rv;
  25688         uint32  hg2_mode = 0;
  25689 
  25690 #if defined(BCM_HURRICANE3_SUPPORT)
  25691         if (soc_feature(unit, soc_feature_wh2)) {
  25692             return bcmi_wh2_port_encap_get(unit, port, mode);
  25693         }
  25694 #endif /* BCM_HURRICANE3_SUPPORT */
  25695         /* MAC encap can report the proper encap type but special setting
  25696         * in port marcro for HG2-Lite case.
  25697         *
  25698         * For HG2-Lite condition :
  25699         *   - in Port Macro(MAC is included in PM), the encap will be IEEE.
  25700         *   - Out of Port Macro, the encap will be HG2
  25701         */
  25702         BCM_IF_ERROR_RETURN
  25703                 (MAC_ENCAP_GET(PORT(unit, port).p_mac, unit, port, mode));
  25704         if (*mode == BCM_PORT_ENCAP_IEEE) {
  25705 #ifdef  BCM_GREYHOUND2_SUPPORT
  25706             if (SOC_IS_GREYHOUND2(unit)) {
  25707                 rv = soc_greyhound2_pgw_encap_field_get(unit,
  25708                         port, HIGIG2_MODEf, &hg2_mode);
  25709             } else 
  25710 #endif  /* GREYHOUDN2 */
  25711             {
  25712             /* only port in XLMAC allows PGW encap setting below */
  25713             rv = soc_greyhound_pgw_encap_field_get(unit,
  25714                     port, HIGIG2_MODEf, &hg2_mode);
  25715              }
  25716 
  25717             if (BCM_SUCCESS(rv)){
  25718                 *mode = (hg2_mode) ? BCM_PORT_ENCAP_HIGIG2_LITE : *mode;
  25719             } else if (rv != BCM_E_UNAVAIL) {
  25720                 /* BCM_E_UNAVAIL can be occurred on the port at QSGMII */
  25721                 return rv;
  25722             }
  25723         }
  25724     } else
  25725 #endif  /* BCM_GREYHOUND_SUPPORT */
  25726     if (IS_GE_PORT(unit, port) && IS_ST_PORT(unit, port)) {
  25727         if (soc_feature(unit, soc_feature_embedded_higig)) {
  25728             *mode = BCM_PORT_ENCAP_IEEE;
  25729         } else {
  25730             uint32 rval;
  25731             soc_field_t hg_en[6] = {-1, HGIG2_EN_S0f, HGIG2_EN_S1f, -1,
  25732                                     HGIG2_EN_S3f, HGIG2_EN_S4f};
  25733            /* The port number check is for Coverity.  No port > 6 will
  25734             * reach this logic on Raven. */
  25735             if (SOC_IS_RAVEN(unit) && (port < 6)) {
  25736                 BCM_IF_ERROR_RETURN(READ_GPORT_CONFIGr(unit, port, &rval));
  25737 
  25738                 if (SOC_REG_FIELD_VALID(unit, GPORT_CONFIGr, hg_en[port])) {
  25739                     *mode = soc_reg_field_get(unit, GPORT_CONFIGr, rval,
  25740                                               hg_en[port]) ?
  25741                         BCM_PORT_ENCAP_HIGIG2 : BCM_PORT_ENCAP_IEEE;
  25742                 } else {
  25743                     return (BCM_E_CONFIG);
  25744                 }
  25745             }
  25746         }
  25747 #if defined(BCM_TRIUMPH3_SUPPORT)
  25748     } else if (SOC_IS_TRIUMPH3(unit) && IS_CE_PORT(unit, port)) {
  25749         uint32 regval;
  25750         BCM_IF_ERROR_RETURN(READ_PORT_CONFIGr(unit, port, &regval));
  25751         if (soc_reg_field_get(unit, PORT_CONFIGr, regval, HIGIG2_MODEf)) {
  25752           *mode = BCM_PORT_ENCAP_HIGIG2;
  25753         } else if (soc_reg_field_get(unit, PORT_CONFIGr, regval, HIGIG_MODEf)) {
  25754           *mode = BCM_PORT_ENCAP_HIGIG;
  25755         } else {
  25756            SOC_IF_ERROR_RETURN
  25757                 (MAC_ENCAP_GET(PORT(unit, port).p_mac, unit, port, mode));
  25758         }
  25759 #endif
  25760     } else {
  25761         SOC_IF_ERROR_RETURN
  25762             (MAC_ENCAP_GET(PORT(unit, port).p_mac, unit, port, mode));
  25763     }
  25764 
  25765     if(*mode == -1) {
  25766         /* Default : Return MAC encap mode */
  25767         SOC_IF_ERROR_RETURN
  25768             (MAC_ENCAP_GET(PORT(unit, port).p_mac, unit, port, mode));
  25769     }
  25770 
  25771     LOG_INFO(BSL_LS_BCM_PORT,
  25772              (BSL_META_U(unit,
  25773                          "bcm_esw_port_encap_get: u=%d p=%d mode=%d\n"),
  25774               unit, port, *mode));
  25775     return BCM_E_NONE;
  25776 }
  25777 
  25778 /*
  25779  * Function:
  25780  *      bcm_port_queued_count_get
  25781  * Purpose:
  25782  *      Returns the count of packets (or cells) currently buffered
  25783  *      for a port.  Useful to know when a port has drained all
  25784  *      data and can then be re-configured.
  25785  * Parameters:
  25786  *      unit - StrataSwitch unit #
  25787  *      port - StrataSwitch port #
  25788  *      count (OUT) - count of packets currently buffered
  25789  * Returns:
  25790  *      BCM_E_XXX
  25791  * Notes:
  25792  *      "packets" may actually be cells on most chips,
  25793  *      If no packets are buffered, the cell count is 0,
  25794  *      If some packets are buffered the cell count will be
  25795  *      greater than or equal to the packet count.
  25796  */
  25797 
  25798 int
  25799 bcm_esw_port_queued_count_get(int unit, bcm_port_t port, uint32 *count)
  25800 {
  25801     uint32      regval;
  25802     int         cos;
  25803 
  25804     *count = 0;
  25805 
  25806     /* Make sure port module is initialized. */
  25807     PORT_INIT(unit);
  25808     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  25809 
  25810     if (SOC_IS_FB_FX_HX(unit) || SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  25811         SOC_IS_GREYHOUND2(unit)) {
  25812         for (cos = 0; cos < NUM_COS(unit); cos++) {
  25813             regval = 0;
  25814             SOC_IF_ERROR_RETURN(READ_COSLCCOUNTr(unit, port, cos, &regval));
  25815             *count += soc_reg_field_get(unit, COSLCCOUNTr, regval, LCCOUNTf);
  25816         }
  25817         return BCM_E_NONE;
  25818     }
  25819 
  25820 #if defined(BCM_XGS12_FABRIC_SUPPORT)
  25821     if (SOC_IS_XGS12_FABRIC(unit)) {
  25822         regval = 0;
  25823         SOC_IF_ERROR_RETURN(READ_MMU_CELLCNTTOTALr(unit, port, &regval));
  25824         *count += soc_reg_field_get(unit, MMU_CELLCNTTOTALr, regval, COUNTf);
  25825         return BCM_E_NONE;
  25826     }
  25827 #endif /* BCM_XGS12_FABRIC_SUPPORT */
  25828 
  25829 #if defined(BCM_BRADLEY_SUPPORT)
  25830     if (SOC_IS_HBX(unit)) {
  25831         regval = 0;
  25832         SOC_IF_ERROR_RETURN(READ_OP_PORT_TOTAL_COUNTr(unit, port, &regval));
  25833         *count += soc_reg_field_get(unit, OP_PORT_TOTAL_COUNTr,
  25834                                     regval, OP_PORT_TOTAL_COUNTf);
  25835         return BCM_E_NONE;
  25836     }
  25837 #endif /* BCM_BRADLEY_SUPPORT  */
  25838 
  25839 #if defined(BCM_TRIDENT_SUPPORT)
  25840     if (SOC_IS_TD_TT(unit)) {
  25841         return soc_egress_cell_count(unit, port, count);
  25842     }
  25843 #endif /* BCM_TRIDENT_SUPPORT */
  25844 
  25845 #if defined(BCM_TRIUMPH3_SUPPORT)
  25846     if (SOC_IS_TRIUMPH3(unit)) {
  25847         regval = 0;
  25848         SOC_IF_ERROR_RETURN(READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port, &regval));
  25849         *count += soc_reg_field_get(unit, OP_PORT_TOTAL_COUNT_CELLr,
  25850                                     regval, TOTAL_COUNTf);
  25851         return BCM_E_NONE;
  25852     }
  25853 #endif /* BCM_TRIUMPH3_SUPPORT  */
  25854 
  25855     return BCM_E_UNAVAIL;
  25856 }
  25857 
  25858     /*
  25859  * Function:
  25860  *      bcm_port_protocol_vlan_add
  25861  * Purpose:
  25862  *      Adds a protocol based vlan to a port.  The protocol
  25863  *      is matched by frame type and ether type.  Returns an
  25864  *      error if hardware does not support protocol vlans
  25865  *      (Strata and Hercules).
  25866  * Parameters:
  25867  *      unit - StrataSwitch unit #
  25868  *      port - StrataSwitch port #
  25869  *      frame - one of BCM_PORT_FRAMETYPE_{ETHER2,8023,LLC}
  25870  *      ether - 16 bit Ethernet type field
  25871  *      vid - VLAN ID
  25872  * Returns:
  25873  *      BCM_E_XXX
  25874  */
  25875 
  25876 int
  25877 bcm_esw_port_protocol_vlan_add(int unit,
  25878                            bcm_port_t port,
  25879                            bcm_port_frametype_t frame,
  25880                            bcm_port_ethertype_t ether,
  25881                            bcm_vlan_t vid)
  25882 {
  25883     int rv = BCM_E_UNAVAIL;
  25884 
  25885     /* Make sure port module is initialized. */
  25886     PORT_INIT(unit);
  25887 #ifdef  BCM_XGS_SWITCH_SUPPORT
  25888 
  25889     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  25890     PORT_SWITCHED_CHECK(unit, port);
  25891 
  25892     PORT_LOCK(unit);
  25893 #ifdef BCM_TRX_SUPPORT
  25894     if (SOC_IS_TRX(unit)) {
  25895         bcm_vlan_action_set_t action;
  25896 
  25897         if (!soc_feature(unit, soc_feature_vlan_action)) {
  25898             PORT_UNLOCK(unit);
  25899             return BCM_E_UNAVAIL;
  25900         }
  25901 
  25902         bcm_vlan_action_set_t_init(&action);
  25903         action.new_outer_vlan = vid;
  25904         action.new_inner_vlan = 0;
  25905         action.priority = PORT(unit, port).p_ut_prio;
  25906         action.ut_outer = bcmVlanActionAdd;
  25907         action.it_outer = bcmVlanActionAdd;
  25908         action.it_inner = bcmVlanActionDelete;
  25909         action.it_inner_prio = bcmVlanActionNone;
  25910         action.ot_outer_prio = bcmVlanActionReplace;
  25911         action.dt_outer_prio = bcmVlanActionReplace;
  25912 
  25913         rv = _bcm_trx_vlan_port_protocol_action_add(unit, port, frame,
  25914                                                      ether, &action);
  25915         PORT_UNLOCK(unit);
  25916         return rv;
  25917     }
  25918 #endif /* BCM_TRX_SUPPORT */
  25919 
  25920 #if defined(BCM_FIREBOLT_SUPPORT)
  25921     if (SOC_IS_FBX(unit)) {
  25922         rv = _bcm_fb_port_protocol_vlan_add(unit, port, frame, ether, vid);
  25923         PORT_UNLOCK(unit);
  25924         return rv;
  25925     }
  25926 #endif /* BCM_FIREBOLT_SUPPORT */
  25927     PORT_UNLOCK(unit);
  25928 #endif /* BCM_XGS_SWITCH_SUPPORT */
  25929     /* not supported on STRATA and HERCULES */
  25930     return rv;
  25931 }
  25932 
  25933 /*
  25934  * Function:
  25935  *      bcm_port_protocol_vlan_delete
  25936  * Purpose:
  25937  *      Remove an already created proto protocol based vlan
  25938  *      on a port.
  25939  * Parameters:
  25940  *      unit - StrataSwitch unit #
  25941  *      port - StrataSwitch port #
  25942  *      frame - one of BCM_PORT_FRAMETYPE_{ETHER2,8023,LLC}
  25943  *      ether - 16 bit Ethernet type field
  25944  * Returns:
  25945  *      BCM_E_XXX
  25946  */
  25947 
  25948 int
  25949 bcm_esw_port_protocol_vlan_delete(int unit,
  25950                               bcm_port_t port,
  25951                               bcm_port_frametype_t frame,
  25952                               bcm_port_ethertype_t ether)
  25953 {
  25954     int rv = BCM_E_UNAVAIL;
  25955     /* Make sure port module is initialized. */
  25956     PORT_INIT(unit);
  25957 #ifdef  BCM_XGS_SWITCH_SUPPORT
  25958     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  25959     PORT_SWITCHED_CHECK(unit, port);
  25960 
  25961     PORT_LOCK(unit);
  25962 
  25963 #ifdef BCM_TRX_SUPPORT
  25964     if (SOC_IS_TRX(unit)) {
  25965         if (!soc_feature(unit, soc_feature_vlan_action)) {
  25966             PORT_UNLOCK(unit);
  25967             return BCM_E_UNAVAIL;
  25968         }
  25969         rv = _bcm_trx_vlan_port_protocol_delete(unit, port, frame, ether);
  25970         PORT_UNLOCK(unit);
  25971         return rv;
  25972     }
  25973 #endif /* BCM_TRX_SUPPORT */
  25974 
  25975 #if defined(BCM_FIREBOLT_SUPPORT)
  25976     if (SOC_IS_FBX(unit)) {
  25977         rv = _bcm_fb_port_protocol_vlan_delete(unit, port, frame, ether);
  25978         PORT_UNLOCK(unit);
  25979         return rv;
  25980 
  25981     }
  25982 #endif /* BCM_FIREBOLT_SUPPORT */
  25983 
  25984     PORT_UNLOCK(unit);
  25985 #endif /* BCM_XGS_SWITCH_SUPPORT */
  25986     /* not supported on STRATA and HERCULES */
  25987     return rv;
  25988 }
  25989 
  25990 /*
  25991  * Function:
  25992  *      bcm_port_protocol_vlan_delete_all
  25993  * Purpose:
  25994  *      Remove all protocol based vlans on a port.
  25995  * Parameters:
  25996  *      unit - StrataSwitch unit #
  25997  *      port - StrataSwitch port #
  25998  * Returns:
  25999  *      BCM_E_XXX
  26000  */
  26001 
  26002 int
  26003 bcm_esw_port_protocol_vlan_delete_all(int unit, bcm_port_t port)
  26004 {
  26005 #ifdef  BCM_XGS_SWITCH_SUPPORT
  26006     int         i;
  26007 
  26008     /* Make sure port module is initialized. */
  26009     PORT_INIT(unit);
  26010 
  26011     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  26012     PORT_SWITCHED_CHECK(unit, port);
  26013 
  26014 #ifdef BCM_TRX_SUPPORT
  26015     if (SOC_IS_TRX(unit)) {
  26016         int rv;
  26017         if (!soc_feature(unit, soc_feature_vlan_action)) {
  26018             return BCM_E_UNAVAIL;
  26019         }
  26020         PORT_LOCK(unit);
  26021         rv = _bcm_trx_vlan_port_protocol_delete_all(unit, port);
  26022         PORT_UNLOCK(unit);
  26023         return rv;
  26024     }
  26025 #endif /* BCM_TRX_SUPPORT */
  26026 
  26027 #if defined(BCM_FIREBOLT_SUPPORT)
  26028     if (SOC_IS_FBX(unit)) {
  26029         vlan_protocol_entry_t        vpe;
  26030         vlan_protocol_data_entry_t   vde;
  26031         bcm_vlan_t                   cvid, defvid;
  26032         int                          idxmin, idxmax;
  26033         int                          vlan_prot_entries;
  26034         int                          vdentry, p, valid;
  26035         _bcm_port_info_t             *pinfo;
  26036         bcm_pbmp_t                   switched_pbm;
  26037 
  26038         idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm);
  26039         idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm);
  26040         vlan_prot_entries = idxmax + 1;
  26041 
  26042         for (i = idxmin; i <= idxmax; i++) {
  26043             vdentry = (port * vlan_prot_entries) + i;
  26044             SOC_IF_ERROR_RETURN
  26045                 (READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY,
  26046                                           vdentry, &vde));
  26047             cvid = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, VLAN_IDf);
  26048             BCM_IF_ERROR_RETURN
  26049                 (bcm_esw_port_untagged_vlan_get(unit, port, &defvid));
  26050             BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
  26051             if (cvid == 0 ||
  26052                 (cvid == defvid && (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, i)))) {
  26053                 continue;
  26054             }
  26055             sal_memset(&vde, 0, sizeof(vde));
  26056             soc_VLAN_PROTOCOL_DATAm_field32_set(unit, &vde, VLAN_IDf, defvid);
  26057             SOC_IF_ERROR_RETURN
  26058                 (WRITE_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ALL, vdentry, &vde));
  26059             _BCM_PORT_VD_PBVL_CLEAR(pinfo, i);
  26060             /*
  26061              * see if any vlan_protocol_data entries are still valid
  26062              * for the current protocol.
  26063              */
  26064             valid = 0;
  26065             switched_pbm = PBMP_E_ALL(unit);
  26066             if (soc_feature(unit, soc_feature_cpuport_switched)) {
  26067                 BCM_PBMP_OR(switched_pbm, PBMP_CMIC(unit));
  26068             }
  26069 
  26070             BCM_PBMP_ITER(switched_pbm, p) {
  26071                 if (p == port) {    /* skip the entry we just "defaulted" */
  26072                     continue;
  26073                 }
  26074                 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, p, &pinfo));
  26075                 /* entry valid if programmed VLAN ID for port */
  26076                 if (_BCM_PORT_VD_PBVL_IS_SET(pinfo, i)) {
  26077                     valid = 1;
  26078                     break;
  26079                 }
  26080             }
  26081             if (!valid) {
  26082                 /*
  26083                  * Clear all VLAN_PROTOCOL_DATA entries associated
  26084                  * with this protocol.
  26085                  */
  26086                 BCM_PBMP_ITER(switched_pbm, p) {
  26087                     vdentry = (p * vlan_prot_entries) + i;
  26088                     sal_memset(&vde, 0, sizeof(vde));
  26089                     SOC_IF_ERROR_RETURN
  26090                         (WRITE_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ALL,
  26091                                                    vdentry, &vde));
  26092                     BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, p, &pinfo));
  26093                     _BCM_PORT_VD_PBVL_CLEAR(pinfo, i);
  26094                 }
  26095                 /* clear VLAN_PROTOCOL entry */
  26096                 sal_memset(&vpe, 0, sizeof(vpe));
  26097                 SOC_IF_ERROR_RETURN
  26098                     (WRITE_VLAN_PROTOCOLm(unit, MEM_BLOCK_ALL, i, &vpe));
  26099             }
  26100         }
  26101         return BCM_E_NONE;
  26102     }
  26103 #endif /* BCM_FIREBOLT_SUPPORT */
  26104 
  26105 #endif /* BCM_XGS_SWITCH_SUPPORT */
  26106 
  26107     /* not supported on STRATA and HERCULES */
  26108 
  26109     return BCM_E_UNAVAIL;
  26110 }
  26111 
  26112 /*
  26113  * Differentiated Services Code Point Mapping
  26114  */
  26115 
  26116 /*
  26117  * Function:
  26118  *      bcm_esw_port_dscp_map_mode_set
  26119  * Purpose:
  26120  *      Set DSCP mapping for the port.
  26121  * Parameters:
  26122  *      unit - switch device
  26123  *      port - switch port      or -1 to apply on all the ports.
  26124  *      mode - BCM_PORT_DSCP_MAP_NONE
  26125  *           - BCM_PORT_DSCP_MAP_ZERO Map if incomming DSCP = 0
  26126  *           - BCM_PORT_DSCP_MAP_ALL DSCP -> DSCP mapping.
  26127  * Returns:
  26128  *      BCM_E_XXX
  26129  */
  26130 static int
  26131 _bcm_esw_port_dscp_map_mode_set(int unit, bcm_port_t port, int mode)
  26132 {
  26133     bcm_port_cfg_t      pcfg;
  26134 
  26135     BCM_IF_ERROR_RETURN
  26136         (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg));
  26137     if (pcfg.pc_dse_mode == -1) {       /* STRATA1 for example */
  26138         return BCM_E_UNAVAIL;
  26139     }
  26140     switch(mode) {
  26141         case BCM_PORT_DSCP_MAP_NONE:
  26142             pcfg.pc_dse_mode = 0;
  26143             pcfg.pc_dse_mode_ipv6 = 0;
  26144 #if defined(BCM_XGS_SWITCH_SUPPORT)
  26145             pcfg.pc_dscp_prio = 0;
  26146 #endif /* BCM_XGS_SWITCH_SUPPORT */
  26147             break;
  26148         case BCM_PORT_DSCP_MAP_ZERO:
  26149             if (soc_feature(unit, soc_feature_dscp_map_mode_all)) {
  26150                 return BCM_E_UNAVAIL;
  26151             }
  26152             pcfg.pc_dse_mode = 1;
  26153 #if defined(BCM_XGS_SWITCH_SUPPORT)
  26154             pcfg.pc_dscp_prio = 1;
  26155 #endif /* BCM_XGS_SWITCH_SUPPORT */
  26156             break;
  26157         case BCM_PORT_DSCP_MAP_ALL:
  26158             if (soc_feature(unit, soc_feature_dscp_map_mode_all)) {
  26159                 pcfg.pc_dse_mode = 1;
  26160                 pcfg.pc_dse_mode_ipv6 = 1;
  26161             } else {
  26162                 pcfg.pc_dse_mode = 2;
  26163             }
  26164 #if defined(BCM_XGS_SWITCH_SUPPORT)
  26165             pcfg.pc_dscp_prio = 1;
  26166 #endif /* BCM_XGS_SWITCH_SUPPORT */
  26167             break;
  26168         case BCM_PORT_DSCP_MAP_IPV4_ONLY:
  26169             if (!soc_feature(unit, soc_feature_dscp_map_mode_all)) {
  26170                 return BCM_E_UNAVAIL;
  26171             }
  26172             pcfg.pc_dse_mode = 1;
  26173 #if defined(BCM_XGS_SWITCH_SUPPORT)
  26174             pcfg.pc_dscp_prio = 1;
  26175 #endif /* BCM_XGS_SWITCH_SUPPORT */
  26176             break;
  26177         case BCM_PORT_DSCP_MAP_IPV6_ONLY:
  26178             if (!soc_feature(unit, soc_feature_dscp_map_mode_all)) {
  26179                 return BCM_E_UNAVAIL;
  26180             }
  26181             pcfg.pc_dse_mode_ipv6 = 1;
  26182 #if defined(BCM_XGS_SWITCH_SUPPORT)
  26183             pcfg.pc_dscp_prio = 1;
  26184 #endif /* BCM_XGS_SWITCH_SUPPORT */
  26185             break;
  26186         case BCM_PORT_DSCP_MAP_IPV4_NONE:
  26187             if (!soc_feature(unit, soc_feature_dscp_map_mode_all)) {
  26188                 return BCM_E_UNAVAIL;
  26189             }
  26190             pcfg.pc_dse_mode = 0;
  26191 #if defined(BCM_XGS_SWITCH_SUPPORT)
  26192             if (!pcfg.pc_dse_mode_ipv6) {
  26193                 pcfg.pc_dscp_prio = 0;
  26194             }
  26195 #endif /* BCM_XGS_SWITCH_SUPPORT */
  26196             break;
  26197         case BCM_PORT_DSCP_MAP_IPV6_NONE:
  26198             if (!soc_feature(unit, soc_feature_dscp_map_mode_all)) {
  26199                 return BCM_E_UNAVAIL;
  26200             }
  26201             pcfg.pc_dse_mode_ipv6 = 0;
  26202 #if defined(BCM_XGS_SWITCH_SUPPORT)
  26203             if (!pcfg.pc_dse_mode) {
  26204                 pcfg.pc_dscp_prio = 0;
  26205             }
  26206 #endif /* BCM_XGS_SWITCH_SUPPORT */
  26207             break;
  26208         default:
  26209             return BCM_E_PARAM;
  26210     }
  26211     BCM_IF_ERROR_RETURN
  26212         (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg));
  26213 
  26214     return BCM_E_NONE;
  26215 }
  26216 
  26217 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  26218 static int
  26219 _bcm_esw_vp_dscp_map_mode_set(int unit, bcm_gport_t port, int mode) {
  26220     if (SOC_IS_KATANAX(unit) ||
  26221         SOC_IS_TD_TT(unit)||
  26222         soc_feature(unit, soc_feature_vp_dscp_map)) {
  26223         return _bcm_tr2_vp_dscp_map_mode_set(unit, port, mode);
  26224     }
  26225     return BCM_E_UNAVAIL;
  26226 }
  26227 
  26228 STATIC int
  26229 _bcm_esw_vp_dscp_map_set(int unit, bcm_gport_t port, int srccp, int mapcp,
  26230                          int prio)
  26231 {
  26232     if (SOC_IS_TD_TT(unit) || soc_feature(unit, soc_feature_vp_dscp_map)) {
  26233         return _bcm_tr2_vp_dscp_map_set(unit, port, srccp, mapcp, prio);
  26234     }
  26235     return BCM_E_UNAVAIL;
  26236 }
  26237 #endif
  26238 
  26239 int
  26240 bcm_esw_port_dscp_map_mode_set(int unit, bcm_port_t port, int mode)
  26241 {
  26242     int rv;
  26243     bcm_port_config_t port_conf;
  26244     bcm_pbmp_t pbmp;
  26245 
  26246     /* Make sure port module is initialized. */
  26247     PORT_INIT(unit);
  26248 
  26249     if (!soc_feature(unit, soc_feature_dscp)) {
  26250         return BCM_E_UNAVAIL;
  26251     }
  26252 
  26253 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  26254     if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) &&
  26255         !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) {
  26256         return _bcm_esw_vp_dscp_map_mode_set(unit, port, mode);
  26257     }
  26258 #endif
  26259 
  26260     if (port != -1) {
  26261         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  26262     }
  26263 
  26264     PORT_LOCK(unit);
  26265 
  26266     /* Get device port configuration. */
  26267     rv = bcm_esw_port_config_get(unit, &port_conf);
  26268     if (BCM_FAILURE(rv)) {
  26269         PORT_UNLOCK(unit);
  26270         return rv;
  26271     }
  26272     BCM_PBMP_ASSIGN(pbmp, port_conf.e);
  26273     if (SOC_IS_XGS3_SWITCH(unit) || SOC_IS_XGS3_FABRIC(unit)) {
  26274         BCM_PBMP_OR(pbmp, port_conf.cpu);
  26275     }
  26276 #ifdef BCM_KATANA2_SUPPORT
  26277     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  26278         rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp);
  26279         if (BCM_FAILURE(rv)) {
  26280             PORT_UNLOCK(unit);
  26281             return (rv);
  26282         }
  26283     }
  26284     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  26285         soc_feature(unit, soc_feature_subtag_coe)) {
  26286         _bcm_kt2_subport_pbmp_update(unit, &pbmp);
  26287     }
  26288 #endif
  26289 
  26290     if (port == -1) {
  26291         PBMP_ITER(pbmp, port) {
  26292             rv = _bcm_esw_port_dscp_map_mode_set(unit, port, mode);
  26293             if (BCM_FAILURE(rv)) {
  26294                 PORT_UNLOCK(unit);
  26295                 return rv;
  26296             }
  26297         }
  26298     } else {
  26299         if (BCM_PBMP_MEMBER(pbmp, port)) {
  26300             rv = _bcm_esw_port_dscp_map_mode_set(unit, port, mode);
  26301         } else {
  26302             rv = BCM_E_PORT;
  26303         }
  26304     }
  26305     PORT_UNLOCK(unit);
  26306     return rv;
  26307 }
  26308 
  26309 /*
  26310  * Function:
  26311  *      bcm_esw_port_dscp_map_mode_get
  26312  * Purpose:
  26313  *      DSCP mapping status for the port.
  26314  * Parameters:
  26315  *      unit - switch device
  26316  *      port - switch port or -1 to get mode from first available port
  26317  *      mode - (OUT)
  26318  *           - BCM_PORT_DSCP_MAP_NONE
  26319  *           - BCM_PORT_DSCP_MAP_ZERO Map if incomming DSCP = 0
  26320  *           - BCM_PORT_DSCP_MAP_ALL DSCP -> DSCP mapping.
  26321  * Returns:
  26322  *      BCM_E_XXX
  26323  */
  26324 
  26325 static int
  26326 _bcm_esw_port_dscp_map_mode_get(int unit, bcm_port_t port, int *mode)
  26327 {
  26328     bcm_port_cfg_t      pcfg;
  26329 
  26330     BCM_IF_ERROR_RETURN
  26331         (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg));
  26332     if (pcfg.pc_dse_mode == -1) {       /* STRATA1 for example */
  26333         return BCM_E_UNAVAIL;
  26334     }
  26335     switch(pcfg.pc_dse_mode) {
  26336         case 1:
  26337             if (soc_feature(unit, soc_feature_dscp_map_mode_all)) {
  26338                 if (pcfg.pc_dse_mode_ipv6) {
  26339                     *mode = BCM_PORT_DSCP_MAP_ALL;
  26340                 } else {
  26341                     *mode = BCM_PORT_DSCP_MAP_IPV4_ONLY;
  26342                 }
  26343             } else {
  26344                 *mode = BCM_PORT_DSCP_MAP_ZERO;
  26345             }
  26346             break;
  26347         case 2:
  26348             if (soc_feature(unit, soc_feature_dscp_map_mode_all)) { 
  26349                 if (pcfg.pc_dse_mode_ipv6) {
  26350             *mode = BCM_PORT_DSCP_MAP_ALL;
  26351                 } else {
  26352                     *mode = BCM_PORT_DSCP_MAP_IPV4_ONLY;
  26353                 }
  26354             } else {
  26355                 *mode = BCM_PORT_DSCP_MAP_ALL;
  26356             }
  26357             break;
  26358         case 0:
  26359             if (pcfg.pc_dse_mode_ipv6) {
  26360                 *mode = BCM_PORT_DSCP_MAP_IPV6_ONLY;
  26361             } else {
  26362                 *mode = BCM_PORT_DSCP_MAP_NONE;
  26363             }
  26364             break;
  26365 
  26366         default:
  26367             *mode = BCM_PORT_DSCP_MAP_NONE;
  26368             break;
  26369     }
  26370 
  26371     return BCM_E_NONE;
  26372 }
  26373 
  26374 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  26375 static int
  26376 _bcm_esw_vp_dscp_map_mode_get(int unit, bcm_gport_t port, int *mode) {
  26377     if (SOC_IS_KATANAX(unit) ||
  26378         SOC_IS_TD_TT(unit) ||
  26379         soc_feature(unit, soc_feature_vp_dscp_map)) {
  26380         return _bcm_tr2_vp_dscp_map_mode_get(unit, port, mode);
  26381     }
  26382     return BCM_E_UNAVAIL;
  26383 }
  26384 
  26385 STATIC int
  26386 _bcm_esw_vp_dscp_map_get(int unit, bcm_gport_t port, int srccp, int *mapcp,
  26387                          int *prio)
  26388 {
  26389     if (SOC_IS_TD_TT(unit) || soc_feature(unit, soc_feature_vp_dscp_map)) {
  26390         return _bcm_tr2_vp_dscp_map_get(unit, port, srccp, mapcp, prio);
  26391     }
  26392     return BCM_E_UNAVAIL;
  26393 }
  26394 #endif
  26395 
  26396 int
  26397 bcm_esw_port_dscp_map_mode_get(int unit, bcm_port_t port, int *mode)
  26398 {
  26399     int rv;
  26400     bcm_port_config_t port_conf;
  26401     bcm_pbmp_t pbmp;
  26402 
  26403     /* Make sure port module is initialized. */
  26404     PORT_INIT(unit);
  26405 
  26406     if (!soc_feature(unit, soc_feature_dscp)) {
  26407         return BCM_E_UNAVAIL;
  26408     }
  26409 
  26410 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  26411     if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) &&
  26412         !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) {
  26413         return _bcm_esw_vp_dscp_map_mode_get(unit, port, mode);
  26414     }
  26415 #endif
  26416 
  26417     if (port != -1) {
  26418         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  26419     }
  26420 
  26421     PORT_LOCK(unit);
  26422 
  26423     /* Get device port configuration. */
  26424     rv = bcm_esw_port_config_get(unit, &port_conf);
  26425     if (BCM_FAILURE(rv)) {
  26426         PORT_UNLOCK(unit);
  26427         return rv;
  26428     }
  26429     BCM_PBMP_ASSIGN(pbmp, port_conf.e);
  26430     if (SOC_IS_XGS3_SWITCH(unit) || SOC_IS_XGS3_FABRIC(unit)) {
  26431         BCM_PBMP_OR(pbmp, port_conf.cpu);
  26432     }
  26433 #ifdef BCM_KATANA2_SUPPORT
  26434     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  26435         rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp);
  26436         if (BCM_FAILURE(rv)) {
  26437             PORT_UNLOCK(unit);
  26438             return (rv);
  26439         }
  26440     }
  26441     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  26442         soc_feature(unit, soc_feature_subtag_coe)) {
  26443         _bcm_kt2_subport_pbmp_update(unit, &pbmp);
  26444     }
  26445 #endif
  26446 
  26447     if (port == -1) {
  26448         PBMP_ITER(pbmp, port) {
  26449             break;
  26450         }
  26451     }
  26452 
  26453     /* coverity[overrun-local : FALSE] */
  26454     if (BCM_PBMP_MEMBER(pbmp, port)) {
  26455         rv = _bcm_esw_port_dscp_map_mode_get(unit, port, mode);
  26456     } else {
  26457         rv = BCM_E_PORT;
  26458     }
  26459     PORT_UNLOCK(unit);
  26460     return rv;
  26461 }
  26462 
  26463 /*
  26464  * Function:
  26465  *      _bcm_port_dscp_map_set
  26466  * Purpose:
  26467  *      Internal implementation for bcm_port_dscp_map_set
  26468  * Parameters:
  26469  *      unit - switch device
  26470  *      port - switch port or -1 for global table
  26471  *      srccp - src code point or -1
  26472  *      mapcp - mapped code point or -1
  26473  *      prio - priority value for mapped code point
  26474  *              -1 to use port default untagged priority
  26475  *              BCM_PRIO_RED    can be or'ed into the priority
  26476  *              BCM_PRIO_YELLOW can be or'ed into the priority
  26477  * Returns:
  26478  *      BCM_E_XXX
  26479  */
  26480 
  26481 STATIC int
  26482 _bcm_port_dscp_map_set(int unit, bcm_port_t port,
  26483                        int srccp, int mapcp, int prio)
  26484 {
  26485 #define DSCP_CODE_POINT_CNT 64
  26486 #define DSCP_CODE_POINT_MAX (DSCP_CODE_POINT_CNT - 1)
  26487     bcm_port_cfg_t      pcfg;
  26488 
  26489     if (mapcp < -1 || mapcp > DSCP_CODE_POINT_MAX) {
  26490         return BCM_E_PARAM;
  26491     }
  26492 
  26493 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  26494     if (SOC_IS_XGS3_SWITCH(unit)) {
  26495         int                  i, cng;
  26496         dscp_table_entry_t   de;
  26497         phb_mapping_tbl_2_entry_t  phb_tbl_2;
  26498         int                  max_index;
  26499         int                  min_index;
  26500         int                  field_len;
  26501 
  26502         if (SOC_IS_TRIDENT3X(unit)) {
  26503             field_len = soc_mem_field_length(unit, PHB_MAPPING_TBL_2m, INT_PRIf);
  26504         } else {
  26505         field_len = soc_mem_field_length(unit, DSCP_TABLEm, PRIf);
  26506         }
  26507 
  26508         if (srccp < -1 || srccp > DSCP_CODE_POINT_MAX) {
  26509             return BCM_E_PARAM;
  26510         }
  26511         /* Extract cng bits and check for valid priority. */
  26512         
  26513         cng = 0; /* Green */
  26514         if (prio < BCM_PRIO_MIN) {
  26515             return BCM_E_PARAM;
  26516         }
  26517         if (prio & BCM_PRIO_RED) {
  26518             cng = 0x01;  /* Red */
  26519             prio &= ~BCM_PRIO_RED;
  26520         } else if (prio & BCM_PRIO_YELLOW) {
  26521             cng = 0x03;  /* Yellow  */
  26522             prio &= ~BCM_PRIO_YELLOW;
  26523         }
  26524         if ((prio & ~BCM_PRIO_MASK) != 0) {
  26525             return BCM_E_PARAM;
  26526         }
  26527         if (prio >= (1 << field_len)) {
  26528             return BCM_E_PARAM;
  26529         }
  26530         if (srccp < 0 && mapcp < 0) {
  26531             /* No mapping */
  26532             return BCM_E_NONE;
  26533         } else if (srccp < 0) {
  26534             /* Map all DSCPs to a new DSCP */
  26535             /* fill all entries in DSCP_TABLEm with mapcp */
  26536 
  26537 #ifdef BCM_TRIDENT2_SUPPORT
  26538             if (SOC_IS_TD2_TT2(unit)) {
  26539                 return (bcm_td2_port_dscp_map_set(unit,
  26540                     port, srccp, mapcp, prio, cng));
  26541             }
  26542 #endif
  26543 #ifdef BCM_KATANA2_SUPPORT
  26544             if (SOC_IS_KATANA2(unit)) {
  26545                 return (bcm_kt2_port_dscp_map_set(unit, port,
  26546                     srccp, mapcp, prio, cng));
  26547             }
  26548 #endif
  26549 
  26550             if (SOC_IS_TRIDENT3X(unit)) {
  26551                 sal_memset(&phb_tbl_2, 0, sizeof(phb_tbl_2));
  26552                 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, DSCPf, mapcp);
  26553                 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, INT_PRIf, prio);
  26554                 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, CNGf, cng);
  26555             } else {
  26556             sal_memset(&de, 0, sizeof(de));
  26557             soc_DSCP_TABLEm_field32_set(unit, &de, DSCPf, mapcp);
  26558             soc_DSCP_TABLEm_field32_set(unit, &de, PRIf, prio);
  26559             soc_DSCP_TABLEm_field32_set(unit, &de, CNGf, cng);
  26560             }
  26561             if (soc_feature(unit, soc_feature_dscp_map_per_port)) {
  26562                 min_index = port * DSCP_CODE_POINT_CNT;
  26563                 max_index = min_index + DSCP_CODE_POINT_MAX;
  26564             } else {
  26565                 if (SOC_IS_TRIDENT3X(unit)) {
  26566                     max_index = soc_mem_index_max(unit, PHB_MAPPING_TBL_2m);
  26567                 } else {
  26568                 max_index = soc_mem_index_max(unit, DSCP_TABLEm);
  26569                 }
  26570                 min_index = 0;
  26571             }
  26572 
  26573             for (i = min_index; i <= max_index; i++) {
  26574                 if (SOC_IS_TRIDENT3X(unit)) {
  26575                     SOC_IF_ERROR_RETURN
  26576                     (WRITE_PHB_MAPPING_TBL_2m(unit, MEM_BLOCK_ALL, i, &phb_tbl_2));
  26577                 } else {
  26578                 SOC_IF_ERROR_RETURN
  26579                     (WRITE_DSCP_TABLEm(unit, MEM_BLOCK_ALL, i, &de));
  26580             }
  26581             }
  26582         } else {
  26583             int num_cosq;
  26584 
  26585 #ifdef BCM_TRIDENT2_SUPPORT
  26586             if (SOC_IS_TD2_TT2(unit)) {
  26587                 return (bcm_td2_port_dscp_map_set(unit, port,
  26588                     srccp, mapcp, prio, cng));
  26589             }
  26590 #endif
  26591 #ifdef BCM_KATANA2_SUPPORT
  26592             if (SOC_IS_KATANA2(unit)) {
  26593                 return (bcm_kt2_port_dscp_map_set(unit, port,
  26594                     srccp, mapcp, prio, cng));
  26595             }
  26596 #endif
  26597 
  26598             num_cosq = 1; /* For all cosqs */
  26599             /* Map a specific DSCP to a new DSCP */
  26600             sal_memset(&de, 0, sizeof(de));
  26601             /* fill specific srccp entry/entries in DSCP_TABLEm with mapcp */
  26602             if (SOC_IS_TRIDENT3X(unit)) {
  26603                 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, DSCPf, mapcp);
  26604                 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, INT_PRIf, prio);
  26605                 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, CNGf, cng);
  26606             } else {
  26607             soc_DSCP_TABLEm_field32_set(unit, &de, DSCPf, mapcp);
  26608             soc_DSCP_TABLEm_field32_set(unit, &de, PRIf, prio);
  26609             soc_DSCP_TABLEm_field32_set(unit, &de, CNGf, cng);
  26610             }
  26611 
  26612             if (soc_feature(unit, soc_feature_dscp_map_per_port)) {
  26613                 if (SOC_IS_TRIDENT3X(unit)) {
  26614                     SOC_IF_ERROR_RETURN
  26615                       (WRITE_PHB_MAPPING_TBL_2m(unit, MEM_BLOCK_ALL,
  26616                                          (port * DSCP_CODE_POINT_CNT) + srccp, &phb_tbl_2));
  26617                 } else {
  26618                 SOC_IF_ERROR_RETURN
  26619                   (WRITE_DSCP_TABLEm(unit, MEM_BLOCK_ALL,
  26620                                      (port * DSCP_CODE_POINT_CNT) + srccp, &de));
  26621                 } 
  26622 
  26623             } else {
  26624                 for (i = 0; i < num_cosq ; i++) {
  26625                     if (SOC_IS_TRIDENT3X(unit)) {
  26626                         SOC_IF_ERROR_RETURN
  26627                           (WRITE_PHB_MAPPING_TBL_2m(unit, MEM_BLOCK_ALL,
  26628                                          (i * DSCP_CODE_POINT_CNT) + srccp, &phb_tbl_2));
  26629                     } else {
  26630                     SOC_IF_ERROR_RETURN
  26631                       (WRITE_DSCP_TABLEm(unit, MEM_BLOCK_ALL,
  26632                                          (i * DSCP_CODE_POINT_CNT) + srccp, &de));
  26633                 }
  26634             }
  26635         }
  26636         }
  26637         return BCM_E_NONE;
  26638     }
  26639 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  26640 
  26641     /* all other switches */
  26642     if (srccp < -1 || srccp > 0) {
  26643         return BCM_E_PARAM;
  26644     }
  26645 
  26646     pcfg.pc_dse_mode = -1;
  26647     BCM_IF_ERROR_RETURN
  26648         (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg));
  26649     if (pcfg.pc_dse_mode == -1) {       /* STRATA1 for example */
  26650         return BCM_E_UNAVAIL;
  26651     }
  26652 
  26653     if (mapcp >= 0) {
  26654         pcfg.pc_dscp = mapcp;
  26655 
  26656         BCM_IF_ERROR_RETURN
  26657             (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg));
  26658     }
  26659 
  26660     return BCM_E_NONE;
  26661 }
  26662 
  26663 /*
  26664  * Function:
  26665  *      bcm_port_dscp_map_set
  26666  * Purpose:
  26667  *      Define a mapping for diffserv code points
  26668  *      The mapping enable/disable is controlled by a seperate API
  26669  *      bcm_port_dscp_map_enable_set/get
  26670  *      Also Enable/Disable control for DSCP mapping for tunnels
  26671  *      are available in the respective tunnel create APIs.
  26672  * Parameters:
  26673  *      unit - switch device
  26674  *      port - switch port      or -1 to setup global mapping table.
  26675  *      srccp - src code point or -1
  26676  *      mapcp - mapped code point or -1
  26677  *      prio - priority value for mapped code point
  26678  *              -1 to use port default untagged priority
  26679  *              BCM_PRIO_DROP_FIRST can be or'ed into the priority
  26680  * Returns:
  26681  *      BCM_E_XXX
  26682  * Notes:
  26683  *      On most xgs switches there are a limited set
  26684  *      of mappings that are possible:
  26685  *              srccp -1, mapcp -1:     no mapping
  26686  *              srccp -1, mapcp 0..63:  map all packets
  26687  *              srccp 0, mapcp 0..63:   map packets with cp 0
  26688  *      On Firebolt/Helix/Felix, there is no per port mapping table.
  26689  *      Only a global mapping table is available.
  26690  */
  26691 
  26692 int
  26693 bcm_esw_port_dscp_map_set(int unit, bcm_port_t port, int srccp, int mapcp,
  26694                       int prio)
  26695 {
  26696     int rv;
  26697     bcm_port_config_t port_conf;
  26698     bcm_pbmp_t pbmp;
  26699 
  26700     /* Make sure port module is initialized. */
  26701     PORT_INIT(unit);
  26702 
  26703     if (!soc_feature(unit, soc_feature_dscp)) {
  26704         return BCM_E_UNAVAIL;
  26705     }
  26706 
  26707 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  26708     if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) &&
  26709         !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) {
  26710         return _bcm_esw_vp_dscp_map_set(unit, port, srccp, mapcp, prio);
  26711     }
  26712 #endif
  26713 
  26714     if (port != -1) {
  26715         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  26716         if (!soc_feature(unit, soc_feature_dscp_map_per_port)) {
  26717             return BCM_E_PORT;
  26718         }
  26719     }
  26720 
  26721     PORT_LOCK(unit);
  26722 
  26723     /* Get device port configuration. */
  26724     rv = bcm_esw_port_config_get(unit, &port_conf);
  26725     if (BCM_FAILURE(rv)) {
  26726         PORT_UNLOCK(unit);
  26727         return rv;
  26728     }
  26729     BCM_PBMP_ASSIGN(pbmp, port_conf.e);
  26730     if (SOC_IS_XGS3_SWITCH(unit) || SOC_IS_XGS3_FABRIC(unit)) {
  26731         BCM_PBMP_OR(pbmp, port_conf.cpu);
  26732     }
  26733 #ifdef BCM_KATANA2_SUPPORT
  26734     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  26735         rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp);
  26736         if (BCM_FAILURE(rv)) {
  26737             PORT_UNLOCK(unit);
  26738             return (rv);
  26739         }
  26740     }
  26741     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  26742         soc_feature(unit, soc_feature_subtag_coe)) {
  26743         _bcm_kt2_subport_pbmp_update(unit, &pbmp);
  26744     }
  26745 #endif
  26746 
  26747     if ((port == -1) && (soc_feature(unit, soc_feature_dscp_map_per_port))) {
  26748         PBMP_ITER(pbmp, port) {
  26749             /* coverity[stack_use_callee] */
  26750             /* coverity[stack_use_overflow] */
  26751             rv = _bcm_port_dscp_map_set(unit, port, srccp, mapcp, prio);
  26752             if (BCM_FAILURE(rv)) {
  26753                 PORT_UNLOCK(unit);
  26754                 return rv;
  26755             }
  26756         }
  26757     } else {
  26758         if (BCM_PBMP_MEMBER(pbmp, port) || (port == -1)) {
  26759             rv = _bcm_port_dscp_map_set(unit, port, srccp, mapcp, prio);
  26760         } else {
  26761             rv = BCM_E_PORT;
  26762         }
  26763     }
  26764     PORT_UNLOCK(unit);
  26765 
  26766     return rv;
  26767 }
  26768 
  26769 /*
  26770  * Function:
  26771  *      _bcm_port_dscp_map_get
  26772  * Purpose:
  26773  *      Get a mapping for diffserv code points
  26774  * Parameters:
  26775  *      unit - switch device
  26776  *      port - switch port
  26777  *      srccp - src code point or -1
  26778  *      mapcp - (OUT) pointer to returned mapped code point
  26779  *      prio - (OUT) Priority value for mapped code point or -1
  26780  *                      May have BCM_PRIO_DROP_FIRST or'ed into it
  26781  * Returns:
  26782  *      BCM_E_XXX
  26783  */
  26784 
  26785 STATIC int
  26786 _bcm_esw_port_dscp_map_get(int unit, bcm_port_t port, int srccp, int *mapcp,
  26787                       int *prio)
  26788 {
  26789     bcm_port_cfg_t      pcfg;
  26790     port_tab_entry_t         pent;
  26791 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  26792     int                      index = 0;
  26793 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  26794     int                      rv = BCM_E_NONE;
  26795 
  26796     if (SOC_IS_TRIDENT3X(unit)) {
  26797         BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_get(unit, port,
  26798                             TRUST_DSCP_PTRf, &index));
  26799     } else if (SOC_IS_TD2_TT2(unit) || SOC_IS_KATANA2(unit)) {
  26800     /* Get profile index from port table. */
  26801         rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY,
  26802                             port, &pent);
  26803         if (BCM_FAILURE(rv)) {
  26804             return rv;
  26805         }
  26806 
  26807 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  26808         index = soc_mem_field32_get(unit, PORT_TABm, &pent, TRUST_DSCP_PTRf);
  26809 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  26810     }
  26811 
  26812     if (srccp < -1 || srccp > DSCP_CODE_POINT_MAX ||
  26813         mapcp == NULL || prio == NULL) {
  26814         return BCM_E_PARAM;
  26815     }
  26816 
  26817 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  26818     if (SOC_IS_XGS3_SWITCH(unit)) {
  26819         int                     base;
  26820         int                     cng;
  26821         dscp_table_entry_t      de;
  26822         phb_mapping_tbl_2_entry_t phb_tbl_2;
  26823 
  26824         /* look up in DSCP_TABLEm */
  26825         if (srccp < 0) {
  26826             srccp = 0;
  26827         }
  26828         if (soc_feature(unit, soc_feature_dscp_map_per_port)) {
  26829             base = (port * DSCP_CODE_POINT_CNT);
  26830 
  26831             if (SOC_IS_TD2_TT2(unit) || SOC_IS_KATANA2(unit)) {
  26832                 base = (index * DSCP_CODE_POINT_CNT);
  26833             }
  26834         } else {
  26835             base = 0;
  26836         }
  26837 
  26838         if (SOC_IS_TRIDENT3X(unit)) {
  26839             SOC_IF_ERROR_RETURN
  26840                 (READ_PHB_MAPPING_TBL_2m(unit, MEM_BLOCK_ANY, base + srccp, &phb_tbl_2));
  26841             *mapcp = soc_PHB_MAPPING_TBL_2m_field32_get(unit, &phb_tbl_2, DSCPf);
  26842             *prio = soc_PHB_MAPPING_TBL_2m_field32_get(unit, &phb_tbl_2, INT_PRIf);
  26843 
  26844              cng   = soc_PHB_MAPPING_TBL_2m_field32_get(unit, &phb_tbl_2, CNGf);
  26845         } else {
  26846         SOC_IF_ERROR_RETURN
  26847             (READ_DSCP_TABLEm(unit, MEM_BLOCK_ANY, base + srccp, &de));
  26848         *mapcp = soc_DSCP_TABLEm_field32_get(unit, &de, DSCPf);
  26849         *prio = soc_DSCP_TABLEm_field32_get(unit, &de, PRIf);
  26850 
  26851         cng   = soc_DSCP_TABLEm_field32_get(unit, &de, CNGf);
  26852         }
  26853         if (cng == 1) {
  26854             *prio |= BCM_PRIO_RED;
  26855         } else if (cng == 3) {
  26856             *prio |= BCM_PRIO_YELLOW;
  26857         } else if (cng != 0) {
  26858             *prio |= BCM_PRIO_DROP_FIRST;
  26859         }
  26860 
  26861         return BCM_E_NONE;
  26862     }
  26863 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  26864 
  26865     /* all other switches */
  26866 
  26867     pcfg.pc_dse_mode = -1;
  26868     BCM_IF_ERROR_RETURN
  26869         (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg));
  26870     if (pcfg.pc_dse_mode == -1) {       /* STRATA1 for example */
  26871         return BCM_E_UNAVAIL;
  26872     }
  26873 
  26874     /*
  26875      * The mapping table is set independently of the mapping mode.
  26876      * So the _get API will return the mapping table setup and not
  26877      * necessarily the actual mapping that will be applied to the packet.
  26878      * The mapping applied to the packet is determined by mapping mode
  26879      * set using bcm_port_dscp_map_mode_set
  26880      */
  26881     *mapcp = pcfg.pc_dscp;
  26882 
  26883     *prio = -1;
  26884 
  26885     return BCM_E_NONE;
  26886 }
  26887 
  26888 /*
  26889  * Function:
  26890  *      bcm_port_dscp_map_get
  26891  * Purpose:
  26892  *      Get a mapping for diffserv code points
  26893  * Parameters:
  26894  *      unit - switch device
  26895  *      port - switch port
  26896  *      srccp - src code point or -1
  26897  *      mapcp - (OUT) pointer to returned mapped code point
  26898  *      prio - (OUT) Priority value for mapped code point or -1
  26899  *                      May have BCM_PRIO_DROP_FIRST or'ed into it
  26900  * Returns:
  26901  *      BCM_E_XXX
  26902  */
  26903 
  26904 int
  26905 bcm_esw_port_dscp_map_get(int unit, bcm_port_t port, int srccp, int *mapcp,
  26906                       int *prio)
  26907 {
  26908     int rv;
  26909     bcm_port_config_t port_conf;
  26910     bcm_pbmp_t pbmp;
  26911 
  26912     /* Make sure port module is initialized. */
  26913     PORT_INIT(unit);
  26914 
  26915     if (!soc_feature(unit, soc_feature_dscp)) {
  26916         return BCM_E_UNAVAIL;
  26917     }
  26918 
  26919 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  26920     if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) &&
  26921         !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) {
  26922         return _bcm_esw_vp_dscp_map_get(unit, port, srccp, mapcp, prio);
  26923     }
  26924 #endif
  26925 
  26926     if (port != -1) {
  26927         if (0 == soc_feature(unit, soc_feature_dscp_map_per_port)) {
  26928             return BCM_E_PORT;
  26929         }
  26930         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  26931     }
  26932 
  26933     PORT_LOCK(unit);
  26934 
  26935     /* Get device port configuration. */
  26936     rv = bcm_esw_port_config_get(unit, &port_conf);
  26937     if (BCM_FAILURE(rv)) {
  26938         PORT_UNLOCK(unit);
  26939         return rv;
  26940     }
  26941     BCM_PBMP_ASSIGN(pbmp, port_conf.e);
  26942     if (SOC_IS_XGS3_SWITCH(unit) || SOC_IS_XGS3_FABRIC(unit)) {
  26943         BCM_PBMP_OR(pbmp, port_conf.cpu);
  26944     }
  26945 #ifdef BCM_KATANA2_SUPPORT
  26946     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  26947         rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp);
  26948         if (BCM_FAILURE(rv)) {
  26949             PORT_UNLOCK(unit);
  26950             return (rv);
  26951         }
  26952     }
  26953     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  26954         soc_feature(unit, soc_feature_subtag_coe)) {
  26955         _bcm_kt2_subport_pbmp_update(unit, &pbmp);
  26956     }
  26957 #endif
  26958 
  26959     if (port == -1) {
  26960         PBMP_ITER(pbmp, port) {
  26961             break;
  26962         }
  26963     }
  26964 
  26965     if (SOC_PORT_VALID(unit, port) && BCM_PBMP_MEMBER(pbmp, port)) {
  26966         rv = _bcm_esw_port_dscp_map_get(unit, port, srccp, mapcp, prio);
  26967     } else {
  26968         rv = BCM_E_PORT;
  26969     }
  26970 
  26971     PORT_UNLOCK(unit);
  26972     return rv;
  26973 }
  26974 
  26975 #ifdef BCM_TRIDENT_SUPPORT
  26976 STATIC int 
  26977 _bcm_td_egr_l3_intf_dscp_map_update(int unit, uint32 dscp_map_id, uint32 new_dscp_map_id)
  26978 {
  26979     char *egr_intf_tbl_ptr = NULL;   /* EGR_L3_INTF dma table pointer.  */
  26980     int rv;
  26981     uint32 *egr_intf_entry_ptr;        /* EGR_L3_INTF entry pointer. */
  26982     int ifindex;
  26983     uint32 dscp_map_ptr;
  26984     int tbl_size;
  26985     int alloc_size;
  26986     
  26987     if (dscp_map_id == new_dscp_map_id) {
  26988         return BCM_E_NONE;
  26989     }
  26990 
  26991     /* Calculate table size. */
  26992     tbl_size =  soc_mem_index_count(unit, EGR_L3_INTFm);
  26993     if (!tbl_size) {
  26994         return (BCM_E_NOT_FOUND);
  26995     }
  26996     alloc_size = sizeof(egr_l3_intf_entry_t) * tbl_size;
  26997 
  26998     /* Allocate memory buffer. */
  26999     egr_intf_tbl_ptr = soc_cm_salloc(unit, alloc_size, "egr_l3_intf_tbl");
  27000     if (egr_intf_tbl_ptr == NULL) {
  27001         return (BCM_E_MEMORY);
  27002     }
  27003 
  27004     /* Reset allocated buffer. */
  27005     sal_memset(egr_intf_tbl_ptr, 0, alloc_size);
  27006 
  27007     /* Read table to the buffer. */
  27008     rv = soc_mem_read_range(unit, EGR_L3_INTFm, MEM_BLOCK_ANY,
  27009                             soc_mem_index_min(unit, EGR_L3_INTFm),
  27010                             soc_mem_index_max(unit, EGR_L3_INTFm), egr_intf_tbl_ptr);
  27011     if (BCM_FAILURE(rv)) {
  27012         goto cleanup;
  27013     }
  27014     for (ifindex = 0; ifindex < tbl_size; ifindex++) {
  27015         egr_intf_entry_ptr =
  27016         soc_mem_table_idx_to_pointer(unit, EGR_L3_INTFm,
  27017                                      uint32 *, egr_intf_tbl_ptr,
  27018                                      ifindex);
  27019         dscp_map_ptr = soc_mem_field32_get(unit, EGR_L3_INTFm,
  27020                                            egr_intf_entry_ptr, DSCP_MAPPING_PTRf);
  27021         if (dscp_map_ptr == dscp_map_id) {
  27022             
  27023             soc_mem_field32_set(unit, EGR_L3_INTFm,
  27024                                 egr_intf_entry_ptr, DSCP_MAPPING_PTRf, 
  27025                                 new_dscp_map_id);
  27026         }
  27027     }
  27028     rv = soc_mem_write_range(unit, EGR_L3_INTFm, MEM_BLOCK_ALL,
  27029                              soc_mem_index_min(unit, EGR_L3_INTFm),
  27030                              soc_mem_index_max(unit, EGR_L3_INTFm), 
  27031                              egr_intf_tbl_ptr);
  27032     if (SOC_FAILURE(rv)) {
  27033         goto cleanup;
  27034     }
  27035     
  27036     _bcm_tr2_qos_id_update(unit, dscp_map_id, new_dscp_map_id);
  27037 
  27038 cleanup:
  27039 
  27040     if (egr_intf_tbl_ptr) {
  27041         soc_cm_sfree(unit, egr_intf_tbl_ptr);
  27042     }
  27043     return rv;
  27044 
  27045 }
  27046 #endif
  27047 
  27048 /*
  27049  * Function:
  27050  *      _bcm_port_dscp_unmap_set
  27051  * Purpose:
  27052  *      Internal implementation for bcm_port_dscp_unmap_set
  27053  * Returns:
  27054  *      BCM_E_XXX
  27055  */
  27056 STATIC int
  27057 _bcm_port_dscp_unmap_set(int unit, bcm_port_t port, int internal_pri,
  27058                          bcm_color_t color, int pkt_dscp)
  27059 {
  27060     int index, port_shift = 6;
  27061     egr_dscp_table_entry_t  dscp_unmap;
  27062     egr_zone_4_qos_mapping_table_entry_t z4_qos_unmap;
  27063 #if defined(BCM_TRIDENT_SUPPORT)     
  27064     egr_dscp_table_entry_t egr_dscp_map_entries[64];
  27065     void *entries[1];
  27066     uint32 dscp_index = 0; 
  27067     uint32 new_dscp_index;
  27068     int ref_count;
  27069     void *entry;
  27070     int port_dscp_map_set;
  27071     int old_pkt_dscp;
  27072 #endif    
  27073     if (pkt_dscp < 0 || pkt_dscp > DSCP_CODE_POINT_MAX) {
  27074         return BCM_E_PARAM;
  27075     }
  27076     if ((internal_pri < 0) || (internal_pri > 15) ||
  27077         ((color != bcmColorGreen) && (color != bcmColorYellow) &&
  27078          (color != bcmColorRed))) {
  27079         return BCM_E_PARAM;
  27080     }
  27081 
  27082     /* EGR_DSCP_TABLE table is indexed with
  27083      * port[5:0] priority[3:0] CNG [1:0]
  27084      */
  27085 
  27086     index = (port << port_shift) | (internal_pri << 2) |
  27087          _BCM_COLOR_ENCODING(unit, color);
  27088 
  27089     if (SOC_IS_TRIDENT3X(unit)) {
  27090         /* This function is obselete - put in the right register for readability*/
  27091         sal_memset(&z4_qos_unmap, 0, sizeof(z4_qos_unmap));
  27092         soc_mem_field32_set(unit, EGR_ZONE_4_QOS_MAPPING_TABLEm, &z4_qos_unmap, QOSf, pkt_dscp);
  27093         SOC_IF_ERROR_RETURN
  27094         (WRITE_EGR_ZONE_4_QOS_MAPPING_TABLEm(unit, MEM_BLOCK_ALL, index, &z4_qos_unmap));
  27095 
  27096         soc_mem_field32_set(unit, EGR_ZONE_2_QOS_MAPPING_TABLEm, &z4_qos_unmap, QOSf, pkt_dscp);
  27097         SOC_IF_ERROR_RETURN
  27098         (WRITE_EGR_ZONE_2_QOS_MAPPING_TABLEm(unit, MEM_BLOCK_ALL, index, &z4_qos_unmap));
  27099     } else 
  27100 #ifdef BCM_TRIDENT_SUPPORT
  27101     if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, OPRI_OCFI_SELf)) {
  27102         dscp_index = port << port_shift;
  27103         index = (internal_pri << 2) | _BCM_COLOR_ENCODING(unit, color);
  27104 
  27105         sal_memset(egr_dscp_map_entries, 0, sizeof(egr_dscp_map_entries));
  27106         entries[0] = &egr_dscp_map_entries;
  27107 
  27108         entry = &egr_dscp_map_entries[index];
  27109         BCM_IF_ERROR_RETURN(
  27110             _bcm_egr_dscp_table_entry_ref_count_get(unit, dscp_index, &ref_count));
  27111         port_dscp_map_set = PORT(unit, port).port_dscp_map_set;
  27112         if (ref_count > 0) {
  27113             BCM_IF_ERROR_RETURN(
  27114                 _bcm_egr_dscp_table_entry_get(unit, dscp_index,
  27115                                               _BCM_QOS_MAP_CHUNK_EGR_DSCP, entries));
  27116             old_pkt_dscp = soc_mem_field32_get(unit, EGR_DSCP_TABLEm, entry, DSCPf);
  27117             if (pkt_dscp != old_pkt_dscp) {
  27118                 int i;
  27119                 int port_dscp_map_count = port_dscp_map_set;
  27120                 /* If this profile is only used by port */
  27121                 if ((ref_count == 1) && (port_dscp_map_set == 1)) {
  27122                     soc_mem_field32_set(unit, EGR_DSCP_TABLEm, entry, DSCPf, pkt_dscp);
  27123                     BCM_IF_ERROR_RETURN(
  27124                         _bcm_egr_dscp_table_entry_set(unit, entries, dscp_index));
  27125                     BCM_IF_ERROR_RETURN(
  27126                         _bcm_egr_dscp_table_entry_delete(unit, dscp_index));
  27127                 } else { /* If this profile is used not only by port */
  27128                     soc_mem_field32_set(unit, EGR_DSCP_TABLEm, entry, DSCPf, 
  27129                                         old_pkt_dscp);
  27130                     BCM_IF_ERROR_RETURN(
  27131                         _bcm_egr_dscp_table_entry_add(unit, entries, 
  27132                                                       _BCM_QOS_MAP_CHUNK_EGR_DSCP, 
  27133                                                       &new_dscp_index, 
  27134                                                       SOC_PROFILE_MEM_F_NO_SHARE));
  27135                     for (i = 0; i < (ref_count - port_dscp_map_count - 1); i++) {
  27136                         BCM_IF_ERROR_RETURN(
  27137                             _bcm_egr_dscp_table_entry_reference(unit, new_dscp_index, 
  27138                                                                 _BCM_QOS_MAP_CHUNK_EGR_DSCP));
  27139                     }
  27140                     BCM_IF_ERROR_RETURN(
  27141                         _bcm_td_egr_l3_intf_dscp_map_update(unit, port, 
  27142                                                             (new_dscp_index >> port_shift)));
  27143                     soc_mem_field32_set(unit, EGR_DSCP_TABLEm, entry, DSCPf, pkt_dscp);
  27144                     BCM_IF_ERROR_RETURN(
  27145                         _bcm_egr_dscp_table_entry_set(unit, entries, dscp_index));                  
  27146                     for (i = 0; i < ref_count; i++) {
  27147                         BCM_IF_ERROR_RETURN(
  27148                             _bcm_egr_dscp_table_entry_delete(unit, dscp_index));
  27149                     }
  27150                 }
  27151             }
  27152         } else {
  27153             soc_mem_field32_set(unit, EGR_DSCP_TABLEm, entry, DSCPf, pkt_dscp);
  27154             _bcm_common_profile_mem_ref_cnt_update(unit, EGR_DSCP_TABLEm, port, 1);
  27155             BCM_IF_ERROR_RETURN(
  27156                 _bcm_egr_dscp_table_entry_set(unit, entries, dscp_index));
  27157             BCM_IF_ERROR_RETURN(
  27158                 _bcm_egr_dscp_table_entry_delete(unit, dscp_index));            
  27159         }    
  27160         PORT(unit, port).port_dscp_map_set = 1;
  27161         
  27162     } else 
  27163 #endif
  27164     {
  27165         sal_memset(&dscp_unmap, 0, sizeof(dscp_unmap));
  27166         soc_mem_field32_set(unit, EGR_DSCP_TABLEm, &dscp_unmap, DSCPf, pkt_dscp);
  27167         SOC_IF_ERROR_RETURN
  27168             (WRITE_EGR_DSCP_TABLEm(unit, MEM_BLOCK_ALL, index, &dscp_unmap));
  27169     }
  27170     return BCM_E_NONE;
  27171 }
  27172 
  27173 /*
  27174  * Function:
  27175  *      bcm_port_dscp_unmap_set
  27176  * Purpose:
  27177  *      Define a mapping for diffserv code points
  27178  *      The mapping enable/disable is controlled by a seperate API
  27179  *      bcm_port_dscp_map_enable_set/get
  27180  *      Also Enable/Disable control for DSCP mapping for tunnels
  27181  *      are available in the respective tunnel create APIs.
  27182  * Parameters:
  27183  *      unit - switch device
  27184  *      port - switch port      or -1 to setup global mapping table.
  27185  *      internal_pri - internal priority
  27186  *      color - Red/Yellow/Green
  27187  *      pkt_dscp - DSCP marking on outgoing packet
  27188  * Returns:
  27189  *      BCM_E_XXX
  27190  */
  27191 int
  27192 bcm_esw_port_dscp_unmap_set(int unit, bcm_port_t port, int internal_pri,
  27193                             bcm_color_t color, int pkt_dscp)
  27194 {
  27195     int rv;
  27196     bcm_port_config_t port_conf;
  27197     bcm_pbmp_t pbmp;
  27198 
  27199     /* Make sure port module is initialized. */
  27200     PORT_INIT(unit);
  27201     if (!soc_feature(unit, soc_feature_dscp) ||
  27202         !soc_feature(unit, soc_feature_egr_dscp_map_per_port)) {
  27203         return BCM_E_UNAVAIL;
  27204     }
  27205 
  27206     if (port != -1) {
  27207         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  27208         if (IS_HG_PORT(unit, port) || IS_ST_PORT(unit, port)) {
  27209             return BCM_E_PORT;
  27210         }
  27211     }
  27212 
  27213     PORT_LOCK(unit);
  27214 
  27215     /* Get device port configuration. */
  27216     rv = bcm_esw_port_config_get(unit, &port_conf);
  27217     if (BCM_FAILURE(rv)) {
  27218         PORT_UNLOCK(unit);
  27219         return rv;
  27220     }
  27221     BCM_PBMP_ASSIGN(pbmp, port_conf.e);
  27222     BCM_PBMP_OR(pbmp, port_conf.cpu);
  27223 #ifdef BCM_KATANA2_SUPPORT
  27224     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  27225         rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp);
  27226         if (BCM_FAILURE(rv)) {
  27227             PORT_UNLOCK(unit);
  27228             return (rv);
  27229         }
  27230     }
  27231     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  27232         soc_feature(unit, soc_feature_subtag_coe)) {
  27233         _bcm_kt2_subport_pbmp_update(unit, &pbmp);
  27234     }
  27235 #endif
  27236 
  27237     if (port == -1) {
  27238         PBMP_ITER(pbmp, port) {
  27239             rv = _bcm_port_dscp_unmap_set(unit, port, internal_pri, color,
  27240                                           pkt_dscp);
  27241             if (BCM_FAILURE(rv)) {
  27242                 PORT_UNLOCK(unit);
  27243                 return rv;
  27244             }
  27245         }
  27246     } else if (SOC_PORT_VALID(unit, port) && BCM_PBMP_MEMBER(pbmp, port)) {
  27247         rv = _bcm_port_dscp_unmap_set(unit, port, internal_pri, color,
  27248                                       pkt_dscp);
  27249     } else {
  27250         rv = BCM_E_PORT;
  27251     }
  27252     PORT_UNLOCK(unit);
  27253 
  27254     return rv;
  27255 }
  27256 
  27257 /*
  27258  * Function:
  27259  *      _bcm_port_dscp_unmap_get
  27260  * Purpose:
  27261  *      Internal implementation for bcm_port_dscp_unmap_get
  27262  * Returns:
  27263  *      BCM_E_XXX
  27264  */
  27265 STATIC int
  27266 _bcm_port_dscp_unmap_get(int unit, bcm_port_t port, int internal_pri,
  27267                          bcm_color_t color, int *pkt_dscp)
  27268 {
  27269     int index, port_shift = 6;
  27270     egr_dscp_table_entry_t  dscp_unmap;
  27271 #if defined(BCM_TRIDENT_SUPPORT)   
  27272     egr_dscp_table_entry_t egr_dscp_map_entries[64];
  27273     void *entries[1];
  27274     uint32 dscp_index = 0; 
  27275     void *entry;
  27276 #endif
  27277     if ((internal_pri < 0) || (internal_pri > 15) ||
  27278         ((color != bcmColorGreen) && (color != bcmColorYellow) &&
  27279          (color != bcmColorRed))) {
  27280         return BCM_E_PARAM;
  27281     }
  27282 
  27283     /* EGR_DSCP_TABLE table is indexed with
  27284      * port[5:0] priority[3:0] CNG [1:0]
  27285      */
  27286     index = (port << port_shift) | (internal_pri << 2) |
  27287                  _BCM_COLOR_ENCODING(unit, color);
  27288 
  27289     if (SOC_IS_TRIDENT3X(unit)) {
  27290         SOC_IF_ERROR_RETURN
  27291         (READ_EGR_ZONE_4_QOS_MAPPING_TABLEm(unit, MEM_BLOCK_ANY, index, &dscp_unmap));
  27292         *pkt_dscp = soc_mem_field32_get(unit, EGR_ZONE_4_QOS_MAPPING_TABLEm,
  27293                                         &dscp_unmap, QOSf);
  27294 
  27295         SOC_IF_ERROR_RETURN
  27296         (READ_EGR_ZONE_2_QOS_MAPPING_TABLEm(unit, MEM_BLOCK_ANY, index, &dscp_unmap));
  27297         *pkt_dscp = soc_mem_field32_get(unit, EGR_ZONE_2_QOS_MAPPING_TABLEm,
  27298                                         &dscp_unmap, QOSf);
  27299     } else 
  27300 #if defined(BCM_TRIDENT_SUPPORT)
  27301     if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, OPRI_OCFI_SELf)) {
  27302         dscp_index = port << port_shift;
  27303         index = (internal_pri << 2) | _BCM_COLOR_ENCODING(unit, color);
  27304 
  27305         sal_memset(egr_dscp_map_entries, 0, sizeof(egr_dscp_map_entries));
  27306         entries[0] = &egr_dscp_map_entries;
  27307 
  27308         BCM_IF_ERROR_RETURN(
  27309             _bcm_egr_dscp_table_entry_get(unit, dscp_index,
  27310                                           _BCM_QOS_MAP_CHUNK_EGR_DSCP, entries));
  27311         entry = &egr_dscp_map_entries[index];
  27312         *pkt_dscp = soc_mem_field32_get(unit, EGR_DSCP_TABLEm,
  27313                                         entry, DSCPf);
  27314     } else 
  27315 #endif
  27316     {
  27317         SOC_IF_ERROR_RETURN
  27318             (READ_EGR_DSCP_TABLEm(unit, MEM_BLOCK_ANY, index, &dscp_unmap));
  27319         *pkt_dscp = soc_mem_field32_get(unit, EGR_DSCP_TABLEm,
  27320                                         &dscp_unmap, DSCPf);
  27321     }
  27322     return BCM_E_NONE;
  27323 }
  27324 
  27325 /*
  27326  * Function:
  27327  *      bcm_port_dscp_unmap_get
  27328  * Purpose:
  27329  *      Retrieve a mapping for diffserv code points
  27330  *      The mapping enable/disable is controlled by a seperate API
  27331  *      bcm_port_dscp_map_enable_set/get
  27332  *      Also Enable/Disable control for DSCP mapping for tunnels
  27333  *      are available in the respective tunnel create APIs.
  27334  * Parameters:
  27335  *      unit - switch device
  27336  *      port - switch port.
  27337  *      internal_pri - internal priority
  27338  *      color - Red/Yellow/Green
  27339  *      pkt_dscp - DSCP marking on outgoing packet
  27340  * Returns:
  27341  *      BCM_E_XXX
  27342  */
  27343 int
  27344 bcm_esw_port_dscp_unmap_get(int unit, bcm_port_t port, int internal_pri,
  27345                             bcm_color_t color, int *pkt_dscp)
  27346 {
  27347     int rv;
  27348     bcm_port_config_t port_conf;
  27349     bcm_pbmp_t pbmp;
  27350 
  27351     /* Make sure port module is initialized. */
  27352     PORT_INIT(unit);
  27353     if (!soc_feature(unit, soc_feature_dscp) ||
  27354         !soc_feature(unit, soc_feature_egr_dscp_map_per_port)) {
  27355         return BCM_E_UNAVAIL;
  27356     }
  27357 
  27358     if (port != -1) {
  27359         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  27360         if (IS_HG_PORT(unit, port) || IS_ST_PORT(unit, port)) {
  27361             return BCM_E_PORT;
  27362         }
  27363     }
  27364 
  27365     PORT_LOCK(unit);
  27366 
  27367     /* Get device port configuration. */
  27368     rv = bcm_esw_port_config_get(unit, &port_conf);
  27369     if (BCM_FAILURE(rv)) {
  27370         PORT_UNLOCK(unit);
  27371         return rv;
  27372     }
  27373     BCM_PBMP_ASSIGN(pbmp, port_conf.e);
  27374     BCM_PBMP_OR(pbmp, port_conf.cpu);
  27375 #ifdef BCM_KATANA2_SUPPORT
  27376     if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) {
  27377         rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp);
  27378         if (BCM_FAILURE(rv)) {
  27379             PORT_UNLOCK(unit);
  27380             return (rv);
  27381         }
  27382     }
  27383     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  27384         soc_feature(unit, soc_feature_subtag_coe)) {
  27385         _bcm_kt2_subport_pbmp_update(unit, &pbmp);
  27386     }
  27387 #endif
  27388 
  27389     if (port == -1) {
  27390         PBMP_ITER(pbmp, port) {
  27391             break;
  27392         }
  27393     }
  27394 
  27395     if (SOC_PORT_VALID(unit, port) && BCM_PBMP_MEMBER(pbmp, port)) {
  27396         rv = _bcm_port_dscp_unmap_get(unit, port, internal_pri, color,
  27397                                       pkt_dscp);
  27398     } else {
  27399         rv = BCM_E_PORT;
  27400     }
  27401 
  27402     PORT_UNLOCK(unit);
  27403     return rv;
  27404 }
  27405 
  27406 #undef DSCP_CODE_POINT_MAX
  27407 #undef DSCP_CODE_POINT_CNT
  27408 
  27409 STATIC int
  27410 _bcm_esw_port_modid_egress_resolve(int unit, _bcm_port_egr_dest_t *egr_dst)
  27411 {
  27412     int             port_adjst = 0, mod_adjust = 0;
  27413     int             isLocal = 0;
  27414     bcm_module_t    my_mod, modid;
  27415 
  27416     if (BCM_GPORT_IS_SET(egr_dst->in_port)) {
  27417         bcm_trunk_t     tid;
  27418         int             id;
  27419         bcm_port_t      port;
  27420 
  27421         BCM_IF_ERROR_RETURN(
  27422             _bcm_esw_gport_resolve(unit, egr_dst->in_port, &modid, &port,
  27423                                    &tid, &id));
  27424         if ((-1 != id) || (-1 != tid)) {
  27425             return BCM_E_PORT;
  27426         }
  27427         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_mod));
  27428         BCM_IF_ERROR_RETURN(
  27429             _bcm_esw_modid_is_local(unit, modid, &isLocal));
  27430 
  27431         if ((TRUE == isLocal) && (modid != my_mod)){
  27432             port_adjst = 32;
  27433             mod_adjust = 1;
  27434         }
  27435         egr_dst->out_min_port = egr_dst->out_max_port = port + port_adjst;
  27436         egr_dst->out_min_modid = egr_dst->out_max_modid = modid - mod_adjust;
  27437     } else {
  27438         if (egr_dst->in_modid < 0) {
  27439             egr_dst->out_min_modid = 0;
  27440             egr_dst->out_max_modid = SOC_MODID_MAX(unit);
  27441         } else if (!SOC_MODID_ADDRESSABLE(unit, egr_dst->in_modid)) {
  27442             return BCM_E_PARAM;
  27443         } else {
  27444             egr_dst->out_min_modid = egr_dst->out_max_modid = egr_dst->in_modid;
  27445         }
  27446 
  27447         if (egr_dst->in_port < 0) {
  27448             egr_dst->out_min_port = 0;
  27449             egr_dst->out_max_port = SOC_PORT_MAX(unit, all);
  27450         } else if (!SOC_PORT_ADDRESSABLE(unit, egr_dst->in_port)) {
  27451             return BCM_E_PORT;
  27452         } else {
  27453             egr_dst->out_min_port = egr_dst->out_max_port = egr_dst->in_port;
  27454         }
  27455     }
  27456 
  27457     return BCM_E_NONE;
  27458 }
  27459 
  27460 
  27461 /*
  27462  * Function:
  27463  *      bcm_port_egress_set
  27464  * Description:
  27465  *      Set switching only to indicated ports from given (modid, port).
  27466  * Parameters:
  27467  *      unit - StrataSwitch PCI device unit number (driver internal).
  27468  *      port  - ingress port number.
  27469  *      modid - source module ID index (in HiGig mod header).
  27470  *      pbmp - bitmap of ports to allow egress.
  27471  * Returns:
  27472  *      BCM_E_xxxx
  27473  * Note:
  27474  *      if port < 0, means all/any port
  27475  *      if modid < 0, means all/any modid
  27476  */
  27477 int
  27478 bcm_esw_port_egress_set(int unit, bcm_port_t port, int modid, bcm_pbmp_t pbmp)
  27479 {
  27480     egr_mask_entry_t        em_entry;
  27481     int                     em_index;
  27482     bcm_module_t            cur_mod, hw_mod;
  27483     bcm_pbmp_t              em_pbmp;
  27484     bcm_port_t              cur_port, hw_port;
  27485     int                     rv = BCM_E_NONE;
  27486     _bcm_port_egr_dest_t    egr_dst;
  27487     int                     mod_is_local = 0;
  27488     int                     mod_port_map_done = 0;
  27489 
  27490     /* Make sure port module is initialized. */
  27491     PORT_INIT(unit);
  27492 
  27493     if(bcm_common_oamp_port_enable_get(unit, port)) {
  27494         LOG_ERROR(BSL_LS_BCM_PORT,
  27495                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  27496                    port));
  27497         return BCM_E_PARAM;
  27498     }
  27499 
  27500 #ifdef BCM_TRIDENT_SUPPORT
  27501     if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) {
  27502         return bcm_td_port_egress_set(unit, port, modid, pbmp);
  27503     }
  27504 #endif /* BCM_TRIDENT_SUPPORT */
  27505 
  27506 #ifdef BCM_HURRICANE3_SUPPORT
  27507     if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  27508         return bcm_hr3_port_egress_set(unit, port, modid, pbmp);
  27509     }
  27510 #endif /* BCM_HURRICANE3_SUPPORT */
  27511 
  27512     if (!SOC_IS_XGS_SWITCH(unit)) {
  27513         if (BCM_PBMP_EQ(pbmp, PBMP_ALL(unit))) {
  27514             return BCM_E_NONE;
  27515         } else {
  27516             return BCM_E_UNAVAIL;
  27517         }
  27518     }
  27519 
  27520     sal_memset(&em_entry, 0, sizeof(egr_mask_entry_t));
  27521 
  27522     BCM_PBMP_NEGATE(em_pbmp, pbmp);
  27523     BCM_PBMP_AND(em_pbmp, PBMP_ALL(unit));
  27524     BCM_PBMP_REMOVE(em_pbmp, PBMP_LB(unit));
  27525     soc_mem_pbmp_field_set(unit, EGR_MASKm, &em_entry, EGRESS_MASKf,
  27526                            &em_pbmp);
  27527 
  27528     egr_dst.in_modid = modid;
  27529     egr_dst.in_port = port;
  27530     BCM_IF_ERROR_RETURN(_bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  27531     /* If the given port is a gport, _bcm_esw_port_modid_egress_resolve had
  27532      * already performed module and port mapping for devices with
  27533      * multiple module IDs.
  27534      */
  27535     mod_port_map_done = BCM_GPORT_IS_SET(port) ? 1 : 0;
  27536 
  27537     soc_mem_lock(unit, EGR_MASKm);
  27538     for (cur_mod = egr_dst.out_min_modid; cur_mod <= egr_dst.out_max_modid; cur_mod++) {
  27539         rv = _bcm_esw_modid_is_local(unit, cur_mod, &mod_is_local);
  27540         if (BCM_FAILURE(rv)) {
  27541             break;
  27542         }
  27543         for (cur_port = egr_dst.out_min_port; cur_port <= egr_dst.out_max_port; cur_port++) {
  27544             if (mod_is_local && (NUM_MODID(unit) > 1) && !mod_port_map_done) {
  27545                 if (cur_port <= SOC_MODPORT_MAX(unit)) {
  27546                     rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET,
  27547                             cur_mod, cur_port, &hw_mod, &hw_port);
  27548                     if (BCM_FAILURE(rv)) {
  27549                         break;
  27550                     }
  27551                 } else {
  27552                     break;
  27553                 }
  27554             } else {
  27555                 hw_mod = cur_mod;
  27556                 hw_port = cur_port;
  27557             }
  27558 
  27559             em_index = (hw_mod & SOC_MODID_MAX(unit)) *
  27560                     (SOC_PORT_ADDR_MAX(unit) + 1) |
  27561                     (hw_port & SOC_PORT_ADDR_MAX(unit));
  27562             rv = soc_mem_write(unit, EGR_MASKm, MEM_BLOCK_ALL,
  27563                     em_index, &em_entry);
  27564             if (!BCM_SUCCESS(rv)) {
  27565                 break;
  27566             }
  27567         }
  27568         if (!BCM_SUCCESS(rv)) {
  27569             break;
  27570         }
  27571     }
  27572     soc_mem_unlock(unit, EGR_MASKm);
  27573 
  27574     return rv;
  27575 }
  27576 
  27577 /*
  27578  * Function:
  27579  *      bcm_port_egress_get
  27580  * Description:
  27581  *      Retrieve bitmap of ports for which switching is enabled
  27582  *      for (modid, port).
  27583  * Parameters:
  27584  *      unit - StrataSwitch PCI device unit number (driver internal).
  27585  *      port  - ingress port number.
  27586  *      modid - source module ID index (in HiGig mod header).
  27587  *      pbmp - (OUT) bitmap of ports where egress allowed.
  27588  * Returns:
  27589  *      BCM_E_xxxx
  27590  */
  27591 int
  27592 bcm_esw_port_egress_get(int unit, bcm_port_t port, int modid, bcm_pbmp_t *pbmp)
  27593 {
  27594     egr_mask_entry_t    em_entry;
  27595     int                 em_index;
  27596     bcm_pbmp_t          em_pbmp, temp_pbmp;
  27597     _bcm_port_egr_dest_t    egr_dst;
  27598     int                 mod_port_map_done = 0;
  27599     bcm_module_t        hw_mod;
  27600     bcm_port_t          hw_port;
  27601 
  27602     /* Make sure port module is initialized. */
  27603     PORT_INIT(unit);
  27604 
  27605     if(bcm_common_oamp_port_enable_get(unit, port)) {
  27606         LOG_ERROR(BSL_LS_BCM_PORT,
  27607                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  27608                    port));
  27609         return BCM_E_PARAM;
  27610     }
  27611 
  27612 #ifdef BCM_TRIDENT_SUPPORT
  27613     if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) {
  27614         return bcm_td_port_egress_get(unit, port, modid, pbmp);
  27615     }
  27616 #endif /* BCM_TRIDENT_SUPPORT */
  27617 
  27618 #ifdef BCM_HURRICANE3_SUPPORT
  27619     if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  27620         return bcm_hr3_port_egress_get(unit, port, modid, pbmp);
  27621     }
  27622 #endif /* BCM_HURRICANE3_SUPPORT */
  27623 
  27624     if (!SOC_IS_XGS_SWITCH(unit)) {
  27625         BCM_PBMP_ASSIGN(*pbmp, PBMP_ALL(unit));
  27626         return BCM_E_NONE;
  27627     }
  27628 
  27629     if ((modid < 0) || (port < 0) ){
  27630             return BCM_E_PARAM;
  27631     }
  27632 
  27633     egr_dst.in_modid = modid;
  27634     egr_dst.in_port = port;
  27635     BCM_IF_ERROR_RETURN(_bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  27636     /* If the given port is a gport, _bcm_esw_port_modid_egress_resolve had
  27637      * already performed module and port mapping for devices with
  27638      * multiple module IDs.
  27639      */
  27640     mod_port_map_done = BCM_GPORT_IS_SET(port) ? 1 : 0;
  27641 
  27642     if (!mod_port_map_done) {
  27643         PORT_DUALMODID_VALID(unit, egr_dst.out_min_port);
  27644         BCM_IF_ERROR_RETURN(_bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET,
  27645                     egr_dst.out_min_modid, egr_dst.out_min_port,
  27646                     &hw_mod, &hw_port));
  27647     } else {
  27648         hw_mod = egr_dst.out_min_modid;
  27649         hw_port = egr_dst.out_min_port;
  27650     }
  27651     em_index = (hw_mod & SOC_MODID_MAX(unit)) *
  27652         (SOC_PORT_ADDR_MAX(unit) + 1) | (hw_port & SOC_PORT_ADDR_MAX(unit));
  27653 
  27654     BCM_IF_ERROR_RETURN
  27655         (READ_EGR_MASKm(unit, MEM_BLOCK_ALL, em_index, &em_entry));
  27656 
  27657     BCM_PBMP_CLEAR(em_pbmp);
  27658     soc_mem_pbmp_field_get(unit, EGR_MASKm, &em_entry, EGRESS_MASKf,
  27659                            &em_pbmp);
  27660     BCM_PBMP_NEGATE(temp_pbmp, em_pbmp);
  27661     BCM_PBMP_AND(temp_pbmp, PBMP_ALL(unit));
  27662     BCM_PBMP_REMOVE(temp_pbmp, PBMP_LB(unit));
  27663     BCM_PBMP_ASSIGN(*pbmp, temp_pbmp);
  27664 
  27665     return BCM_E_NONE;
  27666 }
  27667 
  27668 #ifdef BCM_TRIUMPH2_SUPPORT
  27669 STATIC int
  27670 _bcm_port_src_mod_egress_profile_add(int unit, bcm_port_t port,
  27671                                      int min_mod, int max_mod, pbmp_t pbmp)
  27672 {
  27673     int i, region, modid_cnt, new_region, empty_profile, alloc_size;
  27674     int rv = BCM_E_NONE;
  27675     uint32 val, add_index;
  27676     src_modid_egress_entry_t *srcmodegr_p, *sme_buf;
  27677     pbmp_t test_pbmp;
  27678     void   *entries[1];     /* for profile memories      */
  27679 
  27680     modid_cnt = SOC_MODID_MAX(unit) + 1;
  27681     region = PORT_SRC_MOD_EGR_PROF_PTR(unit, port);
  27682     empty_profile = TRUE;
  27683     new_region = -1;
  27684 
  27685     alloc_size = modid_cnt * sizeof(*srcmodegr_p);
  27686     sme_buf = sal_alloc(alloc_size, "SRC_MODID_EGRESS update buffer");
  27687     if (NULL == sme_buf) {
  27688         return BCM_E_MEMORY;
  27689     }
  27690     sal_memset(sme_buf, 0, alloc_size);
  27691     entries[0] = sme_buf;
  27692 
  27693     if (0 <= region) {
  27694         rv = soc_profile_mem_get(unit, PORT_SRC_MOD_EGR_PROFILE(unit),
  27695                                  region * modid_cnt, modid_cnt, entries);
  27696     } /* Else cleared by memset above.  Null entry is all 0's */
  27697 
  27698     if (BCM_SUCCESS(rv)) {
  27699         for (i = min_mod; i <= max_mod; i++) {
  27700             /* Profile memory is an array of entries, not a DMA buffer */
  27701             srcmodegr_p = sme_buf + i; /* Both same pointer type */
  27702             soc_mem_pbmp_field_set(unit, SRC_MODID_EGRESSm, srcmodegr_p,
  27703                                    PORT_BLOCK_MASK_BITMAPf, &pbmp);
  27704         }
  27705 
  27706         if (BCM_PBMP_IS_NULL(pbmp)) {
  27707             /* Check for empty bitmap */
  27708             for (i = 0; i < modid_cnt; i++) {
  27709                 srcmodegr_p = sme_buf + i; /* Both same pointer type */
  27710                 soc_mem_pbmp_field_get(unit, SRC_MODID_EGRESSm, srcmodegr_p,
  27711                                        PORT_BLOCK_MASK_BITMAPf, &test_pbmp);
  27712                 if (BCM_PBMP_NOT_NULL(test_pbmp)) {
  27713                     empty_profile = FALSE;
  27714                     break;
  27715                 }
  27716             }
  27717         } else {
  27718             empty_profile = FALSE;
  27719         }
  27720 
  27721         if (!empty_profile) {
  27722             rv = soc_profile_mem_add(unit, PORT_SRC_MOD_EGR_PROFILE(unit),
  27723                                      entries, modid_cnt, &add_index);
  27724             if (BCM_SUCCESS(rv)) {
  27725                 new_region = add_index / modid_cnt;
  27726             }
  27727         }
  27728     }
  27729 
  27730     sal_free(sme_buf);
  27731     BCM_IF_ERROR_RETURN(rv);
  27732 
  27733     BCM_IF_ERROR_RETURN(READ_SRC_MODID_EGRESS_SELr(unit, port, &val));
  27734     if (empty_profile) {
  27735         soc_reg_field_set(unit, SRC_MODID_EGRESS_SELr, &val, ENABLEf, 0);
  27736         soc_reg_field_set(unit, SRC_MODID_EGRESS_SELr, &val,
  27737                           SRCMOD_INDEXf, 0);
  27738     } else {
  27739         soc_reg_field_set(unit, SRC_MODID_EGRESS_SELr, &val, ENABLEf, 1);
  27740         soc_reg_field_set(unit, SRC_MODID_EGRESS_SELr, &val,
  27741                           SRCMOD_INDEXf, new_region);
  27742     }
  27743     BCM_IF_ERROR_RETURN(WRITE_SRC_MODID_EGRESS_SELr(unit, port, val));
  27744 
  27745     if (-1 != region) {
  27746         BCM_IF_ERROR_RETURN
  27747             (soc_profile_mem_delete(unit, PORT_SRC_MOD_EGR_PROFILE(unit),
  27748                                     region * modid_cnt));
  27749     }
  27750 
  27751     PORT_SRC_MOD_EGR_PROF_PTR(unit, port) = new_region;
  27752     return BCM_E_NONE;
  27753 }
  27754 #endif
  27755 
  27756 /*
  27757  * Function:
  27758  *      bcm_port_modid_egress_set
  27759  * Description:
  27760  *      Set port bitmap of egress ports on which the incoming packets
  27761  *      will be forwarded.
  27762  * Parameters:
  27763  *      unit - StrataSwitch PCI device unit number (driver internal).
  27764  *      port  - ingress port number.
  27765  *      modid - source module ID index (in HiGig mod header).
  27766  *      pbmp - bitmap of ports to allow egress.
  27767  * Returns:
  27768  *      BCM_E_xxxx
  27769  * Note:
  27770  *      if port < 0, means all/any port
  27771  *      if modid < 0, means all/any modid
  27772  */
  27773 int
  27774 bcm_esw_port_modid_egress_set(int unit, bcm_port_t port,
  27775                               bcm_module_t modid, bcm_pbmp_t pbmp)
  27776 {
  27777 #if defined(BCM_HERCULES15_SUPPORT) || defined(BCM_FIREBOLT_SUPPORT)
  27778     int rv=BCM_E_UNAVAIL;
  27779 
  27780     /* Make sure port module is initialized. */
  27781     PORT_INIT(unit);
  27782 
  27783 #ifdef  BCM_HERCULES15_SUPPORT
  27784     if (SOC_IS_HERCULES15(unit)) {
  27785         mem_ing_srcmodblk_entry_t srcmod;
  27786         uint32 smf;
  27787         bcm_module_t mod_idx, min_mod, max_mod;
  27788         bcm_pbmp_t mod_pbmp;
  27789         int bk=-1, blk;
  27790 
  27791         if (port >= 0) {
  27792             if (!SOC_PORT_VALID(unit, port) || !IS_HG_PORT(unit, port)) {
  27793                 return BCM_E_PORT;
  27794             }
  27795             bk = SOC_PORT_BLOCK(unit, port);
  27796         }
  27797 
  27798         if (modid < 0) {
  27799             min_mod = soc_mem_index_min(unit, MEM_ING_SRCMODBLKm);
  27800             max_mod = soc_mem_index_max(unit, MEM_ING_SRCMODBLKm);
  27801         } else if (modid > soc_mem_index_max(unit, MEM_ING_SRCMODBLKm)) {
  27802             return BCM_E_PARAM;
  27803         } else {
  27804             min_mod = max_mod = modid;
  27805         }
  27806 
  27807         BCM_PBMP_ASSIGN(mod_pbmp, pbmp);
  27808         BCM_PBMP_AND(mod_pbmp, PBMP_ALL(unit));
  27809         if (BCM_PBMP_NEQ(pbmp, mod_pbmp)) {
  27810             return BCM_E_PARAM;
  27811         }
  27812 
  27813         soc_mem_lock(unit, MEM_ING_SRCMODBLKm);
  27814         SOC_MEM_BLOCK_ITER(unit, MEM_ING_SRCMODBLKm, blk) {
  27815             if ((port >= 0) && (bk !=blk)) {
  27816                 continue;
  27817             }
  27818             for (mod_idx = min_mod; mod_idx <= max_mod; mod_idx++) {
  27819                  sal_memset(&srcmod, 0, sizeof(srcmod));
  27820                  rv = READ_MEM_ING_SRCMODBLKm(unit, blk, mod_idx, &srcmod);
  27821                  if (rv >= 0) {
  27822                      SOC_PBMP_WORD_SET(mod_pbmp, 0,
  27823                          soc_MEM_ING_SRCMODBLKm_field32_get(unit, &srcmod, BITMAPf));
  27824                      if (BCM_PBMP_NEQ(pbmp, mod_pbmp)) {
  27825                          smf = SOC_PBMP_WORD_GET(pbmp, 0);
  27826                          soc_MEM_ING_SRCMODBLKm_field_set(unit, &srcmod, BITMAPf, &smf);
  27827                          rv = WRITE_MEM_ING_SRCMODBLKm(unit, blk, mod_idx, &srcmod);
  27828                      }
  27829                  }
  27830             }
  27831         }
  27832         soc_mem_unlock(unit, MEM_ING_SRCMODBLKm);
  27833     }
  27834 #endif /* BCM_HERCULES15_SUPPORT */
  27835 
  27836 #ifdef BCM_TRIUMPH2_SUPPORT
  27837     if (soc_feature(unit, soc_feature_src_modid_blk_profile)) {
  27838         src_modid_ingress_block_entry_t srcmoding;
  27839         _bcm_port_egr_dest_t egr_dst;
  27840         int all_st_ports;
  27841         int i;
  27842         bcm_port_t p;
  27843         pbmp_t mod_pbmp, all_pbmp;
  27844 
  27845         if ((port != -1) && (!SOC_PORT_VALID(unit, port))) {
  27846             return BCM_E_PORT;
  27847         }
  27848         egr_dst.in_port = port;
  27849         egr_dst.in_modid = modid;
  27850         BCM_IF_ERROR_RETURN(
  27851             _bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  27852 
  27853         if (egr_dst.out_min_port == egr_dst.out_max_port) {
  27854             all_st_ports = 0;
  27855         } else {
  27856             all_st_ports = 1;
  27857         }
  27858 
  27859         SOC_PBMP_CLEAR(all_pbmp);
  27860         SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  27861 
  27862 #ifdef BCM_KATANA2_SUPPORT
  27863         if (soc_feature(unit, soc_feature_linkphy_coe) ||
  27864             soc_feature(unit, soc_feature_subtag_coe)) {
  27865             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  27866         }
  27867 #endif
  27868         /* First program the ingress blocking */
  27869         soc_mem_lock(unit, SRC_MODID_INGRESS_BLOCKm);
  27870         for (i = egr_dst.out_min_modid; i <= egr_dst.out_max_modid; i++) {
  27871             rv = READ_SRC_MODID_INGRESS_BLOCKm(unit, MEM_BLOCK_ANY, i,
  27872                                                &srcmoding);
  27873             if (BCM_FAILURE(rv)) {
  27874                 soc_mem_unlock(unit, SRC_MODID_INGRESS_BLOCKm);
  27875                 return rv;
  27876             }
  27877             if (!all_st_ports) {
  27878                 soc_mem_pbmp_field_get(unit, SRC_MODID_INGRESS_BLOCKm,
  27879                                        &srcmoding, PORT_BITMAPf, &mod_pbmp);
  27880                 BCM_PBMP_PORT_REMOVE(mod_pbmp, egr_dst.out_min_port);
  27881             } else {
  27882                 BCM_PBMP_ASSIGN(mod_pbmp, all_pbmp);
  27883                 BCM_PBMP_OR(mod_pbmp, PBMP_LB(unit));
  27884                 PBMP_ST_ITER(unit, p) {
  27885                     BCM_PBMP_PORT_REMOVE(mod_pbmp, p);
  27886                 }
  27887             }
  27888             soc_mem_pbmp_field_set(unit, SRC_MODID_INGRESS_BLOCKm,
  27889                                    &srcmoding, PORT_BITMAPf, &mod_pbmp);
  27890             rv = WRITE_SRC_MODID_INGRESS_BLOCKm(unit, MEM_BLOCK_ALL, i,
  27891                                                 &srcmoding);
  27892             if (BCM_FAILURE(rv)) {
  27893                 soc_mem_unlock(unit, SRC_MODID_INGRESS_BLOCKm);
  27894                 return rv;
  27895             }
  27896         }
  27897         soc_mem_unlock(unit, SRC_MODID_INGRESS_BLOCKm);
  27898 
  27899         /* Deal with the egress blocking - use one of 8 profiles */
  27900         BCM_PBMP_ASSIGN(mod_pbmp, pbmp);
  27901         BCM_PBMP_AND(mod_pbmp, all_pbmp);
  27902         BCM_PBMP_REMOVE(mod_pbmp, PBMP_LB(unit));
  27903         if (BCM_PBMP_NEQ(pbmp, mod_pbmp)) {
  27904             return BCM_E_PARAM;
  27905         }
  27906 
  27907         BCM_PBMP_NEGATE(mod_pbmp, pbmp);
  27908         BCM_PBMP_AND(mod_pbmp, all_pbmp);
  27909         BCM_PBMP_REMOVE(mod_pbmp, PBMP_LB(unit));
  27910 
  27911         soc_mem_lock(unit, SRC_MODID_EGRESSm);
  27912         if (!all_st_ports) {
  27913             /* Deal with a single stack port and its profile */
  27914             /* coverity[overrun-call : FALSE] */
  27915             rv = _bcm_port_src_mod_egress_profile_add(unit,
  27916                                                       egr_dst.out_min_port,
  27917                                                       egr_dst.out_min_modid,
  27918                                                       egr_dst.out_max_modid,
  27919                                                       mod_pbmp);
  27920             if (BCM_FAILURE(rv)) {
  27921                 soc_mem_unlock(unit, SRC_MODID_EGRESSm);
  27922                 return rv;
  27923             }
  27924         } else {
  27925             /* Deal with all stack ports and their profiles */
  27926             PBMP_ST_ITER(unit, p) {
  27927                 /* coverity[overrun-local : FALSE] */
  27928                 rv = _bcm_port_src_mod_egress_profile_add(unit, p,
  27929                                                      egr_dst.out_min_modid,
  27930                                                      egr_dst.out_max_modid,
  27931                                                           mod_pbmp);
  27932                 if (BCM_FAILURE(rv)) {
  27933                     soc_mem_unlock(unit, SRC_MODID_EGRESSm);
  27934                     return rv;
  27935                 }
  27936             }
  27937         }
  27938         soc_mem_unlock(unit, SRC_MODID_EGRESSm);
  27939 
  27940         return rv;
  27941     }
  27942 #endif
  27943 
  27944 #ifdef BCM_TRX_SUPPORT
  27945     if (SOC_IS_TRX(unit)) {
  27946         src_modid_block_entry_t srcmod;
  27947         int modid_cnt, idx, i, j;
  27948         bcm_pbmp_t mod_pbmp;
  27949         _bcm_port_egr_dest_t    egr_dst;
  27950 
  27951         /* Number of supported MODIDs for this unit */
  27952         modid_cnt = SOC_MODID_MAX(unit) + 1;
  27953 
  27954         egr_dst.in_port = port;
  27955         egr_dst.in_modid = modid;
  27956         BCM_IF_ERROR_RETURN(
  27957             _bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  27958 
  27959         if (egr_dst.out_min_port == egr_dst.out_max_port) {
  27960             /* process to retrieve hg_port index from port */
  27961             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  27962                 SOC_IS_GREYHOUND2(unit)) {
  27963                 egr_dst.out_min_port = egr_dst.out_max_port;
  27964             } else {
  27965                 SOC_IF_ERROR_RETURN(
  27966                     soc_xgs3_port_num_to_higig_port_num(unit,
  27967                                 egr_dst.out_max_port, &egr_dst.out_min_port));
  27968             }
  27969 
  27970             egr_dst.out_max_port = egr_dst.out_min_port;
  27971         } else {
  27972             egr_dst.out_min_port = soc_mem_index_min(unit, SRC_MODID_BLOCKm) / modid_cnt;
  27973             egr_dst.out_max_port = soc_mem_index_max(unit, SRC_MODID_BLOCKm) / modid_cnt;
  27974         }
  27975 
  27976         BCM_PBMP_ASSIGN(mod_pbmp, pbmp);
  27977         BCM_PBMP_AND(mod_pbmp, PBMP_ALL(unit));
  27978         if (BCM_PBMP_NEQ(pbmp, mod_pbmp)) {
  27979             return BCM_E_PARAM;
  27980         }
  27981 
  27982         BCM_PBMP_NEGATE(mod_pbmp, pbmp);
  27983         BCM_PBMP_AND(mod_pbmp, PBMP_ALL(unit));
  27984 
  27985         soc_mem_lock(unit, SRC_MODID_BLOCKm);
  27986         for (i = egr_dst.out_min_port; i <= egr_dst.out_max_port; i++) {
  27987             for (j = egr_dst.out_min_modid; j <= egr_dst.out_max_modid; j++) {
  27988                 idx = i * modid_cnt + j;
  27989                 rv = READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, &srcmod);
  27990                 if (rv >= 0) {
  27991                     soc_SRC_MODID_BLOCKm_field_set(unit, &srcmod,
  27992                                                    PORT_BLOCK_MASK_BITMAPf,
  27993                                                    (uint32 *)&mod_pbmp);
  27994                     rv = WRITE_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ALL, idx,
  27995                                                 &srcmod);
  27996                 }
  27997                 if (rv < 0) {
  27998                     soc_mem_unlock(unit, SRC_MODID_BLOCKm);
  27999                     return rv;
  28000                 }
  28001             }
  28002         }
  28003         soc_mem_unlock(unit, SRC_MODID_BLOCKm);
  28004         return rv;
  28005     }
  28006 #endif /* BCM_TRX_SUPPORT */
  28007 
  28008 #ifdef BCM_FIREBOLT_SUPPORT
  28009     if (soc_feature(unit, soc_feature_src_modid_blk)) {
  28010         src_modid_block_entry_t srcmod;
  28011         bcm_module_t mod_idx;
  28012         int p_idx, min_p, max_p;
  28013         int tbl_size, modid_cnt, idx;
  28014         bcm_pbmp_t mod_pbmp, tst_pbmp, hg_pbmp;
  28015         int cpu=0, ether=0;
  28016         uint32 xge_val;
  28017         _bcm_port_egr_dest_t    egr_dst;
  28018 #if defined(BCM_RAPTOR_SUPPORT)
  28019         uint32  rp_val;
  28020 #endif /* BCM_RAPTOR_SUPPORT */
  28021         /* Number of supported MODIDs for this unit */
  28022         modid_cnt = SOC_MODID_MAX(unit) + 1;
  28023 
  28024 
  28025         egr_dst.in_port = port;
  28026         egr_dst.in_modid = modid;
  28027         BCM_IF_ERROR_RETURN(
  28028             _bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  28029 
  28030         if (egr_dst.out_min_port == egr_dst.out_max_port) {
  28031             min_p = max_p = egr_dst.out_min_port - SOC_HG_OFFSET(unit);
  28032         } else {
  28033             min_p = 0;
  28034             tbl_size = soc_mem_index_count(unit, SRC_MODID_BLOCKm);
  28035             max_p = (tbl_size / modid_cnt) - 1;
  28036             assert(max_p >= 0);
  28037         }
  28038 
  28039         BCM_PBMP_ASSIGN(mod_pbmp, pbmp);
  28040         BCM_PBMP_AND(mod_pbmp, PBMP_ALL(unit));
  28041         if (BCM_PBMP_NEQ(pbmp, mod_pbmp)) {
  28042             return BCM_E_PARAM;
  28043         }
  28044 
  28045         BCM_PBMP_NEGATE(mod_pbmp, pbmp);
  28046         BCM_PBMP_AND(mod_pbmp, PBMP_ALL(unit));
  28047 
  28048         BCM_PBMP_ASSIGN(tst_pbmp, mod_pbmp);
  28049         BCM_PBMP_AND(tst_pbmp, PBMP_CMIC(unit));
  28050         if (BCM_PBMP_NOT_NULL(tst_pbmp)) {
  28051             cpu = 1;
  28052         }
  28053 
  28054         BCM_PBMP_ASSIGN(tst_pbmp, mod_pbmp);
  28055         BCM_PBMP_AND(tst_pbmp, PBMP_E_ALL(unit));
  28056         if (BCM_PBMP_NOT_NULL(tst_pbmp)) {
  28057             ether = 1;
  28058             BCM_PBMP_ASSIGN(tst_pbmp, PBMP_XE_ALL(unit));
  28059         }
  28060 
  28061         BCM_PBMP_ASSIGN(hg_pbmp, mod_pbmp);
  28062         BCM_PBMP_AND(hg_pbmp, PBMP_ST_ALL(unit));
  28063 
  28064         if (ether && BCM_PBMP_NOT_NULL(tst_pbmp)) {
  28065             BCM_PBMP_OR(hg_pbmp, tst_pbmp);
  28066         }
  28067         xge_val = SOC_PBMP_WORD_GET(hg_pbmp, 0) >> SOC_HG_OFFSET(unit);
  28068 
  28069         /* In Raven, port #3 is the GMII port and it introduces a hole in the ST pbmp */
  28070         soc_mem_lock(unit, SRC_MODID_BLOCKm);
  28071         for (p_idx = min_p; p_idx <= max_p; p_idx++) {
  28072             if (SOC_IS_RAVEN(unit) && p_idx == 3) {
  28073                 continue;
  28074             }
  28075             for (mod_idx = egr_dst.out_min_modid; mod_idx <= egr_dst.out_max_modid; mod_idx++) {
  28076                  sal_memset(&srcmod, 0, sizeof(srcmod));
  28077                  /* Table is 2-dimensional array */
  28078                  if (SOC_IS_RAVEN(unit) && p_idx >= 4) {
  28079                      idx = (p_idx - 1) * modid_cnt + mod_idx;
  28080                  } else {
  28081                      idx = (p_idx * modid_cnt) + mod_idx;
  28082                  }
  28083                  rv = READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, &srcmod);
  28084                  if (rv >= 0) {
  28085                      soc_SRC_MODID_BLOCKm_field32_set(unit, &srcmod,
  28086                                                       CPU_PORT_BLOCK_MASKf,
  28087                                                       (cpu) ? 1 : 0);
  28088                      if (SOC_IS_FB_FX_HX(unit)) {
  28089                          soc_SRC_MODID_BLOCKm_field32_set(unit, &srcmod,
  28090                                                           GE_PORT_BLOCK_MASKf,
  28091                                                           (ether) ? 1 : 0);
  28092                      }
  28093                      soc_SRC_MODID_BLOCKm_field32_set(unit, &srcmod,
  28094                                                       HIGIG_XGE_PORT_BLOCK_MASKf,
  28095                                                       xge_val);
  28096 #if defined(BCM_RAPTOR_SUPPORT)
  28097                      if (soc_mem_field_valid(unit, SRC_MODID_BLOCKm,
  28098                                              PORT_0_5_BLOCK_MASKf)) {
  28099                           rp_val = (SOC_PBMP_WORD_GET(mod_pbmp, 0)) &
  28100                               ((1 << soc_reg_field_length(unit, SRC_MODID_BLOCKm,
  28101                                                    PORT_0_5_BLOCK_MASKf )) - 1);
  28102                           soc_SRC_MODID_BLOCKm_field32_set(unit, &srcmod,
  28103                                                            PORT_0_5_BLOCK_MASKf,
  28104                                                            rp_val);
  28105                      }
  28106 #endif /* BCM_RAPTOR_SUPPORT */
  28107                      rv = WRITE_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ALL,
  28108                                                  idx, &srcmod);
  28109                  }
  28110             }
  28111         }
  28112         soc_mem_unlock(unit, SRC_MODID_BLOCKm);
  28113     }
  28114 #endif /* BCM_FIREBOLT_SUPPORT */
  28115 
  28116     return rv;
  28117 #else
  28118     return BCM_E_UNAVAIL;
  28119 #endif  /* BCM_HERCULES15_SUPPORT || BCM_FIREBOLT_SUPPORT */
  28120 }
  28121 
  28122 /*
  28123  * Function:
  28124  *      bcm_port_modid_egress_get
  28125  * Description:
  28126  *      Retrieve port bitmap of egress ports on which the incoming packets
  28127  *      will be forwarded.
  28128  * Parameters:
  28129  *      unit - StrataSwitch PCI device unit number (driver internal).
  28130  *      port  - ingress port number.
  28131  *      modid - source module ID index (in HiGig mod header).
  28132  *      pbmp - (OUT) bitmap of ports where egress allowed.
  28133  * Returns:
  28134  *      BCM_E_xxxx
  28135  */
  28136 int
  28137 bcm_esw_port_modid_egress_get(int unit, bcm_port_t port,
  28138                               bcm_module_t modid, bcm_pbmp_t *pbmp)
  28139 {
  28140 #if defined(BCM_HERCULES15_SUPPORT) || defined(BCM_FIREBOLT_SUPPORT)
  28141     int rv=BCM_E_UNAVAIL;
  28142 
  28143     /* Make sure port module is initialized. */
  28144     PORT_INIT(unit);
  28145 
  28146 #ifdef  BCM_HERCULES15_SUPPORT
  28147     if (SOC_IS_HERCULES15(unit)) {
  28148         mem_ing_srcmodblk_entry_t srcmod;
  28149         bcm_module_t min_mod, max_mod;
  28150         int blk, rv=BCM_E_NONE;
  28151 
  28152         if (!SOC_PORT_VALID(unit, port) || !IS_HG_PORT(unit, port)) {
  28153             return BCM_E_PORT;
  28154         }
  28155 
  28156         min_mod = soc_mem_index_min(unit, MEM_ING_SRCMODBLKm);
  28157         max_mod = soc_mem_index_max(unit, MEM_ING_SRCMODBLKm);
  28158         if ((modid < min_mod) || (modid > max_mod))  {
  28159             return BCM_E_PARAM;
  28160         }
  28161 
  28162         blk = SOC_PORT_BLOCK(unit, port);
  28163         SOC_PBMP_CLEAR(*pbmp);
  28164         rv = READ_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod);
  28165         if (rv >= 0) {
  28166             SOC_PBMP_WORD_SET(*pbmp, 0,
  28167                 soc_MEM_ING_SRCMODBLKm_field32_get(unit, &srcmod, BITMAPf));
  28168         }
  28169     }
  28170 #endif /* BCM_HERCULES15_SUPPORT */
  28171 
  28172 #ifdef BCM_TRIUMPH2_SUPPORT
  28173     if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  28174         SOC_IS_VALKYRIE2(unit) || SOC_IS_TD_TT(unit) ||
  28175         SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) {
  28176         src_modid_egress_entry_t srcmodegr;
  28177         int idx;
  28178         _bcm_port_egr_dest_t    egr_dst;
  28179         bcm_pbmp_t all_pbmp;
  28180 
  28181         SOC_PBMP_CLEAR(all_pbmp);
  28182         SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  28183 
  28184 #ifdef BCM_KATANA2_SUPPORT
  28185         if (soc_feature(unit, soc_feature_linkphy_coe) ||
  28186             soc_feature(unit, soc_feature_subtag_coe)) {
  28187             _bcm_kt2_subport_pbmp_update(unit, &all_pbmp);
  28188         }
  28189 #endif
  28190 
  28191         egr_dst.in_port = port;
  28192         egr_dst.in_modid = modid;
  28193         BCM_IF_ERROR_RETURN(
  28194             _bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  28195 
  28196         if (egr_dst.out_min_modid != egr_dst.out_max_modid) {
  28197             return BCM_E_PARAM;
  28198         }
  28199         if (egr_dst.out_max_port != egr_dst.out_min_port) {
  28200             return BCM_E_PORT;
  28201         }
  28202 
  28203         idx = PORT_SRC_MOD_EGR_PROF_PTR(unit, egr_dst.out_min_port) *
  28204               (SOC_MODID_MAX(unit) + 1) + egr_dst.out_min_modid;
  28205         SOC_IF_ERROR_RETURN(READ_SRC_MODID_EGRESSm(unit, MEM_BLOCK_ANY, idx,
  28206                                                    &srcmodegr));
  28207         soc_mem_pbmp_field_get(unit, SRC_MODID_EGRESSm, &srcmodegr,
  28208                                PORT_BLOCK_MASK_BITMAPf, pbmp);
  28209         BCM_PBMP_NEGATE(*pbmp, *pbmp);
  28210         BCM_PBMP_AND(*pbmp, all_pbmp);
  28211         BCM_PBMP_REMOVE(*pbmp, PBMP_LB(unit));
  28212         return SOC_E_NONE;
  28213     }
  28214 #endif
  28215 
  28216 #ifdef BCM_TRX_SUPPORT
  28217     if (SOC_IS_TRX(unit)) {
  28218         src_modid_block_entry_t srcmod;
  28219         int hg_port, idx;
  28220         _bcm_port_egr_dest_t    egr_dst;
  28221 
  28222         egr_dst.in_port = port;
  28223         egr_dst.in_modid = modid;
  28224         BCM_IF_ERROR_RETURN(
  28225             _bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  28226 
  28227         if (egr_dst.out_min_modid != egr_dst.out_max_modid) {
  28228             return BCM_E_PARAM;
  28229         }
  28230         if (egr_dst.out_max_port != egr_dst.out_min_port) {
  28231             return BCM_E_PORT;
  28232         }
  28233 
  28234         /* process to retrieve hg_port index from port */
  28235         if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  28236             SOC_IS_GREYHOUND2(unit)) {
  28237             hg_port = egr_dst.out_min_port;
  28238         } else {
  28239             SOC_IF_ERROR_RETURN(
  28240                 soc_xgs3_port_num_to_higig_port_num(unit,
  28241                                         egr_dst.out_min_port, &hg_port));
  28242         }
  28243 
  28244         idx = hg_port * (SOC_MODID_MAX(unit) + 1) + egr_dst.out_min_modid;
  28245         SOC_IF_ERROR_RETURN(READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx,
  28246                                                   &srcmod));
  28247         soc_SRC_MODID_BLOCKm_field_get(unit, &srcmod, PORT_BLOCK_MASK_BITMAPf,
  28248                                        (uint32 *)pbmp);
  28249         BCM_PBMP_NEGATE(*pbmp, *pbmp);
  28250         BCM_PBMP_AND(*pbmp, PBMP_ALL(unit));
  28251 
  28252         return SOC_E_NONE;
  28253     }
  28254 #endif
  28255 
  28256 #ifdef BCM_FIREBOLT_SUPPORT
  28257     if (soc_feature(unit, soc_feature_src_modid_blk)) {
  28258         src_modid_block_entry_t srcmod;
  28259         int modid_cnt, p_idx, idx;
  28260         _bcm_port_egr_dest_t    egr_dst;
  28261 
  28262         egr_dst.in_port = port;
  28263         egr_dst.in_modid = modid;
  28264         BCM_IF_ERROR_RETURN(
  28265             _bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  28266 
  28267         if (egr_dst.out_min_modid != egr_dst.out_max_modid) {
  28268             return BCM_E_PARAM;
  28269         }
  28270         if (egr_dst.out_max_port != egr_dst.out_min_port) {
  28271             return BCM_E_PORT;
  28272         }
  28273 
  28274         modid_cnt = SOC_MODID_MAX(unit) + 1;
  28275         p_idx = egr_dst.out_min_port - SOC_HG_OFFSET(unit);
  28276         if (SOC_IS_RAVEN(unit) && p_idx >= 4) {
  28277             idx = (p_idx - 1) * modid_cnt + egr_dst.out_min_modid;
  28278         } else {
  28279             idx = (p_idx * modid_cnt) + egr_dst.out_min_modid;
  28280         }
  28281 
  28282         rv = READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, &srcmod);
  28283         BCM_PBMP_CLEAR(*pbmp);
  28284         if (rv >= 0) {
  28285             int cpu, ether;
  28286             pbmp_t hg_pbmp;
  28287             uint32 xge_val;
  28288 #if defined(BCM_RAPTOR_SUPPORT)
  28289             uint32 rp_val;
  28290 #endif /* BCM_RAPTOR_SUPPORT */
  28291             cpu = soc_SRC_MODID_BLOCKm_field32_get(unit, &srcmod,
  28292                                                    CPU_PORT_BLOCK_MASKf);
  28293             if (SOC_IS_FB_FX_HX(unit)) {
  28294                 ether = soc_SRC_MODID_BLOCKm_field32_get(unit, &srcmod,
  28295                                                          GE_PORT_BLOCK_MASKf);
  28296             } else {
  28297                 ether = 0;
  28298             }
  28299             xge_val = soc_SRC_MODID_BLOCKm_field32_get(unit, &srcmod,
  28300                                                        HIGIG_XGE_PORT_BLOCK_MASKf);
  28301             SOC_PBMP_CLEAR(hg_pbmp);
  28302             SOC_PBMP_WORD_SET(hg_pbmp, 0, xge_val << SOC_HG_OFFSET(unit));
  28303 
  28304 #if defined(BCM_RAPTOR_SUPPORT)
  28305             if (soc_mem_field_valid(unit, SRC_MODID_BLOCKm,
  28306                                     PORT_0_5_BLOCK_MASKf)) {
  28307                 rp_val = soc_SRC_MODID_BLOCKm_field32_get(unit, &srcmod,
  28308                                                          PORT_0_5_BLOCK_MASKf);
  28309                 SOC_PBMP_WORD_SET(hg_pbmp, 0, rp_val);
  28310             }
  28311 #endif /* BCM_RAPTOR_SUPPORT */
  28312             BCM_PBMP_ASSIGN(*pbmp, PBMP_ALL(unit));
  28313             if (cpu) {
  28314                 BCM_PBMP_REMOVE(*pbmp, PBMP_CMIC(unit));
  28315             }
  28316             if (ether) {
  28317                 BCM_PBMP_REMOVE(*pbmp, PBMP_E_ALL(unit));
  28318             }
  28319             if (BCM_PBMP_NOT_NULL(hg_pbmp)) {
  28320                 BCM_PBMP_REMOVE(*pbmp, hg_pbmp);
  28321             }
  28322         }
  28323     }
  28324 #endif /* BCM_FIREBOLT_SUPPORT */
  28325 
  28326     return rv;
  28327 #else
  28328     return BCM_E_UNAVAIL;
  28329 #endif  /* BCM_HERCULES15_SUPPORT  || BCM_FIREBOLT_SUPPORT */
  28330 }
  28331 
  28332 /*
  28333  * Function:
  28334  *    bcm_port_modid_enable_set
  28335  * Purpose:
  28336  *    Enable/block packets from a specific module on a port.
  28337  * Parameters:
  28338  *    unit - StrataSwitch PCI device unit number (driver internal).
  28339  *    port - StrataSwitch port number.
  28340  *    modid - Which source module id to enable/disable
  28341  *    enable - TRUE/FALSE Enable/disable forwarding packets from
  28342  *             source module arriving on port.
  28343  * Returns:
  28344  *    BCM_E_XXX
  28345  */
  28346 int
  28347 bcm_esw_port_modid_enable_set(int unit, bcm_port_t port, int modid, int enable)
  28348 {
  28349     int max_mod;
  28350 #ifdef BCM_HERCULES_SUPPORT
  28351     uint32 smf, osmf;
  28352 #endif /* BCM_HERCULES_SUPPORT */
  28353 #ifdef BCM_HERCULES1_SUPPORT
  28354     uint32 mask;
  28355 #endif /* BCM_HERCULES1_SUPPORT */
  28356 #ifdef BCM_HERCULES15_SUPPORT
  28357     mem_ing_srcmodblk_entry_t srcmod;
  28358     int blk;
  28359 #endif /* BCM_HERCULES15_SUPPORT */
  28360 #if defined(BCM_HERCULES15_SUPPORT) || defined(BCM_FIREBOLT_SUPPORT)
  28361     int rv=BCM_E_NONE;
  28362 #endif /* BCM_HERCULES15_SUPPORT || BCM_FIREBOLT_SUPPORT */
  28363 
  28364     /* Make sure port module is initialized. */
  28365     PORT_INIT(unit);
  28366 
  28367     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  28368 
  28369 #ifdef BCM_TRX_SUPPORT
  28370     if (SOC_IS_TRX(unit)) {
  28371         src_modid_ingress_block_entry_t srcmoding;
  28372         src_modid_block_entry_t srcmod;
  28373         int modid_cnt, hg_port, idx, i;
  28374         bcm_pbmp_t pbmp;
  28375         _bcm_port_egr_dest_t    egr_dst;
  28376 
  28377         egr_dst.in_port = port;
  28378         egr_dst.in_modid = modid;
  28379         BCM_IF_ERROR_RETURN(
  28380             _bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  28381 
  28382         if (egr_dst.out_max_port != egr_dst.out_min_port) {
  28383             return BCM_E_PORT;
  28384         }
  28385 
  28386         if (!IS_E_PORT(unit, egr_dst.out_max_port) &&
  28387             !IS_ST_PORT(unit, egr_dst.out_max_port)) {
  28388             return BCM_E_PORT;
  28389         }
  28390 
  28391 
  28392         if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  28393             SOC_IS_VALKYRIE2(unit) || SOC_IS_TD_TT(unit) ||
  28394             SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) {
  28395             soc_mem_lock(unit, SRC_MODID_INGRESS_BLOCKm);
  28396             for (i = egr_dst.out_min_modid; i <= egr_dst.out_max_modid; i++) {
  28397                 rv = READ_SRC_MODID_INGRESS_BLOCKm(unit, MEM_BLOCK_ANY, i,
  28398                                                    &srcmoding);
  28399                 if (rv >= 0) {
  28400                     soc_mem_pbmp_field_get(unit, SRC_MODID_INGRESS_BLOCKm,
  28401                                            &srcmoding, PORT_BITMAPf, &pbmp);
  28402                     if (enable) {
  28403                         BCM_PBMP_PORT_REMOVE(pbmp, egr_dst.out_max_port);
  28404                     } else {
  28405                         BCM_PBMP_PORT_ADD(pbmp, egr_dst.out_max_port);
  28406                     }
  28407                     soc_mem_pbmp_field_set(unit, SRC_MODID_INGRESS_BLOCKm,
  28408                                            &srcmoding, PORT_BITMAPf, &pbmp);
  28409                     rv = WRITE_SRC_MODID_INGRESS_BLOCKm(unit, MEM_BLOCK_ALL, i,
  28410                                                         &srcmoding);
  28411                 }
  28412                 if (rv < 0) {
  28413                     soc_mem_unlock(unit, SRC_MODID_INGRESS_BLOCKm);
  28414                     return rv;
  28415                 }
  28416             }
  28417             soc_mem_unlock(unit, SRC_MODID_INGRESS_BLOCKm);
  28418         } else {
  28419             modid_cnt = SOC_MODID_MAX(unit) + 1;
  28420 
  28421             /* process to retrieve hg_port index from port */
  28422             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  28423                 SOC_IS_GREYHOUND2(unit)) {
  28424                 hg_port = port;
  28425             } else {
  28426                 SOC_IF_ERROR_RETURN(
  28427                     soc_xgs3_port_num_to_higig_port_num(unit, port, &hg_port));
  28428             }
  28429 
  28430             soc_mem_lock(unit, SRC_MODID_BLOCKm);
  28431             for (i = egr_dst.out_min_modid; i <= egr_dst.out_max_modid; i++) {
  28432                 idx = hg_port * modid_cnt + i;
  28433                 rv = READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, &srcmod);
  28434                 if (rv >= 0) {
  28435                     if (!enable) {
  28436                         SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit));
  28437                     } else {
  28438                         SOC_PBMP_CLEAR(pbmp);
  28439                     }
  28440                     soc_mem_pbmp_field_set(unit, SRC_MODID_BLOCKm, &srcmod,
  28441                                            PORT_BLOCK_MASK_BITMAPf,&pbmp);
  28442                     rv = WRITE_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ALL, idx, &srcmod);
  28443                 }
  28444                 if (rv < 0) {
  28445                     soc_mem_unlock(unit, SRC_MODID_BLOCKm);
  28446                     return rv;
  28447                 }
  28448             }
  28449             soc_mem_unlock(unit, SRC_MODID_BLOCKm);
  28450         }
  28451         return rv;
  28452     }
  28453 #endif  /* BCM_TRX_SUPPORT */
  28454 
  28455 #ifdef BCM_FIREBOLT_SUPPORT
  28456     if (soc_feature(unit, soc_feature_src_modid_blk)) {
  28457         src_modid_block_entry_t src_mod;
  28458         int modid_cnt, mod_idx, p_idx, idx, val;
  28459         _bcm_port_egr_dest_t    egr_dst;
  28460 
  28461         egr_dst.in_port = port;
  28462         egr_dst.in_modid = modid;
  28463         BCM_IF_ERROR_RETURN(
  28464             _bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  28465 
  28466         if (egr_dst.out_max_port != egr_dst.out_min_port) {
  28467             return BCM_E_PORT;
  28468         }
  28469 
  28470         modid_cnt = SOC_MODID_MAX(unit) + 1;
  28471         p_idx = egr_dst.out_min_port - SOC_HG_OFFSET(unit);
  28472         soc_mem_lock(unit, SRC_MODID_BLOCKm);
  28473         for (mod_idx = egr_dst.out_min_modid; mod_idx <= egr_dst.out_max_modid; mod_idx++) {
  28474              sal_memset(&src_mod, 0, sizeof(src_mod));
  28475              if (SOC_IS_RAVEN(unit) && p_idx >= 4) {
  28476                  idx = (p_idx - 1) * modid_cnt + mod_idx;
  28477              } else {
  28478                  idx = (p_idx * modid_cnt) + mod_idx;
  28479              }
  28480              rv = READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, &src_mod);
  28481              if (rv >= 0) {
  28482                  soc_SRC_MODID_BLOCKm_field32_set(unit, &src_mod,
  28483                                                   CPU_PORT_BLOCK_MASKf,
  28484                                                   (enable) ? 0 : 1);
  28485                  if (SOC_IS_FB_FX_HX(unit)) {
  28486                      soc_SRC_MODID_BLOCKm_field32_set(unit, &src_mod,
  28487                                                       GE_PORT_BLOCK_MASKf,
  28488                                                       (enable) ? 0 : 1);
  28489                  }
  28490 
  28491                  val = (1 << soc_mem_field_length(unit, SRC_MODID_BLOCKm,
  28492                                              HIGIG_XGE_PORT_BLOCK_MASKf)) - 1;
  28493 
  28494                  soc_SRC_MODID_BLOCKm_field32_set(unit, &src_mod,
  28495                                                   HIGIG_XGE_PORT_BLOCK_MASKf,
  28496                                                   (enable) ? 0 : val);
  28497 #if defined(BCM_RAPTOR_SUPPORT)
  28498                  if (soc_mem_field_valid(unit, SRC_MODID_BLOCKm,
  28499                                          PORT_0_5_BLOCK_MASKf)) {
  28500 
  28501                      val = (1 << soc_mem_field_length(unit, SRC_MODID_BLOCKm,
  28502                                                  PORT_0_5_BLOCK_MASKf)) - 1;
  28503 
  28504                      soc_SRC_MODID_BLOCKm_field32_set(unit, &src_mod,
  28505                                                       PORT_0_5_BLOCK_MASKf,
  28506                                                       (enable) ? 0 : val);
  28507 
  28508                  }
  28509 #endif /* BCM_RAPTOR_SUPPORT */
  28510                  rv = WRITE_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ALL,
  28511                                              idx, &src_mod);
  28512              }
  28513         }
  28514         soc_mem_unlock(unit, SRC_MODID_BLOCKm);
  28515 
  28516         return rv;
  28517     }
  28518 #endif /* BCM_FIREBOLT_SUPPORT */
  28519 
  28520     if (!IS_PORT(unit, port)) {
  28521         return BCM_E_PORT;
  28522     }
  28523 
  28524     if (!soc_feature(unit, soc_feature_srcmod_filter)) {
  28525         if (enable) {
  28526             return BCM_E_NONE;
  28527         } else {
  28528             return BCM_E_UNAVAIL;
  28529         }
  28530     }
  28531 
  28532     max_mod = 128;
  28533     if (modid >= max_mod) {
  28534         return BCM_E_PARAM;
  28535     }
  28536 
  28537 #ifdef BCM_HERCULES15_SUPPORT
  28538     if (SOC_IS_HERCULES15(unit)) {
  28539         blk = SOC_PORT_BLOCK(unit, port);
  28540         soc_mem_lock(unit, MEM_ING_SRCMODBLKm);
  28541         if (modid < 0) {
  28542             for (modid = 0; modid < max_mod; modid++) {
  28543                 rv = READ_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod);
  28544                 if (rv < 0) {
  28545                     break;
  28546                 }
  28547                 soc_MEM_ING_SRCMODBLKm_field_get(unit, &srcmod, BITMAPf,
  28548                                                  &osmf);
  28549                 smf = (enable) ? SOC_PBMP_WORD_GET(PBMP_ALL(unit), 0) : 0;
  28550                 if (osmf != smf) {
  28551                     soc_MEM_ING_SRCMODBLKm_field_set(unit, &srcmod, BITMAPf,
  28552                                                      &smf);
  28553                     rv = WRITE_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod);
  28554                     if (rv < 0) {
  28555                         break;
  28556                     }
  28557                 }
  28558             }
  28559         } else {
  28560             rv = READ_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod);
  28561             if (rv >= 0) {
  28562                 soc_MEM_ING_SRCMODBLKm_field_get(unit, &srcmod, BITMAPf,
  28563                                                  &osmf);
  28564                 smf = (enable) ? SOC_PBMP_WORD_GET(PBMP_ALL(unit), 0) : 0;
  28565                 if (osmf != smf) {
  28566                     soc_MEM_ING_SRCMODBLKm_field_set(unit, &srcmod, BITMAPf,
  28567                                                      &smf);
  28568                     rv = WRITE_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod);
  28569                 }
  28570             }
  28571         }
  28572         soc_mem_unlock(unit, MEM_ING_SRCMODBLKm);
  28573     }
  28574 #endif /* BCM_HERCULES15_SUPPORT */
  28575 
  28576     return BCM_E_NONE;
  28577 }
  28578 
  28579 /*
  28580  * Function:
  28581  *    bcm_port_modid_enable_get
  28582  * Purpose:
  28583  *    Return enable/block state for a specific module on a port.
  28584  * Parameters:
  28585  *    unit - StrataSwitch PCI device unit number (driver internal).
  28586  *    port - StrataSwitch port number.
  28587  *    modid - Which source module id to enable/disable
  28588  *    enable - (OUT) TRUE/FALSE Enable/disable forwarding packets from
  28589  *             source module arriving on port.
  28590  * Returns:
  28591  *    BCM_E_XXX
  28592  */
  28593 int
  28594 bcm_esw_port_modid_enable_get(int unit, bcm_port_t port, int modid, int *enable)
  28595 {
  28596     int max_mod;
  28597 #ifdef BCM_HERCULES_SUPPORT
  28598     uint32 smf;
  28599 #endif /* BCM_HERCULES_SUPPORT */
  28600 #ifdef BCM_HERCULES1_SUPPORT
  28601     uint32 mask;
  28602 #endif /* BCM_HERCULES1_SUPPORT */
  28603 #ifdef BCM_HERCULES15_SUPPORT
  28604     mem_ing_srcmodblk_entry_t srcmod;
  28605     int blk, rv;
  28606 #endif /* BCM_HERCULES15_SUPPORT */
  28607 
  28608     /* Make sure port module is initialized. */
  28609     PORT_INIT(unit);
  28610 
  28611     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  28612 
  28613 #ifdef BCM_TRX_SUPPORT
  28614     if (SOC_IS_TRX(unit)) {
  28615         src_modid_ingress_block_entry_t srcmoding;
  28616         src_modid_block_entry_t srcmod;
  28617         int hg_port, idx;
  28618         bcm_pbmp_t pbmp;
  28619         _bcm_port_egr_dest_t    egr_dst;
  28620 
  28621         egr_dst.in_port = port;
  28622         egr_dst.in_modid = modid;
  28623         BCM_IF_ERROR_RETURN(
  28624             _bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  28625 
  28626         if (egr_dst.out_max_port != egr_dst.out_min_port) {
  28627             return BCM_E_PORT;
  28628         }
  28629         if (egr_dst.out_max_modid != egr_dst.out_min_modid) {
  28630             return BCM_E_PARAM;
  28631         }
  28632 
  28633         if (!IS_E_PORT(unit, egr_dst.out_max_port) &&
  28634             !IS_ST_PORT(unit, egr_dst.out_max_port)) {
  28635             return BCM_E_PORT;
  28636         }
  28637 
  28638         SOC_PBMP_CLEAR(pbmp);
  28639         if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  28640             SOC_IS_VALKYRIE2(unit) || SOC_IS_TD_TT(unit) ||
  28641             SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) {
  28642             SOC_IF_ERROR_RETURN(
  28643                 READ_SRC_MODID_INGRESS_BLOCKm(unit, MEM_BLOCK_ANY,
  28644                                               egr_dst.out_min_modid, &srcmoding));
  28645             soc_mem_pbmp_field_get(unit, SRC_MODID_INGRESS_BLOCKm,
  28646                                    &srcmoding, PORT_BITMAPf, &pbmp);
  28647         } else {
  28648             /* process to retrieve hg_port index from port */
  28649             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  28650                 SOC_IS_GREYHOUND2(unit)) {
  28651                 hg_port = egr_dst.out_min_port;
  28652             } else {
  28653                 SOC_IF_ERROR_RETURN(soc_xgs3_port_num_to_higig_port_num(unit,
  28654                         egr_dst.out_min_port, &hg_port));
  28655             }
  28656 
  28657             idx = hg_port * (SOC_MODID_MAX(unit) + 1) + egr_dst.out_min_modid;
  28658             SOC_IF_ERROR_RETURN(READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx,
  28659                                                       &srcmod));
  28660             soc_mem_pbmp_field_get(unit, SRC_MODID_BLOCKm, &srcmod,
  28661                                    PORT_BLOCK_MASK_BITMAPf, &pbmp);
  28662         }
  28663 
  28664         *enable = !SOC_PBMP_MEMBER(pbmp, egr_dst.out_max_port);
  28665 
  28666         return BCM_E_NONE;
  28667     }
  28668 #endif /* BCM_TRIUMPH_SUPPORT */
  28669 
  28670 #ifdef BCM_FIREBOLT_SUPPORT
  28671     if (soc_feature(unit, soc_feature_src_modid_blk)) {
  28672         uint32 config;
  28673         src_modid_block_entry_t src_mod;
  28674         int gable, modid_cnt, p_idx, idx;
  28675         _bcm_port_egr_dest_t    egr_dst;
  28676 
  28677         egr_dst.in_port = port;
  28678         egr_dst.in_modid = modid;
  28679         BCM_IF_ERROR_RETURN(
  28680             _bcm_esw_port_modid_egress_resolve(unit, &egr_dst));
  28681 
  28682         if (egr_dst.out_max_port != egr_dst.out_min_port) {
  28683             return BCM_E_PORT;
  28684         }
  28685         if (egr_dst.out_max_modid != egr_dst.out_min_modid) {
  28686             return BCM_E_PARAM;
  28687         }
  28688 
  28689         SOC_IF_ERROR_RETURN(READ_ING_CONFIGr(unit, &config));
  28690         gable = !soc_reg_field_get(unit, ING_CONFIGr, config,
  28691                                    FB_A0_COMPATIBLEf);
  28692         if (gable) {
  28693             modid_cnt = SOC_MODID_MAX(unit) + 1;
  28694             p_idx = egr_dst.out_min_port - SOC_HG_OFFSET(unit);
  28695             if (SOC_IS_RAVEN(unit) && p_idx >= 4) {
  28696                 idx = (p_idx - 1) * modid_cnt + egr_dst.out_min_modid;
  28697             } else {
  28698                 idx = (p_idx * modid_cnt) + egr_dst.out_min_modid;
  28699             }
  28700             SOC_IF_ERROR_RETURN
  28701                 (READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY,
  28702                                        idx, &src_mod));
  28703             *enable = (soc_SRC_MODID_BLOCKm_field32_get(unit, &src_mod,
  28704                                                         CPU_PORT_BLOCK_MASKf) |
  28705                        soc_SRC_MODID_BLOCKm_field32_get(unit, &src_mod,
  28706                                                         HIGIG_XGE_PORT_BLOCK_MASKf)
  28707                                                         ) ? 0 : 1;
  28708             if (SOC_IS_FB_FX_HX(unit)) {
  28709                 *enable = (soc_SRC_MODID_BLOCKm_field32_get(unit, &src_mod,
  28710                                                             GE_PORT_BLOCK_MASKf)
  28711                                                             ) ? 0 : 1;
  28712             }
  28713 
  28714 #if defined(BCM_RAPTOR_SUPPORT)
  28715             if (soc_mem_field_valid(unit, SRC_MODID_BLOCKm,
  28716                                     PORT_0_5_BLOCK_MASKf)) {
  28717                 *enable = (soc_SRC_MODID_BLOCKm_field32_get(unit, &src_mod,
  28718                                                  PORT_0_5_BLOCK_MASKf)
  28719                                                  ) ? 0 : 1;
  28720             }
  28721 #endif /* BCM_RAPTOR_SUPPORT */
  28722 
  28723         } else {
  28724             *enable = gable;
  28725         }
  28726 
  28727         return BCM_E_NONE;
  28728     }
  28729 #endif /* BCM_FIREBOLT_SUPPORT */
  28730 
  28731     if (!IS_PORT(unit, port)) {
  28732         return BCM_E_PORT;
  28733     }
  28734 
  28735     if (!soc_feature(unit, soc_feature_srcmod_filter)) {
  28736         *enable = TRUE;
  28737         return BCM_E_NONE;
  28738     }
  28739 
  28740     max_mod = 128;
  28741     if (!((modid >= 0) && (modid < max_mod))) {
  28742         return BCM_E_PARAM;
  28743     }
  28744 
  28745 #ifdef BCM_HERCULES15_SUPPORT
  28746     if (SOC_IS_HERCULES15(unit)) {
  28747         blk = SOC_PORT_BLOCK(unit, port);
  28748         rv = READ_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod);
  28749         if (rv >= 0) {
  28750             soc_MEM_ING_SRCMODBLKm_field_get(unit, &srcmod, BITMAPf, &smf);
  28751             *enable = (smf & SOC_PBMP_WORD_GET(PBMP_ALL(unit),0)) ? 1 : 0;
  28752         }
  28753     }
  28754 #endif /* BCM_HERCULES15_SUPPORT */
  28755 
  28756     return BCM_E_NONE;
  28757 }
  28758 
  28759 
  28760 /*
  28761  * Function:
  28762  *      _bcm_port_flood_block_op
  28763  * Purpose:
  28764  *      Set or get port membership in one of the egress block registers
  28765  * Parameters:
  28766  *      unit
  28767  *      set_op          - TRUE for set, FALSE for get
  28768  *      ingress_port    - ingress port on which the egress blocking
  28769  *                        will be enabled
  28770  *      egress_port     - port for which egress will be blocked
  28771  *      mode            - BCM_PORT_FLOOD_BLOCK_XXX
  28772  *      enable          - Whether blocking should be enabled or disabled
  28773  *                        This is also BCM_PORT_FLOOD_BLOCK_XXX
  28774  * Returns:
  28775  *      BCM_E_UNAVAIL   - This chip does not support this feature
  28776  *      BCM_E_NONE
  28777  */
  28778 STATIC int
  28779 _bcm_port_flood_block_op(int unit, int set_op,
  28780                          bcm_port_t ingress_port, bcm_port_t egress_port,
  28781                          uint32 mode, uint32 *enable)
  28782 {
  28783     soc_reg_t reg, mask_reg[2], mask_hi_reg[2];
  28784     soc_mem_t mem;
  28785     soc_field_t field;
  28786     uint64 rval;
  28787     uint32 fval;
  28788     uint32 entry[SOC_MAX_MEM_WORDS];
  28789     pbmp_t pbmp;
  28790     int index;
  28791     int cpu_hg_index = 0;
  28792 
  28793     mask_reg[0] = mask_reg[1] = INVALIDr;
  28794     mask_hi_reg[0] = mask_hi_reg[1] = INVALIDr;
  28795     mem = INVALIDm;
  28796     field = INVALIDf;
  28797 
  28798     switch (mode) {
  28799     case BCM_PORT_FLOOD_BLOCK_BCAST:
  28800         if (SOC_MEM_IS_VALID(unit, BCAST_BLOCK_MASKm)) {
  28801             mem = BCAST_BLOCK_MASKm;
  28802             field = BLK_BITMAPf;
  28803         /* coverity[result_independent_of_operands] */
  28804         } else if (SOC_REG_IS_VALID(unit, BCAST_BLOCK_MASK_64r)) {
  28805             mask_reg[0] = BCAST_BLOCK_MASK_64r;
  28806             mask_reg[1] = IBCAST_BLOCK_MASK_64r;
  28807         } else if (SOC_REG_IS_VALID(unit, BCAST_BLOCK_MASK_LO_64r)) {
  28808             mask_reg[0] = BCAST_BLOCK_MASK_LO_64r;
  28809             mask_reg[1] = IBCAST_BLOCK_MASK_LO_64r;
  28810             mask_hi_reg[0] = BCAST_BLOCK_MASK_HI_64r;
  28811             mask_hi_reg[1] = IBCAST_BLOCK_MASK_HI_64r;            
  28812         } else if (SOC_REG_IS_VALID(unit, BCAST_BLOCK_MASKr)) {
  28813             mask_reg[0] = BCAST_BLOCK_MASKr;
  28814             mask_reg[1] = IBCAST_BLOCK_MASKr;
  28815         } else {
  28816             return BCM_E_UNAVAIL;
  28817         }
  28818         break;
  28819     case BCM_PORT_FLOOD_BLOCK_UNKNOWN_UCAST:
  28820         if (SOC_MEM_IS_VALID(unit, UNKNOWN_UCAST_BLOCK_MASKm)) {
  28821             mem = UNKNOWN_UCAST_BLOCK_MASKm;
  28822             field = BLK_BITMAPf;
  28823         } else if (SOC_REG_IS_VALID(unit, UNKNOWN_UCAST_BLOCK_MASK_64r)) {
  28824             mask_reg[0] = UNKNOWN_UCAST_BLOCK_MASK_64r;
  28825             mask_reg[1] = IUNKNOWN_UCAST_BLOCK_MASK_64r;
  28826         } else if (SOC_REG_IS_VALID(unit, UNKNOWN_UCAST_BLOCK_MASK_LO_64r)) {
  28827             mask_reg[0] = UNKNOWN_UCAST_BLOCK_MASK_LO_64r;
  28828             mask_reg[1] = IUNKNOWN_UCAST_BLOCK_MASK_LO_64r;
  28829             mask_hi_reg[0] = UNKNOWN_UCAST_BLOCK_MASK_HI_64r;
  28830             mask_hi_reg[1] = IUNKNOWN_UCAST_BLOCK_MASK_HI_64r;            
  28831         } else if (SOC_REG_IS_VALID(unit, UNKNOWN_UCAST_BLOCK_MASKr)) {
  28832             mask_reg[0] = UNKNOWN_UCAST_BLOCK_MASKr;
  28833             mask_reg[1] = IUNKNOWN_UCAST_BLOCK_MASKr;
  28834         } else {
  28835             return BCM_E_UNAVAIL;
  28836         }
  28837         break;
  28838     case BCM_PORT_FLOOD_BLOCK_UNKNOWN_MCAST:
  28839         if (SOC_MEM_IS_VALID(unit, UNKNOWN_MCAST_BLOCK_MASKm)) {
  28840             mem = UNKNOWN_MCAST_BLOCK_MASKm;
  28841             field = BLK_BITMAPf;
  28842         } else if (SOC_REG_IS_VALID(unit, UNKNOWN_MCAST_BLOCK_MASK_64r)) {
  28843             mask_reg[0] = UNKNOWN_MCAST_BLOCK_MASK_64r;
  28844             mask_reg[1] = IUNKNOWN_MCAST_BLOCK_MASK_64r;
  28845         } else if (SOC_REG_IS_VALID(unit, UNKNOWN_MCAST_BLOCK_MASK_LO_64r)) {
  28846             mask_reg[0] = UNKNOWN_MCAST_BLOCK_MASK_LO_64r;
  28847             mask_reg[1] = IUNKNOWN_MCAST_BLOCK_MASK_LO_64r;
  28848             mask_hi_reg[0] = UNKNOWN_MCAST_BLOCK_MASK_HI_64r;
  28849             mask_hi_reg[1] = IUNKNOWN_MCAST_BLOCK_MASK_HI_64r;            
  28850         } else if (SOC_REG_IS_VALID(unit, UNKNOWN_MCAST_BLOCK_MASKr)) {
  28851             mask_reg[0] = UNKNOWN_MCAST_BLOCK_MASKr;
  28852             mask_reg[1] = IUNKNOWN_MCAST_BLOCK_MASKr;
  28853         } else {
  28854             return BCM_E_UNAVAIL;
  28855         }
  28856         break;
  28857     case BCM_PORT_FLOOD_BLOCK_KNOWN_MCAST:
  28858         if (SOC_MEM_IS_VALID(unit, KNOWN_MCAST_BLOCK_MASKm)) {
  28859             mem = KNOWN_MCAST_BLOCK_MASKm;
  28860             field = BLK_BITMAPf;
  28861         } else if (SOC_REG_IS_VALID(unit, KNOWN_MCAST_BLOCK_MASK_64r)) {
  28862             mask_reg[0] = KNOWN_MCAST_BLOCK_MASK_64r;
  28863             mask_reg[1] = IKNOWN_MCAST_BLOCK_MASK_64r;
  28864         } else if (SOC_REG_IS_VALID(unit, KNOWN_MCAST_BLOCK_MASK_LOr)) {
  28865             mask_reg[0] = KNOWN_MCAST_BLOCK_MASK_LOr;
  28866             mask_reg[1] = IKNOWN_MCAST_BLOCK_MASK_LOr;
  28867             mask_hi_reg[0] = KNOWN_MCAST_BLOCK_MASK_HIr;
  28868             mask_hi_reg[1] = IKNOWN_MCAST_BLOCK_MASK_HIr;            
  28869         } else if (SOC_REG_IS_VALID(unit, KNOWN_MCAST_BLOCK_MASKr)) {
  28870             mask_reg[0] = KNOWN_MCAST_BLOCK_MASKr;
  28871             mask_reg[1] = IKNOWN_MCAST_BLOCK_MASKr;
  28872         } else {
  28873             return BCM_E_UNAVAIL;
  28874         }
  28875         break;
  28876     case BCM_PORT_FLOOD_BLOCK_ALL:
  28877         if (SOC_MEM_IS_VALID(unit, ING_EGRMSKBMAPm)) {
  28878             mem = ING_EGRMSKBMAPm;
  28879             field = BITMAPf;
  28880         } else if (SOC_REG_IS_VALID(unit, ING_EGRMSKBMAP_64r)) {
  28881             mask_reg[0] = ING_EGRMSKBMAP_64r;
  28882             mask_reg[1] = IING_EGRMSKBMAP_64r;
  28883         } else if (SOC_REG_IS_VALID(unit, ING_EGRMSKBMAP_LOr)) {
  28884             mask_reg[0] = ING_EGRMSKBMAP_LOr;
  28885             mask_reg[1] = IING_EGRMSKBMAP_LOr;
  28886             mask_hi_reg[0] = ING_EGRMSKBMAP_HIr;
  28887             mask_hi_reg[1] = IING_EGRMSKBMAP_HIr;            
  28888         } else if (SOC_REG_IS_VALID(unit, ING_EGRMSKBMAPr)) {
  28889             mask_reg[0] = ING_EGRMSKBMAPr;
  28890             mask_reg[1] = IING_EGRMSKBMAPr;
  28891         } else {
  28892             return BCM_E_UNAVAIL;
  28893         }
  28894         break;
  28895     default:
  28896         return BCM_E_INTERNAL;
  28897     }
  28898 
  28899     if (mem != INVALIDm) {
  28900         BCM_IF_ERROR_RETURN
  28901             (soc_mem_read(unit, mem, MEM_BLOCK_ANY, ingress_port, entry));
  28902         soc_mem_pbmp_field_get(unit, mem, entry, field, &pbmp);
  28903         if (!set_op) {
  28904             *enable = SOC_PBMP_WORD_GET(pbmp, egress_port / 32) &
  28905                 (1 << (egress_port & 0x1f)) ? mode : 0;
  28906             return BCM_E_NONE;
  28907         }
  28908         if (*enable & mode) {
  28909             SOC_PBMP_PORT_ADD(pbmp, egress_port);
  28910         } else {
  28911             SOC_PBMP_PORT_REMOVE(pbmp, egress_port);
  28912         }
  28913         soc_mem_pbmp_field_set(unit, mem, entry, field, &pbmp);
  28914         BCM_IF_ERROR_RETURN
  28915             (soc_mem_write(unit, mem, MEM_BLOCK_ANY, ingress_port, entry));
  28916 
  28917         cpu_hg_index = SOC_IS_KATANA2(unit) ?
  28918                        SOC_INFO(unit).cpu_hg_pp_port_index :
  28919                        SOC_INFO(unit).cpu_hg_index;
  28920         if (IS_CPU_PORT(unit, ingress_port) && cpu_hg_index != -1) {
  28921             BCM_IF_ERROR_RETURN
  28922                 (soc_mem_read(unit, mem, MEM_BLOCK_ANY, cpu_hg_index, entry));
  28923             soc_mem_pbmp_field_get(unit, mem, entry, field, &pbmp);
  28924             if (*enable & mode) {
  28925                 SOC_PBMP_PORT_ADD(pbmp, egress_port);
  28926             } else {
  28927                 SOC_PBMP_PORT_REMOVE(pbmp, egress_port);
  28928             }
  28929             soc_mem_pbmp_field_set(unit, mem, entry, field, &pbmp);
  28930             BCM_IF_ERROR_RETURN
  28931                 (soc_mem_write(unit, mem, MEM_BLOCK_ANY, cpu_hg_index, entry));
  28932         }
  28933     } else {
  28934         if (!IS_CPU_PORT(unit, ingress_port)) {
  28935             if (IS_ST_PORT(unit, ingress_port)) {
  28936                 mask_reg[0] = INVALIDr;
  28937                 mask_hi_reg[0] = INVALIDr;
  28938             } else {
  28939                 mask_reg[1] = INVALIDr;
  28940                 mask_hi_reg[1] = INVALIDr;
  28941             }
  28942         }
  28943 
  28944         for (index = 0; index < 2; index++) {
  28945             if (soc_feature (unit, soc_feature_high_portcount_register)) {
  28946                 uint64      fval64, rval64;
  28947                 uint32      t_port;
  28948                 pbmp_t      curr_pbmp;
  28949 
  28950                 /* 
  28951                 *  pbmp reg split to multiple reg due to high port count 
  28952                 *  example :
  28953                 *   - BCAST_BLOCK_MASK_64r was split to
  28954                 *      {BCAST_BLOCK_MASK_LO_64r + BCAST_BLOCK_MASK_HI_64r}
  28955                 *   - ING_EGRMSKBMAP_64r was split to
  28956                 *      {ING_EGRMSKBMAP_LOr + ING_EGRMSKBMAP_HIr}
  28957                 */
  28958                 BCM_PBMP_CLEAR(curr_pbmp);
  28959                 COMPILER_64_ZERO(fval64);
  28960                 COMPILER_64_ZERO(rval64);
  28961 
  28962                 if (egress_port < 64) {
  28963                     reg = mask_reg[index];
  28964                     t_port = egress_port;
  28965                 } else {
  28966                     reg = mask_hi_reg[index];
  28967                     t_port = egress_port - 64;
  28968                 }
  28969                 field = BLK_BITMAPf;
  28970 
  28971                 if (SOC_REG_IS_VALID(unit, reg)) {
  28972                     BCM_IF_ERROR_RETURN(soc_reg_get(unit, 
  28973                             reg, ingress_port, 0, &rval64));
  28974 
  28975                     fval64 = soc_reg64_field_get(unit, reg, rval64, field);
  28976                     SOC_PBMP_WORD_SET(curr_pbmp, 0, COMPILER_64_LO(fval64));
  28977                     SOC_PBMP_WORD_SET(curr_pbmp, 1, COMPILER_64_HI(fval64));
  28978 
  28979                     if (!set_op) {
  28980                         /* for GET */
  28981                         *enable = SOC_PBMP_MEMBER(curr_pbmp, t_port) ? mode : 0;
  28982                     } else {
  28983                         /* for SET */
  28984                         if (*enable & mode) {
  28985                             SOC_PBMP_PORT_ADD(curr_pbmp, t_port);
  28986                         } else {
  28987                             SOC_PBMP_PORT_REMOVE(curr_pbmp, t_port);
  28988                         }
  28989                         COMPILER_64_SET(fval64,
  28990                                 SOC_PBMP_WORD_GET(curr_pbmp, 1),
  28991                                 SOC_PBMP_WORD_GET(curr_pbmp, 0));
  28992                         soc_reg64_field_set(unit, reg,
  28993                                 &rval64, field, fval64);
  28994                         BCM_IF_ERROR_RETURN(soc_reg_set(unit, 
  28995                                 reg, ingress_port, 0, rval64));
  28996                     }
  28997                 }
  28998             } else {
  28999             reg = mask_reg[index];
  29000             if (reg == INVALIDr) {
  29001                 continue;
  29002             }
  29003             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, ingress_port, 0, &rval));
  29004             if (SOC_REG_IS_64(unit, reg)) {
  29005                 if (egress_port < 32) {
  29006                     if (soc_reg_field_valid(unit, reg, BLK_BITMAP_LOf)) {
  29007                         field = BLK_BITMAP_LOf;
  29008                     } else {
  29009                         field = BLK_BITMAP_0f;
  29010                     }
  29011                 } else {
  29012                     if (soc_reg_field_valid(unit, reg, BLK_BITMAP_HIf)) {
  29013                         field = BLK_BITMAP_HIf;
  29014                     } else {
  29015                         field = BLK_BITMAP_1f;
  29016                     }
  29017                 }
  29018             } else {
  29019                 field = BLK_BITMAPf;
  29020             }
  29021             fval = soc_reg64_field32_get(unit, reg, rval, field);
  29022             if (!set_op) {
  29023                 *enable = fval & (1 << (egress_port & 0x1f)) ? mode : 0;
  29024                 return BCM_E_NONE;
  29025             }
  29026             if (*enable & mode) {
  29027                 fval |= 1 << (egress_port & 0x1f);
  29028             } else {
  29029                 fval &= ~(1 << (egress_port & 0x1f));
  29030             }
  29031             soc_reg64_field32_set(unit, reg, &rval, field, fval);
  29032             BCM_IF_ERROR_RETURN(soc_reg_set(unit, reg, ingress_port, 0, rval));
  29033         }
  29034     }
  29035     }
  29036 
  29037     return BCM_E_NONE;
  29038 }
  29039 
  29040 #if defined(BCM_RAPTOR_SUPPORT)
  29041 /*
  29042  * Function:
  29043  *      _bcm_port_flood_block_hi_set
  29044  * Purpose:
  29045  *      Enable/disable port membership in one of the egress block registers
  29046  * Parameters:
  29047  *      unit
  29048  *      ingress_port    - ingress port on which the egress blocking
  29049  *                        will be enabled
  29050  *      egress_port     - port for which egress will be blocked
  29051  *      reg             - egress block register.
  29052  *      enable          - Whether blocking should be enabled or disabled
  29053  * Returns:
  29054  *      BCM_E_UNAVAIL   - This chip does not support this feature
  29055  *      BCM_E_NONE
  29056  * Notes:
  29057  *      'reg' must be one of BCAST_BLOCK_MASKr,
  29058  *      UNKNOWN_UCAST_BLOCK_MASKr, UNKNOWN_MCAST_BLOCK_MASKr, or
  29059  *      their Stack port variants.
  29060  *
  29061  *      This function is a helper for bcm_port_flood_block_set()
  29062  */
  29063 
  29064 STATIC int
  29065 _bcm_port_flood_block_hi_set(int unit,
  29066                               bcm_port_t ingress_port, bcm_port_t egress_port,
  29067                               soc_reg_t reg, uint32 enable)
  29068 {
  29069     uint32 rval;
  29070     pbmp_t pbmp;
  29071     uint32 pbmp32;
  29072     uint32 bitmap32, obitmap32;
  29073 
  29074     if (!soc_feature(unit, soc_feature_register_hi)) {
  29075         return BCM_E_UNAVAIL;
  29076     }
  29077 
  29078     SOC_PBMP_PORT_SET(pbmp, egress_port);
  29079     pbmp32 = SOC_PBMP_WORD_GET(pbmp, 1);
  29080 
  29081     if (!pbmp32) {
  29082         return BCM_E_NONE;
  29083     }
  29084 
  29085     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, ingress_port, 0, &rval));
  29086 
  29087     obitmap32 = bitmap32 = soc_reg_field_get(unit, reg, rval, BLK_BITMAPf);
  29088     if (enable) {
  29089         bitmap32 |= pbmp32;
  29090     } else {
  29091         bitmap32 &= ~pbmp32;
  29092     }
  29093 
  29094     if (obitmap32 != bitmap32) {
  29095         soc_reg_field_set(unit, reg, &rval, BLK_BITMAPf, bitmap32);
  29096         return soc_reg32_set(unit, reg, ingress_port, 0, rval);
  29097     }
  29098 
  29099     return BCM_E_NONE;
  29100 }
  29101 
  29102 /*
  29103  * Function:
  29104  *      _bcm_port_flood_block_hi_get
  29105  * Purpose:
  29106  *      Retrieve the current state egress block state on a port
  29107  * Parameters:
  29108  *      unit
  29109  *      ingress_port    - ingress_port for which the state will be retreived
  29110  *      egress_port     - port for which the egress blocking state
  29111  *                        on ingress_port is requested
  29112  *      reg             - block mask register
  29113  *      enable          - (OUT) receives the block state
  29114  * Returns:
  29115  *      BCM_E_UNAVAIL   - Feature unavailable on this chip
  29116  *      BCM_E_NONE
  29117  * Notes:
  29118  *      See _bcm_port_flood_block_hi_set()
  29119  *      This is a helper function for bcm_port_flood_block_get()
  29120  */
  29121 
  29122 STATIC int
  29123 _bcm_port_flood_block_hi_get(int unit,
  29124                           bcm_port_t ingress_port, bcm_port_t egress_port,
  29125                           soc_reg_t reg, uint32 *enable)
  29126 {
  29127     uint32 rval;
  29128     pbmp_t pbmp;
  29129     uint32 pbmp32;
  29130     uint32 bitmap32;
  29131 
  29132     if (!soc_feature(unit, soc_feature_register_hi)) {
  29133         return BCM_E_UNAVAIL;
  29134     }
  29135 
  29136     SOC_PBMP_PORT_SET(pbmp, egress_port);
  29137     pbmp32 = SOC_PBMP_WORD_GET(pbmp, 1);
  29138     if (!pbmp32) {
  29139         *enable = 0;
  29140         return BCM_E_NONE;
  29141     }
  29142 
  29143     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg, ingress_port, 0, &rval));
  29144 
  29145     bitmap32 = soc_reg_field_get(unit, reg, rval, BLK_BITMAPf);
  29146     *enable = (pbmp32 & bitmap32) ? 1 : 0;
  29147 
  29148     return BCM_E_NONE;
  29149 }
  29150 #endif /* BCM_RAPTOR_SUPPORT */
  29151 
  29152 /*
  29153  * Function:
  29154  *      bcm_port_flood_block_set
  29155  * Purpose:
  29156  *      Set selective per-port blocking of flooded VLAN traffic
  29157  * Parameters:
  29158  *      unit            - unit number
  29159  *      ingress_port    - Port traffic is ingressing
  29160  *      egress_port     - Port for which the traffic should be blocked.
  29161  *      flags           - Specifies the type of traffic to block
  29162  * Returns:
  29163  *      BCM_E_UNAVAIL   - Functionality not available
  29164  *      BCM_E_NONE
  29165  *
  29166  * NOTE:  For fabrics, this changes egrmskbmap; as a result, all traffic
  29167  * will be blocked (or enabled) to the given egress port, including
  29168  * unicast traffic.
  29169  */
  29170 
  29171 int
  29172 bcm_esw_port_flood_block_set(int unit,
  29173                          bcm_port_t ingress_port, bcm_port_t egress_port,
  29174                          uint32 flags)
  29175 {
  29176     /* Make sure port module is initialized. */
  29177     PORT_INIT(unit);
  29178 
  29179     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, ingress_port,
  29180                                                      &ingress_port));
  29181     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, egress_port,
  29182                                                      &egress_port));
  29183 
  29184 #if defined(BCM_XGS12_FABRIC_SUPPORT)
  29185     /* See note above */
  29186     if (SOC_IS_XGS12_FABRIC(unit)) {
  29187         uint32  ports, oports;
  29188         pbmp_t  pbmp;
  29189 
  29190         if (!IS_HG_PORT(unit, ingress_port)) {
  29191             return BCM_E_PORT;
  29192         }
  29193 
  29194         SOC_IF_ERROR_RETURN
  29195             (READ_ING_EGRMSKBMAPr(unit, ingress_port, &ports));
  29196         oports = ports;
  29197         SOC_PBMP_CLEAR(pbmp);
  29198         SOC_PBMP_WORD_SET(pbmp, 0, ports);
  29199         if (flags) {
  29200             SOC_PBMP_PORT_REMOVE(pbmp, egress_port);
  29201         } else {
  29202             SOC_PBMP_PORT_ADD(pbmp, egress_port);
  29203         }
  29204         ports = SOC_PBMP_WORD_GET(pbmp, 0);
  29205         if (ports != oports) {
  29206             SOC_IF_ERROR_RETURN
  29207                 (WRITE_ING_EGRMSKBMAPr(unit, ingress_port, ports));
  29208         }
  29209         return BCM_E_NONE;
  29210     }
  29211 #endif /* BCM_XGS12_FABRIC_SUPPORT */
  29212 
  29213 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \
  29214         || defined(BCM_BRADLEY_SUPPORT)
  29215     if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit)||
  29216         SOC_IS_HBX(unit) || SOC_IS_TRX(unit) || SOC_IS_HAWKEYE(unit)) {
  29217         BCM_IF_ERROR_RETURN
  29218             (_bcm_port_flood_block_op(unit, TRUE, ingress_port, egress_port,
  29219                                       BCM_PORT_FLOOD_BLOCK_ALL, &flags));
  29220     }
  29221 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || \
  29222           BCM_BRADLEY_SUPPORT */
  29223 
  29224     BCM_IF_ERROR_RETURN
  29225         (_bcm_port_flood_block_op(unit, TRUE, ingress_port, egress_port,
  29226                                   BCM_PORT_FLOOD_BLOCK_BCAST, &flags));
  29227 
  29228     BCM_IF_ERROR_RETURN
  29229         (_bcm_port_flood_block_op(unit, TRUE, ingress_port, egress_port,
  29230                                   BCM_PORT_FLOOD_BLOCK_UNKNOWN_MCAST, &flags));
  29231 
  29232     /*
  29233      * For some devices like RAVEN , which do not have support for
  29234      * blocking KNOWN_MCAST , continue processing.
  29235      */
  29236     BCM_IF_ERROR_NOT_UNAVAIL_RETURN
  29237         (_bcm_port_flood_block_op(unit, TRUE, ingress_port, egress_port,
  29238                                   BCM_PORT_FLOOD_BLOCK_KNOWN_MCAST, &flags));
  29239 
  29240     BCM_IF_ERROR_RETURN
  29241         (_bcm_port_flood_block_op(unit, TRUE, ingress_port, egress_port,
  29242                                   BCM_PORT_FLOOD_BLOCK_UNKNOWN_UCAST, &flags));
  29243 
  29244     /*
  29245      * Handle the devices with > 32 ports that use _HI convention
  29246      */
  29247 #if defined(BCM_RAPTOR_SUPPORT)
  29248        if (soc_feature(unit, soc_feature_register_hi)){
  29249            soc_reg_t reg;
  29250            uint32 enable;
  29251             reg = IS_ST_PORT(unit, ingress_port) ?
  29252                 IUNKNOWN_UCAST_BLOCK_MASK_HIr : UNKNOWN_UCAST_BLOCK_MASK_HIr;
  29253             enable = flags & BCM_PORT_FLOOD_BLOCK_UNKNOWN_UCAST;
  29254             BCM_IF_ERROR_RETURN
  29255                 (_bcm_port_flood_block_hi_set(unit, ingress_port, egress_port,
  29256                                               reg, enable));
  29257 
  29258             reg = IS_ST_PORT(unit, ingress_port) ?
  29259                 IUNKNOWN_MCAST_BLOCK_MASK_HIr : UNKNOWN_MCAST_BLOCK_MASK_HIr;
  29260             enable = flags & BCM_PORT_FLOOD_BLOCK_UNKNOWN_MCAST;
  29261             BCM_IF_ERROR_RETURN
  29262                 (_bcm_port_flood_block_hi_set(unit, ingress_port, egress_port,
  29263                                               reg, enable));
  29264 
  29265             reg = IS_ST_PORT(unit, ingress_port) ?
  29266                 IBCAST_BLOCK_MASK_HIr : BCAST_BLOCK_MASK_HIr;
  29267             enable = flags & BCM_PORT_FLOOD_BLOCK_BCAST;
  29268             BCM_IF_ERROR_RETURN
  29269                 (_bcm_port_flood_block_hi_set(unit, ingress_port, egress_port,
  29270                                               reg, enable));
  29271        }
  29272 #endif /* BCM_RAPTOR_SUPPORT */
  29273 
  29274     return BCM_E_NONE;
  29275 }
  29276 
  29277 /*
  29278  * Function:
  29279  *      bcm_port_flood_block_get
  29280  * Purpose:
  29281  *      Get the current per-port flood block settings
  29282  * Parameters:
  29283  *      unit            - unit number
  29284  *      ingress_port    - Port traffic is ingressing
  29285  *      egress_port     - Port for which the traffic would be blocked
  29286  *      flags           - (OUT) Returns the current settings
  29287  * Returns:
  29288  *      BCM_E_UNAVAIL   - Functionality not available
  29289  *      BCM_E_NONE
  29290  */
  29291 
  29292 int
  29293 bcm_esw_port_flood_block_get(int unit,
  29294                          bcm_port_t ingress_port, bcm_port_t egress_port,
  29295                          uint32 *flags)
  29296 {
  29297     uint32 enable;
  29298 
  29299     /* Make sure port module is initialized. */
  29300     PORT_INIT(unit);
  29301 
  29302     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, ingress_port,
  29303                                                      &ingress_port));
  29304     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, egress_port,
  29305                                                      &egress_port));
  29306 
  29307     *flags = 0;
  29308 
  29309 #if defined(BCM_XGS12_FABRIC_SUPPORT)
  29310     if (SOC_IS_XGS12_FABRIC(unit)) {
  29311         uint32  ports;
  29312         pbmp_t  pbmp;
  29313 
  29314         if (!IS_HG_PORT(unit, ingress_port)) {
  29315             return BCM_E_PORT;
  29316         }
  29317 
  29318         SOC_IF_ERROR_RETURN
  29319             (READ_ING_EGRMSKBMAPr(unit, ingress_port, &ports));
  29320         SOC_PBMP_CLEAR(pbmp);
  29321         SOC_PBMP_WORD_SET(pbmp, 0, ports);
  29322         if (!SOC_PBMP_MEMBER(pbmp, egress_port)) {
  29323             *flags = -1;        
  29324         }
  29325         return BCM_E_NONE;
  29326     }
  29327 #endif
  29328 
  29329 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \
  29330         || defined(BCM_BRADLEY_SUPPORT)
  29331     if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit)||
  29332         SOC_IS_HBX(unit) || SOC_IS_TRX(unit) || SOC_IS_HAWKEYE(unit)) {
  29333         BCM_IF_ERROR_RETURN
  29334             (_bcm_port_flood_block_op(unit, FALSE, ingress_port, egress_port,
  29335                                       BCM_PORT_FLOOD_BLOCK_ALL, &enable));
  29336         *flags |= enable;
  29337     }
  29338 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_BRADLEY_SUPPORT */
  29339 
  29340     BCM_IF_ERROR_RETURN
  29341         (_bcm_port_flood_block_op(unit, FALSE, ingress_port, egress_port,
  29342                                   BCM_PORT_FLOOD_BLOCK_BCAST, &enable));
  29343     *flags |= enable;
  29344 
  29345     BCM_IF_ERROR_RETURN
  29346         (_bcm_port_flood_block_op(unit, FALSE, ingress_port, egress_port,
  29347                                   BCM_PORT_FLOOD_BLOCK_UNKNOWN_MCAST,
  29348                                   &enable));
  29349     *flags |= enable;
  29350 
  29351     /*
  29352      * For some devices like RAVEN , which do not have support for
  29353      * blocking KNOWN_MCAST , continue processing.
  29354      */
  29355     BCM_IF_ERROR_NOT_UNAVAIL_RETURN
  29356         (_bcm_port_flood_block_op(unit, FALSE, ingress_port, egress_port,
  29357                                   BCM_PORT_FLOOD_BLOCK_KNOWN_MCAST,
  29358                                   &enable));
  29359     *flags |= enable;
  29360 
  29361     BCM_IF_ERROR_RETURN
  29362         (_bcm_port_flood_block_op(unit, FALSE, ingress_port, egress_port,
  29363                                   BCM_PORT_FLOOD_BLOCK_UNKNOWN_UCAST,
  29364                                   &enable));
  29365     *flags |= enable;
  29366 
  29367 #if defined(BCM_RAPTOR_SUPPORT)
  29368     if (soc_feature(unit, soc_feature_register_hi)){
  29369         soc_reg_t reg;
  29370         reg = IS_ST_PORT(unit, ingress_port) ?
  29371             IBCAST_BLOCK_MASK_HIr : BCAST_BLOCK_MASK_HIr;
  29372         BCM_IF_ERROR_RETURN
  29373             (_bcm_port_flood_block_hi_get(unit, ingress_port, egress_port,
  29374                                        reg, &enable));
  29375         *flags |= (enable) ? BCM_PORT_FLOOD_BLOCK_BCAST : 0;
  29376 
  29377         reg = IS_ST_PORT(unit, ingress_port) ?
  29378             IUNKNOWN_MCAST_BLOCK_MASK_HIr : UNKNOWN_MCAST_BLOCK_MASK_HIr;
  29379         BCM_IF_ERROR_RETURN
  29380             (_bcm_port_flood_block_hi_get(unit, ingress_port, egress_port,
  29381                                        reg, &enable));
  29382         *flags |= (enable) ? BCM_PORT_FLOOD_BLOCK_UNKNOWN_MCAST : 0;
  29383 
  29384         reg = IS_ST_PORT(unit, ingress_port) ?
  29385             IUNKNOWN_UCAST_BLOCK_MASK_HIr : UNKNOWN_UCAST_BLOCK_MASK_HIr;
  29386         BCM_IF_ERROR_RETURN
  29387             (_bcm_port_flood_block_hi_get(unit, ingress_port, egress_port,
  29388                                        reg, &enable));
  29389         *flags |= (enable) ? BCM_PORT_FLOOD_BLOCK_UNKNOWN_UCAST : 0;
  29390     }
  29391 #endif /* BCM_RAPTOR_SUPPORT */
  29392 
  29393     return BCM_E_NONE;
  29394 }
  29395 
  29396 /*
  29397  * Per-port leaky bucket ingress and egress rate limiting
  29398  *
  29399  * Granularity is in kbits/sec and a rate of 0 disables rate limiting.
  29400  * The max burst size is set in kbits.
  29401  */
  29402 
  29403 /*
  29404  * Function:
  29405  *      bcm_port_rate_egress_set
  29406  * Purpose:
  29407  *      Set egress rate limiting parameters
  29408  * Parameters:
  29409  *      unit - Device number
  29410  *      port - Port number
  29411  *      kbits_sec - Rate in kilobits (1000 bits) per second.
  29412  *                      Rate of 0 disables rate limiting.
  29413  *      kbits_burst - Maximum burst size in kilobits (1000 bits).
  29414  * Returns:
  29415  *      BCM_E_XXX
  29416  */
  29417 
  29418 int
  29419 bcm_esw_port_rate_egress_set(int unit,
  29420                              bcm_port_t port,
  29421                              uint32 kbits_sec,
  29422                              uint32 kbits_burst)
  29423 {
  29424     /* Make sure port module is initialized. */
  29425     PORT_INIT(unit);
  29426 
  29427     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  29428 
  29429     if (!soc_feature(unit, soc_feature_egress_metering)) {
  29430         return BCM_E_UNAVAIL;
  29431     } else {
  29432         return mbcm_driver[unit]->mbcm_port_rate_egress_set(unit, port,
  29433                                                             kbits_sec,
  29434                                                             kbits_burst,
  29435                                                             _BCM_PORT_RATE_BYTE_MODE);
  29436     }
  29437 
  29438     return BCM_E_NONE;
  29439 }
  29440 
  29441 /*
  29442  * Function:
  29443  *      bcm_port_rate_egress_pps_set
  29444  * Purpose:
  29445  *      Set egress rate limiting parameter in packet mode.
  29446  * Parameters:
  29447  *      unit - Device number
  29448  *      port - Port number
  29449  *      pps -  Rate in pps
  29450  *             Rate of 0 disables rate limiting.
  29451  *      burst - Maximum burst size
  29452  * Returns:
  29453  *      BCM_E_XXX
  29454  */
  29455 
  29456 int
  29457 bcm_esw_port_rate_egress_pps_set(int unit,
  29458                              bcm_port_t port,
  29459                              uint32 pps,
  29460                              uint32 burst)
  29461 {
  29462     /* Make sure port module is initialized. */
  29463     PORT_INIT(unit);
  29464 
  29465     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  29466 
  29467     if (!soc_feature(unit, soc_feature_egress_metering)) {
  29468         return BCM_E_UNAVAIL;
  29469     } else {
  29470         return mbcm_driver[unit]->mbcm_port_rate_egress_set(unit, port,
  29471                                                             pps,
  29472                                                             burst,
  29473                                                             _BCM_PORT_RATE_PPS_MODE);
  29474     }
  29475 
  29476     return BCM_E_NONE;
  29477 }
  29478 
  29479 
  29480 /*
  29481  * Function:
  29482  *      bcm_port_rate_egress_get
  29483  * Purpose:
  29484  *      Get egress rate limiting parameters
  29485  * Parameters:
  29486  *      unit - Device number
  29487  *      port - Port number
  29488  *      kbits_sec - (OUT) Rate in kilobits (1000 bits) per second, or
  29489  *                        zero if rate limiting is disabled.
  29490  *      kbits_burst - (OUT) Maximum burst size in kilobits (1000 bits).
  29491  * Returns:
  29492  *      BCM_E_XXX
  29493  */
  29494 
  29495 int
  29496 bcm_esw_port_rate_egress_get(int unit,
  29497                              bcm_port_t port,
  29498                              uint32 *kbits_sec,
  29499                              uint32 *kbits_burst)
  29500 {
  29501     uint32 flags = 0;
  29502     int    rv = BCM_E_NONE;
  29503 
  29504     /* Make sure port module is initialized. */
  29505     PORT_INIT(unit);
  29506 
  29507     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  29508 
  29509     if (!soc_feature(unit, soc_feature_egress_metering)) {
  29510         return BCM_E_UNAVAIL;
  29511     } else {
  29512         rv = mbcm_driver[unit]->mbcm_port_rate_egress_get(unit, port,
  29513                                                             kbits_sec,
  29514                                                             kbits_burst,
  29515                                                             &flags);
  29516     }
  29517 
  29518     if (BCM_SUCCESS(rv)) {
  29519         if (flags == _BCM_PORT_RATE_BYTE_MODE) {
  29520             return BCM_E_NONE;
  29521         } else {
  29522             /* Set as pps; kbits cannot be returned */
  29523             return BCM_E_CONFIG;
  29524         }
  29525     }
  29526 
  29527     return rv;
  29528 }
  29529 
  29530 /*
  29531  * Function:
  29532  *      bcm_port_rate_egress_pps_get
  29533  * Purpose:
  29534  *      Get egress rate limiting parameter in packet mode.
  29535  * Parameters:
  29536  *      unit - Device number
  29537  *      port - Port number
  29538  *      pps -  (OUT) Rate in pps
  29539  *                   0 if rate limiting is disabled
  29540  *      burst -(OUT) burst size
  29541  * Returns:
  29542  *      BCM_E_XXX
  29543  */
  29544 
  29545 int
  29546 bcm_esw_port_rate_egress_pps_get(int unit,
  29547                              bcm_port_t port,
  29548                              uint32 *pps,
  29549                              uint32 *burst)
  29550 {
  29551     uint32 flags = 0;
  29552     int    rv = BCM_E_NONE;
  29553 
  29554     /* Make sure port module is initialized. */
  29555     PORT_INIT(unit);
  29556 
  29557     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  29558 
  29559     if (!soc_feature(unit, soc_feature_egress_metering)) {
  29560         return BCM_E_UNAVAIL;
  29561     } else {
  29562         rv = mbcm_driver[unit]->mbcm_port_rate_egress_get(unit, port,
  29563                                                             pps,
  29564                                                             burst,
  29565                                                             &flags);
  29566     }
  29567 
  29568     if (BCM_SUCCESS(rv)) {
  29569         if (flags == _BCM_PORT_RATE_PPS_MODE) {
  29570             return BCM_E_NONE;
  29571         } else {
  29572             /* Set as kbits; pps cannot be returned */
  29573             return BCM_E_CONFIG;
  29574         }
  29575     }
  29576     return rv;
  29577 }
  29578 
  29579 /*
  29580  * Function:
  29581  *      bcm_port_rate_ingress_set
  29582  * Purpose:
  29583  *      Set ingress rate limiting parameters
  29584  * Parameters:
  29585  *      unit - Device number
  29586  *      port - Port number
  29587  *      kbits_sec - Rate in kilobits (1000 bits) per second.
  29588  *                  Rate of 0 disables rate limiting.
  29589  *      kbits_burst - Maximum burst size in kilobits (1000 bits).
  29590  * Returns:
  29591  *      BCM_E_XXX
  29592  */
  29593 
  29594 int
  29595 bcm_esw_port_rate_ingress_set(int unit,
  29596                               bcm_port_t port,
  29597                               uint32 kbits_sec,
  29598                               uint32 kbits_burst)
  29599 {
  29600     /* Make sure port module is initialized. */
  29601     PORT_INIT(unit);
  29602 
  29603     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  29604 
  29605 #ifdef BCM_XGS3_SWITCH_SUPPORT
  29606     if (SOC_IS_XGS3_SWITCH(unit)) {
  29607         /*
  29608          * Use port-based ingress metering function.
  29609          * Enabling rate-based ingress metering on the Firebolt
  29610          * will also enable rate-based pause frames on this port.
  29611          */
  29612         return bcm_xgs3_port_rate_ingress_set(unit, port, kbits_sec,
  29613                                               kbits_burst);
  29614     }
  29615 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  29616 
  29617     return BCM_E_UNAVAIL;
  29618 }
  29619 
  29620 /*
  29621  * Function:
  29622  *      bcm_port_rate_ingress_get
  29623  * Purpose:
  29624  *      Get ingress rate limiting parameters
  29625  * Parameters:
  29626  *      unit - Device number
  29627  *      port - Port number
  29628  *      kbits_sec - (OUT) Rate in kilobits (1000 bits) per second, or
  29629  *                        zero if rate limiting is disabled.
  29630  *      kbits_burst - (OUT) Maximum burst size in kilobits (1000 bits).
  29631  * Returns:
  29632  *      BCM_E_XXX
  29633  */
  29634 
  29635 int
  29636 bcm_esw_port_rate_ingress_get(int unit,
  29637                               bcm_port_t port,
  29638                               uint32 *kbits_sec,
  29639                               uint32 *kbits_burst)
  29640 {
  29641     /* Make sure port module is initialized. */
  29642     PORT_INIT(unit);
  29643 
  29644     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  29645 
  29646     if (!kbits_sec || !kbits_burst) {
  29647         return BCM_E_PARAM;
  29648     }
  29649 
  29650 #ifdef BCM_XGS3_SWITCH_SUPPORT
  29651     if (SOC_IS_XGS3_SWITCH(unit)) {
  29652        /* Use port-based ingress metering function */
  29653         return bcm_xgs3_port_rate_ingress_get(unit, port, kbits_sec,
  29654                                             kbits_burst);
  29655     }
  29656 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  29657 
  29658     *kbits_sec = 0;
  29659     *kbits_burst = 0;
  29660 
  29661     return BCM_E_UNAVAIL;
  29662 }
  29663 
  29664 /*
  29665  * Function:
  29666  *      bcm_port_rate_pause_set
  29667  * Purpose:
  29668  *      Set ingress rate limiting pause frame control parameters
  29669  * Parameters:
  29670  *      unit - Device number
  29671  *      port - Port number
  29672  *      kbits_pause - Pause threshold in kbits (1000 bits).
  29673  *              A value of zero disables the pause/resume mechanism.
  29674  *      kbits_resume - Resume threshold in kbits (1000 bits).
  29675  * Returns:
  29676  *      BCM_E_XXX
  29677  * Notes:
  29678  *      This interface applies only when port ingress rate limiting
  29679  *      is active.  Currently, only the 566x supports this feature.
  29680  *
  29681  *      If the maximum of bits that could be received before dropping a
  29682  *      frame falls below the kbits_pause, a pause frame is sent.
  29683  *      A resume frame will be sent once it becomes possible to receive
  29684  *      kbits_resume bits of data without dropping.
  29685  */
  29686 
  29687 int
  29688 bcm_esw_port_rate_pause_set(int unit,
  29689                             bcm_port_t port,
  29690                             uint32 kbits_pause,
  29691                             uint32 kbits_resume)
  29692 {
  29693     /* Make sure port module is initialized. */
  29694     PORT_INIT(unit);
  29695 
  29696     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  29697 
  29698 #ifdef BCM_FIREBOLT_SUPPORT
  29699     /*
  29700      * For Firebolt, rate-based pause frames are generated as
  29701      * a result of rate-based metering. As such, their behavior
  29702      * is not directly controllable, but may be read.
  29703      * see bcm_port_rate_pause_get().
  29704      */
  29705 #endif /* BCM_FIREBOLT_SUPPORT */
  29706     /* Otherwise, not supported  */
  29707     return (kbits_pause == 0) ? BCM_E_NONE : BCM_E_UNAVAIL;
  29708 }
  29709 
  29710 /*
  29711  * Function:
  29712  *      bcm_port_rate_pause_get
  29713  * Purpose:
  29714  *      Get ingress rate limiting pause frame control parameters
  29715  * Parameters:
  29716  *      unit - Device number
  29717  *      port - Port number
  29718  *      kbits_pause - (OUT) Pause threshold in kbits (1000 bits).
  29719  *              Zero indicates the pause/resume mechanism is disabled.
  29720  *      kbits_resume - (OUT) Resume threshold in kbits (1000 bits).
  29721  * Returns:
  29722  *      BCM_E_XXX
  29723  */
  29724 
  29725 int
  29726 bcm_esw_port_rate_pause_get(int unit,
  29727                             bcm_port_t port,
  29728                             uint32 *kbits_pause,
  29729                             uint32 *kbits_resume)
  29730 {
  29731     /* Make sure port module is initialized. */
  29732     PORT_INIT(unit);
  29733 
  29734 #if defined(BCM_HGPROXY_COE_SUPPORT)
  29735     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  29736         BCM_GPORT_IS_SET(port) &&
  29737         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  29738         return BCM_E_PORT;
  29739     } else
  29740 #endif /* BCM_HGPROXY_COE_SUPPORT */
  29741 
  29742 #if defined(BCM_KATANA2_SUPPORT)
  29743     if (BCM_GPORT_IS_SET(port) &&
  29744         _BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port)) {
  29745         return BCM_E_PORT;
  29746     }
  29747 #endif
  29748     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  29749 
  29750 #ifdef BCM_MONTEREY_SUPPORT
  29751     if (SOC_IS_MONTEREY(unit)) {
  29752         *kbits_pause = 0;
  29753         *kbits_resume = 0;
  29754         return BCM_E_UNAVAIL;
  29755     } else
  29756 #endif
  29757 #ifdef BCM_TOMAHAWK_SUPPORT
  29758     if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
  29759         *kbits_pause = 0;
  29760         *kbits_resume = 0;
  29761         return BCM_E_UNAVAIL;
  29762     } else
  29763 #endif /* BCM_TOMAHAWK_SUPPORT */
  29764 #ifdef BCM_TRIDENT2_SUPPORT
  29765     if (SOC_IS_TD2_TT2(unit)) {
  29766         return bcm_td2_port_rate_pause_get(unit, port, kbits_pause,
  29767                                            kbits_resume);
  29768     } else
  29769 #endif /* BCM_TRIDENT2_SUPPORT */
  29770 #ifdef BCM_TRIUMPH_SUPPORT
  29771     if (SOC_IS_TR_VL(unit) && !SOC_IS_HURRICANEX(unit) &&
  29772         !SOC_IS_GREYHOUND(unit) && !SOC_IS_GREYHOUND2(unit)) {
  29773         return bcm_tr_port_rate_pause_get(unit, port, kbits_pause,
  29774                                           kbits_resume);
  29775     }
  29776 #endif /* BCM_TRIUMPH_SUPPORT */
  29777 #ifdef BCM_FIREBOLT_SUPPORT
  29778     if (SOC_IS_FBX(unit)) {
  29779         return bcm_fb_port_rate_pause_get(unit, port, kbits_pause,
  29780                                           kbits_resume);
  29781     }
  29782 #endif /* BCM_FIREBOLT_SUPPORT */
  29783     /* Otherwise, not supported */
  29784     *kbits_pause = 0;
  29785     *kbits_resume = 0;
  29786     return BCM_E_UNAVAIL;
  29787 }
  29788 
  29789 /*
  29790  * Function:
  29791  *      bcm_port_sample_rate_set
  29792  * Purpose:
  29793  *      Control the sampling of packets ingressing or egressing a port
  29794  * Parameters:
  29795  *      unit - Device number
  29796  *      port - Port number
  29797  *      ingress_rate - Every 1/ingress_rate packets will be sampled
  29798  *              0 indicates no sampling
  29799  *              1 indicates sampling all packets
  29800  *      egress_rate - Every 1/egress_rate packets will be sampled
  29801  *              0 indicates no sampling
  29802  *              1 indicates sampling all packets
  29803  * Returns:
  29804  *      BCM_E_XXX
  29805  * Notes:
  29806  *      This API is a building block for supporting sFlow (RFC 3176)
  29807  */
  29808 
  29809 int
  29810 bcm_esw_port_sample_rate_set(int unit, bcm_port_t port,
  29811                          int ingress_rate, int egress_rate)
  29812 {
  29813     /* Make sure port module is initialized. */
  29814     PORT_INIT(unit);
  29815 
  29816     /*
  29817      * IMPLEMENTATION NOTES
  29818      *
  29819      * ingress_rate maps into the per port SFLOW_ING_THRESHOLD reg:
  29820      *  if (ingress_rate <= 0) {
  29821      *          SFLOW_ING_THRESHOLD.ENABLE=0
  29822      *          SFLOW_ING_THRESHOLD.THRESHOLD=0
  29823      *  } else {
  29824      *          SFLOW_ING_THRESHOLD.ENABLE=1
  29825      *          SFLOW_ING_THRESHOLD.THRESHOLD=0xffff/ingress_rate
  29826      *  }
  29827      * egress_rate maps into the per port SFLOW_EGR_THRESHOLD reg:
  29828      *  if (egress_rate <= 0) {
  29829      *          SFLOW_EGR_THRESHOLD.ENABLE=0
  29830      *          SFLOW_EGR_THRESHOLD.THRESHOLD=0
  29831      *  } else {
  29832      *          SFLOW_EGR_THRESHOLD.ENABLE=1
  29833      *          SFLOW_EGR_THRESHOLD.THRESHOLD=0xffff/egress_rate
  29834      *  }
  29835      *
  29836      * bcmSwitchCpuSamplePrio maps to CPU_CONTROL_2.CPU_SFLOW_PRIORITY
  29837      * bcmSwitchSampleIngressRandomSeed maps to SFLOW_ING_RAND_SEED.SEED
  29838      * bcmSwitchSampleEgressRandomSeed maps to SFLOW_EGR_RAND_SEED.SEED
  29839      *
  29840      * There are two related RX reason codes defined in <bcm/rx.h>
  29841      *  BCM_RX_PR_SAMPLE_SRC
  29842      *  BCM_RX_PR_SAMPLE_DST
  29843      */
  29844 
  29845     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  29846     if (ingress_rate < 0 || egress_rate < 0) {
  29847         return BCM_E_PARAM;
  29848     }
  29849 
  29850 #ifdef BCM_XGS3_SWITCH_SUPPORT
  29851     if (SOC_IS_XGS3_SWITCH(unit)) {
  29852         return bcm_xgs3_port_sample_rate_set(unit, port,
  29853                                              ingress_rate, egress_rate);
  29854     }
  29855 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  29856 
  29857     return BCM_E_UNAVAIL;
  29858 }
  29859 
  29860 /*
  29861  * Function:
  29862  *      bcm_port_sample_rate_get
  29863  * Purpose:
  29864  *      Get the sampling of packets ingressing or egressing a port
  29865  * Parameters:
  29866  *      unit - Device number
  29867  *      port - Port number
  29868  *      ingress_rate - Every 1/ingress_rate packets will be sampled
  29869  *              0 indicates no sampling
  29870  *              1 indicates sampling all packets
  29871  *      egress_rate - Every 1/egress_rate packets will be sampled
  29872  *              0 indicates no sampling
  29873  *              1 indicates sampling all packets
  29874  * Returns:
  29875  *      BCM_E_UNIT
  29876  *      BCM_E_PARAM
  29877  *      BCM_E_UNAVAIL
  29878  *      BCM_E_XXX
  29879  * Notes:
  29880  *      This API is a building block for supporting sFlow (RFC 3176)
  29881  */
  29882 
  29883 int
  29884 bcm_esw_port_sample_rate_get(int unit, bcm_port_t port,
  29885                          int *ingress_rate, int *egress_rate)
  29886 {
  29887     /* Make sure port module is initialized. */
  29888     PORT_INIT(unit);
  29889 
  29890     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  29891 
  29892     if (ingress_rate == NULL  || egress_rate == NULL) {
  29893         return BCM_E_PARAM;
  29894     }
  29895 
  29896 #ifdef BCM_XGS3_SWITCH_SUPPORT
  29897     if (SOC_IS_XGS3_SWITCH(unit)) {
  29898         return bcm_xgs3_port_sample_rate_get(unit, port,
  29899                                            ingress_rate, egress_rate);
  29900     }
  29901 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  29902 
  29903 
  29904     return BCM_E_UNAVAIL;
  29905 }
  29906 
  29907 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  29908 #ifdef BCM_WARM_BOOT_SUPPORT
  29909 STATIC int
  29910 _bcm_esw_sflow_counter_wb_recover(int unit, soc_mem_t mem)
  29911 {
  29912     int idx_min, idx_max, i, id, rv = 0;
  29913     soc_counter_non_dma_t *non_dma = NULL;
  29914     soc_control_t *soc;
  29915     uint32 count = 0, subset_ct = 0, sflow_enable = 0;
  29916     uint8 *sflow_tbl_chunk = NULL;
  29917     void *sflow_entry;
  29918 
  29919     soc = SOC_CONTROL(unit);
  29920 
  29921     idx_min = soc_mem_index_min(unit, mem);
  29922     idx_max = soc_mem_index_max(unit, mem);
  29923     sflow_tbl_chunk = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, mem),
  29924                         "sFlow Ingress Data Source table buffer");
  29925     if (sflow_tbl_chunk == NULL) {
  29926         return BCM_E_MEMORY;
  29927     }
  29928 
  29929     /* Read Ingress rate data table entries */
  29930     sal_memset(sflow_tbl_chunk, 0, SOC_MEM_TABLE_BYTES(unit, mem));
  29931     rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, idx_min, idx_max,
  29932                             sflow_tbl_chunk);
  29933     if (SOC_FAILURE(rv)) {
  29934         soc_cm_sfree(unit, sflow_tbl_chunk);
  29935         return rv;
  29936     }
  29937 
  29938     if (mem == SFLOW_ING_DATA_SOURCEm) {
  29939         id = SOC_COUNTER_NON_DMA_SFLOW_ING_PKT;
  29940     } else {
  29941         id = SOC_COUNTER_NON_DMA_SFLOW_FLEX_PKT;
  29942     }
  29943 
  29944     for(i = idx_min; i < idx_max; i++) {
  29945         sflow_entry = soc_mem_table_idx_to_pointer(unit, mem, void *,
  29946                                                    sflow_tbl_chunk, i);
  29947         sflow_enable = soc_mem_field32_get(unit, mem, sflow_entry, ENABLEf);
  29948 
  29949         if (sflow_enable) {
  29950             non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START];
  29951             /* Do PACKET_CTRf and BYTE_CTRf sequentially. Hence 2x loop */
  29952             subset_ct = non_dma->extra_ctr_ct << 1;
  29953             non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID;
  29954             non_dma = non_dma->extra_ctrs;
  29955 
  29956             do {
  29957                 non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID;
  29958                 /* BYTE_CTRf not currently supported */
  29959                 count += 2;
  29960                 non_dma += 2;
  29961             } while ((count < subset_ct));
  29962             break;
  29963         }
  29964     }
  29965 
  29966     soc_cm_sfree(unit, sflow_tbl_chunk);
  29967     return BCM_E_NONE;
  29968 }
  29969 
  29970 /**
  29971  * Function:
  29972  *      _bcm_esw_sflow_wb_recover
  29973  * Purpose:
  29974  *      sFlow Warmboot Recovery
  29975  * Parameters:
  29976  *      unit - (IN) Unit number
  29977  * Returns:
  29978  *      BCM_E_xxx
  29979  */
  29980 STATIC int
  29981 _bcm_esw_sflow_wb_recover(int unit) {
  29982     int rv = 0;
  29983 
  29984     if (soc_feature(unit, soc_feature_sflow_ing_mem)) {
  29985         rv = _bcm_esw_sflow_counter_wb_recover(unit, SFLOW_ING_DATA_SOURCEm);
  29986         if (BCM_FAILURE(rv)) {
  29987             return rv;
  29988         }
  29989     }
  29990 
  29991     if (soc_feature(unit, soc_feature_sflow_flex)) {
  29992         rv = _bcm_esw_sflow_counter_wb_recover(unit,
  29993                 SFLOW_ING_FLEX_DATA_SOURCEm);
  29994         if (BCM_FAILURE(rv)) {
  29995             return rv;
  29996         }
  29997     }
  29998 
  29999     return BCM_E_NONE;
  30000 }
  30001 #endif /* BCM_WARM_BOOT_SUPPORT */
  30002 #endif /* BCM_TOMAHAWK_SUPPORT */
  30003 
  30004 /*
  30005  * Double Tagging
  30006  */
  30007 
  30008 /*
  30009  * Function:
  30010  *      bcm_port_dtag_mode_set
  30011  * Description:
  30012  *      Set the double-tagging mode of a port.
  30013  * Parameters:
  30014  *      unit - Device number
  30015  *      port - Port number
  30016  *      mode - Double-tagging mode, one of:
  30017  *              BCM_PORT_DTAG_MODE_NONE            No double tagging
  30018  *              BCM_PORT_DTAG_MODE_INTERNAL        Service Provider port
  30019  *              BCM_PORT_DTAG_MODE_EXTERNAL        Customer port
  30020  *              BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG  Remove customer tag
  30021  *              BCM_PORT_DTAG_ADD_EXTERNAL_TAG     Add customer tag
  30022  * Return Value:
  30023  *      BCM_E_XXX
  30024  * Notes:
  30025  *      BCM_PORT_DTAG_MODE_INTERNAL is for service provider ports.
  30026  *              A tag will be added if the packet does not already
  30027  *              have the internal TPID (see bcm_port_tpid_set below).
  30028  *              Internally this sets DT_MODE and clears IGNORE_TAG.
  30029  *      BCM_PORT_DTAG_MODE_EXTERNAL is for customer ports.
  30030  *              The service provider TPID will always be added
  30031  *              (see bcm_port_tpid_set below).
  30032  *              Internally this sets DT_MODE and sets IGNORE_TAG.
  30033  *      On some chips, such as BCM5665, double-tag enable is a system-wide
  30034  *              setting rather than a port setting, so enabling double-
  30035  *              tagging on one port may enable it on all ports.
  30036  */
  30037 
  30038 int
  30039 bcm_esw_port_dtag_mode_set(int unit, bcm_port_t port, int mode)
  30040 {
  30041 #ifdef BCM_FIREBOLT_SUPPORT
  30042     int         dt_mode, ignore_tag;
  30043 #endif
  30044     int         dt_mode_mask;
  30045 
  30046     /* Make sure port module is initialized. */
  30047     PORT_INIT(unit);
  30048 
  30049     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  30050     /* Skip PORT_SWITCHED_CHECK for Higig lookup (for q-in-q proxy) */
  30051     if (!(IS_ST_PORT(unit, port) &&
  30052           soc_feature(unit, soc_feature_higig_lookup))) {
  30053         PORT_SWITCHED_CHECK(unit, port);
  30054     }
  30055 
  30056     dt_mode_mask = BCM_PORT_DTAG_MODE_INTERNAL |
  30057         BCM_PORT_DTAG_MODE_EXTERNAL;
  30058 
  30059 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || defined(BCM_TRX_SUPPORT)
  30060     if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || \
  30061         SOC_IS_HAWKEYE(unit) || SOC_IS_TRX(unit)) {
  30062         if (mode & ~(BCM_PORT_DTAG_MODE_INTERNAL |
  30063                      BCM_PORT_DTAG_MODE_EXTERNAL |
  30064                      BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG |
  30065                      BCM_PORT_DTAG_ADD_EXTERNAL_TAG)) {
  30066             return BCM_E_UNAVAIL;
  30067         }
  30068 
  30069         if (IS_ST_PORT(unit, port)) {
  30070             /* Addition or removal of two tags is not supported on
  30071              * Higig / Higig Lite ports.
  30072              */
  30073             if (mode & BCM_PORT_DTAG_ADD_EXTERNAL_TAG ||
  30074                 mode & BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG) {
  30075                 return BCM_E_PARAM;
  30076             }
  30077         }
  30078 
  30079         /* Removal of two tags should be enable only for UNI egress ports. */
  30080         if (mode == (BCM_PORT_DTAG_MODE_INTERNAL |
  30081                      BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG)) {
  30082             return BCM_E_PARAM;
  30083         }
  30084 
  30085 #ifdef BCM_TRX_SUPPORT
  30086         if (SOC_IS_TRX(unit)) {
  30087             if (!soc_feature(unit, soc_feature_vlan_action)) {
  30088                 return BCM_E_UNAVAIL;
  30089             }
  30090             return  _bcm_trx_port_dtag_mode_set(unit, port, mode);
  30091         }
  30092 #endif
  30093     } else
  30094 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
  30095     if (0 != (mode & ~dt_mode_mask)) {
  30096         /* Some devices do not support the add/remove tag options */
  30097         return BCM_E_UNAVAIL;
  30098     }
  30099 
  30100 #ifdef BCM_FIREBOLT_SUPPORT
  30101     switch (mode & dt_mode_mask) {
  30102       case BCM_PORT_DTAG_MODE_NONE:
  30103           dt_mode = 0;
  30104           ignore_tag = 0;
  30105           break;
  30106       case BCM_PORT_DTAG_MODE_INTERNAL:
  30107           dt_mode = 1;
  30108           ignore_tag = 0;
  30109           break;
  30110       case BCM_PORT_DTAG_MODE_EXTERNAL:
  30111           dt_mode = 1;
  30112           ignore_tag = 1;
  30113           break;
  30114       default:
  30115           return BCM_E_PARAM;
  30116     }
  30117 
  30118     if (SOC_IS_FBX(unit)) {
  30119         return _bcm_fb_port_dtag_mode_set(unit, port, mode,
  30120                                           dt_mode, ignore_tag);
  30121     }
  30122 #endif
  30123     return BCM_E_UNAVAIL;
  30124 }
  30125 
  30126 /*
  30127  * Function:
  30128  *      bcm_port_dtag_mode_get
  30129  * Description:
  30130  *      Return the current double-tagging mode of a port.
  30131  * Parameters:
  30132  *      unit - Device number
  30133  *      port - Port number
  30134  *      mode - (OUT) Double-tagging mode
  30135  * Return Value:
  30136  *      BCM_E_XXX
  30137  */
  30138 
  30139 int
  30140 bcm_esw_port_dtag_mode_get(int unit, bcm_port_t port, int *mode)
  30141 {
  30142     /* Make sure port module is initialized. */
  30143     PORT_INIT(unit);
  30144 
  30145     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  30146     /* Skip PORT_SWITCHED_CHECK for Higig lookup (for q-in-q proxy) */
  30147     if (!(IS_ST_PORT(unit, port) &&
  30148           soc_feature(unit, soc_feature_higig_lookup))) {
  30149         PORT_SWITCHED_CHECK(unit, port);
  30150     }
  30151 
  30152     if (mode == NULL) {
  30153         return BCM_E_PARAM;
  30154     }
  30155 
  30156 #ifdef BCM_TRX_SUPPORT
  30157     if (SOC_IS_TRX(unit)) {
  30158         *mode = PORT(unit, port).dtag_mode;
  30159         return BCM_E_NONE;
  30160     }
  30161 #endif
  30162 
  30163 #ifdef BCM_FIREBOLT_SUPPORT
  30164     if (SOC_IS_FBX(unit)) {
  30165         return _bcm_fb_port_dtag_mode_get(unit, port, mode);
  30166     }
  30167 #endif
  30168 
  30169     return BCM_E_UNAVAIL;
  30170 }
  30171 
  30172 /*
  30173  * Function:
  30174  *      _bcm_esw_mod_port_tpid_set
  30175  * Description:
  30176  *      Set the Tag Protocol ID for a (module, port).
  30177  * Parameters:
  30178  *      unit - Device number
  30179  *      mod  - Module ID
  30180  *      port - Port number
  30181  *      tpid - Tag Protocol ID
  30182  * Return Value:
  30183  *      BCM_E_XXX
  30184  */
  30185 STATIC int
  30186 _bcm_esw_mod_port_tpid_set(int unit, bcm_module_t mod, bcm_port_t port,
  30187         uint16 tpid)
  30188 {
  30189 #ifdef BCM_HURRICANE3_SUPPORT
  30190     if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  30191         return _bcm_hr3_mod_port_tpid_set(unit, mod, port, tpid);
  30192     } else
  30193 #endif /* BCM_HURRICANE3_SUPPORT */
  30194 #ifdef BCM_TRIDENT_SUPPORT
  30195     {
  30196         return _bcm_td_mod_port_tpid_set(unit, mod, port, tpid);
  30197     }
  30198 #endif /* BCM_TRIDENT_SUPPORT */
  30199     return BCM_E_UNAVAIL;
  30200 }
  30201 
  30202 #if defined(BCM_MONTEREY_SUPPORT)
  30203 STATIC
  30204 void bcm_port_inner_tpid_obm_set(int unit, bcm_port_t port, uint16 tpid)
  30205 {
  30206    uint32 rval32 = 0;
  30207    int obm, pgw, pgw_inst;
  30208    soc_info_t  *si;
  30209    soc_reg_t reg;
  30210    static const soc_reg_t obm_inner_tpid_regs[] = {
  30211         IDB_OBM0_INNER_TPIDr, IDB_OBM1_INNER_TPIDr,
  30212         IDB_OBM2_INNER_TPIDr, IDB_OBM3_INNER_TPIDr,
  30213         IDB_OBM4_INNER_TPIDr, IDB_OBM5_INNER_TPIDr,
  30214         IDB_OBM6_INNER_TPIDr, IDB_OBM7_INNER_TPIDr
  30215     };
  30216     if ((port < 1) || (port > 64)) {
  30217         return;
  30218     }
  30219     si = &SOC_INFO(unit);
  30220     obm = si->port_serdes[port];
  30221     obm %= MONTEREY_TSCS_PER_PGW;
  30222 
  30223     pgw = si->port_group[port];
  30224     pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK);
  30225 
  30226     reg =  obm_inner_tpid_regs[obm];
  30227 
  30228     soc_reg32_get(unit, reg, pgw_inst, 0, &rval32);
  30229     soc_reg_field_set(unit, reg, &rval32, TPIDf, tpid);
  30230     soc_reg_field_set(unit, reg, &rval32, ENABLEf, tpid ? 1 : 0);
  30231     soc_reg32_set(unit, reg, pgw_inst, 0, rval32);
  30232     return;
  30233 }
  30234 STATIC
  30235 void bcm_inner_tpid_obm_set(int unit, uint16 tpid)
  30236 {
  30237    int port;
  30238    BCM_PBMP_ITER(PBMP_PORT_ALL(unit), port) {
  30239         bcm_port_inner_tpid_obm_set(unit, port, tpid);
  30240    }
  30241    return;
  30242 }
  30243 STATIC
  30244 void bcm_port_outer_tpid_obm_set(int unit, bcm_port_t port,
  30245                                  uint16 tpid, int tpid_index)
  30246 {
  30247    uint32 rval32 = 0;
  30248    int obm, pgw, pgw_inst;
  30249    soc_info_t  *si;
  30250    soc_reg_t reg;
  30251    static const soc_reg_t obm_inner_tpid_regs[][4] = {
  30252         {IDB_OBM0_OUTER_TPID_0r, IDB_OBM0_OUTER_TPID_1r,
  30253          IDB_OBM0_OUTER_TPID_2r, IDB_OBM0_OUTER_TPID_3r},
  30254         {IDB_OBM1_OUTER_TPID_0r, IDB_OBM1_OUTER_TPID_1r,
  30255          IDB_OBM1_OUTER_TPID_2r, IDB_OBM1_OUTER_TPID_3r},
  30256         {IDB_OBM2_OUTER_TPID_0r, IDB_OBM2_OUTER_TPID_1r,
  30257          IDB_OBM2_OUTER_TPID_2r, IDB_OBM2_OUTER_TPID_3r},
  30258         {IDB_OBM3_OUTER_TPID_0r, IDB_OBM3_OUTER_TPID_1r,
  30259          IDB_OBM3_OUTER_TPID_2r, IDB_OBM3_OUTER_TPID_3r},
  30260         {IDB_OBM4_OUTER_TPID_0r, IDB_OBM4_OUTER_TPID_1r,
  30261          IDB_OBM4_OUTER_TPID_2r, IDB_OBM4_OUTER_TPID_3r},
  30262         {IDB_OBM5_OUTER_TPID_0r, IDB_OBM5_OUTER_TPID_1r,
  30263          IDB_OBM5_OUTER_TPID_2r, IDB_OBM5_OUTER_TPID_3r},
  30264         {IDB_OBM6_OUTER_TPID_0r, IDB_OBM6_OUTER_TPID_1r,
  30265          IDB_OBM6_OUTER_TPID_2r, IDB_OBM6_OUTER_TPID_3r},
  30266         {IDB_OBM7_OUTER_TPID_0r, IDB_OBM7_OUTER_TPID_1r,
  30267          IDB_OBM7_OUTER_TPID_2r, IDB_OBM7_OUTER_TPID_3r}
  30268     };
  30269     if ((port < 1) || (port > 64) ||
  30270         (tpid_index < 0) || (tpid_index > 3)) {
  30271         return;
  30272     }
  30273     si = &SOC_INFO(unit);
  30274     obm = si->port_serdes[port];
  30275     obm %= MONTEREY_TSCS_PER_PGW;
  30276 
  30277     pgw = si->port_group[port];
  30278     pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK);
  30279 
  30280     reg =  obm_inner_tpid_regs[obm][tpid_index];
  30281 
  30282     soc_reg32_get(unit, reg, pgw_inst, 0, &rval32);
  30283     soc_reg_field_set(unit, reg, &rval32, TPIDf, tpid);
  30284     soc_reg_field_set(unit, reg, &rval32, ENABLEf, tpid ? 1 : 0);
  30285     soc_reg32_set(unit, reg, pgw_inst, 0, rval32);
  30286     return;
  30287 }
  30288 #endif
  30289 /*
  30290  * Function:
  30291  *      bcm_port_tpid_set
  30292  * Description:
  30293  *      Set the default Tag Protocol ID for a port.
  30294  * Parameters:
  30295  *      unit - Device number
  30296  *      port - Port number
  30297  *      tpid - Tag Protocol ID
  30298  * Return Value:
  30299  *      BCM_E_XXX
  30300  * Notes:
  30301  *      This API is not specifically double-tagging-related, but
  30302  *      the port TPID becomes the service provider TPID when double-tagging
  30303  *      is enabled on a port.  The default TPID is 0x8100.
  30304  *      On BCM5665, only 0x8100 is allowed for the inner (customer) tag.
  30305  */
  30306 
  30307 int
  30308 bcm_esw_port_tpid_set(int unit, bcm_port_t port, uint16 tpid)
  30309 {
  30310     int rv = BCM_E_UNAVAIL;
  30311     bcm_module_t mod_out;
  30312     bcm_port_t port_out;
  30313     bcm_trunk_t tgid_out;
  30314     int id_out;
  30315     int is_local = 0, tpid_index = 0;
  30316 #ifdef BCM_FIREBOLT_SUPPORT
  30317     bcm_port_t orig_port = -1;
  30318 #endif
  30319 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  30320     int vp = -1;
  30321 #endif
  30322 
  30323     /* Make sure port module is initialized. */
  30324     PORT_INIT(unit);
  30325 
  30326     if(bcm_common_oamp_port_enable_get(unit, port)) {
  30327         LOG_ERROR(BSL_LS_BCM_PORT,
  30328                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  30329                    port));
  30330         return BCM_E_PARAM;
  30331     }
  30332 
  30333     if (BCM_GPORT_IS_SET(port)) {
  30334         /* Handle virtual ports separetly */
  30335         if (BCM_GPORT_IS_MPLS_PORT(port) ||
  30336             BCM_GPORT_IS_MIM_PORT(port) ||
  30337             BCM_GPORT_IS_VXLAN_PORT(port) ||
  30338             BCM_GPORT_IS_VLAN_PORT(port)) {
  30339             if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  30340 #if defined(BCM_TRX_SUPPORT)
  30341                 PORT_LOCK(unit);
  30342                 rv = _bcm_trx_vp_tpid_set(unit, port, tpid);
  30343                 PORT_UNLOCK(unit);
  30344 #endif
  30345             }
  30346             return rv;
  30347         } else if (BCM_GPORT_IS_SUBPORT_GROUP(port)) {
  30348             if (soc_feature(unit, soc_feature_subtag_coe)) {
  30349 #if defined(BCM_KATANA2_SUPPORT)
  30350                 PORT_LOCK(unit);
  30351                 rv = bcm_kt2_subport_subtag_port_tpid_set(unit, port, tpid);
  30352                 PORT_UNLOCK(unit);
  30353 #endif
  30354             }
  30355             return rv;
  30356         } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
  30357 
  30358             if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) {
  30359 #ifdef BCM_HGPROXY_COE_SUPPORT
  30360                 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  30361                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  30362                         &mod_out, &port_out, &tgid_out, &id_out));
  30363                     orig_port = port;
  30364                     BCM_IF_ERROR_RETURN(
  30365                         _bcmi_coe_subport_physical_port_get(unit,
  30366                                     port, &port));
  30367                     } else {
  30368                         return BCM_E_PORT;
  30369                 }
  30370 #endif
  30371         } else if (soc_feature(unit, soc_feature_subtag_coe) ||
  30372                 soc_feature(unit, soc_feature_linkphy_coe)) {
  30373 #ifdef BCM_KATANA2_SUPPORT
  30374                 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit,
  30375                     port)) {
  30376                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  30377                         &mod_out, &port_out, &tgid_out, &id_out));
  30378                     BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit,
  30379                         mod_out, port_out, &port));
  30380                 } else {
  30381                     return BCM_E_PORT;
  30382                 }
  30383 #endif
  30384             } else {
  30385                 return BCM_E_PORT;
  30386             }
  30387         } else if (BCM_GPORT_IS_TRUNK(port)) {
  30388 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  30389             if (soc_feature(unit, soc_feature_vp_lag)) {
  30390                 BCM_IF_ERROR_RETURN(
  30391                     _bcm_esw_trunk_tid_to_vp_lag_vp(
  30392                         unit, BCM_GPORT_TRUNK_GET(port), &vp));
  30393                 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) {
  30394                     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  30395                         PORT_LOCK(unit);
  30396                         rv = _bcm_trx_vp_tpid_set(unit, port, tpid);
  30397                         PORT_UNLOCK(unit);
  30398                         return rv;
  30399                     }
  30400                 } else {
  30401                     return BCM_E_PARAM;
  30402                 }
  30403             }
  30404 #endif
  30405             return BCM_E_PARAM;
  30406         } else {
  30407             BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  30408                         &mod_out, &port_out, &tgid_out, &id_out));
  30409             if ((-1 != tgid_out) || (-1 != id_out)) {
  30410                 return BCM_E_PARAM;
  30411             }
  30412 
  30413             BCM_IF_ERROR_RETURN
  30414                 (_bcm_esw_modid_is_local(unit, mod_out, &is_local));
  30415 #if defined(BCM_HURRICANE3_SUPPORT)
  30416             /* Here only take care non-local port, the local port will
  30417              * be handled later (by _bcm_fb2_port_tpid_set) */
  30418             if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  30419                 if (!is_local) {
  30420                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  30421                         return _bcm_esw_mod_port_tpid_set(unit, mod_out,
  30422                                                           port_out, tpid);
  30423                     } else {
  30424                         return BCM_E_PARAM;
  30425                     }
  30426                 } else {
  30427                     BCM_IF_ERROR_RETURN(
  30428                         bcm_esw_port_local_get(unit, port, &port));
  30429                 }
  30430             } else
  30431 #endif
  30432             {
  30433                 if (!is_local) {
  30434                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  30435                         return _bcm_esw_mod_port_tpid_set(unit, mod_out,
  30436                                                           port_out, tpid);
  30437                     } else {
  30438                         return BCM_E_PARAM;
  30439                     }
  30440                 } else {
  30441                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  30442                         BCM_IF_ERROR_RETURN
  30443                             (_bcm_esw_mod_port_tpid_set(unit, mod_out,
  30444                                                         port_out, tpid));
  30445                     }
  30446                     BCM_IF_ERROR_RETURN(
  30447                         bcm_esw_port_local_get(unit, port, &port));
  30448                 }
  30449             }
  30450         }
  30451     } else if (!SOC_PORT_VALID(unit, port)) {
  30452         return BCM_E_PORT;
  30453     }
  30454 
  30455 #if defined (BCM_TRX_SUPPORT)
  30456     if (SOC_IS_TRX(unit) &&
  30457         (PORT(unit, port).dtag_mode == BCM_PORT_DTAG_MODE_EXTERNAL)) {
  30458         /* For DT mode external ports, don't enable any outer TPIDs */
  30459         return BCM_E_NONE;
  30460     }
  30461 #endif
  30462 
  30463 #ifdef BCM_FIREBOLT_SUPPORT
  30464     if (SOC_IS_FBX(unit)) {
  30465         PORT_LOCK(unit);
  30466 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) || \
  30467         defined(BCM_RAVEN_SUPPORT)
  30468         if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  30469             if (orig_port != -1) {
  30470                 rv = _bcm_fb2_port_tpid_set(unit, orig_port, tpid, &tpid_index);
  30471             } else {
  30472                 rv = _bcm_fb2_port_tpid_set(unit, port, tpid, &tpid_index);
  30473             }
  30474 #if defined(BCM_TOMAHAWK_SUPPORT)
  30475     /* For Tomahawk low latency mode, use outer_tpid field  */
  30476     /* of EGR_VLAN_TAG_ACTION_FOR_BYPASSr on egress side    */
  30477             if (soc_feature(unit, soc_feature_fast_egr_vlan_action)) {
  30478                 uint32 rval;
  30479                 bcm_port_t local_port;
  30480 
  30481                 if (orig_port != -1)
  30482                     local_port = orig_port;
  30483                 else {
  30484                     local_port = port;
  30485                 }
  30486 
  30487                 rv = READ_EGR_VLAN_TAG_ACTION_FOR_BYPASSr(unit, local_port,
  30488                                                           &rval);
  30489                 if (SOC_FAILURE(rv)) {
  30490                     PORT_UNLOCK(unit);
  30491                     return (rv);
  30492                 }
  30493 
  30494                 soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr, &rval,
  30495                                   OUTER_TPIDf, tpid);
  30496 
  30497                 rv = WRITE_EGR_VLAN_TAG_ACTION_FOR_BYPASSr(unit, local_port,
  30498                                                            rval);
  30499                 if (SOC_FAILURE(rv)) {
  30500                     PORT_UNLOCK(unit);
  30501                     return (rv);
  30502                 }
  30503             }
  30504 #endif
  30505 #if defined(BCM_MONTEREY_SUPPORT)
  30506     if (soc_feature(unit, soc_feature_obm_tpid_sync)) {
  30507         bcm_port_outer_tpid_obm_set(unit, port, tpid, tpid_index);
  30508     }
  30509 #endif
  30510         } else
  30511 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
  30512         {
  30513             rv = _bcm_fb_port_tpid_set(unit, port, tpid);
  30514         }
  30515         /* coverity[negative_shift] */
  30516         if (BCM_SUCCESS(rv) && SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
  30517 
  30518             
  30519             if(!SOC_IS_TOMAHAWK3(unit)) {
  30520                 /* 
  30521                  * At now, this mac drvier is only supported by XMAC & XLMAC
  30522                  * If function return BCM_E_UNAVAIL, it should be correct. 
  30523                  */
  30524                 if (SOC_USE_PORTCTRL(unit)) {
  30525                     rv = bcmi_esw_portctrl_vlan_tpid_set(unit, port, tpid);
  30526                 } else {
  30527                     rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  30528                                      SOC_MAC_CONTROL_RX_VLAN_TAG_OUTER_TPID, tpid);
  30529                     if (rv == BCM_E_UNAVAIL) {
  30530                         rv = BCM_E_NONE;
  30531                     }
  30532                 }
  30533             }
  30534         }
  30535         PORT_UNLOCK(unit);
  30536         return rv;
  30537     }
  30538 #endif
  30539 
  30540     if (tpid == 0x8100) {
  30541         return BCM_E_NONE;
  30542     }
  30543     return BCM_E_UNAVAIL;
  30544 }
  30545 
  30546 /*
  30547  * Function:
  30548  *      _bcm_esw_mod_port_tpid_get
  30549  * Description:
  30550  *      Retrieve the Tag Protocol ID for a (module, port).
  30551  * Parameters:
  30552  *      unit - Device number
  30553  *      mod  - Module ID 
  30554  *      port - Port number
  30555  *      tpid - (OUT) Tag Protocol ID
  30556  * Return Value:
  30557  *      BCM_E_XXX
  30558  */
  30559 STATIC int
  30560 _bcm_esw_mod_port_tpid_get(int unit, bcm_module_t mod, bcm_port_t port,
  30561         uint16 *tpid)
  30562 {
  30563 #ifdef BCM_HURRICANE3_SUPPORT
  30564     if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  30565         return _bcm_hr3_mod_port_tpid_get(unit, mod, port, tpid);
  30566     } else
  30567 #endif /* BCM_HURRICANE3_SUPPORT */
  30568 #ifdef BCM_TRIDENT_SUPPORT
  30569     {
  30570         return _bcm_td_mod_port_tpid_get(unit, mod, port, tpid);
  30571     }
  30572 #endif /* BCM_TRIDENT_SUPPORT */
  30573     return BCM_E_UNAVAIL;
  30574 }
  30575 
  30576 
  30577 /*
  30578  * Function:
  30579  *      bcm_port_tpid_get
  30580  * Description:
  30581  *      Retrieve the default Tag Protocol ID for a port.
  30582  * Parameters:
  30583  *      unit - Device number
  30584  *      port - Port number
  30585  *      tpid - (OUT) Tag Protocol ID
  30586  * Return Value:
  30587  *      BCM_E_XXX
  30588  */
  30589 
  30590 int
  30591 bcm_esw_port_tpid_get(int unit, bcm_port_t port, uint16 *tpid)
  30592 {
  30593     int rv = BCM_E_UNAVAIL;
  30594     bcm_module_t mod_out;
  30595     bcm_port_t port_out;
  30596     bcm_trunk_t tgid_out;
  30597     int id_out;
  30598     int is_local = 0;
  30599 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  30600     int vp = -1;
  30601 #endif
  30602 
  30603     /* Make sure port module is initialized. */
  30604     PORT_INIT(unit);
  30605 
  30606     if(bcm_common_oamp_port_enable_get(unit, port)) {
  30607         LOG_ERROR(BSL_LS_BCM_PORT,
  30608                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  30609                    port));
  30610         return BCM_E_PARAM;
  30611     }
  30612 
  30613     if (BCM_GPORT_IS_SET(port)) {
  30614         /* Handle virtual ports separetly */
  30615         if (BCM_GPORT_IS_MPLS_PORT(port) ||
  30616             BCM_GPORT_IS_MIM_PORT(port) ||
  30617             BCM_GPORT_IS_VXLAN_PORT(port) ||
  30618             BCM_GPORT_IS_VLAN_PORT(port)) {
  30619 
  30620             if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  30621 #if defined(BCM_TRX_SUPPORT)
  30622                 PORT_LOCK(unit);
  30623                 rv = _bcm_trx_vp_tpid_get(unit, port, tpid);
  30624                 PORT_UNLOCK(unit);
  30625 #endif
  30626             }
  30627             return rv;
  30628         } else if (BCM_GPORT_IS_SUBPORT_GROUP(port)) {
  30629             if (soc_feature(unit, soc_feature_subtag_coe)) {
  30630 #if defined(BCM_KATANA2_SUPPORT)
  30631                 PORT_LOCK(unit);
  30632                 rv = bcm_kt2_subport_subtag_port_tpid_get(unit, port, tpid);
  30633                 PORT_UNLOCK(unit);
  30634 #endif
  30635             }
  30636             return rv;
  30637         } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
  30638 
  30639             if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) {
  30640 #ifdef BCM_HGPROXY_COE_SUPPORT
  30641                 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  30642                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  30643                         &mod_out, &port_out, &tgid_out, &id_out));
  30644                     } else {
  30645                         return BCM_E_PORT;
  30646                 }
  30647 #endif
  30648             } else if (soc_feature(unit, soc_feature_subtag_coe) ||
  30649                        soc_feature(unit, soc_feature_linkphy_coe)) {
  30650 #ifdef BCM_KATANA2_SUPPORT
  30651                 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit,
  30652                     port)) {
  30653                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  30654                         &mod_out, &port_out, &tgid_out, &id_out));
  30655                     BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit,
  30656                         mod_out, port_out, &port));
  30657                 } else {
  30658                     return BCM_E_PORT;
  30659                 }
  30660 #endif
  30661             } else {
  30662                 return BCM_E_PORT;
  30663             }
  30664         } else if (BCM_GPORT_IS_TRUNK(port)) {
  30665 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  30666             if (soc_feature(unit, soc_feature_vp_lag)) {
  30667                 BCM_IF_ERROR_RETURN(
  30668                     _bcm_esw_trunk_tid_to_vp_lag_vp(
  30669                         unit, BCM_GPORT_TRUNK_GET(port), &vp));
  30670                 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) {
  30671                     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  30672                         PORT_LOCK(unit);
  30673                         rv = _bcm_trx_vp_tpid_get(unit, port, tpid);
  30674                         PORT_UNLOCK(unit);
  30675                         return rv;
  30676                     }
  30677                 } else {
  30678                     return BCM_E_PARAM;
  30679                 }
  30680             }
  30681 #endif
  30682             return BCM_E_PARAM;
  30683         } else {
  30684             BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  30685                         &mod_out, &port_out, &tgid_out, &id_out));
  30686             if ((-1 != tgid_out) || (-1 != id_out)) {
  30687                 return BCM_E_PARAM;
  30688             }
  30689 
  30690             BCM_IF_ERROR_RETURN
  30691                 (_bcm_esw_modid_is_local(unit, mod_out, &is_local));
  30692             if (!is_local) {
  30693                 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  30694                     return _bcm_esw_mod_port_tpid_get(unit, mod_out, port_out,
  30695                             tpid);
  30696                 } else {
  30697                     return BCM_E_PARAM;
  30698                 }
  30699             } else {
  30700                 BCM_IF_ERROR_RETURN(
  30701                         bcm_esw_port_local_get(unit, port, &port));
  30702             }
  30703         }
  30704 
  30705     } else if (!SOC_PORT_VALID(unit, port)) {
  30706         return BCM_E_PORT;
  30707     }
  30708 
  30709     if (tpid == NULL) {
  30710         return BCM_E_PARAM;
  30711     }
  30712 
  30713 #ifdef BCM_FIREBOLT_SUPPORT
  30714     if (SOC_IS_FBX(unit)) {
  30715          PORT_LOCK(unit);
  30716 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
  30717         || defined(BCM_RAVEN_SUPPORT)
  30718         if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  30719             rv = _bcm_fb2_port_tpid_get(unit, port, tpid);
  30720         } else
  30721 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
  30722         {
  30723             rv = _bcm_fb_port_tpid_get(unit, port, tpid);
  30724         }
  30725         PORT_UNLOCK(unit);
  30726         return rv;
  30727     }
  30728 #endif /* BCM_FIREBOLT_SUPPORT */
  30729     *tpid = 0x8100;
  30730     return (BCM_E_NONE);
  30731 }
  30732 
  30733 /*
  30734  * Function:
  30735  *      _bcm_esw_mod_port_tpid_add
  30736  * Description:
  30737  *      Add TPID for a (module, port).
  30738  * Parameters:
  30739  *      unit - (IN) Device number
  30740  *      mod  - (IN) Module ID
  30741  *      port - (IN) Port number
  30742  *      tpid - (IN) Tag Protocol ID
  30743  * Return Value:
  30744  *      BCM_E_XXX
  30745  */
  30746 STATIC int
  30747 _bcm_esw_mod_port_tpid_add(int unit, bcm_module_t mod, bcm_port_t port, 
  30748                       uint16 tpid)
  30749 {
  30750 #ifdef BCM_HURRICANE3_SUPPORT
  30751     if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  30752         return _bcm_hr3_mod_port_tpid_add(unit, mod, port, tpid);
  30753     } else
  30754 #endif /* BCM_HURRICANE3_SUPPORT */
  30755 #ifdef BCM_TRIDENT_SUPPORT
  30756     {
  30757         return _bcm_td_mod_port_tpid_add(unit, mod, port, tpid);
  30758     }
  30759 #endif /* BCM_TRIDENT_SUPPORT */
  30760     return BCM_E_UNAVAIL;
  30761 }
  30762 
  30763 /*
  30764  * Function:
  30765  *      bcm_esw_port_tpid_add
  30766  * Description:
  30767  *      Add allowed TPID for a port.
  30768  * Parameters:
  30769  *      unit         - (IN) Device number
  30770  *      port         - (IN) Port number
  30771  *      tpid         - (IN) Tag Protocol ID
  30772  *      color_select - (IN) Color mode for TPID
  30773  * Return Value:
  30774  *      BCM_E_XXX
  30775  */
  30776 int
  30777 bcm_esw_port_tpid_add(int unit, bcm_port_t port,
  30778                       uint16 tpid, int color_select)
  30779 {
  30780     int rv = BCM_E_UNAVAIL;
  30781     bcm_module_t mod_out;
  30782     bcm_port_t port_out;
  30783     bcm_trunk_t tgid_out;
  30784     int id_out;
  30785     int is_local = 0;
  30786 #ifdef BCM_FIREBOLT_SUPPORT
  30787     bcm_port_t orig_port = -1;
  30788 #endif
  30789 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  30790     int vp = -1;
  30791 #endif
  30792 
  30793     if (color_select != BCM_COLOR_PRIORITY &&
  30794         color_select != BCM_COLOR_OUTER_CFI &&
  30795         color_select != BCM_COLOR_INNER_CFI) {
  30796         return BCM_E_PARAM;
  30797     }
  30798 
  30799     /* Make sure port module is initialized. */
  30800     PORT_INIT(unit);
  30801 
  30802     if(bcm_common_oamp_port_enable_get(unit, port)) {
  30803         LOG_ERROR(BSL_LS_BCM_PORT,
  30804                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  30805                    port));
  30806         return BCM_E_PARAM;
  30807     }
  30808 
  30809     if (BCM_GPORT_IS_SET(port)) {
  30810         /* Handle virtual ports separetly */
  30811         if (BCM_GPORT_IS_MPLS_PORT(port) ||
  30812             BCM_GPORT_IS_MIM_PORT(port) ||
  30813             BCM_GPORT_IS_TRILL_PORT(port) ||
  30814             BCM_GPORT_IS_VXLAN_PORT(port) ||
  30815             BCM_GPORT_IS_VLAN_PORT(port)) {
  30816 
  30817             if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  30818 #if defined(BCM_TRX_SUPPORT)
  30819                 PORT_LOCK(unit);
  30820                 rv = _bcm_trx_vp_tpid_add(unit, port, tpid, color_select);
  30821                 PORT_UNLOCK(unit);
  30822 #endif
  30823             }
  30824             return rv;
  30825         } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
  30826 
  30827             if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) {
  30828 #ifdef BCM_HGPROXY_COE_SUPPORT
  30829                 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  30830                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  30831                         &mod_out, &port_out, &tgid_out, &id_out));
  30832                     orig_port = port;
  30833                     BCM_IF_ERROR_RETURN(
  30834                         _bcmi_coe_subport_physical_port_get(unit,
  30835                                     port, &port));
  30836                     } else {
  30837                         return BCM_E_PORT;
  30838                     }
  30839 #endif
  30840             } else if (soc_feature(unit, soc_feature_subtag_coe) ||
  30841                        soc_feature(unit, soc_feature_linkphy_coe)) {
  30842 #ifdef BCM_KATANA2_SUPPORT
  30843                 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit,
  30844                     port)) {
  30845                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  30846                         &mod_out, &port_out, &tgid_out, &id_out));
  30847                     BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit,
  30848                         mod_out, port_out, &port));
  30849                 } else {
  30850                     return BCM_E_PORT;
  30851                 }
  30852 #endif
  30853             } else {
  30854                 return BCM_E_PORT;
  30855             }
  30856         } else if (BCM_GPORT_IS_TRUNK(port)) {
  30857 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  30858             if (soc_feature(unit, soc_feature_vp_lag)) {
  30859                 BCM_IF_ERROR_RETURN(
  30860                     _bcm_esw_trunk_tid_to_vp_lag_vp(
  30861                         unit, BCM_GPORT_TRUNK_GET(port), &vp));
  30862                 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) {
  30863                     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  30864                         PORT_LOCK(unit);
  30865                         rv = _bcm_trx_vp_tpid_add(unit, port, tpid,
  30866                                                   color_select);
  30867                         PORT_UNLOCK(unit);
  30868                         return rv;
  30869                     }
  30870                 } else {
  30871                     return BCM_E_PARAM;
  30872                 }
  30873             }
  30874 #endif
  30875             return BCM_E_PARAM;
  30876         } else {
  30877             BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  30878                         &mod_out, &port_out, &tgid_out, &id_out));
  30879             if ((-1 != tgid_out) || (-1 != id_out)) {
  30880                 return BCM_E_PARAM;
  30881             }
  30882 
  30883             BCM_IF_ERROR_RETURN
  30884                 (_bcm_esw_modid_is_local(unit, mod_out, &is_local));
  30885 #if defined(BCM_HURRICANE3_SUPPORT)
  30886             /* Here only take care non-local port, the local port will
  30887              * be handled later (by _bcm_fb2_port_tpid_add) */
  30888             if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  30889                 if (!is_local) {
  30890                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  30891                         return _bcm_esw_mod_port_tpid_add(unit, mod_out,
  30892                                                           port_out, tpid);
  30893                     } else {
  30894                         return BCM_E_PARAM;
  30895                     }
  30896                 } else {
  30897                     BCM_IF_ERROR_RETURN(
  30898                             bcm_esw_port_local_get(unit, port, &port));
  30899                 }
  30900             } else
  30901 #endif
  30902             {
  30903                 if (!is_local) {
  30904                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  30905                         return _bcm_esw_mod_port_tpid_add(unit, mod_out,
  30906                                                           port_out, tpid);
  30907                     } else {
  30908                         return BCM_E_PARAM;
  30909                     }
  30910                 } else {
  30911                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  30912                         BCM_IF_ERROR_RETURN
  30913                             (_bcm_esw_mod_port_tpid_add(unit, mod_out,
  30914                                                         port_out, tpid));
  30915                     }
  30916                     BCM_IF_ERROR_RETURN(
  30917                         bcm_esw_port_local_get(unit, port, &port));
  30918                 }
  30919             }
  30920         }
  30921 
  30922     } else if (!SOC_PORT_VALID(unit, port)) {
  30923         return BCM_E_PORT;
  30924     }
  30925 
  30926 #if defined (BCM_TRX_SUPPORT)
  30927     if (SOC_IS_TRX(unit) &&
  30928         (PORT(unit, port).dtag_mode == BCM_PORT_DTAG_MODE_EXTERNAL)) {
  30929         /* For DT mode external ports, don't enable any outer TPIDs */
  30930         return BCM_E_NONE;
  30931     }
  30932 #endif
  30933 
  30934 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
  30935     || defined(BCM_RAVEN_SUPPORT)
  30936     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  30937         PORT_LOCK(unit);
  30938         if (orig_port != -1) {
  30939             rv = _bcm_fb2_port_tpid_add(unit, orig_port, tpid, color_select);
  30940         } else {
  30941             rv = _bcm_fb2_port_tpid_add(unit, port, tpid, color_select);
  30942         }
  30943         PORT_UNLOCK(unit);
  30944     }
  30945 #endif
  30946     return rv;
  30947 }
  30948 
  30949 /*
  30950  * Function:
  30951  *      _bcm_esw_mod_port_tpid_delete
  30952  * Description:
  30953  *      Delete TPID for a (module, port).
  30954  * Parameters:
  30955  *      unit - (IN) Device number
  30956  *      mod  - (IN) Module ID
  30957  *      port - (IN) Port number
  30958  *      tpid - (IN) Tag Protocol ID
  30959  * Return Value:
  30960  *      BCM_E_XXX
  30961  */
  30962 STATIC int
  30963 _bcm_esw_mod_port_tpid_delete(int unit, bcm_module_t mod, bcm_port_t port,
  30964         uint16 tpid)
  30965 {
  30966 #ifdef BCM_HURRICANE3_SUPPORT
  30967     if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  30968         return _bcm_hr3_mod_port_tpid_delete(unit, mod, port, tpid);
  30969     } else
  30970 #endif /* BCM_HURRICANE3_SUPPORT */
  30971 #ifdef BCM_TRIDENT_SUPPORT
  30972     {
  30973         return _bcm_td_mod_port_tpid_delete(unit, mod, port, tpid);
  30974     }
  30975 #endif /* BCM_TRIDENT_SUPPORT */
  30976     return BCM_E_UNAVAIL;
  30977 }
  30978 
  30979 /*
  30980  * Function:
  30981  *      bcm_esw_port_tpid_delete
  30982  * Description:
  30983  *      Delete allowed TPID for a port.
  30984  * Parameters:
  30985  *      unit - (IN) Device number
  30986  *      port - (IN) Port number
  30987  *      tpid - (IN) Tag Protocol ID
  30988  * Return Value:
  30989  *      BCM_E_XXX
  30990  */
  30991 int
  30992 bcm_esw_port_tpid_delete(int unit, bcm_port_t port, uint16 tpid)
  30993 {
  30994     int rv = BCM_E_UNAVAIL;
  30995     bcm_module_t mod_out;
  30996     bcm_port_t port_out;
  30997     bcm_trunk_t tgid_out;
  30998     int id_out;
  30999     int is_local = 0;
  31000 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  31001     int vp = -1;
  31002 #endif
  31003 
  31004     /* Make sure port module is initialized. */
  31005     PORT_INIT(unit);
  31006 
  31007     if(bcm_common_oamp_port_enable_get(unit, port)) {
  31008         LOG_ERROR(BSL_LS_BCM_PORT,
  31009                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  31010                    port));
  31011         return BCM_E_PARAM;
  31012     }
  31013 
  31014     if (BCM_GPORT_IS_SET(port)) {
  31015         /* Handle virtual ports separetly */
  31016         if (BCM_GPORT_IS_MPLS_PORT(port) ||
  31017             BCM_GPORT_IS_TRILL_PORT(port) ||
  31018             BCM_GPORT_IS_MIM_PORT(port) ||
  31019             BCM_GPORT_IS_VXLAN_PORT(port) ||
  31020             BCM_GPORT_IS_VLAN_PORT(port)) {
  31021 
  31022             if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  31023 #if defined(BCM_TRX_SUPPORT)
  31024                 PORT_LOCK(unit);
  31025                 rv = _bcm_trx_vp_tpid_delete(unit, port, tpid);
  31026                 PORT_UNLOCK(unit);
  31027 #endif
  31028             }
  31029             return rv;
  31030         }  else if (BCM_GPORT_IS_SUBPORT_GROUP(port)) {
  31031             if (soc_feature(unit, soc_feature_subtag_coe)) {
  31032 #if defined(BCM_KATANA2_SUPPORT)
  31033                 PORT_LOCK(unit);
  31034                 rv = bcm_kt2_subport_subtag_port_tpid_delete(unit, port, tpid);
  31035                 PORT_UNLOCK(unit);
  31036 #endif
  31037             }
  31038             return rv;
  31039         } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
  31040 
  31041             if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) {
  31042 #ifdef BCM_HGPROXY_COE_SUPPORT
  31043                 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  31044                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  31045                         &mod_out, &port_out, &tgid_out, &id_out));
  31046                     } else {
  31047                         return BCM_E_PORT;
  31048                     }
  31049 #endif
  31050             } else if (soc_feature(unit, soc_feature_subtag_coe) ||
  31051                        soc_feature(unit, soc_feature_linkphy_coe)) {
  31052 #ifdef BCM_KATANA2_SUPPORT
  31053                 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit,
  31054                     port)) {
  31055                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  31056                         &mod_out, &port_out, &tgid_out, &id_out));
  31057                     BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit,
  31058                         mod_out, port_out, &port));
  31059                 } else {
  31060                     return BCM_E_PORT;
  31061                 }
  31062 #endif
  31063             } else {
  31064                 return BCM_E_PORT;
  31065             }
  31066         } else if (BCM_GPORT_IS_TRUNK(port)) {
  31067 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  31068             if (soc_feature(unit, soc_feature_vp_lag)) {
  31069                 BCM_IF_ERROR_RETURN(
  31070                     _bcm_esw_trunk_tid_to_vp_lag_vp(
  31071                         unit, BCM_GPORT_TRUNK_GET(port), &vp));
  31072                 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) {
  31073                     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  31074                         PORT_LOCK(unit);
  31075                         rv = _bcm_trx_vp_tpid_delete(unit, port, tpid);
  31076                         PORT_UNLOCK(unit);
  31077                         return rv;
  31078                     }
  31079                 } else {
  31080                     return BCM_E_PARAM;
  31081                 }
  31082             }
  31083 #endif
  31084             return BCM_E_PARAM;
  31085         } else {
  31086             BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  31087                         &mod_out, &port_out, &tgid_out, &id_out));
  31088             if ((-1 != tgid_out) || (-1 != id_out)) {
  31089                 return BCM_E_PARAM;
  31090             }
  31091 
  31092             BCM_IF_ERROR_RETURN
  31093                 (_bcm_esw_modid_is_local(unit, mod_out, &is_local));
  31094 #if defined(BCM_HURRICANE3_SUPPORT)
  31095             /* Here only take care non-local port, the local port will
  31096              * be handled later (by _bcm_fb2_port_tpid_delete) */
  31097             if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  31098                 if (!is_local) {
  31099                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  31100                         return _bcm_esw_mod_port_tpid_delete(unit, mod_out,
  31101                                                              port_out, tpid);
  31102                     } else {
  31103                         return BCM_E_PARAM;
  31104                     }
  31105                 } else {
  31106                     BCM_IF_ERROR_RETURN(
  31107                         bcm_esw_port_local_get(unit, port, &port));
  31108                 }
  31109             } else
  31110 #endif
  31111             {
  31112                 if (!is_local) {
  31113                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  31114                         return _bcm_esw_mod_port_tpid_delete(unit, mod_out,
  31115                                                              port_out, tpid);
  31116                     } else {
  31117                         return BCM_E_PARAM;
  31118                     }
  31119                 } else {
  31120                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  31121                         BCM_IF_ERROR_RETURN
  31122                             (_bcm_esw_mod_port_tpid_delete(unit, mod_out,
  31123                                                            port_out, tpid));
  31124                     }
  31125                     BCM_IF_ERROR_RETURN(
  31126                         bcm_esw_port_local_get(unit, port, &port));
  31127                 }
  31128             }
  31129         }
  31130 
  31131     } else if (!SOC_PORT_VALID(unit, port)) {
  31132         return BCM_E_PORT;
  31133     }
  31134 
  31135 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
  31136     || defined(BCM_RAVEN_SUPPORT)
  31137     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  31138         PORT_LOCK(unit);
  31139         rv = _bcm_fb2_port_tpid_delete(unit, port, tpid);
  31140         PORT_UNLOCK(unit);
  31141     }
  31142 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
  31143     return rv;
  31144 }
  31145 
  31146 /*
  31147  * Function:
  31148  *      _bcm_esw_mod_port_tpid_delete_all
  31149  * Description:
  31150  *      Delete all TPID for a (module, port).
  31151  * Parameters:
  31152  *      unit - (IN) Device number
  31153  *      mod  - (IN) Module ID
  31154  *      port - (IN) Port number
  31155  * Return Value:
  31156  *      BCM_E_XXX
  31157  */
  31158 STATIC int 
  31159 _bcm_esw_mod_port_tpid_delete_all(int unit, bcm_module_t mod, bcm_port_t port)
  31160 {
  31161 #ifdef BCM_HURRICANE3_SUPPORT
  31162     if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  31163         return _bcm_hr3_mod_port_tpid_delete_all(unit, mod, port);
  31164     } else
  31165 #endif /* BCM_HURRICANE3_SUPPORT */
  31166 #ifdef BCM_TRIDENT_SUPPORT
  31167     {
  31168         return _bcm_td_mod_port_tpid_delete_all(unit, mod, port);
  31169     }
  31170 #endif /* BCM_TRIDENT_SUPPORT */
  31171     return BCM_E_UNAVAIL;
  31172 }
  31173 
  31174 /*
  31175  * Function:
  31176  *      bcm_esw_port_tpid_delete_all
  31177  * Description:
  31178  *      Delete all allowed TPID for a port.
  31179  * Parameters:
  31180  *      unit - (IN) Device number
  31181  *      port - (IN) Port number
  31182  * Return Value:
  31183  *      BCM_E_XXX
  31184  */
  31185 int
  31186 bcm_esw_port_tpid_delete_all(int unit, bcm_port_t port)
  31187 {
  31188     int rv = BCM_E_UNAVAIL;
  31189     bcm_module_t mod_out;
  31190     bcm_port_t port_out;
  31191     bcm_trunk_t tgid_out;
  31192     int id_out;
  31193     int is_local = 0;
  31194 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  31195     int vp = -1;
  31196 #endif
  31197 
  31198     /* Make sure port module is initialized. */
  31199     PORT_INIT(unit);
  31200 
  31201     if(bcm_common_oamp_port_enable_get(unit, port)) {
  31202         LOG_ERROR(BSL_LS_BCM_PORT,
  31203                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  31204                    port));
  31205         return BCM_E_PARAM;
  31206     }
  31207 
  31208     if (BCM_GPORT_IS_SET(port)) {
  31209         /* Handle virtual ports separetly */
  31210         if (BCM_GPORT_IS_MPLS_PORT(port) ||
  31211             BCM_GPORT_IS_MIM_PORT(port) ||
  31212             BCM_GPORT_IS_VXLAN_PORT(port) ||
  31213             BCM_GPORT_IS_VLAN_PORT(port)) {
  31214 
  31215             if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  31216 #if defined(BCM_TRX_SUPPORT)
  31217                 PORT_LOCK(unit);
  31218                 rv = _bcm_trx_vp_tpid_delete_all(unit, port);
  31219                 PORT_UNLOCK(unit);
  31220 #endif
  31221             }
  31222             return rv;
  31223         } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
  31224 
  31225             if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) {
  31226 #ifdef BCM_HGPROXY_COE_SUPPORT
  31227                 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  31228                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  31229                         &mod_out, &port_out, &tgid_out, &id_out));
  31230                     } else {
  31231                         return BCM_E_PORT;
  31232                     }
  31233 #endif
  31234              } else if (soc_feature(unit, soc_feature_subtag_coe) ||
  31235                       soc_feature(unit, soc_feature_linkphy_coe)) {
  31236 #ifdef BCM_KATANA2_SUPPORT
  31237                 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit,
  31238                     port)) {
  31239                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  31240                         &mod_out, &port_out, &tgid_out, &id_out));
  31241                     BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit,
  31242                         mod_out, port_out, &port));
  31243                 } else {
  31244                     return BCM_E_PORT;
  31245                 }
  31246 #endif
  31247             } else {
  31248                 return BCM_E_PORT;
  31249             }
  31250         } else if (BCM_GPORT_IS_TRUNK(port)) {
  31251 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  31252             if (soc_feature(unit, soc_feature_vp_lag)) {
  31253                 BCM_IF_ERROR_RETURN(
  31254                     _bcm_esw_trunk_tid_to_vp_lag_vp(
  31255                         unit, BCM_GPORT_TRUNK_GET(port), &vp));
  31256                 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) {
  31257                     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  31258                         PORT_LOCK(unit);
  31259                         rv = _bcm_trx_vp_tpid_delete_all(unit, port);
  31260                         PORT_UNLOCK(unit);
  31261                         return rv;
  31262                     }
  31263                 } else {
  31264                     return BCM_E_PARAM;
  31265                 }
  31266             }
  31267 #endif
  31268             return BCM_E_PARAM;
  31269         } else {
  31270             BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  31271                         &mod_out, &port_out, &tgid_out, &id_out));
  31272             if ((-1 != tgid_out) || (-1 != id_out)) {
  31273                 return BCM_E_PARAM;
  31274             }
  31275 
  31276             BCM_IF_ERROR_RETURN
  31277                 (_bcm_esw_modid_is_local(unit, mod_out, &is_local));
  31278 #if defined(BCM_HURRICANE3_SUPPORT)
  31279             /* Here only take care non-local port, the local port will
  31280              * be handled later (by _bcm_fb2_port_tpid_delete_all) */
  31281             if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  31282                 if (!is_local) {
  31283                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  31284                         return _bcm_esw_mod_port_tpid_delete_all(unit, mod_out,
  31285                                                                  port_out);
  31286                     } else {
  31287                         return BCM_E_PARAM;
  31288                     }
  31289                 } else {
  31290                     BCM_IF_ERROR_RETURN(
  31291                         bcm_esw_port_local_get(unit, port, &port));
  31292                 }
  31293             } else
  31294 #endif
  31295             {
  31296                 if (!is_local) {
  31297                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  31298                         return _bcm_esw_mod_port_tpid_delete_all(unit, mod_out,
  31299                                                                  port_out);
  31300                     } else {
  31301                         return BCM_E_PARAM;
  31302                     }
  31303                 } else {
  31304                     if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  31305                         BCM_IF_ERROR_RETURN
  31306                             (_bcm_esw_mod_port_tpid_delete_all(unit, mod_out,
  31307                                                                port_out));
  31308                     }
  31309                     BCM_IF_ERROR_RETURN(
  31310                         bcm_esw_port_local_get(unit, port, &port));
  31311                 }
  31312             }
  31313         }
  31314 
  31315     } else if (!SOC_PORT_VALID(unit, port)) {
  31316         return BCM_E_PORT;
  31317     }
  31318 
  31319 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
  31320  || defined(BCM_RAVEN_SUPPORT)
  31321     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  31322         PORT_LOCK(unit);
  31323         rv = _bcm_fb2_port_tpid_delete_all(unit, port);
  31324         PORT_UNLOCK(unit);
  31325     }
  31326 #endif
  31327     return rv;
  31328 }
  31329 
  31330 /*
  31331  * Function:
  31332  *      _bcm_esw_mod_port_inner_tpid_enable
  31333  * Description:
  31334  *      Enable the Inner Tag Protocol ID for a (module, port).
  31335  * Parameters:
  31336  *      unit - Device number
  31337  *      mod  - Module ID
  31338  *      port - Port number
  31339  * Return Value:
  31340  *      BCM_E_XXX
  31341  */
  31342 STATIC int
  31343 _bcm_esw_mod_port_inner_tpid_enable(int unit, bcm_module_t mod, bcm_port_t port)
  31344 {
  31345     int rv = BCM_E_NONE;
  31346     if (!SOC_MEM_IS_VALID(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) {
  31347         int sys_index = 0;
  31348         uint32 enable = 1;
  31349         system_config_table_entry_t systab;
  31350         sys_index = mod * 64 + port;
  31351         rv = READ_SYSTEM_CONFIG_TABLEm(unit, MEM_BLOCK_ANY, sys_index,
  31352                                        &systab);
  31353         if (BCM_SUCCESS(rv)) {
  31354             soc_SYSTEM_CONFIG_TABLEm_field32_set(unit, &systab,
  31355                                                  INNER_TPID_ENABLEf, enable);
  31356             rv = WRITE_SYSTEM_CONFIG_TABLEm(unit, MEM_BLOCK_ALL,
  31357                                             sys_index, &systab);
  31358         }
  31359     } else {
  31360 #ifdef BCM_HURRICANE3_SUPPORT
  31361         if (SOC_IS_HURRICANE3(unit)) {
  31362             rv = _bcm_hr3_mod_port_inner_tpid_enable_write(unit, mod, port, 1);
  31363         }
  31364 #endif /* BCM_HURRICANE3_SUPPORT */
  31365     }
  31366     return rv;
  31367 }
  31368 
  31369 /*
  31370  * Function:
  31371  *      bcm_port_inner_tpid_set
  31372  * Purpose:
  31373  *      Set the expected TPID for the inner tag in double-tagging mode.
  31374  * Parameters:
  31375  *      unit - Device number
  31376  *      port - Port number
  31377  *      tpid - Tag Protocol ID
  31378  * Returns:
  31379  *      BCM_E_NONE - Success.
  31380  *      BCM_E_XXX
  31381  */
  31382 int
  31383 bcm_esw_port_inner_tpid_set(int unit, bcm_port_t port, uint16 tpid)
  31384 {
  31385     int rv = BCM_E_UNAVAIL;
  31386     bcm_module_t mod_out = BCM_MODID_INVALID;
  31387     bcm_port_t port_out;
  31388     bcm_trunk_t tgid_out;
  31389     int is_local = TRUE;
  31390     int id_out;
  31391 
  31392     /* Make sure port module is initialized. */
  31393     PORT_INIT(unit);
  31394 
  31395     if(bcm_common_oamp_port_enable_get(unit, port)) {
  31396         LOG_ERROR(BSL_LS_BCM_PORT,
  31397                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  31398                    port));
  31399         return BCM_E_PARAM;
  31400     }
  31401 
  31402     if (BCM_GPORT_IS_SET(port)) {
  31403         /* Handle virtual ports separetly */
  31404         if (BCM_GPORT_IS_MPLS_PORT(port) ||
  31405             BCM_GPORT_IS_MIM_PORT(port) ||
  31406             BCM_GPORT_IS_VLAN_PORT(port)) {
  31407 
  31408             if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  31409 #if defined(BCM_TRX_SUPPORT)
  31410                 PORT_LOCK(unit);
  31411                 rv = _bcm_trx_vp_tpid_set(unit, port,tpid);
  31412                 PORT_UNLOCK(unit);
  31413 #endif
  31414             }
  31415             return rv;
  31416         } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
  31417             if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) {
  31418 #ifdef BCM_HGPROXY_COE_SUPPORT
  31419                 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  31420                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  31421                         &mod_out, &port_out, &tgid_out, &id_out));
  31422                     BCM_IF_ERROR_RETURN(
  31423                         _bcmi_coe_subport_physical_port_get(unit,
  31424                                     port, &port));
  31425                     } else {
  31426                         return BCM_E_PORT;
  31427                     }
  31428 #endif
  31429             } else if (soc_feature(unit, soc_feature_subtag_coe) ||
  31430                 soc_feature(unit, soc_feature_linkphy_coe)) {
  31431 #ifdef BCM_KATANA2_SUPPORT
  31432                 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit,
  31433                     port)) {
  31434                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  31435                         &mod_out, &port_out, &tgid_out, &id_out));
  31436                     BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit,
  31437                         mod_out, port_out, &port));
  31438                 } else {
  31439                     return BCM_E_PORT;
  31440                 }
  31441 #endif
  31442             } else {
  31443                 return BCM_E_PORT;
  31444             }
  31445         } else {
  31446             BCM_IF_ERROR_RETURN(
  31447                 _bcm_esw_gport_resolve(unit, port, &mod_out, &port_out,
  31448                                        &tgid_out, &id_out));
  31449             if ((-1 != tgid_out) || (-1 != id_out)) {
  31450                 return BCM_E_PARAM;
  31451             }
  31452             port = port_out;
  31453             BCM_IF_ERROR_RETURN(
  31454                 _bcm_esw_modid_is_local(unit, mod_out, &is_local));
  31455         }
  31456     } else if (!SOC_PORT_VALID(unit, port)) {
  31457         return BCM_E_PORT;
  31458     }
  31459 
  31460     if (soc_feature(unit, soc_feature_inner_tpid_enable)) {
  31461         if (BCM_MODID_INVALID == mod_out) {
  31462             BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mod_out));
  31463         }
  31464         BCM_IF_ERROR_RETURN(
  31465             _bcm_esw_mod_port_inner_tpid_enable(unit, mod_out, port));
  31466 
  31467         if (TRUE == is_local) {
  31468         uint32 enable = 1;
  31469             BCM_IF_ERROR_RETURN(
  31470                 soc_mem_field32_modify(unit, PORT_TABm, port,
  31471                                        INNER_TPID_ENABLEf, enable));
  31472         if(soc_reg_field_valid(unit, EGR_VLAN_CONTROL_1r, INNER_TPID_ENABLEf)){
  31473             soc_reg_field32_modify(unit, EGR_VLAN_CONTROL_1r, port,
  31474                        INNER_TPID_ENABLEf, enable);
  31475         }
  31476         }
  31477     } else {
  31478     /*  INNER_TPID_ENABLEf is also in SYSTEM_CONFIG_TABLE which is for Higig.
  31479          *  Hence, bypass the switched port check */
  31480 
  31481         PORT_SWITCHED_CHECK(unit, port);
  31482     }
  31483 
  31484 #ifdef BCM_FIREBOLT_SUPPORT
  31485     if (SOC_IS_FBX(unit)) {
  31486         uint32 rval;
  31487 #if 0
  31488         int tpid_index;
  31489 
  31490         for (tpid_index = 0; tpid_index < 4; tpid_index++) {
  31491             if (SOC_REG_IS_VALID(unit, PARSER1_ING_INNER_TPIDr)) {
  31492                 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit,
  31493                     PARSER1_ING_INNER_TPIDr, tpid_index, TPIDf, tpid));
  31494                 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit,
  31495                     PARSER2_ING_INNER_TPIDr, tpid_index, TPIDf, tpid));
  31496             }
  31497 
  31498             if (SOC_REG_IS_VALID(unit, EGR_INNER_TPIDr)) {
  31499                 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit,
  31500                     EGR_INNER_TPIDr, tpid_index, TPIDf, tpid));
  31501             }
  31502 
  31503             if (SOC_REG_IS_VALID(unit, EGR_PARSER_INNER_TPIDr)) {
  31504                 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit,
  31505                     EGR_PARSER_INNER_TPIDr, tpid_index, TPIDf, tpid));
  31506             }
  31507         }
  31508 #endif
  31509 
  31510         BCM_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &rval));
  31511         soc_reg_field_set(unit, VLAN_CTRLr, &rval, INNER_TPIDf, tpid);
  31512         BCM_IF_ERROR_RETURN(WRITE_VLAN_CTRLr(unit, rval));
  31513         if (soc_reg_field_valid(unit, EGR_CONFIGr, INNER_TPIDf)) {
  31514         BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_CONFIGr,
  31515                                 REG_PORT_ANY, INNER_TPIDf, tpid));
  31516         }
  31517 #ifdef BCM_TRIDENT3_SUPPORT
  31518         if (SOC_IS_TRIDENT3X(unit)) {
  31519             if (soc_reg_field_valid(unit, EGR_CONFIG_1_64r, INNER_TPIDf)) {
  31520                 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_CONFIG_1_64r,
  31521                                     REG_PORT_ANY, INNER_TPIDf, tpid));
  31522             }
  31523         }
  31524 #endif
  31525         if (SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) {
  31526             /* 
  31527              * At now, this mac drvier is only supported by XMAC & XLMAC
  31528              * If function return BCM_E_UNAVAIL, it should be correct. 
  31529              */
  31530             if (SOC_USE_PORTCTRL(unit)) {
  31531                 (void)bcmi_esw_portctrl_vlan_inner_tpid_set(unit, port, tpid);
  31532             } else {
  31533                 BCM_IF_ERROR_NOT_UNAVAIL_RETURN(
  31534                     MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  31535                                 SOC_MAC_CONTROL_RX_VLAN_TAG_INNER_TPID, tpid));       
  31536             }
  31537         }
  31538         rv = BCM_E_NONE;
  31539     }
  31540 #endif
  31541 #if defined(BCM_MONTEREY_SUPPORT)
  31542     if (soc_feature(unit, soc_feature_obm_tpid_sync) && (rv == BCM_E_NONE)) {
  31543         bcm_inner_tpid_obm_set(unit, tpid);
  31544     }
  31545 #endif
  31546      return rv;
  31547 }
  31548 
  31549 /*
  31550  * Function:
  31551  *      bcm_port_inner_tpid_get
  31552  * Purpose:
  31553  *      Get the expected TPID for the inner tag in double-tagging mode.
  31554  * Parameters:
  31555  *      unit - Device number
  31556  *      port - Port number
  31557  *      tpid - (OUT) Tag Protocol ID
  31558  * Returns:
  31559  *      BCM_E_NONE - Success.
  31560  *      BCM_E_XXX
  31561  */
  31562 int
  31563 bcm_esw_port_inner_tpid_get(int unit, bcm_port_t port, uint16 *tpid)
  31564 {
  31565     int rv = BCM_E_UNAVAIL;
  31566 
  31567     /* Make sure port module is initialized. */
  31568     PORT_INIT(unit);
  31569 
  31570     if(bcm_common_oamp_port_enable_get(unit, port)) {
  31571         LOG_ERROR(BSL_LS_BCM_PORT,
  31572                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  31573                    port));
  31574         return BCM_E_PARAM;
  31575     }
  31576 
  31577     if (BCM_GPORT_IS_SET(port)) {
  31578         /* Handle virtual ports separetly */
  31579         if (BCM_GPORT_IS_MPLS_PORT(port) ||
  31580             BCM_GPORT_IS_MIM_PORT(port) ||
  31581             BCM_GPORT_IS_VLAN_PORT(port)) {
  31582 
  31583             if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  31584 #if defined(BCM_TRX_SUPPORT)
  31585                 PORT_LOCK(unit);
  31586                 rv = _bcm_trx_vp_tpid_get(unit, port,tpid);
  31587                 PORT_UNLOCK(unit);
  31588 #endif
  31589             }
  31590             return rv;
  31591         } else {
  31592             BCM_IF_ERROR_RETURN(
  31593                 _bcm_esw_port_gport_validate(unit, port, &port));
  31594         }
  31595 
  31596     } else if (!SOC_PORT_VALID(unit, port)) {
  31597         return BCM_E_PORT;
  31598     }
  31599 
  31600     PORT_SWITCHED_CHECK(unit, port);
  31601 
  31602     if (tpid == NULL) {
  31603         return BCM_E_PARAM;
  31604     }
  31605 
  31606 #ifdef BCM_FIREBOLT_SUPPORT
  31607     if (SOC_IS_FBX(unit)) {
  31608         uint32 rval;
  31609         BCM_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &rval));
  31610         *tpid = soc_reg_field_get(unit, VLAN_CTRLr, rval, INNER_TPIDf);
  31611         return BCM_E_NONE;
  31612     }
  31613 #endif
  31614 
  31615     return BCM_E_UNAVAIL;
  31616 }
  31617 
  31618 /*
  31619  * Function:
  31620  *      bcm_esw_port_frame_max_set
  31621  * Description:
  31622  *      Set the maximum receive frame size for the port
  31623  * Parameters:
  31624  *      unit - Device number
  31625  *      in_port - Port number
  31626  *      size - Maximum frame size in bytes
  31627  * Return Value:
  31628  *      BCM_E_XXX
  31629  * Notes:
  31630  *      Depending on chip or port type the actual maximum receive frame size
  31631  *      might be slightly higher.
  31632  *
  31633  *      It looks like this operation is performed the same way on all the chips
  31634  *      and the only depends on the port type.
  31635  */
  31636 int
  31637 bcm_esw_port_frame_max_set(int unit, bcm_port_t in_port, int size)
  31638 {
  31639     bcm_port_t port;
  31640     int max_size = BCM_PORT_JUMBO_MAXSZ;
  31641 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  31642     uint32 rval;
  31643 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  31644 #if defined(BCM_KATANA2_SUPPORT)
  31645     int         min_pp_port = SOC_INFO(unit).pp_port_index_min;
  31646 #endif /* BCM_KATANA2_SUPPORT */
  31647 
  31648     /* Make sure port module is initialized. */
  31649     PORT_INIT(unit);
  31650 
  31651     if(bcm_common_oamp_port_enable_get(unit, in_port)) {
  31652         LOG_ERROR(BSL_LS_BCM_PORT,
  31653                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  31654                    in_port));
  31655         return BCM_E_PARAM;
  31656     }
  31657 
  31658     /* Call Port Control module */
  31659     if (SOC_USE_PORTCTRL(unit)) {
  31660         return bcmi_esw_portctrl_frame_max_set(unit, in_port, size);
  31661     }
  31662 
  31663     /* Set jumbo max size to 12k for Katana2 as per Arch team recommendation */
  31664     max_size = SOC_INFO(unit).max_mtu;
  31665 #ifdef BCM_TRIDENT2_SUPPORT
  31666     if (SOC_IS_TRIDENT2(unit) || SOC_IS_TOMAHAWKX(unit)) {
  31667         if (IS_XE_PORT(unit, in_port) || IS_GE_PORT(unit, in_port)
  31668             || IS_CE_PORT(unit, in_port)
  31669             || (IS_C_PORT(unit, in_port) && IS_E_PORT(unit, in_port))) {
  31670             max_size -= 4;
  31671         }
  31672     }
  31673 #endif
  31674     if (size < 0 || size > max_size) {
  31675         return BCM_E_PARAM;
  31676     }
  31677 
  31678     if (!BCM_GPORT_IS_SET(in_port)) {
  31679         if (!SOC_PBMP_MEMBER((PBMP_PORT_ALL(unit)), in_port)) {
  31680             return BCM_E_PORT;
  31681         }
  31682     }
  31683     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, in_port, &port));
  31684 
  31685 #if defined(BCM_KATANA2_SUPPORT)
  31686     /* LinkPHY/SubportTag CoE subport does not have MAC */
  31687 #if defined(BCM_METROLITE_SUPPORT)
  31688     if ((soc_feature(unit, soc_feature_linkphy_coe) ||
  31689         soc_feature(unit, soc_feature_subtag_coe)) &&
  31690         soc_feature(unit, soc_feature_discontinuous_pp_port) &&
  31691         (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, port) &&
  31692         !_SOC_IS_PORT_LINKPHY_SUBTAG(unit, port))) {
  31693     } else 
  31694 #endif
  31695     if ((soc_feature(unit, soc_feature_linkphy_coe) ||
  31696         soc_feature(unit, soc_feature_subtag_coe)) &&
  31697         !soc_feature(unit, soc_feature_discontinuous_pp_port) &&
  31698         (port >= min_pp_port)) {
  31699     } else
  31700 #endif
  31701     {
  31702         SOC_IF_ERROR_RETURN
  31703             (MAC_FRAME_MAX_SET(PORT(unit, port).p_mac, unit, port, size));
  31704     }
  31705 
  31706 #ifdef BCM_SHADOW_SUPPORT
  31707     if (SOC_IS_SHADOW(unit)) {
  31708         SOC_IF_ERROR_RETURN(READ_EGR_L2_MTUr(unit, port, &rval));
  31709         soc_reg_field_set(unit, EGR_L2_MTUr, &rval,
  31710                           VALUEf, size + 4);
  31711         SOC_IF_ERROR_RETURN(WRITE_EGR_L2_MTUr(unit, port, rval));
  31712     } else
  31713 #endif /* BCM_SHADOW_SUPPORT */
  31714 
  31715 #ifdef BCM_XGS3_SWITCH_SUPPORT
  31716     if (SOC_IS_XGS3_SWITCH(unit)) {
  31717         soc_reg_t reg;
  31718         egr_mtu_entry_t mtu;
  31719         uint32 mtu_size = size;
  31720         uint32 field_val_set = 1;
  31721 
  31722         if (IS_XE_PORT(unit, port) || IS_GE_PORT(unit, port)
  31723             || IS_CE_PORT(unit, port)
  31724             || (IS_C_PORT(unit, port) && IS_E_PORT(unit, port))) {
  31725             mtu_size += 4;
  31726         }
  31727 
  31728         if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) {
  31729             soc_mem_t mem = EGR_MTUm;
  31730             if (soc_feature(unit, soc_feature_egr_all_profile)) {
  31731                 BCM_IF_ERROR_RETURN(
  31732                     bcm_esw_port_egr_lport_field_set(unit, port, mem,
  31733                     MTU_SIZEf, mtu_size));
  31734                 
  31735             } else {
  31736                 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY,
  31737                                              port, &mtu));
  31738                 soc_mem_field_set (unit, mem, (uint32 *)&mtu, MTU_SIZEf,
  31739                                &mtu_size);
  31740             if (soc_mem_field_valid(unit, EGR_MTUm, MTU_ENABLEf)) {
  31741                 soc_mem_field_set(unit, EGR_MTUm, (uint32 *)&mtu,
  31742                                   MTU_ENABLEf, &field_val_set);
  31743             }
  31744 
  31745                 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ANY,
  31746                                              port, &mtu));
  31747             }
  31748         } else {
  31749             reg = SOC_REG_IS_VALID(unit, EGR_MTUr) ? EGR_MTUr : EGR_MTU_SIZEr;
  31750 
  31751             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval));
  31752             soc_reg_field_set(unit, reg, &rval, MTU_SIZEf, mtu_size);
  31753             if (soc_reg_field_valid(unit, reg, MTU_ENABLEf)) {
  31754                 soc_reg_field_set(unit, reg, &rval, MTU_ENABLEf, 1);
  31755             }
  31756             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
  31757         }
  31758     }
  31759 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  31760 
  31761     return BCM_E_NONE;
  31762 }
  31763 
  31764 /*
  31765  * Function:
  31766  *      bcm_esw_port_frame_max_get
  31767  * Description:
  31768  *      Get the maximum receive frame size for the port
  31769  * Parameters:
  31770  *      unit - Device number
  31771  *      in_port - Port number
  31772  *      size - Maximum frame size in bytes
  31773  * Return Value:
  31774  *      BCM_E_XXX
  31775  * Notes:
  31776  *      Depending on chip or port type the actual maximum receive frame size
  31777  *      might be slightly higher.
  31778  *
  31779  *      For GE ports that use 2 separate MACs (one for GE and another one for
  31780  *      10/100 modes) the function returns the maximum rx frame size set for
  31781  *      the current mode.
  31782  */
  31783 int
  31784 bcm_esw_port_frame_max_get(int unit, bcm_port_t in_port, int *size)
  31785 {
  31786     int rv = BCM_E_UNAVAIL;
  31787     bcm_port_t port;
  31788 #if defined(BCM_KATANA2_SUPPORT)
  31789     uint32 rval;
  31790     int min_pp_port = SOC_INFO(unit).pp_port_index_min;
  31791     int max_phy_port = KT2_MAX_PHYSICAL_PORTS;
  31792 
  31793 #if defined(BCM_SABER2_SUPPORT)
  31794     if(SOC_IS_SABER2(unit)) {
  31795         max_phy_port = SB2_MAX_PHYSICAL_PORTS;
  31796     }
  31797 #endif
  31798 #endif
  31799 
  31800     /* Make sure port module is initialized. */
  31801     PORT_INIT(unit);
  31802 
  31803     /* Call Port Control module */
  31804     if (SOC_USE_PORTCTRL(unit)) {
  31805         return bcmi_esw_portctrl_frame_max_get(unit, in_port, size);
  31806     }
  31807 
  31808 #if defined(BCM_KATANA2_SUPPORT)
  31809     if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(in_port)) &&
  31810         (!((in_port >= 1) && (in_port <= max_phy_port) &&
  31811          SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit),in_port)))) {
  31812           return BCM_E_PORT;
  31813     }
  31814 #endif
  31815 
  31816     if(bcm_common_oamp_port_enable_get(unit, in_port)) {
  31817         LOG_ERROR(BSL_LS_BCM_PORT,
  31818                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  31819                    in_port));
  31820         return BCM_E_PARAM;
  31821     }
  31822 
  31823     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, in_port, &port));
  31824 
  31825 #if defined(BCM_KATANA2_SUPPORT)
  31826     /* LinkPHY/SubportTag CoE subport does not have MAC */
  31827 #if defined(BCM_METROLITE_SUPPORT)
  31828     if ((soc_feature(unit, soc_feature_linkphy_coe) ||
  31829         soc_feature(unit, soc_feature_subtag_coe)) &&
  31830          soc_feature(unit, soc_feature_discontinuous_pp_port) &&
  31831         (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, port) &&
  31832          !_SOC_IS_PORT_LINKPHY_SUBTAG(unit, port))) {
  31833         *size = 0;
  31834         if (SOC_REG_IS_VALID(unit, EGR_MTUr)) {
  31835             SOC_IF_ERROR_RETURN(READ_EGR_MTUr(unit, port, &rval));
  31836             if (soc_reg_field_get(unit, EGR_MTUr, rval, MTU_ENABLEf)) {
  31837                 *size = soc_reg_field_get(unit, EGR_MTUr, rval, MTU_SIZEf) - 4;
  31838             }
  31839         }
  31840         rv = BCM_E_NONE;
  31841     } else 
  31842 #endif
  31843     if ((soc_feature(unit, soc_feature_linkphy_coe) ||
  31844         soc_feature(unit, soc_feature_subtag_coe)) &&
  31845         !soc_feature(unit, soc_feature_discontinuous_pp_port) &&
  31846         (port >= min_pp_port)) {
  31847         *size = 0;
  31848         if (SOC_REG_IS_VALID(unit, EGR_MTUr)) {
  31849             SOC_IF_ERROR_RETURN(READ_EGR_MTUr(unit, port, &rval));
  31850             if (soc_reg_field_get(unit, EGR_MTUr, rval, MTU_ENABLEf)) {
  31851                 *size = soc_reg_field_get(unit, EGR_MTUr, rval, MTU_SIZEf) - 4;
  31852             }
  31853         }
  31854         rv = BCM_E_NONE;
  31855     } else
  31856 #endif
  31857     {
  31858         rv = MAC_FRAME_MAX_GET(PORT(unit, port).p_mac, unit, port, size);
  31859     }
  31860 
  31861     return rv;
  31862 }
  31863 
  31864 /*
  31865  * Function:
  31866  *      bcm_esw_port_l3_mtu_set
  31867  * Description:
  31868  *      Set the maximum L3 frame size for the port
  31869  * Parameters:
  31870  *      unit - Device number
  31871  *      port - Port number
  31872  *      size - Maximum frame size in bytes
  31873  * Return Value:
  31874  *      BCM_E_XXX
  31875  */
  31876 int
  31877 bcm_esw_port_l3_mtu_set(int unit, bcm_port_t port, int size)
  31878 {
  31879     int rv = BCM_E_UNAVAIL;
  31880     /* Make sure port module is initialized. */
  31881     PORT_INIT(unit);
  31882 
  31883     COMPILER_REFERENCE(rv);
  31884 
  31885     if(bcm_common_oamp_port_enable_get(unit, port)) {
  31886         LOG_ERROR(BSL_LS_BCM_PORT,
  31887                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  31888                    port));
  31889         return BCM_E_PARAM;
  31890     }
  31891 
  31892 #if defined(BCM_XGS3_SWITCH_SUPPORT) && defined(INCLUDE_L3)
  31893 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  31894     if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) {
  31895 
  31896         soc_field_t fields[2];
  31897         uint32 values[2];
  31898 
  31899        if (soc_feature(unit, soc_feature_egr_all_profile) ||
  31900            (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  31901               _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))) {
  31902 
  31903             /* Setup the fields and their values */
  31904             fields[0] = MTU_SIZEf;  values[0] = size;
  31905             fields[1] = MTU_ENABLEf; values[1] = 1;
  31906 
  31907             return bcm_esw_port_egr_lport_fields_set(unit, port,
  31908                         EGR_MTUm, 2, fields, values);
  31909 
  31910         } else {
  31911             egr_mtu_entry_t egr_mtu_entry;
  31912 
  31913             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  31914             SOC_IF_ERROR_RETURN(soc_mem_read(unit, EGR_MTUm,
  31915                             MEM_BLOCK_ANY, port, &egr_mtu_entry));
  31916             /* Set up the fields */
  31917             soc_mem_field32_set(unit, EGR_MTUm, &egr_mtu_entry, MTU_SIZEf, size);
  31918             soc_mem_field32_set(unit, EGR_MTUm, &egr_mtu_entry, MTU_ENABLEf,
  31919                                 1);
  31920             /* Write data to hardware */
  31921             return soc_mem_write(unit, EGR_MTUm, MEM_BLOCK_ANY, port, &egr_mtu_entry);
  31922         }
  31923     } else
  31924 #endif
  31925     {
  31926         if (soc_feature(unit, soc_feature_egr_l3_mtu)) {
  31927             soc_reg_t reg;
  31928 
  31929             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  31930             reg = SOC_REG_IS_VALID(unit, EGR_MTUr) ? EGR_MTUr : EGR_MTU_SIZEr;
  31931             return soc_reg_field32_modify(unit, reg, port,
  31932                     (SOC_REG_FIELD_VALID(unit, reg, L3_MTU_SIZEf) ?
  31933                     L3_MTU_SIZEf : MTU_SIZEf), size);
  31934         }
  31935     }
  31936 #endif /* BCM_XGS3_SWITCH_SUPPORT && INCLUDE_L3 */
  31937 
  31938     return BCM_E_UNAVAIL;
  31939 
  31940 }
  31941 
  31942 /*
  31943  * Function:
  31944  *      bcm_esw_port_l3_mtu_get
  31945  * Description:
  31946  *      Get the maximum L3 frame size for the port
  31947  * Parameters:
  31948  *      unit - Device number
  31949  *      port - Port number
  31950  *      size - Maximum frame size in bytes
  31951  * Return Value:
  31952  *      BCM_E_XXX
  31953  */
  31954 int
  31955 bcm_esw_port_l3_mtu_get(int unit, bcm_port_t port, int *size)
  31956 {
  31957     /* Make sure port module is initialized. */
  31958     PORT_INIT(unit);
  31959 
  31960     if(bcm_common_oamp_port_enable_get(unit, port)) {
  31961         LOG_ERROR(BSL_LS_BCM_PORT,
  31962                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  31963                    port));
  31964         return BCM_E_PARAM;
  31965     }
  31966 
  31967 #if defined(BCM_XGS3_SWITCH_SUPPORT) && defined(INCLUDE_L3)
  31968 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  31969     if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) {
  31970         if (soc_feature(unit, soc_feature_egr_all_profile) ||
  31971             (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  31972              _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))) {
  31973             return bcm_esw_port_egr_lport_field_get(unit, port,
  31974                     EGR_MTUm, MTU_SIZEf, (uint32*)size);
  31975         } else {
  31976             egr_mtu_entry_t entry;
  31977 
  31978             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  31979             SOC_IF_ERROR_RETURN(soc_mem_read(unit, EGR_MTUm, MEM_BLOCK_ANY, port, &entry));
  31980             *size = soc_mem_field32_get(unit, EGR_MTUm, &entry, MTU_SIZEf);
  31981             return BCM_E_NONE;
  31982         }
  31983     } else
  31984 #endif
  31985     {
  31986         if (soc_feature(unit, soc_feature_egr_l3_mtu)) {
  31987             soc_reg_t reg;
  31988             uint32 rval;
  31989 
  31990             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  31991 
  31992             reg = SOC_REG_IS_VALID(unit, EGR_MTUr) ? EGR_MTUr : EGR_MTU_SIZEr;
  31993 
  31994             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval));
  31995             *size = soc_reg_field_get(unit, reg, rval,
  31996                     (SOC_REG_FIELD_VALID(unit, reg,L3_MTU_SIZEf) ?
  31997                      L3_MTU_SIZEf : MTU_SIZEf));
  31998             return BCM_E_NONE;
  31999         }
  32000     }
  32001 #endif /* BCM_XGS3_SWITCH_SUPPORT && INCLUDE_L3 */
  32002 
  32003     return BCM_E_UNAVAIL;
  32004 }
  32005 
  32006 #ifdef BCM_WARM_BOOT_SUPPORT            
  32007 /*
  32008  * Function:
  32009  *     _bcm_esw_port_ipg_ifg_wb_set
  32010  * Purpose:
  32011  *     Restore the ifg based on the working speed and duplex
  32012  */
  32013 STATIC int
  32014 _bcm_esw_port_ipg_ifg_wb_set(
  32015     int unit,
  32016     bcm_port_t port,
  32017     soc_ipg_t *ipg,
  32018     uint32 ifg)
  32019 {
  32020     int speed, duplex;
  32021 
  32022     if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) {
  32023         /* XLMAC or CLMAC */
  32024         ipg->fd_xe = ifg;
  32025     } else {
  32026         /* UNIMAC */
  32027         BCM_IF_ERROR_RETURN(
  32028             MAC_SPEED_GET(PORT(unit, port).p_mac, unit, port, &speed));
  32029         BCM_IF_ERROR_RETURN(
  32030             MAC_DUPLEX_GET(PORT(unit, port).p_mac, unit, port, &duplex));
  32031         if (duplex == BCM_PORT_DUPLEX_FULL) {
  32032             switch (speed) {
  32033                 case 10:
  32034                     ipg->fd_10 = ifg;
  32035                     break;
  32036                 case 100:
  32037                     ipg->fd_100 = ifg;
  32038                     break;
  32039                 case 1000:
  32040                     ipg->fd_1000 = ifg;
  32041                     break;
  32042                 case 2500:
  32043                     ipg->fd_2500 = ifg;
  32044                     break;
  32045                 default:
  32046                     return BCM_E_PARAM;
  32047             }
  32048         } else {
  32049             switch (speed) {
  32050                 case 10:
  32051                     ipg->hd_10 = ifg;
  32052                     break;
  32053                 case 100:
  32054                     ipg->hd_100 = ifg;
  32055                     break;
  32056                 default:
  32057                     return BCM_E_PARAM;
  32058             }
  32059         }
  32060     }
  32061     return BCM_E_NONE;
  32062 }
  32063 
  32064 /*
  32065  * Function:
  32066  *     _bcm_esw_port_ipg_ifg_wb_get
  32067  * Purpose:
  32068  *     Get the ifg based on the working speed and duplex
  32069  */
  32070 STATIC int
  32071 _bcm_esw_port_ipg_ifg_wb_get(
  32072     int unit,
  32073     bcm_port_t port,
  32074     soc_ipg_t *ipg,
  32075     uint32 *ifg)
  32076 {
  32077     int speed, duplex;
  32078 
  32079     if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) {
  32080         /* XLMAC or CLMAC */
  32081         *ifg = ipg->fd_xe;
  32082     } else {
  32083         /* UNIMAC */
  32084         BCM_IF_ERROR_RETURN(
  32085             MAC_SPEED_GET(PORT(unit, port).p_mac, unit, port, &speed));
  32086         BCM_IF_ERROR_RETURN(
  32087             MAC_DUPLEX_GET(PORT(unit, port).p_mac, unit, port, &duplex));
  32088         if (duplex == BCM_PORT_DUPLEX_FULL) {
  32089             switch (speed) {
  32090                 case 10:
  32091                     *ifg = ipg->fd_10;
  32092                     break;
  32093                 case 100:
  32094                     *ifg = ipg->fd_100;
  32095                     break;
  32096                 case 1000:
  32097                     *ifg = ipg->fd_1000;
  32098                     break;
  32099                 case 2500:
  32100                     *ifg = ipg->fd_2500;
  32101                     break;
  32102                 default:
  32103                     return BCM_E_PARAM;
  32104             }
  32105         } else {
  32106             switch (speed) {
  32107                 case 10:
  32108                     *ifg = ipg->hd_10;
  32109                     break;
  32110                 case 100:
  32111                     *ifg = ipg->hd_100;
  32112                     break;
  32113                 default:
  32114                     return BCM_E_PARAM;
  32115             }
  32116         }
  32117     }
  32118     return BCM_E_NONE;
  32119 }
  32120 
  32121 /*
  32122  * Function:
  32123  *     _bcm_esw_port_ifg_wb_sync
  32124  * Purpose:
  32125  *     Sync port_ifg DB to scache.
  32126  * Parameters:
  32127  *     unit - Device unit number
  32128  *     scache_ptr - Scache pointer.
  32129  * Returns:
  32130  *     BCM_E_XXX
  32131  */
  32132 STATIC int
  32133 _bcm_esw_port_ifg_wb_sync(int unit, uint8 **scache_ptr)
  32134 {
  32135     bcm_port_t  port;
  32136     soc_ipg_t   *si = NULL;
  32137     uint32      ifg = 0;
  32138     int         mode = 0;
  32139     int         rv = BCM_E_NONE;
  32140 
  32141     if ((scache_ptr == NULL) || (*scache_ptr == NULL)) {
  32142         return BCM_E_PARAM;
  32143     }
  32144 
  32145     PBMP_ALL_ITER(unit, port) {
  32146         si = &SOC_PERSIST(unit)->ipg[port];
  32147         if (IS_E_PORT(unit, port)) {
  32148             if (soc_feature(unit, soc_feature_ifg_wb_include_unimac)) {
  32149                 BCM_IF_ERROR_RETURN(
  32150                     _bcm_esw_port_ipg_ifg_wb_get(unit, port, si, &ifg));
  32151             } else {
  32152                 ifg = si->fd_xe;
  32153             }
  32154         } else {
  32155             if (soc_feature(unit, soc_feature_xmac)) {
  32156                 rv = bcm_esw_port_encap_get(unit, port, &mode);
  32157                 if (BCM_E_NONE == rv) {
  32158                     if (BCM_PORT_ENCAP_HIGIG2 == mode) {
  32159                         ifg = si->fd_hg2;
  32160                     } else {
  32161                         ifg = si->fd_hg;
  32162                     }
  32163                 }
  32164             } else {
  32165                 ifg = si->fd_hg;
  32166             }
  32167         }
  32168         sal_memcpy(*scache_ptr, &ifg, sizeof(uint32));
  32169         *scache_ptr += sizeof(uint32);
  32170     }
  32171 
  32172     return BCM_E_NONE;
  32173 }
  32174 
  32175 /*
  32176  * Function:
  32177  *     _bcm_esw_port_ifg_wb_reinit
  32178  * Purpose:
  32179  *     Retrieve port_ifg from scache.
  32180  * Parameters:
  32181  *     unit - Device unit number
  32182  *     scache_ptr - Scache pointer.
  32183  * Returns:
  32184  *     BCM_E_XXX
  32185  */
  32186 STATIC int
  32187 _bcm_esw_port_ifg_wb_reinit(int unit, uint8 **scache_ptr)
  32188 {
  32189     bcm_port_t  port;
  32190     soc_ipg_t   *si = NULL;
  32191     uint32      ifg = 0;
  32192     int         mode = 0;
  32193     int         rv = BCM_E_NONE;
  32194     
  32195     if ((scache_ptr == NULL) || (*scache_ptr == NULL)) {
  32196         return BCM_E_PARAM;
  32197     }
  32198     
  32199     PBMP_ALL_ITER(unit, port) {
  32200         si = &SOC_PERSIST(unit)->ipg[port];
  32201         sal_memcpy(&ifg, *scache_ptr, sizeof(uint32));
  32202         if (IS_E_PORT(unit, port)) {
  32203             if (soc_feature(unit, soc_feature_ifg_wb_include_unimac)) {
  32204                 BCM_IF_ERROR_RETURN(
  32205                     _bcm_esw_port_ipg_ifg_wb_set(unit, port, si, ifg));
  32206             } else {
  32207                 si->fd_xe = ifg;
  32208             }
  32209         } else {
  32210             if (soc_feature(unit, soc_feature_xmac)) {
  32211                 rv = bcm_esw_port_encap_get(unit, port, &mode);
  32212                 if (BCM_E_NONE == rv) {
  32213                     if (BCM_PORT_ENCAP_HIGIG2 == mode) {
  32214                         si->fd_hg2 = ifg;
  32215                     } else {
  32216                         si->fd_hg = ifg;
  32217                     }
  32218                 }
  32219             } else {
  32220                 si->fd_hg = ifg;
  32221             }
  32222         }
  32223         *scache_ptr += sizeof(uint32);
  32224     }
  32225 
  32226     return BCM_E_NONE;
  32227 }
  32228 #endif
  32229 
  32230 /*
  32231  * Function:
  32232  *      bcm_esw_port_ifg_set
  32233  * Description:
  32234  *      Sets the new ifg (Inter-frame gap) value
  32235  * Parameters:
  32236  *      unit   - Device number
  32237  *      port   - Port number
  32238  *      speed  - the speed for which the IFG is being set
  32239  *      duplex - the duplex for which the IFG is being set
  32240  *      ifg    - Inter-frame gap in bit-times
  32241  * Return Value:
  32242  *      BCM_E_XXX
  32243  * Notes:
  32244  *      The function makes sure the IFG value makes sense and updates the
  32245  *      IPG register in case the speed/duplex match the current settings
  32246  */
  32247 int
  32248 bcm_esw_port_ifg_set(int unit, bcm_port_t port,
  32249                  int speed, bcm_port_duplex_t duplex,
  32250                  int ifg)
  32251 {
  32252 
  32253     /* Make sure port module is initialized. */
  32254     PORT_INIT(unit);
  32255 
  32256     if (SOC_USE_PORTCTRL(unit)) {
  32257         return bcmi_esw_portctrl_ifg_set(unit, port, speed, duplex, ifg);
  32258     }
  32259 
  32260     if(bcm_common_oamp_port_enable_get(unit, port)) {
  32261         LOG_ERROR(BSL_LS_BCM_PORT,
  32262                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  32263                    port));
  32264         return BCM_E_PARAM;
  32265     }
  32266 
  32267     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  32268 
  32269     return MAC_IFG_SET(PORT(unit, port).p_mac, unit, port,
  32270                        speed, duplex, ifg);
  32271 }
  32272 
  32273 /*
  32274  * Function:
  32275  *      bcm_port_ifg_get
  32276  * Description:
  32277  *      Gets the new ifg (Inter-frame gap) value
  32278  * Parameters:
  32279  *      unit   - Device number
  32280  *      port   - Port number
  32281  *      speed  - the speed for which the IFG is being set
  32282  *      duplex - the duplex for which the IFG is being set
  32283  *      ifg    - Inter-frame gap in bit-times
  32284  * Return Value:
  32285  *      BCM_E_XXX
  32286  * Notes:
  32287  */
  32288 int
  32289 bcm_esw_port_ifg_get(int unit, bcm_port_t port,
  32290                  int speed, bcm_port_duplex_t duplex,
  32291                  int *ifg)
  32292 {
  32293     /* Make sure port module is initialized. */
  32294     PORT_INIT(unit);
  32295 
  32296     if (SOC_USE_PORTCTRL(unit)) {
  32297         return bcmi_esw_portctrl_ifg_get(unit, port, speed, duplex, ifg);
  32298     }
  32299 
  32300     if(bcm_common_oamp_port_enable_get(unit, port)) {
  32301         LOG_ERROR(BSL_LS_BCM_PORT,
  32302                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  32303                    port));
  32304         return BCM_E_PARAM;
  32305     }
  32306 
  32307     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  32308 
  32309     return MAC_IFG_GET(PORT(unit, port).p_mac, unit, port,
  32310                        speed, duplex, ifg);
  32311 }
  32312 
  32313 /*
  32314  * Function:
  32315  *      bcm_port_phy_get
  32316  * Description:
  32317  *      General PHY register read
  32318  * Parameters:
  32319  *      unit - Device number
  32320  *      port - Port number or PHY MDIO address (refer BCM_PORT_PHY_NOMAP)
  32321  *      flags - Logical OR of one or more of the following flags:
  32322  *              BCM_PORT_PHY_INTERNAL
  32323  *                      Address internal SERDES PHY for port
  32324  *              BCM_PORT_PHY_NOMAP
  32325  *                      Instead of mapping port to PHY MDIO address,
  32326  *                      treat port parameter as actual PHY MDIO address.
  32327  *              BCM_PORT_PHY_CLAUSE45
  32328  *                      Assume Clause 45 device instead of Clause 22
  32329  *      phy_addr - PHY internal register address
  32330  *      phy_data - (OUT) Data that was read
  32331  * Returns:
  32332  *      BCM_E_XXX
  32333  */
  32334 int
  32335 bcm_esw_port_phy_get(int unit, bcm_port_t port, uint32 flags,
  32336                  uint32 phy_reg_addr, uint32 *phy_data)
  32337 {
  32338     uint16  phy_id;
  32339     uint8  phy_devad;
  32340     uint16 phy_reg;
  32341     uint16 phy_rd_data;
  32342     uint32 reg_flag;
  32343     int    rv;
  32344     int lane = -1;
  32345     int phyn = -1, sys_side = 0;
  32346     bcm_port_t local_port = -1;
  32347 
  32348     if (SOC_USE_PORTCTRL(unit)) {
  32349         return bcmi_esw_portctrl_phy_get(unit, port, flags, phy_reg_addr,
  32350                                          phy_data);
  32351     }
  32352 
  32353     /* Make sure port module is initialized. */
  32354     PORT_INIT(unit);
  32355 
  32356     if(bcm_common_oamp_port_enable_get(unit, port)) {
  32357         LOG_ERROR(BSL_LS_BCM_PORT,
  32358                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  32359                    port));
  32360         return BCM_E_PARAM;
  32361     }
  32362 
  32363     if (!(flags & BCM_PORT_PHY_NOMAP)) {
  32364         BCM_IF_ERROR_RETURN
  32365             (_bcm_esw_port_gport_phyn_validate(unit, port,
  32366                                            &local_port, &phyn,
  32367                                            &lane, &sys_side));
  32368         if (local_port != -1) {
  32369             port = local_port;
  32370         }
  32371         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  32372 
  32373         if(!(SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) {
  32374             return BCM_E_PORT;
  32375         }
  32376     }
  32377 
  32378     if (flags & (SOC_PHY_I2C_DATA8 | SOC_PHY_I2C_DATA16 | SOC_PHY_PVT_DATA)) {
  32379         PORT_LOCK(unit);
  32380         rv = soc_phyctrl_reg_read(unit, port, flags, phy_reg_addr, phy_data);
  32381         PORT_UNLOCK(unit);
  32382         return rv;
  32383     }
  32384 
  32385     rv       = BCM_E_UNAVAIL;
  32386     reg_flag = BCM_PORT_PHY_REG_FLAGS(phy_reg_addr);
  32387     if ( (reg_flag & SOC_PHY_REG_INDIRECT) ||
  32388          (flags & (BCM_PORT_PHY_REG_RDB | BCM_PORT_PHY_REG_MACSEC)) ) {
  32389         if (flags & BCM_PORT_PHY_NOMAP) {
  32390             /* Indirect register access is performed through PHY driver.
  32391              * Therefore, indirect register access is not supported if
  32392              * BCM_PORT_PHY_NOMAP flag is set.
  32393              */
  32394             return BCM_E_PARAM;
  32395         }
  32396         phy_reg_addr &= ~SOC_PHY_REG_INDIRECT;
  32397 
  32398         if (lane >= 0) {
  32399 #if defined(PHYMOD_SUPPORT)
  32400             SOC_PHY_PHYMOD_FORCE_LANE_SET(phy_reg_addr, lane);
  32401 #endif
  32402         }       
  32403         if (phyn == 1) {
  32404             flags |= SOC_PHY_INTERNAL;
  32405         }
  32406         PORT_LOCK(unit);
  32407         rv = soc_phyctrl_reg_read(unit, port, flags, phy_reg_addr, phy_data);
  32408         PORT_UNLOCK(unit);
  32409     }
  32410 
  32411     if (rv == BCM_E_UNAVAIL) {
  32412         if (flags & BCM_PORT_PHY_NOMAP) {
  32413             phy_id = port;
  32414         } else if (flags & BCM_PORT_PHY_INTERNAL) {
  32415             phy_id = PORT_TO_PHY_ADDR_INT(unit, port);
  32416         } else {
  32417             phy_id = PORT_TO_PHY_ADDR(unit, port);
  32418         }
  32419 
  32420         PORT_LOCK(unit);
  32421         if (flags & BCM_PORT_PHY_CLAUSE45) {
  32422             phy_devad = BCM_PORT_PHY_CLAUSE45_DEVAD(phy_reg_addr);
  32423             phy_reg   = BCM_PORT_PHY_CLAUSE45_REGAD(phy_reg_addr);
  32424             rv = soc_miimc45_read(unit, phy_id, phy_devad,
  32425                                   phy_reg, &phy_rd_data);
  32426 
  32427         } else {
  32428             phy_reg = phy_reg_addr;
  32429             rv = soc_miim_read(unit, phy_id, phy_reg, &phy_rd_data);
  32430         }
  32431         PORT_UNLOCK(unit);
  32432 
  32433         if (BCM_SUCCESS(rv)) {
  32434            *phy_data = phy_rd_data;
  32435         }
  32436     }
  32437 
  32438     LOG_INFO(BSL_LS_BCM_PORT,
  32439              (BSL_META_U(unit,
  32440                          "bcm_esw_port_phy_get: u=%d p=%d flags=0x%08x "
  32441                          "phy_reg=0x%08x, phy_data=0x%08x, rv=%d\n"),
  32442               unit, port, flags, phy_reg_addr, *phy_data, rv));
  32443 
  32444     return rv;
  32445 }
  32446 
  32447 /*
  32448  * Function:
  32449  *      bcm_port_phy_set
  32450  * Description:
  32451  *      General PHY register write
  32452  * Parameters:
  32453  *      unit - Device number
  32454  *      port - Port number or PHY MDIO address (refer BCM_PORT_PHY_NOMAP)
  32455  *      flags - Logical OR of one or more of the following flags:
  32456  *              BCM_PORT_PHY_INTERNAL
  32457  *                      Address internal SERDES PHY for port
  32458  *              BCM_PORT_PHY_NOMAP
  32459  *                      Instead of mapping port to PHY MDIO address,
  32460  *                      treat port parameter as actual PHY MDIO address.
  32461  *              BCM_PORT_PHY_CLAUSE45
  32462  *                      Assume Clause 45 device instead of Clause 22
  32463  *      phy_addr - PHY internal register address
  32464  *      phy_data - Data to write
  32465  * Returns:
  32466  *      BCM_E_XXX
  32467  */
  32468 int
  32469 bcm_esw_port_phy_set(int unit, bcm_port_t port, uint32 flags,
  32470                  uint32 phy_reg_addr, uint32 phy_data)
  32471 {
  32472     uint16 phy_id;
  32473     uint8  phy_devad;
  32474     uint16 phy_reg;
  32475     uint16 phy_wr_data;
  32476     uint32 reg_flag;
  32477     int    rv;
  32478     int lane = -1;
  32479     int phyn = -1, sys_side = 0;
  32480     bcm_port_t local_port = -1;
  32481 
  32482     if (SOC_USE_PORTCTRL(unit)) {
  32483         return bcmi_esw_portctrl_phy_set(unit, port, flags, phy_reg_addr,
  32484                                          phy_data);
  32485     }
  32486 
  32487     /* Make sure port module is initialized. */
  32488     PORT_INIT(unit);
  32489 
  32490     if(bcm_common_oamp_port_enable_get(unit, port)) {
  32491         LOG_ERROR(BSL_LS_BCM_PORT,
  32492                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  32493                    port));
  32494         return BCM_E_PARAM;
  32495     }
  32496 
  32497     if (!(flags & BCM_PORT_PHY_NOMAP)) {
  32498         BCM_IF_ERROR_RETURN
  32499             (_bcm_esw_port_gport_phyn_validate(unit, port,
  32500                                            &local_port, &phyn,
  32501                                            &lane, &sys_side));
  32502         if (local_port != -1) {
  32503             port = local_port;
  32504         }
  32505         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  32506 
  32507         if(!(SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) {
  32508             return BCM_E_PORT;
  32509         }
  32510     }
  32511 
  32512     LOG_INFO(BSL_LS_BCM_PORT,
  32513              (BSL_META_U(unit,
  32514                          "bcm_esw_port_phy_set: u=%d p=%d flags=0x%08x "
  32515                          "phy_reg=0x%08x phy_data=0x%08x\n"),
  32516               unit, port, flags, phy_reg_addr, phy_data));
  32517 
  32518     if (flags & (SOC_PHY_I2C_DATA8 | SOC_PHY_I2C_DATA16 | SOC_PHY_PVT_DATA)) {
  32519         PORT_LOCK(unit);
  32520         rv = soc_phyctrl_reg_write(unit, port, flags, phy_reg_addr, phy_data);
  32521         PORT_UNLOCK(unit);
  32522         return rv;
  32523     }
  32524 
  32525     rv       = BCM_E_UNAVAIL;
  32526     reg_flag = BCM_PORT_PHY_REG_FLAGS(phy_reg_addr);
  32527     if ( (reg_flag & SOC_PHY_REG_INDIRECT) ||
  32528          (flags & (BCM_PORT_PHY_REG_RDB | BCM_PORT_PHY_REG_MACSEC)) ) {
  32529         if (flags & BCM_PORT_PHY_NOMAP) {
  32530             /* Indirect register access is performed through PHY driver.
  32531              * Therefore, indirect register access is not supported if
  32532              * BCM_PORT_PHY_NOMAP flag is set.
  32533              */
  32534             return BCM_E_PARAM;
  32535         }
  32536         phy_reg_addr &= ~SOC_PHY_REG_INDIRECT;
  32537         if (lane >= 0) {
  32538 #if defined(PHYMOD_SUPPORT)
  32539             SOC_PHY_PHYMOD_FORCE_LANE_SET(phy_reg_addr, lane);
  32540 #endif
  32541         }
  32542         if (phyn == 1) {
  32543             flags |= SOC_PHY_INTERNAL;
  32544         }
  32545         PORT_LOCK(unit);
  32546         rv = soc_phyctrl_reg_write(unit, port, flags, phy_reg_addr, phy_data);
  32547         PORT_UNLOCK(unit);
  32548     }
  32549 
  32550     if (rv == BCM_E_UNAVAIL) {
  32551         if (flags & BCM_PORT_PHY_NOMAP) {
  32552             phy_id = port;
  32553         } else if (flags & BCM_PORT_PHY_INTERNAL) {
  32554             phy_id = PORT_TO_PHY_ADDR_INT(unit, port);
  32555         } else {
  32556             phy_id = PORT_TO_PHY_ADDR(unit, port);
  32557         }
  32558 
  32559         phy_wr_data = (uint16) (phy_data & 0xffff);
  32560         PORT_LOCK(unit);
  32561         if (flags & BCM_PORT_PHY_CLAUSE45) {
  32562             phy_devad = BCM_PORT_PHY_CLAUSE45_DEVAD(phy_reg_addr);
  32563             phy_reg   = BCM_PORT_PHY_CLAUSE45_REGAD(phy_reg_addr);
  32564             rv = soc_miimc45_write(unit, phy_id, phy_devad,
  32565                                    phy_reg, phy_wr_data);
  32566         } else {
  32567             phy_reg = phy_reg_addr;
  32568             rv = soc_miim_write(unit, phy_id, phy_reg, phy_wr_data);
  32569         }
  32570         PORT_UNLOCK(unit);
  32571     }
  32572     return rv;
  32573 }
  32574 /*
  32575  * Function:
  32576  *      bcm_port_phy_multi_get
  32577  * Description:
  32578  *      General PHY register read
  32579  * Parameters:
  32580  *      unit - Device number
  32581  *      port - Port number
  32582  *      flags - TBD
  32583  *      dev_addr - Device address on the PHY's bus (ex. I2C addr)
  32584  *      offset - Offset within device
  32585  *      max_size - Requested data size
  32586  *      data - Data buffer
  32587  *      actual_size - Received data size
  32588  * Returns:
  32589  *      BCM_E_XXX
  32590  */
  32591 int
  32592 bcm_esw_port_phy_multi_get(int unit, bcm_port_t port, uint32 flags,
  32593                  uint32 dev_addr, uint32 offset, int max_size, uint8 *data, int *actual_size)
  32594 {
  32595     int rv;
  32596 
  32597     if (SOC_USE_PORTCTRL(unit)) {
  32598         return bcmi_esw_portctrl_phy_multi_get(unit, port, flags, dev_addr,
  32599                                                offset, max_size, data, 
  32600                                                actual_size);
  32601     }
  32602 
  32603     /* Make sure port module is initialized. */
  32604     PORT_INIT(unit);
  32605 
  32606     if(bcm_common_oamp_port_enable_get(unit, port)) {
  32607         LOG_ERROR(BSL_LS_BCM_PORT,
  32608                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  32609                    port));
  32610         return BCM_E_PARAM;
  32611     }
  32612 
  32613     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  32614 
  32615     PORT_LOCK(unit);
  32616     rv = soc_phyctrl_port_phy_multi_get(unit, port, flags, dev_addr, offset, max_size, data, actual_size);
  32617     PORT_UNLOCK(unit);
  32618     /*
  32619     LOG_INFO(BSL_LS_BCM_PORT,
  32620              (BSL_META_U(unit,
  32621                          "bcm_esw_port_phy_multi_get: u=%d p=%d flags=0x%08x "
  32622                          "dev_addr=0x%08x, offset=0x%08x, max_size=%d data=%p actual_size=%d rv=%d\n"),
  32623               unit, port, flags, dev_addr, offset, max_size, data, *actual_size, rv));
  32624     */
  32625     return rv;
  32626 }
  32627 
  32628 /*
  32629  * Function:
  32630  *      bcm_port_phy_modify
  32631  * Description:
  32632  *      General PHY register modify
  32633  * Parameters:
  32634  *      unit - Device number
  32635  *      port - Port number  or PHY MDIO address (refer BCM_PORT_PHY_NOMAP)
  32636  *      flags - Logical OR of one or more of the following flags:
  32637  *              BCM_PORT_PHY_INTERNAL
  32638  *                      Address internal SERDES PHY for port
  32639  *              BCM_PORT_PHY_NOMAP
  32640  *                      Instead of mapping port to PHY MDIO address,
  32641  *                      treat port parameter as actual PHY MDIO address.
  32642  *              BCM_PORT_PHY_CLAUSE45
  32643  *                      Assume Clause 45 device instead of Clause 22
  32644  *      phy_addr - PHY internal register address
  32645  *      phy_data - Data to write
  32646  *      phy_mask - Bits to modify using phy_data
  32647  * Returns:
  32648  *      BCM_E_XXX
  32649  */
  32650 int
  32651 bcm_esw_port_phy_modify(int unit, bcm_port_t port, uint32 flags,
  32652                         uint32 phy_reg_addr, uint32 phy_data, uint32 phy_mask)
  32653 {
  32654     uint16 phy_id;
  32655     uint8  phy_devad;
  32656     uint16 phy_reg;
  32657     uint16 phy_rd_data;
  32658     uint16 phy_wr_data;
  32659     uint32 reg_flag;
  32660     int    rv;
  32661     int lane = -1;
  32662     int phyn = -1, sys_side = 0;
  32663     bcm_port_t local_port = -1;
  32664 
  32665     if (SOC_USE_PORTCTRL(unit)) {
  32666         return bcmi_esw_portctrl_phy_modify(unit, port, flags, phy_reg_addr,
  32667                                             phy_data, phy_mask);
  32668     }
  32669 
  32670     /* Make sure port module is initialized. */
  32671     PORT_INIT(unit);
  32672 
  32673     if(bcm_common_oamp_port_enable_get(unit, port)) {
  32674         LOG_ERROR(BSL_LS_BCM_PORT,
  32675                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  32676                    port));
  32677         return BCM_E_PARAM;
  32678     }
  32679 
  32680     if (!(flags & BCM_PORT_PHY_NOMAP)) {
  32681         BCM_IF_ERROR_RETURN
  32682             (_bcm_esw_port_gport_phyn_validate(unit, port,
  32683                                            &local_port, &phyn,
  32684                                            &lane, &sys_side));
  32685         if (local_port != -1) {
  32686             port = local_port;
  32687         }
  32688         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  32689 
  32690         if(!(SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) {
  32691             return BCM_E_PORT;
  32692         }
  32693     }
  32694 
  32695     LOG_INFO(BSL_LS_BCM_PORT,
  32696              (BSL_META_U(unit,
  32697                          "bcm_esw_port_phy_modify: u=%d p=%d flags=0x%08x "
  32698                          "phy_reg=0x%08x phy_data=0x%08x phy_mask=0x%08x\n"),
  32699               unit, port, flags, phy_reg_addr, phy_data, phy_mask));
  32700 
  32701     rv       = BCM_E_UNAVAIL;
  32702     reg_flag = BCM_PORT_PHY_REG_FLAGS(phy_reg_addr);
  32703     if (reg_flag & SOC_PHY_REG_INDIRECT) {
  32704         if (flags & BCM_PORT_PHY_NOMAP) {
  32705             /* Indirect register access is performed through PHY driver.
  32706              * Therefore, indirect register access is not supported if
  32707              * BCM_PORT_PHY_NOMAP flag is set.
  32708              */
  32709             return BCM_E_PARAM;
  32710         }
  32711         phy_reg_addr &= ~SOC_PHY_REG_INDIRECT;
  32712         if (lane >= 0) {
  32713 #if defined(PHYMOD_SUPPORT)
  32714            SOC_PHY_PHYMOD_FORCE_LANE_SET(phy_reg_addr, lane); 
  32715 #endif
  32716         }
  32717         if (phyn == 1) {
  32718             flags |= SOC_PHY_INTERNAL;
  32719         }
  32720         PORT_LOCK(unit);
  32721         rv = soc_phyctrl_reg_modify(unit, port, flags, phy_reg_addr,
  32722                                     phy_data, phy_mask);
  32723         PORT_UNLOCK(unit);
  32724     }
  32725 
  32726     if (rv == BCM_E_UNAVAIL) {
  32727         if (flags & BCM_PORT_PHY_NOMAP) {
  32728             phy_id = port;
  32729         } else if (flags & BCM_PORT_PHY_INTERNAL) {
  32730             phy_id = PORT_TO_PHY_ADDR_INT(unit, port);
  32731         } else {
  32732             phy_id = PORT_TO_PHY_ADDR(unit, port);
  32733         }
  32734 
  32735         phy_wr_data = (uint16) (phy_data & phy_mask & 0xffff);
  32736         PORT_LOCK(unit);
  32737         if (flags & BCM_PORT_PHY_CLAUSE45) {
  32738             phy_devad = BCM_PORT_PHY_CLAUSE45_DEVAD(phy_reg_addr);
  32739             phy_reg   = BCM_PORT_PHY_CLAUSE45_REGAD(phy_reg_addr);
  32740             rv = soc_miimc45_read(unit, phy_id, phy_devad,
  32741                                   phy_reg, &phy_rd_data);
  32742             phy_wr_data |= (phy_rd_data & ~phy_mask);
  32743             rv = soc_miimc45_write(unit, phy_id, phy_devad,
  32744                                    phy_reg, phy_wr_data);
  32745         } else {
  32746             phy_reg = phy_reg_addr;
  32747             rv = soc_miim_read(unit, phy_id, phy_reg, &phy_rd_data);
  32748             if (BCM_SUCCESS(rv)) {
  32749                 phy_wr_data |= (phy_rd_data & ~phy_mask);
  32750                 rv = soc_miim_write(unit, phy_id, phy_reg, phy_wr_data);
  32751             }
  32752         }
  32753         PORT_UNLOCK(unit);
  32754     }
  32755     return rv;
  32756 }
  32757 
  32758 /*
  32759  * Function:
  32760  *      bcm_port_mdix_set
  32761  * Description:
  32762  *      Set the Auto-MDIX mode of a port/PHY
  32763  * Parameters:
  32764  *      unit - Device number
  32765  *      port - Port number
  32766  *      mode - One of:
  32767  *              BCM_PORT_MDIX_AUTO
  32768  *                      Enable auto-MDIX when autonegotiation is enabled
  32769  *              BCM_PORT_MDIX_FORCE_AUTO
  32770  *                      Enable auto-MDIX always
  32771  *              BCM_PORT_MDIX_NORMAL
  32772  *                      Disable auto-MDIX
  32773  *              BCM_PORT_MDIX_XOVER
  32774  *                      Disable auto-MDIX, and swap cable pairs
  32775  * Return Value:
  32776  *      BCM_E_UNAVAIL - feature unsupported by hardware
  32777  *      BCM_E_XXX - other error
  32778  */
  32779 int
  32780 bcm_esw_port_mdix_set(int unit, bcm_port_t port, bcm_port_mdix_t mode)
  32781 {
  32782     int rv;
  32783 
  32784     /* Make sure port module is initialized. */
  32785     PORT_INIT(unit);
  32786 
  32787     /* Call Port Control module */
  32788     if (SOC_USE_PORTCTRL(unit)) {
  32789         return bcmi_esw_portctrl_mdix_set(unit, port, mode);
  32790     }
  32791 
  32792     if(bcm_common_oamp_port_enable_get(unit, port)) {
  32793         LOG_ERROR(BSL_LS_BCM_PORT,
  32794                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  32795                    port));
  32796         return BCM_E_PARAM;
  32797     }
  32798 
  32799     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  32800 
  32801     PORT_LOCK(unit);
  32802     rv = soc_phyctrl_mdix_set(unit, port, mode);
  32803     PORT_UNLOCK(unit);
  32804     return rv;
  32805 }
  32806 
  32807 /*
  32808  * Function:
  32809  *      bcm_port_mdix_get
  32810  * Description:
  32811  *      Get the Auto-MDIX mode of a port/PHY
  32812  * Parameters:
  32813  *      unit - Device number
  32814  *      port - Port number
  32815  *      mode - (Out) One of:
  32816  *              BCM_PORT_MDIX_AUTO
  32817  *                      Enable auto-MDIX when autonegotiation is enabled
  32818  *              BCM_PORT_MDIX_FORCE_AUTO
  32819  *                      Enable auto-MDIX always
  32820  *              BCM_PORT_MDIX_NORMAL
  32821  *                      Disable auto-MDIX
  32822  *              BCM_PORT_MDIX_XOVER
  32823  *                      Disable auto-MDIX, and swap cable pairs
  32824  * Return Value:
  32825  *      BCM_E_UNAVAIL - feature unsupported by hardware
  32826  *      BCM_E_XXX - other error
  32827  */
  32828 int
  32829 bcm_esw_port_mdix_get(int unit, bcm_port_t port, bcm_port_mdix_t *mode)
  32830 {
  32831     int rv=BCM_E_NONE;
  32832 
  32833     /* Make sure port module is initialized. */
  32834     PORT_INIT(unit);
  32835 
  32836     /* Call Port Control module */
  32837     if (SOC_USE_PORTCTRL(unit)) {
  32838         return bcmi_esw_portctrl_mdix_get(unit, port, mode);
  32839     }
  32840 
  32841     if(bcm_common_oamp_port_enable_get(unit, port)) {
  32842         LOG_ERROR(BSL_LS_BCM_PORT,
  32843                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  32844                    port));
  32845         return BCM_E_PARAM;
  32846     }
  32847 
  32848     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  32849     PORT_LOCK(unit);
  32850     rv = soc_phyctrl_mdix_get(unit, port, mode);
  32851     PORT_UNLOCK(unit);
  32852 
  32853     return rv;
  32854 }
  32855 
  32856 /*
  32857  * Function:
  32858  *      bcm_port_mdix_status_get
  32859  * Description:
  32860  *      Get the current MDIX status on a port/PHY
  32861  * Parameters:
  32862  *      unit    - Device number
  32863  *      port    - Port number
  32864  *      status  - (OUT) One of:
  32865  *              BCM_PORT_MDIX_STATUS_NORMAL
  32866  *                      Straight connection
  32867  *              BCM_PORT_MDIX_STATUS_XOVER
  32868  *                      Crossover has been performed
  32869  * Return Value:
  32870  *      BCM_E_UNAVAIL - feature unsupported by hardware
  32871  *      BCM_E_XXX - other error
  32872  */
  32873 int
  32874 bcm_esw_port_mdix_status_get(int unit, bcm_port_t port,
  32875                          bcm_port_mdix_status_t *status)
  32876 {
  32877     int rv=BCM_E_NONE;
  32878 
  32879     /* Make sure port module is initialized. */
  32880     PORT_INIT(unit);
  32881 
  32882     /* Call Port Control module */
  32883     if (SOC_USE_PORTCTRL(unit)) {
  32884         return bcmi_esw_portctrl_mdix_status_get(unit, port, status);
  32885     }
  32886 
  32887     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  32888     PORT_LOCK(unit);
  32889     rv = soc_phyctrl_mdix_status_get(unit, port, status);
  32890     PORT_UNLOCK(unit);
  32891     return rv;
  32892 }
  32893 
  32894 /*
  32895  * Function:
  32896  *      bcm_port_medium_config_set
  32897  * Description:
  32898  *      Set the medium-specific configuration for a combo port
  32899  * Parameters:
  32900  *      unit     - Device number
  32901  *      port     - Port number
  32902  *      medium   - The medium (BCM_PORT_MEDIUM_COPPER or BCM_PORT_MEDIUM_FIBER)
  32903  *                 to apply the configuration to
  32904  *      config   - per-medium configuration
  32905  * Return Value:
  32906  *      BCM_E_XXX
  32907  */
  32908 int
  32909 bcm_esw_port_medium_config_set(int unit, bcm_port_t port,
  32910                            bcm_port_medium_t medium,
  32911                            bcm_phy_config_t  *config)
  32912 {
  32913     int rv;
  32914 
  32915     /* Make sure port module is initialized. */
  32916     PORT_INIT(unit);
  32917     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  32918 
  32919 #ifdef PORTMOD_SUPPORT
  32920     if (SOC_USE_PORTCTRL(unit)) {
  32921         rv = bcmi_esw_portctrl_medium_config_set(unit, port, medium, config);
  32922     } else
  32923 #endif /* PORTMOD_SUPPORT */
  32924     {
  32925         PORT_LOCK(unit);
  32926         rv = soc_phyctrl_medium_config_set(unit, port, medium, config);
  32927         PORT_UNLOCK(unit);
  32928     }
  32929 
  32930     return rv;
  32931 }
  32932 
  32933 /*
  32934  * Function:
  32935  *      bcm_port_medium_config_get
  32936  * Description:
  32937  *      Get the medium-specific configuration for a combo port
  32938  * Parameters:
  32939  *      unit     - Device number
  32940  *      port     - Port number
  32941  *      medium   - The medium (BCM_PORT_MEDIUM_COPPER or BCM_PORT_MEDIUM_FIBER)
  32942  *                 to get the config for
  32943  *      config   - per-medium configuration
  32944  * Return Value:
  32945  *      BCM_E_XXX
  32946  */
  32947 int
  32948 bcm_esw_port_medium_config_get(int unit, bcm_port_t port,
  32949                            bcm_port_medium_t  medium,
  32950                            bcm_phy_config_t  *config)
  32951 {
  32952     int rv;
  32953 
  32954     /* Make sure port module is initialized. */
  32955     PORT_INIT(unit);
  32956     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  32957 
  32958 #ifdef PORTMOD_SUPPORT
  32959     if (SOC_USE_PORTCTRL(unit)) {
  32960         rv = bcmi_esw_portctrl_medium_config_get(unit, port, medium, config);
  32961     } else
  32962 #endif /* PORTMOD_SUPPORT */
  32963     {
  32964         PORT_LOCK(unit);
  32965         rv = soc_phyctrl_medium_config_get(unit, port, medium, config);
  32966         PORT_UNLOCK(unit);
  32967     }
  32968     return rv;
  32969 }
  32970 
  32971 /*
  32972  * Function:
  32973  *      bcm_port_medium_get
  32974  * Description:
  32975  *      Get the current medium used by a combo port
  32976  * Parameters:
  32977  *      unit     - Device number
  32978  *      port     - Port number
  32979  *      medium   - The medium (BCM_PORT_MEDIUM_COPPER or BCM_PORT_MEDIUM_FIBER)
  32980  *                 which is currently selected
  32981  * Return Value:
  32982  *      BCM_E_XXX
  32983  */
  32984 int
  32985 bcm_esw_port_medium_get(int unit, bcm_port_t port,
  32986                     bcm_port_medium_t *medium)
  32987 {
  32988     int rv=BCM_E_NONE;
  32989     /* Make sure port module is initialized. */
  32990     PORT_INIT(unit);
  32991 
  32992     /* Call Port Control module */
  32993     if (SOC_USE_PORTCTRL(unit)) {
  32994         return bcmi_esw_portctrl_medium_get(unit, port, medium);
  32995     }
  32996 
  32997     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  32998     PORT_LOCK(unit);
  32999     rv = soc_phyctrl_medium_get(unit, port, medium);
  33000     PORT_UNLOCK(unit);
  33001     return rv;
  33002 }
  33003 
  33004 /*
  33005  * Function:
  33006  *      bcm_port_medium_status_register
  33007  * Description:
  33008  *      Register a callback function to be called on medium change event
  33009  * Parameters:
  33010  *      unit      - Device number
  33011  *      port      - port number
  33012  *      callback  - The callback function to call
  33013  *      user_data - An opaque cookie to pass to callback function
  33014  *                  whenever it is called
  33015  * Returns:
  33016  *      BCM_E_NONE
  33017  *      BCM_E_PARAM  -- NULL function pointer or bad {unit, port} combination
  33018  *      BCM_E_FULL   -- Cannot register more than 1 callback per {unit, port}
  33019  */
  33020 int
  33021 bcm_esw_port_medium_status_register(int                          unit,
  33022                                 bcm_port_t                   port,
  33023                                 bcm_port_medium_status_cb_t  callback,
  33024                                 void                        *user_data)
  33025 {
  33026     /* Make sure port module is initialized. */
  33027     PORT_INIT(unit);
  33028 
  33029     return soc_phy_medium_status_register(unit, port, callback, user_data);
  33030 }
  33031 
  33032 /*
  33033  * Function:
  33034  *      bcm_port_medium_status_unregister
  33035  * Description:
  33036  *      Unregister a callback function to be called on medium change event
  33037  * Parameters:
  33038  *      unit      - Device number
  33039  *      port      - port number
  33040  *      callback  - The callback function to call
  33041  *      user_data - An opaque cookie to pass to callback function
  33042  *                  whenever it is called
  33043  * Returns:
  33044  *      BCM_E_NONE
  33045  *      BCM_E_PARAM       -- Bad {unit, port} combination
  33046  *      BCM_E_NOT_FOUND   -- The specified {unit, port, callback, user_data}
  33047  *                           combination have not been registered before
  33048  */
  33049 int
  33050 bcm_esw_port_medium_status_unregister(int                          unit,
  33051                                   bcm_port_t                   port,
  33052                                   bcm_port_medium_status_cb_t  callback,
  33053                                   void                        *user_data)
  33054 {
  33055     /* Make sure port module is initialized. */
  33056     PORT_INIT(unit);
  33057 
  33058     return soc_phy_medium_status_unregister(unit, port, callback, user_data);
  33059 }
  33060 
  33061 /*
  33062  * Function:
  33063  *      bcm_port_phy_reset
  33064  * Description:
  33065  *      This function performs the low-level PHY reset and is intended to be
  33066  *      called ONLY from callback function registered with
  33067  *      bcm_port_phy_reset_register. Attempting to call it from any other
  33068  *      place will break lots of things.
  33069  * Parameters:
  33070  *      unit    - Device number
  33071  *      port    - Port number
  33072  * Returns:
  33073  *      BCM_E_XXX
  33074  */
  33075 int
  33076 bcm_esw_port_phy_reset(int unit, bcm_port_t port)
  33077 {
  33078     int rv;
  33079 
  33080     /* Make sure port module is initialized. */
  33081     PORT_INIT(unit);
  33082 
  33083     /* Call Port Control module */
  33084     if (SOC_USE_PORTCTRL(unit)) {
  33085         return (bcmi_esw_portctrl_phy_reset(unit, port));
  33086     }
  33087 
  33088     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33089 
  33090     if (!(BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) {
  33091         return BCM_E_PORT;
  33092     }
  33093 
  33094     PORT_LOCK(unit);
  33095     rv = soc_phyctrl_reset(unit, port, NULL);
  33096     PORT_UNLOCK(unit);
  33097     return rv;
  33098 }
  33099 
  33100 /*
  33101  * Function:
  33102  *      bcm_port_phy_reset_register
  33103  * Description:
  33104  *      Register a callback function to be called whenever a PHY driver
  33105  *      needs to perform a PHY reset
  33106  * Parameters:
  33107  *      unit      - Device number
  33108  *      port      - port number
  33109  *      callback  - The callback function to call
  33110  *      user_data - An opaque cookie to pass to callback function
  33111  *                  whenever it is called
  33112  * Returns:
  33113  *      BCM_E_NONE
  33114  *      BCM_E_PARAM       -- Bad {unit, port} combination
  33115  *      BCM_E_NOT_FOUND   -- The specified {unit, port, callback, user_data}
  33116  *                           combination have not been registered before
  33117  */
  33118 int
  33119 bcm_esw_port_phy_reset_register(int unit, bcm_port_t port,
  33120                             bcm_port_phy_reset_cb_t callback,
  33121                             void  *user_data)
  33122 {
  33123     /* Make sure port module is initialized. */
  33124     PORT_INIT(unit);
  33125 
  33126     return soc_phy_reset_register(unit, port, callback, user_data, FALSE);
  33127 }
  33128 
  33129 /*
  33130  * Function:
  33131  *      bcm_port_phy_reset_unregister
  33132  * Description:
  33133  *      Unregister a callback function to be called whenever a PHY driver
  33134  *      needs to perform a PHY reset
  33135  * Parameters:
  33136  *      unit      - Device number
  33137  *      port      - port number
  33138  *      callback  - The callback function to call
  33139  *      user_data - An opaque cookie to pass to callback function
  33140  *                  whenever it is called
  33141  * Returns:
  33142  *      BCM_E_NONE
  33143  *      BCM_E_PARAM       -- Bad {unit, port} combination
  33144  *      BCM_E_NOT_FOUND   -- The specified {unit, port, callback, user_data}
  33145  *                           combination have not been registered before
  33146  */
  33147 int
  33148 bcm_esw_port_phy_reset_unregister(int unit, bcm_port_t port,
  33149                               bcm_port_phy_reset_cb_t callback,
  33150                               void  *user_data)
  33151 {
  33152     /* Make sure port module is initialized. */
  33153     PORT_INIT(unit);
  33154 
  33155     return soc_phy_reset_unregister(unit, port, callback, user_data);
  33156 }
  33157 
  33158 /*
  33159  * Function:
  33160  *      bcm_port_jam_set
  33161  * Description:
  33162  *      Enable or disable half duplex jamming on a port
  33163  * Parameters:
  33164  *      unit - Device number
  33165  *      port - Port number
  33166  *      enable - non-zero to enable jamming
  33167  * Return Value:
  33168  *      BCM_E_XXX
  33169  */
  33170 int
  33171 bcm_esw_port_jam_set(int unit, bcm_port_t port, int enable)
  33172 {
  33173     /* Make sure port module is initialized. */
  33174     PORT_INIT(unit);
  33175 
  33176     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33177 
  33178     if (!IS_E_PORT(unit, port)) {       /* HG, CPU ports */
  33179         return enable ? BCM_E_CONFIG : BCM_E_NONE;
  33180     }
  33181 
  33182 #ifdef  BCM_XGS3_SWITCH_SUPPORT
  33183     if (SOC_IS_XGS3_SWITCH(unit)) {
  33184         uint32                  rval;
  33185         int                     oenable;
  33186 
  33187         if (!IS_GE_PORT(unit, port) && !IS_FE_PORT(unit, port)) {
  33188             return BCM_E_UNAVAIL;
  33189         } else if (!soc_reg_field_valid(unit, GE_PORT_CONFIGr, JAM_ENf) &&
  33190                    !soc_feature(unit, soc_feature_unimac)) {
  33191             return BCM_E_UNAVAIL;
  33192         }
  33193 
  33194         if (soc_feature(unit, soc_feature_unimac)) {
  33195 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_HURRICANE_SUPPORT)
  33196             if ((SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANEX(unit) ||
  33197                  SOC_IS_GREYHOUND2(unit)) && 
  33198                 (IS_XL_PORT(unit,port) || IS_CL_PORT(unit, port))) {
  33199                 return BCM_E_UNAVAIL;
  33200             }
  33201 #endif
  33202 #ifdef BCM_KATANA_SUPPORT
  33203             /* In KATANA, certain GE ports do not use UNIMAC driver */
  33204             if ((SOC_IS_KATANA(unit)) && (IS_MXQ_PORT(unit, port))) {
  33205                 return BCM_E_UNAVAIL;
  33206             }
  33207 #endif            
  33208             SOC_IF_ERROR_RETURN(READ_IPG_HD_BKP_CNTLr(unit, port, &rval));
  33209             oenable = soc_reg_field_get(unit, IPG_HD_BKP_CNTLr, rval,
  33210                                         HD_FC_ENAf);
  33211 #ifdef BCM_HAWKEYE_SUPPORT
  33212             if(SOC_IS_HAWKEYE(unit)) {
  33213                 /*
  33214                 * In HAWKEYE A0, the back-pressure is disabled
  33215                 *      when the bit HD_FC_ENA is cleared (binary 0).
  33216                 * In other revision of HAWKEYE, the back-pressure is disabled
  33217                 *      when the bit HD_FC_ENA is set (binary 1).
  33218                 */
  33219                 if(soc_feature(unit, soc_feature_hawkeye_a0_war)) {
  33220                     enable = enable ? 1 : 0;
  33221                 } else {
  33222                     enable = enable ? 0 : 1;
  33223                 }
  33224             } else
  33225 #endif /* BCM_HAWKEYE_SUPPORT */
  33226             {
  33227                 enable = enable ? 1 : 0;
  33228             }
  33229             if (oenable != enable) {
  33230                 soc_reg_field_set(unit, IPG_HD_BKP_CNTLr, &rval, HD_FC_ENAf,
  33231                                   enable);
  33232                 SOC_IF_ERROR_RETURN(WRITE_IPG_HD_BKP_CNTLr(unit, port, rval));
  33233             }
  33234         } else {
  33235             SOC_IF_ERROR_RETURN(READ_GE_PORT_CONFIGr(unit, port, &rval));
  33236             oenable = soc_reg_field_get(unit, GE_PORT_CONFIGr, rval, JAM_ENf);
  33237             enable = enable ? 1 : 0;
  33238             if (oenable != enable) {
  33239                 soc_reg_field_set(unit, GE_PORT_CONFIGr, &rval, JAM_ENf, enable);
  33240                 SOC_IF_ERROR_RETURN(WRITE_GE_PORT_CONFIGr(unit, port, rval));
  33241             }
  33242         }
  33243         return BCM_E_NONE;
  33244     }
  33245 #endif
  33246 
  33247     /* XE ports */
  33248     return enable ? BCM_E_CONFIG : BCM_E_NONE;
  33249 }
  33250 
  33251 /*
  33252  * Function:
  33253  *      bcm_port_jam_get
  33254  * Description:
  33255  *      Return half duplex jamming state
  33256  * Parameters:
  33257  *      unit - Device number
  33258  *      port - Port number
  33259  *      enable - (OUT) non-zero if jamming enabled
  33260  * Return Value:
  33261  *      BCM_E_XXX
  33262  */
  33263 int
  33264 bcm_esw_port_jam_get(int unit, bcm_port_t port, int *enable)
  33265 {
  33266     /* Make sure port module is initialized. */
  33267     PORT_INIT(unit);
  33268 
  33269     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33270 
  33271     if (!IS_E_PORT(unit, port)) {       /* HG, CPU ports */
  33272         *enable = 0;
  33273         return BCM_E_NONE;
  33274     }
  33275 
  33276 #ifdef  BCM_XGS3_SWITCH_SUPPORT
  33277     if (SOC_IS_XGS3_SWITCH(unit)) {
  33278         uint32                  rval;
  33279 
  33280         if (!IS_GE_PORT(unit, port) && !IS_FE_PORT(unit, port)) {
  33281             return BCM_E_UNAVAIL;
  33282         } else if (!soc_reg_field_valid(unit, GE_PORT_CONFIGr, JAM_ENf) &&
  33283                    !soc_feature(unit, soc_feature_unimac)) {
  33284             return BCM_E_UNAVAIL;
  33285         }
  33286 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_HURRICANE_SUPPORT)
  33287         else if ((SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANEX(unit) ||
  33288                  SOC_IS_GREYHOUND2(unit)) && 
  33289                 (IS_XL_PORT(unit,port) || IS_CL_PORT(unit, port))) {
  33290             return BCM_E_UNAVAIL;
  33291         }
  33292 #endif
  33293 
  33294         if (soc_feature(unit, soc_feature_unimac)) {
  33295 #ifdef BCM_KATANA_SUPPORT
  33296         /* In KATANA, certain GE ports do not use UNIMAC driver */
  33297             if ((SOC_IS_KATANA(unit)) && (IS_MXQ_PORT(unit, port))) {
  33298                 return BCM_E_UNAVAIL;
  33299             }
  33300 #endif
  33301             SOC_IF_ERROR_RETURN(READ_IPG_HD_BKP_CNTLr(unit, port, &rval));
  33302             *enable = soc_reg_field_get(unit, IPG_HD_BKP_CNTLr, rval, HD_FC_ENAf);
  33303         } else {
  33304             SOC_IF_ERROR_RETURN(READ_GE_PORT_CONFIGr(unit, port, &rval));
  33305             *enable = soc_reg_field_get(unit, GE_PORT_CONFIGr, rval, JAM_ENf);
  33306         }
  33307         return BCM_E_NONE;
  33308     }
  33309 #endif
  33310 
  33311     *enable = 0;
  33312     return BCM_E_NONE;
  33313 }
  33314 
  33315 /*
  33316  * Function:
  33317  *      bcm_port_cable_diag
  33318  * Description:
  33319  *      Run Cable Diagnostics on port
  33320  * Parameters:
  33321  *      unit - Device number
  33322  *      port - Port number
  33323  *      status - (OUT) cable diag status structure
  33324  * Return Value:
  33325  *      BCM_E_XXX
  33326  * Notes:
  33327  *      Cable diagnostics are only supported by some phy types
  33328  *      (currently 5248 10/100 phy and 546x 10/100/1000 phys)
  33329  */
  33330 int
  33331 bcm_esw_port_cable_diag(int unit, bcm_port_t port,
  33332                     bcm_port_cable_diag_t *status)
  33333 {
  33334     int rv = BCM_E_NONE;
  33335 
  33336     /* Make sure port module is initialized. */
  33337     PORT_INIT(unit);
  33338 
  33339     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33340 
  33341 #ifdef BCM_RCPU_SUPPORT
  33342     if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) {
  33343         return BCM_E_PORT;
  33344     }
  33345 #endif /* BCM_RCPU_SUPPORT */
  33346 
  33347 #ifdef PORTMOD_SUPPORT
  33348     if (SOC_USE_PORTCTRL(unit)) {
  33349         return bcmi_esw_portctrl_cable_diag(unit, port, status);
  33350     } else
  33351 #endif /* PORTMOD_SUPPORT */
  33352     {
  33353         PORT_LOCK(unit);
  33354         rv = soc_phyctrl_cable_diag(unit, port, status);
  33355         PORT_UNLOCK(unit);
  33356     }
  33357 
  33358     return rv;
  33359 }
  33360 
  33361 /*
  33362  * Function:
  33363  *      bcm_esw_port_fault_get
  33364  * Description:
  33365  *      Get link fault type
  33366  * Parameters:
  33367  *      unit - Device number
  33368  *      port - Port number
  33369  *      flags - (OUT) flags to indicate fault type
  33370  * Return Value:
  33371  *      BCM_E_XXX
  33372  */
  33373 
  33374 int
  33375 bcm_esw_port_fault_get(int unit, bcm_port_t port, uint32 *flags)
  33376 {
  33377     int rv, local_fault, remote_fault;
  33378     int faults;
  33379     soc_persist_t *sop = SOC_PERSIST(unit);
  33380 
  33381     /* Make sure port module is initialized. */
  33382     PORT_INIT(unit);
  33383 
  33384     if(bcm_common_oamp_port_enable_get(unit, port)) {
  33385         LOG_ERROR(BSL_LS_BCM_PORT,
  33386                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  33387                    port));
  33388         return BCM_E_PARAM;
  33389     }
  33390 
  33391     if (SOC_PBMP_MEMBER(sop->lc_pbm_eth_buffer_mode, port)) {
  33392         faults = FALSE;
  33393         SOC_IF_ERROR_RETURN(soc_phyctrl_linkfault_get(unit, port, &faults));
  33394     }
  33395 
  33396     /* Call Port Control module */
  33397     if (SOC_USE_PORTCTRL(unit)) {
  33398         rv = bcmi_esw_portctrl_fault_get(unit, port, flags);
  33399         if (SOC_PBMP_MEMBER(sop->lc_pbm_eth_buffer_mode, port)) {
  33400             if (faults) {
  33401                 *flags |= faults;
  33402             }
  33403         }
  33404         return (rv);
  33405     }
  33406 
  33407     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33408 
  33409     rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  33410                          SOC_MAC_CONTROL_FAULT_LOCAL_STATUS, &local_fault);
  33411     if (rv == SOC_E_UNAVAIL) {
  33412         return BCM_E_PORT;
  33413     }
  33414     SOC_IF_ERROR_RETURN
  33415         (MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  33416                          SOC_MAC_CONTROL_FAULT_REMOTE_STATUS, &remote_fault));
  33417 
  33418     *flags = 0;
  33419     if (remote_fault) {
  33420         *flags |= BCM_PORT_FAULT_REMOTE;
  33421     }
  33422     if (local_fault) {
  33423         *flags |= BCM_PORT_FAULT_LOCAL;
  33424     }
  33425 
  33426     if (SOC_PBMP_MEMBER(sop->lc_pbm_eth_buffer_mode, port)) {
  33427         *flags |= faults;
  33428     }
  33429 
  33430     return BCM_E_NONE;
  33431 }
  33432 
  33433 /*
  33434  * Function:
  33435  *      bcm_port_trunk_index_set
  33436  * Description:
  33437  *      Set port index of a trunk for ingress port that is used to select
  33438  *      the egress port in the trunk.
  33439  * Parameters:
  33440  *      unit       - StrataSwitch PCI device unit number (driver internal).
  33441  *      port       - Ingress port.
  33442  *      port_index - Port index of a trunk.
  33443  * Returns:
  33444  *      BCM_E_xxxx
  33445  * Note:
  33446  *      The psc (aka rtag) vlaue needs to be 7 (set in bcm_trunk_set()) for
  33447  *      a trunk in order to utilize this programmable hashing mechanism.
  33448  */
  33449 
  33450 int
  33451 bcm_esw_port_trunk_index_set(int unit, bcm_port_t port, int port_index)
  33452 {
  33453 #if defined(BCM_FIREBOLT_SUPPORT)
  33454     uint32 val, mask = 0x7;
  33455 
  33456     /* Make sure port module is initialized. */
  33457     PORT_INIT(unit);
  33458 
  33459     if (soc_feature(unit, soc_feature_port_trunk_index)) {
  33460         if (IS_ST_PORT(unit, port)) {
  33461             if (!SOC_REG_IS_VALID(unit, IUSER_TRUNK_HASH_SELECTr)) {
  33462                 return BCM_E_UNAVAIL;
  33463             }
  33464 
  33465             val = 0;
  33466             if (!SOC_IS_RAVEN(unit)) {
  33467                 mask = 0x3;
  33468             }
  33469             soc_reg_field_set(unit, IUSER_TRUNK_HASH_SELECTr, &val,
  33470                               TRUNK_CFG_VALf, port_index & mask);
  33471             SOC_IF_ERROR_RETURN
  33472                 (WRITE_IUSER_TRUNK_HASH_SELECTr(unit, port, val));
  33473         } else if (IS_E_PORT(unit, port)) {
  33474             if (!SOC_REG_IS_VALID(unit, USER_TRUNK_HASH_SELECTr)) {
  33475                 return BCM_E_UNAVAIL;
  33476             }
  33477 
  33478             val = 0;
  33479             soc_reg_field_set(unit, USER_TRUNK_HASH_SELECTr, &val,
  33480                               TRUNK_CFG_VALf, port_index & mask);
  33481             SOC_IF_ERROR_RETURN
  33482                 (WRITE_USER_TRUNK_HASH_SELECTr(unit, port, val));
  33483         }
  33484 
  33485         return BCM_E_NONE;
  33486     }
  33487 #endif  /* BCM_FIREBOLT_SUPPORT */
  33488 
  33489     return BCM_E_UNAVAIL;
  33490 }
  33491 
  33492 /*
  33493  * Function:
  33494  *      bcm_port_trunk_index_get
  33495  * Description:
  33496  *      Get port index of a trunk for ingress port that is used to select
  33497  *      the egress port in the trunk.
  33498  * Parameters:
  33499  *      unit       - StrataSwitch PCI device unit number (driver internal).
  33500  *      port       - Ingress port.
  33501  *      port_index - (OUT) Port index of a trunk.
  33502  * Returns:
  33503  *      BCM_E_xxxx
  33504  */
  33505 
  33506 int
  33507 bcm_esw_port_trunk_index_get(int unit, bcm_port_t port, int *port_index)
  33508 {
  33509 #if defined(BCM_FIREBOLT_SUPPORT)
  33510     uint32 val;
  33511 
  33512     /* Make sure port module is initialized. */
  33513     PORT_INIT(unit);
  33514 
  33515     if (soc_feature(unit, soc_feature_port_trunk_index)) {
  33516         if (IS_ST_PORT(unit, port)) {
  33517             if (!SOC_REG_IS_VALID(unit, IUSER_TRUNK_HASH_SELECTr)) {
  33518                 return BCM_E_UNAVAIL;
  33519             }
  33520 
  33521             SOC_IF_ERROR_RETURN
  33522                (READ_IUSER_TRUNK_HASH_SELECTr(unit, port, &val));
  33523             *port_index = soc_reg_field_get(unit, IUSER_TRUNK_HASH_SELECTr,
  33524                                             val, TRUNK_CFG_VALf);
  33525         } else if (IS_E_PORT(unit, port)) {
  33526             if (!SOC_REG_IS_VALID(unit, USER_TRUNK_HASH_SELECTr)) {
  33527                 return BCM_E_UNAVAIL;
  33528             }
  33529 
  33530             SOC_IF_ERROR_RETURN
  33531                (READ_USER_TRUNK_HASH_SELECTr(unit, port, &val));
  33532             *port_index = soc_reg_field_get(unit, USER_TRUNK_HASH_SELECTr,
  33533                                             val, TRUNK_CFG_VALf);
  33534         }
  33535 
  33536         return BCM_E_NONE;
  33537     }
  33538 #endif  /* BCM_FIREBOLT_SUPPORT */
  33539 
  33540     return BCM_E_UNAVAIL;
  33541 }
  33542 
  33543 #ifdef BCM_XGS3_SWITCH_SUPPORT
  33544 
  33545 static soc_field_t _bcm_xgs3_priority_fields[] = {
  33546     PRIORITY0_CNGf,
  33547     PRIORITY1_CNGf,
  33548     PRIORITY2_CNGf,
  33549     PRIORITY3_CNGf,
  33550     PRIORITY4_CNGf,
  33551     PRIORITY5_CNGf,
  33552     PRIORITY6_CNGf,
  33553     PRIORITY7_CNGf,
  33554 };
  33555 
  33556 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  33557 
  33558 #ifdef BCM_TRIUMPH2_SUPPORT
  33559 STATIC 
  33560 int _bcm_esw_vp_ing_pri_cng_set(int unit, bcm_gport_t port, int untagged, 
  33561                                 int pkt_pri, int cfi, 
  33562                                 int internal_pri, bcm_color_t color)
  33563 {
  33564     if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit)) {
  33565         return _bcm_tr2_vp_ing_pri_cng_set(unit, port, untagged,
  33566                                            pkt_pri, cfi,
  33567                                            internal_pri, color);       
  33568     }                                                                          
  33569     return BCM_E_PORT;
  33570 }
  33571 
  33572 STATIC 
  33573 int _bcm_esw_vp_ing_pri_cng_get(int unit, bcm_gport_t port, int untagged,
  33574                                 int pkt_pri, int cfi, 
  33575                                 int *internal_pri, bcm_color_t *color)
  33576 {
  33577     if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit)) {
  33578         return _bcm_tr2_vp_ing_pri_cng_get(unit, port, untagged,
  33579                                            pkt_pri, cfi,
  33580                                            internal_pri, color);       
  33581     }                                                                          
  33582     return BCM_E_PORT;
  33583 }
  33584 #endif
  33585 /*
  33586  * Function:
  33587  *      bcm_port_priority_color_set
  33588  * Purpose:
  33589  *      Specify the color selection for the given priority.
  33590  * Parameters:
  33591  *      unit -  StrataSwitch PCI device unit number (driver internal).
  33592  *      port -  Port to configure
  33593  *      prio -  priority (aka 802.1p CoS)
  33594  *      color - color assigned to packets with indicated priority.
  33595  * Returns:
  33596  *      BCM_E_NONE - Success.
  33597  *      BCM_E_XXX
  33598  * Notes:
  33599  *      Available on XGS3 only.
  33600  */
  33601 int
  33602 bcm_esw_port_priority_color_set(int unit, bcm_port_t port,
  33603                                 int prio, bcm_color_t color)
  33604 {
  33605     /* Make sure port module is initialized. */
  33606     PORT_INIT(unit);
  33607 
  33608 #ifdef BCM_XGS3_SWITCH_SUPPORT
  33609     if (soc_feature(unit, soc_feature_color)) {
  33610 
  33611         VLAN_CHK_PRIO(unit, prio);
  33612 
  33613 #if defined(BCM_TRIUMPH2_SUPPORT)
  33614         if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  33615             if (BCM_GPORT_IS_SET(port) && 
  33616                 !BCM_GPORT_IS_MODPORT(port) &&           
  33617                 !BCM_GPORT_IS_LOCAL(port) && 
  33618                 !BCM_GPORT_IS_SUBPORT_PORT(port)) {  
  33619                 return _bcm_esw_vp_ing_pri_cng_set(unit, port, FALSE, prio, 
  33620                                                    -1, -1, color);
  33621             }
  33622         }
  33623 #endif
  33624 
  33625         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33626 
  33627 #ifdef BCM_TRIUMPH2_SUPPORT
  33628         if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  33629 #ifdef BCM_TRIDENT3_SUPPORT
  33630             if (SOC_IS_TRIDENT3X(unit)) {
  33631                 return bcm_td3_port_ing_pri_cng_set(unit, port, FALSE,
  33632                                                     prio, -1, -1, color);
  33633             } else
  33634 #endif
  33635 #ifdef BCM_TRIDENT_SUPPORT
  33636             if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) ||
  33637                 SOC_IS_TRIUMPH3(unit)) {
  33638                 return bcm_td_port_ing_pri_cng_set(unit, port, FALSE,
  33639                                                    prio, -1, -1, color);
  33640             } else
  33641 #endif /* BCM_TRIDENT_SUPPORT */
  33642             {
  33643                 return _bcm_tr2_port_priority_color_set(unit, port,
  33644                                                         prio, color);
  33645             }
  33646         } else
  33647 #endif
  33648         {
  33649             uint32 val, oval;
  33650 
  33651             SOC_IF_ERROR_RETURN(READ_CNG_MAPr(unit, port, &val));
  33652             oval = val;
  33653             soc_reg_field_set(unit, CNG_MAPr, &val,
  33654                               _bcm_xgs3_priority_fields[prio],
  33655                               _BCM_COLOR_ENCODING(unit, color));
  33656             if (oval != val) {
  33657                 SOC_IF_ERROR_RETURN(WRITE_CNG_MAPr(unit, port, val));
  33658             }
  33659             return BCM_E_NONE;
  33660         }
  33661     }
  33662 #endif
  33663     return BCM_E_UNAVAIL;
  33664 }
  33665 
  33666 /*
  33667  * Function:
  33668  *      bcm_port_priority_color_get
  33669  * Purpose:
  33670  *      Get the color selection for the given priority.
  33671  * Parameters:
  33672  *      unit -  StrataSwitch PCI device unit number (driver internal).
  33673  *      port -  Port to configure
  33674  *      prio -  priority (aka 802.1p CoS)
  33675  *      color - (OUT) color assigned to packets with indicated priority.
  33676  * Returns:
  33677  *      BCM_E_NONE - Success.
  33678  *      BCM_E_XXX
  33679  * Notes:
  33680  *      Available on XGS3 only.
  33681  */
  33682 int
  33683 bcm_esw_port_priority_color_get(int unit, bcm_port_t port,
  33684                                 int prio, bcm_color_t *color)
  33685 {
  33686     /* Make sure port module is initialized. */
  33687     PORT_INIT(unit);
  33688 
  33689 #ifdef BCM_XGS3_SWITCH_SUPPORT
  33690     if (soc_feature(unit, soc_feature_color)) {
  33691         uint32 val, hw_color;
  33692         cng_map_entry_t cng_map_entry;
  33693         int ptr;
  33694 
  33695         /* Input parameters check. */
  33696         if ((NULL == color)) {
  33697             return (BCM_E_PARAM);
  33698         }
  33699 
  33700         VLAN_CHK_PRIO(unit, prio);
  33701 
  33702 #if defined(BCM_TRIUMPH2_SUPPORT)
  33703         if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  33704             if (BCM_GPORT_IS_SET(port) && 
  33705                 !BCM_GPORT_IS_MODPORT(port) &&           
  33706                 !BCM_GPORT_IS_LOCAL(port) && 
  33707                 !BCM_GPORT_IS_SUBPORT_PORT(port)) {  
  33708                 return _bcm_esw_vp_ing_pri_cng_get(unit, port, FALSE, prio, 
  33709                                                    0, NULL, color);
  33710             }
  33711         }
  33712 #endif
  33713         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33714         ptr = port;
  33715 
  33716 #ifdef BCM_TRIUMPH2_SUPPORT
  33717         if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  33718 #ifdef BCM_TRIDENT3_SUPPORT
  33719             if (SOC_IS_TRIDENT3X(unit)) {
  33720                 return bcm_td3_port_ing_pri_cng_get(unit, port, FALSE,
  33721                                                     prio, 0, NULL, color);
  33722             } else
  33723 #endif /* BCM_TRIDENT3_SUPPORT */
  33724 #ifdef BCM_TRIDENT_SUPPORT
  33725             if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) ||
  33726                 SOC_IS_TRIUMPH3(unit)) {
  33727                 return bcm_td_port_ing_pri_cng_get(unit, port, FALSE,
  33728                                                    prio, 0, NULL, color);
  33729             } else
  33730 #endif /* BCM_TRIDENT_SUPPORT */
  33731             {
  33732                 /* Get the pointer from the ING_PRI_CNG_MAP table */
  33733                 port_tab_entry_t pent;
  33734                 BCM_IF_ERROR_RETURN
  33735                     (soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY,
  33736                                   SOC_PORT_MOD_OFFSET(unit, port), &pent));
  33737                 ptr = soc_PORT_TABm_field32_get(unit, &pent,
  33738                                                 TRUST_DOT1P_PTRf);
  33739             }
  33740         }
  33741 #endif
  33742         if (SOC_MEM_IS_VALID(unit, CNG_MAPm)) {
  33743             SOC_IF_ERROR_RETURN(READ_CNG_MAPm(unit, MEM_BLOCK_ANY,
  33744                                               ptr, &cng_map_entry));
  33745             hw_color = soc_CNG_MAPm_field32_get(unit, &cng_map_entry,
  33746                                                _bcm_xgs3_priority_fields[prio]);
  33747         } else {
  33748             SOC_IF_ERROR_RETURN(READ_CNG_MAPr(unit, ptr, &val));
  33749             hw_color = soc_reg_field_get(unit, CNG_MAPr, val,
  33750                                          _bcm_xgs3_priority_fields[prio]);
  33751         }
  33752         *color = _BCM_COLOR_DECODING(unit, hw_color);
  33753         return BCM_E_NONE;
  33754     }
  33755 #endif
  33756     return BCM_E_UNAVAIL;
  33757 }
  33758 
  33759 /*
  33760  * Function:
  33761  *      bcm_port_cfi_color_set
  33762  * Purpose:
  33763  *      Specify the color selection for the given CFI.
  33764  * Parameters:
  33765  *      unit -  StrataSwitch PCI device unit number (driver internal).
  33766  *      port -  Port to configure
  33767  *      cfi -   Canonical format indicator (TRUE/FALSE)
  33768  *      color - color assigned to packets with indicated CFI.
  33769  * Returns:
  33770  *      BCM_E_NONE - Success.
  33771  *      BCM_E_XXX
  33772  * Notes:
  33773  *      Available on XGS3 only.
  33774  */
  33775 int
  33776 bcm_esw_port_cfi_color_set(int unit, bcm_port_t port,
  33777                            int cfi, bcm_color_t color)
  33778 {
  33779     /* Make sure port module is initialized. */
  33780     PORT_INIT(unit);
  33781 
  33782 #ifdef BCM_XGS3_SWITCH_SUPPORT
  33783     if (soc_feature(unit, soc_feature_color)) {
  33784         if (cfi < 0 || cfi > 1) {
  33785             return BCM_E_PARAM;
  33786         }
  33787 
  33788 #if defined(BCM_TRIUMPH2_SUPPORT)
  33789         if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  33790             if (BCM_GPORT_IS_SET(port) && 
  33791                 !BCM_GPORT_IS_MODPORT(port) &&           
  33792                 !BCM_GPORT_IS_LOCAL(port) && 
  33793                 !BCM_GPORT_IS_SUBPORT_PORT(port)) {  
  33794                 return _bcm_esw_vp_ing_pri_cng_set(unit, port, FALSE, -1, 
  33795                                                    cfi, -1, color);
  33796             }
  33797         }
  33798 #endif
  33799 
  33800         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33801 #ifdef BCM_TRIDENT3_SUPPORT
  33802         if (SOC_IS_TRIDENT3X(unit)) {
  33803             return bcm_td3_port_ing_pri_cng_set(unit, port, FALSE,
  33804                                                 -1, cfi, -1, color);
  33805         } else
  33806 #endif
  33807 #ifdef BCM_TRIDENT_SUPPORT
  33808         if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) ||
  33809             SOC_IS_TRIUMPH3(unit)) {
  33810             return bcm_td_port_ing_pri_cng_set(unit, port, FALSE,
  33811                                                -1, cfi, -1, color);
  33812         } else
  33813 #endif /* BCM_TRIDENT_SUPPORT */
  33814 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \
  33815         || defined (BCM_TRX_SUPPORT)
  33816         if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || SOC_IS_TRX(unit) ||
  33817             SOC_IS_HAWKEYE(unit)) {
  33818             int                     index, pkt_pri;
  33819             uint32 pri_map[SOC_MAX_MEM_FIELD_WORDS];
  33820 
  33821             sal_memset(pri_map, 0, sizeof(pri_map));
  33822 
  33823 #if defined(BCM_TRIUMPH2_SUPPORT)
  33824             if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  33825                 pkt_pri = -1;
  33826                 return _bcm_tr2_port_vlan_priority_map_set(unit, port, pkt_pri,
  33827                         cfi,
  33828                         pkt_pri, color);
  33829             } else
  33830 #endif /* BCM_TRIUMPH2_SUPPORT */
  33831             {
  33832                 for (pkt_pri = 0; pkt_pri <= 7; pkt_pri++) {
  33833                     /* ING_PRI_CNG_MAP table is indexed with
  33834                      * port[0:4] incoming priority[2:0] incoming CFI[0]
  33835                      */
  33836                     index = (port << 4) | (pkt_pri << 1) | cfi;
  33837                     if (SOC_IS_TRIDENT3X(unit)) {
  33838                         soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &pri_map, PRIf,
  33839                                             pkt_pri);
  33840                         soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &pri_map, CNGf,
  33841                                             _BCM_COLOR_ENCODING(unit, color));
  33842                         SOC_IF_ERROR_RETURN(WRITE_PHB_MAPPING_TBL_1m(unit,
  33843                                                 MEM_BLOCK_ALL, index, &pri_map));
  33844                     } else {
  33845                     soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map, PRIf,
  33846                                         pkt_pri);
  33847                     soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map, CNGf,
  33848                                         _BCM_COLOR_ENCODING(unit, color));
  33849                     SOC_IF_ERROR_RETURN(WRITE_ING_PRI_CNG_MAPm(unit,
  33850                                             MEM_BLOCK_ALL, index, &pri_map));
  33851                 }
  33852             }
  33853             }
  33854         } else
  33855 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
  33856         {
  33857             uint32 val, oval;
  33858             SOC_IF_ERROR_RETURN(READ_CNG_MAPr(unit, port, &val));
  33859             oval = val;
  33860             soc_reg_field_set(unit, CNG_MAPr, &val,
  33861                               cfi ? CFI1_CNGf : CFI0_CNGf,
  33862                              _BCM_COLOR_ENCODING(unit, color));
  33863             if (oval != val) {
  33864                 SOC_IF_ERROR_RETURN(WRITE_CNG_MAPr(unit, port, val));
  33865             }
  33866         }
  33867         return BCM_E_NONE;
  33868     }
  33869 #endif
  33870     return BCM_E_UNAVAIL;
  33871 }
  33872 
  33873 /*
  33874  * Function:
  33875  *      bcm_port_cfi_color_get
  33876  * Purpose:
  33877  *      Get the color selection for the given CFI.
  33878  * Parameters:
  33879  *      unit -  StrataSwitch PCI device unit number (driver internal).
  33880  *      port -  Port to configure
  33881  *      cfi -   Canonical format indicator (TRUE/FALSE)
  33882  *      color - (OUT) color assigned to packets with indicated CFI.
  33883  * Returns:
  33884  *      BCM_E_NONE - Success.
  33885  *      BCM_E_XXX
  33886  * Notes:
  33887  *      Available on XGS3 only.
  33888  */
  33889 int
  33890 bcm_esw_port_cfi_color_get(int unit, bcm_port_t port,
  33891                            int cfi, bcm_color_t *color)
  33892 {
  33893     /* Make sure port module is initialized. */
  33894     PORT_INIT(unit);
  33895 
  33896 #ifdef BCM_XGS3_SWITCH_SUPPORT
  33897     if (soc_feature(unit, soc_feature_color)) {
  33898         uint32 hw_color;
  33899 
  33900         if (cfi < 0 || cfi > 1) {
  33901             return BCM_E_PARAM;
  33902         }
  33903 
  33904         /* Input parameters check. */
  33905         if ((NULL == color)) {
  33906             return (BCM_E_PARAM);
  33907         }
  33908 
  33909 #if defined(BCM_TRIUMPH2_SUPPORT)
  33910         if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  33911             if (BCM_GPORT_IS_SET(port) && 
  33912                 !BCM_GPORT_IS_MODPORT(port) &&           
  33913                 !BCM_GPORT_IS_LOCAL(port) && 
  33914                 !BCM_GPORT_IS_SUBPORT_PORT(port)) {  
  33915                 return _bcm_esw_vp_ing_pri_cng_get(unit, port, FALSE, 0, 
  33916                                                    cfi, NULL, color);
  33917             }
  33918         }
  33919 #endif
  33920 
  33921     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  33922 
  33923 #ifdef BCM_TRIDENT3_SUPPORT
  33924         if (SOC_IS_TRIDENT3X(unit)) {
  33925             return bcm_td3_port_ing_pri_cng_get(unit, port, FALSE, 0, cfi, NULL,
  33926                                                 color);
  33927         } else
  33928 #endif /* BCM_TRIDENT3_SUPPORT */
  33929 #ifdef BCM_TRIDENT_SUPPORT
  33930     if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) ||
  33931         SOC_IS_TRIUMPH3(unit)) {
  33932         return bcm_td_port_ing_pri_cng_get(unit, port, FALSE, 0, cfi, NULL,
  33933                                            color);
  33934     } else
  33935 #endif /* BCM_TRIDENT_SUPPORT */
  33936 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \
  33937         || defined(BCM_TRX_SUPPORT)
  33938     if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit)
  33939         || SOC_IS_TRX(unit) || SOC_IS_HAWKEYE(unit)) {
  33940         int index;
  33941         uint32 pri_map[SOC_MAX_MEM_FIELD_WORDS];
  33942 
  33943         sal_memset(pri_map, 0, sizeof(pri_map));
  33944 
  33945 #if defined(BCM_TRIUMPH2_SUPPORT)
  33946         if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  33947             int pkt_pri = 0;
  33948             return _bcm_tr2_port_vlan_priority_map_get(unit, port, 0,
  33949                                                        cfi, &pkt_pri, color);
  33950         } else
  33951 #endif /* BCM_TRIUMPH2_SUPPORT */
  33952         {
  33953             /* ING_PRI_CNG_MAP table is indexed with
  33954              * port[0:4] incoming priority[2:0] incoming CFI[0]
  33955              */
  33956             index = (port << 4) | cfi;
  33957             if (SOC_IS_TRIDENT3X(unit)) {
  33958                 SOC_IF_ERROR_RETURN(READ_PHB_MAPPING_TBL_1m(unit, MEM_BLOCK_ANY,
  33959                                                           index, &pri_map));
  33960                 hw_color = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m,
  33961                                                &pri_map, CNGf);
  33962             } else {
  33963             SOC_IF_ERROR_RETURN(READ_ING_PRI_CNG_MAPm(unit, MEM_BLOCK_ANY,
  33964                                                       index, &pri_map));
  33965             hw_color = soc_mem_field32_get(unit, ING_PRI_CNG_MAPm,
  33966                                            &pri_map, CNGf);
  33967         }
  33968         }
  33969     } else
  33970 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT */
  33971         {
  33972             uint32 val;
  33973 
  33974             SOC_IF_ERROR_RETURN(READ_CNG_MAPr(unit, port, &val));
  33975             hw_color = soc_reg_field_get(unit, CNG_MAPr, val,
  33976                                          cfi ? CFI1_CNGf : CFI0_CNGf);
  33977         }
  33978         *color = _BCM_COLOR_DECODING(unit, hw_color);
  33979         return BCM_E_NONE;
  33980     }
  33981 #endif
  33982     return BCM_E_UNAVAIL;
  33983 }
  33984 
  33985 /*
  33986  * Function:
  33987  *      bcm_esw_port_vlan_priority_map_set
  33988  * Description:
  33989  *      Define the mapping of incomming port, packet priority, and cfi bit to
  33990  *      switch internal priority and color.
  33991  * Parameters:
  33992  *      unit         - (IN) Device number
  33993  *      port         - (IN) Port number
  33994  *      pkt_pri      - (IN) Packet priority
  33995  *      cfi          - (IN) Packet CFI
  33996  *      internal_pri - (IN) Internal priority
  33997  *      color        - (IN) color
  33998  * Return Value:
  33999  *      BCM_E_XXX
  34000  * Note:
  34001  *      This API programs only the mapping table.
  34002  */
  34003 int
  34004 bcm_esw_port_vlan_priority_map_set(int unit, bcm_port_t port, int pkt_pri,
  34005                                    int cfi, int internal_pri, bcm_color_t color)
  34006 {
  34007 #ifdef BCM_TRIUMPH2_SUPPORT
  34008     int untagged = FALSE;
  34009 #endif /* BCM_TRIUMPH2_SUPPORT */
  34010 
  34011     /* Make sure port module is initialized. */
  34012     PORT_INIT(unit);
  34013 
  34014     if (!soc_feature(unit, soc_feature_color_prio_map) ||
  34015         soc_feature(unit, soc_feature_deprecated_api)) {
  34016         return BCM_E_UNAVAIL;
  34017     }
  34018 
  34019     if (SOC_MEM_IS_VALID(unit, ING_UNTAGGED_PHBm)) {
  34020         if (pkt_pri == -1 && cfi == -1) {
  34021 #ifdef BCM_TRIDENT_SUPPORT
  34022             untagged = TRUE;
  34023 #endif /* BCM_TRIDENT_SUPPORT */
  34024             pkt_pri = 0;
  34025             cfi = 0;
  34026         }
  34027     }
  34028 
  34029     if (pkt_pri < 0 || pkt_pri > 7 || cfi < 0 || cfi > 1 || internal_pri < 0 ) {
  34030         return BCM_E_PARAM;
  34031     }
  34032 
  34033     if (SOC_IS_TRIDENT3X(unit)) {
  34034        if (internal_pri >= (1 << soc_mem_field_length(unit, PHB_MAPPING_TBL_1m, PRIf))) {
  34035            return BCM_E_PARAM;
  34036        } 
  34037     } else {
  34038        if (internal_pri >= (1 << soc_mem_field_length(unit, ING_PRI_CNG_MAPm, PRIf))) {
  34039            return BCM_E_PARAM;
  34040        } 
  34041     }
  34042 
  34043 #if defined(BCM_TRIUMPH2_SUPPORT)                          
  34044     if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  34045         if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) &&           
  34046             !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) {  
  34047             return _bcm_esw_vp_ing_pri_cng_set(unit, port, untagged, pkt_pri, 
  34048                                                cfi, internal_pri, color);
  34049         }
  34050     }
  34051 #endif 
  34052 
  34053     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  34054 
  34055 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \
  34056         || defined(BCM_TRX_SUPPORT)
  34057 #if defined(BCM_TRIUMPH2_SUPPORT)
  34058     if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  34059 #ifdef BCM_TRIDENT3_SUPPORT
  34060         if (SOC_IS_TRIDENT3X(unit)) {
  34061             return bcm_td3_port_ing_pri_cng_set(unit, port, untagged,
  34062                                                 pkt_pri, cfi,
  34063                                                 internal_pri, color);
  34064         } else
  34065 #endif
  34066 #if defined BCM_TRIDENT_SUPPORT
  34067         if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) ||
  34068             SOC_IS_TRIUMPH3(unit)) {
  34069             return bcm_td_port_ing_pri_cng_set(unit, port, untagged,
  34070                                                pkt_pri, cfi,
  34071                                                internal_pri, color);
  34072         } else
  34073 #endif /* BCM_TRIDENT_SUPPORT */
  34074         {
  34075             return _bcm_tr2_port_vlan_priority_map_set(unit, port, pkt_pri,
  34076                                                        cfi,
  34077                                                        internal_pri, color);
  34078         }
  34079     } else
  34080 #endif
  34081     if (soc_feature(unit, soc_feature_color_prio_map)) {
  34082         int                      index;
  34083         uint32 pri_map[SOC_MAX_MEM_FIELD_WORDS];
  34084 
  34085         sal_memset(pri_map, 0, sizeof(pri_map));
  34086 
  34087         /* ING_PRI_CNG_MAP table is indexed with
  34088          * port[0:4] incoming priority[2:0] incoming CFI[0]
  34089          */
  34090         index = (port << 4) | (pkt_pri << 1) | cfi;
  34091 
  34092         if (SOC_IS_TRIDENT3X(unit)) {
  34093             soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &pri_map, PRIf,
  34094                                 internal_pri);
  34095             soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &pri_map, CNGf,
  34096                                 _BCM_COLOR_ENCODING(unit, color));
  34097             SOC_IF_ERROR_RETURN
  34098                 (WRITE_PHB_MAPPING_TBL_1m(unit, MEM_BLOCK_ALL, index, &pri_map));
  34099         } else {
  34100         soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map, PRIf,
  34101                             internal_pri);
  34102         soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map, CNGf,
  34103                             _BCM_COLOR_ENCODING(unit, color));
  34104         SOC_IF_ERROR_RETURN
  34105             (WRITE_ING_PRI_CNG_MAPm(unit, MEM_BLOCK_ALL, index, &pri_map));
  34106         }
  34107 
  34108         return BCM_E_NONE;
  34109    }
  34110 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
  34111     return BCM_E_UNAVAIL;
  34112 }
  34113 
  34114 /*
  34115  * Function:
  34116  *      bcm_esw_port_vlan_priority_map_get
  34117  * Description:
  34118  *      Get the mapping of incomming port, packet priority, and cfi bit to
  34119  *      switch internal priority and color.
  34120  * Parameters:
  34121  *      unit         - (IN) Device number
  34122  *      port         - (IN) Port number
  34123  *      pkt_pri      - (IN) Packet priority
  34124  *      cfi          - (IN) Packet CFI
  34125  *      internal_pri - (OUT) Internal priority
  34126  *      color        - (OUT) color
  34127  * Return Value:
  34128  *      BCM_E_XXX
  34129  * Note:
  34130  *      This API programs only the mapping table.
  34131  */
  34132 int
  34133 bcm_esw_port_vlan_priority_map_get(int unit, bcm_port_t port, int pkt_pri,
  34134                                    int cfi, int *internal_pri,
  34135                                    bcm_color_t *color)
  34136 {
  34137 #if defined BCM_TRIUMPH2_SUPPORT
  34138     int untagged = FALSE;
  34139 #endif /* BCM_TRIUMPH2_SUPPORT */
  34140 
  34141     /* Make sure port module is initialized. */
  34142     PORT_INIT(unit);
  34143 
  34144     if (!soc_feature(unit, soc_feature_color_prio_map) ||
  34145         soc_feature(unit, soc_feature_deprecated_api)) {
  34146         return BCM_E_UNAVAIL;
  34147     }
  34148 
  34149     /* Input parameters check. */
  34150     if ((NULL == internal_pri) || (NULL == color)) {
  34151         return (BCM_E_PARAM);
  34152     }
  34153 
  34154     if (SOC_MEM_IS_VALID(unit, ING_UNTAGGED_PHBm)) {
  34155         if (pkt_pri == -1 && cfi == -1) {
  34156 #if defined BCM_TRIDENT_SUPPORT
  34157             untagged = TRUE;
  34158 #endif /* BCM_TRIDENT_SUPPORT */
  34159             pkt_pri = 0;
  34160             cfi = 0;
  34161         }
  34162     }
  34163 
  34164     if (pkt_pri < 0 || pkt_pri > 7 || cfi < 0 || cfi > 1) {
  34165         return BCM_E_PARAM;
  34166     }
  34167 
  34168 #if defined(BCM_TRIUMPH2_SUPPORT)                          
  34169     if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  34170         if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) &&           
  34171             !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) {  
  34172             return _bcm_esw_vp_ing_pri_cng_get(unit, port, untagged, pkt_pri, 
  34173                                                cfi, internal_pri, color);
  34174         }
  34175     }
  34176 #endif 
  34177 
  34178     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  34179 
  34180 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \
  34181         || defined(BCM_TRX_SUPPORT)
  34182 #if defined(BCM_TRIUMPH2_SUPPORT)
  34183     if (soc_feature(unit, soc_feature_color_prio_map_profile)) {
  34184 #ifdef BCM_TRIDENT3_SUPPORT
  34185         if (SOC_IS_TRIDENT3X(unit)) {
  34186             return bcm_td3_port_ing_pri_cng_get(unit, port, untagged,
  34187                                                 pkt_pri, cfi,
  34188                                                 internal_pri, color);
  34189         } else
  34190 #endif /* BCM_TRIDENT3_SUPPORT */
  34191 #if defined BCM_TRIDENT_SUPPORT
  34192         if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) ||
  34193             SOC_IS_TRIUMPH3(unit)) {
  34194             return bcm_td_port_ing_pri_cng_get(unit, port, untagged,
  34195                                                pkt_pri, cfi,
  34196                                                internal_pri, color);
  34197         } else
  34198 #endif /* BCM_TRIDENT_SUPPORT */
  34199         {
  34200             return _bcm_tr2_port_vlan_priority_map_get(unit, port, pkt_pri,
  34201                                                        cfi, internal_pri,
  34202                                                        color);
  34203         }
  34204     } else
  34205 #endif
  34206     if (soc_feature(unit, soc_feature_color_prio_map)) {
  34207         int index, hw_color;
  34208         uint32 pri_map[SOC_MAX_MEM_FIELD_WORDS];
  34209 
  34210         sal_memset(pri_map, 0, sizeof(pri_map));
  34211 
  34212         /* ING_PRI_CNG_MAP table is indexed with
  34213          * port[4:0] incoming priority[2:0] incoming CFI[0]
  34214          */
  34215         index = (port << 4) | (pkt_pri << 1) | cfi;
  34216 
  34217         LOG_INFO(BSL_LS_BCM_PORT,
  34218                  (BSL_META_U(unit,
  34219                              "bcm_esw_port_vlan_priority_map_get: u=%d p=%d index=%d\n"),
  34220                   unit, port, index));
  34221 
  34222         if (SOC_IS_TRIDENT3X(unit)) {
  34223             SOC_IF_ERROR_RETURN
  34224                 (READ_PHB_MAPPING_TBL_1m(unit, MEM_BLOCK_ANY, index, &pri_map));
  34225             *internal_pri = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, &pri_map, INT_PRIf);
  34226             hw_color = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, &pri_map, CNGf);
  34227         } else {
  34228         SOC_IF_ERROR_RETURN
  34229             (READ_ING_PRI_CNG_MAPm(unit, MEM_BLOCK_ANY, index, &pri_map));
  34230             *internal_pri = soc_mem_field32_get(unit, ING_PRI_CNG_MAPm, &pri_map, PRIf);
  34231         hw_color = soc_mem_field32_get(unit, ING_PRI_CNG_MAPm, &pri_map, CNGf);
  34232         }
  34233 
  34234         *color = _BCM_COLOR_DECODING(unit, hw_color);
  34235         return BCM_E_NONE;
  34236    }
  34237 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
  34238     return BCM_E_UNAVAIL;
  34239 
  34240 }
  34241 
  34242 /*
  34243  * Function:
  34244  *      bcm_esw_port_vlan_priority_unmap_set
  34245  * Description:
  34246  *      Define the mapping of outgoing port, internal priority, and color to
  34247  *  outgoing packet priority and cfi bit.
  34248  * Parameters:
  34249  *      unit         - (IN) Device number
  34250  *      port         - (IN) Port number
  34251  *      internal_pri - (IN) Internal priority
  34252  *      color        - (IN) Color
  34253  *      pkt_pri      - (IN) Packet priority
  34254  *      cfi          - (IN) Packet CFI
  34255  * Return Value:
  34256  *      BCM_E_XXX
  34257  * Note:
  34258  *      This API programs only the mapping table.
  34259  */
  34260 int
  34261 bcm_esw_port_vlan_priority_unmap_set(int unit, bcm_port_t port,
  34262                                      int internal_pri, bcm_color_t color,
  34263                                      int pkt_pri, int cfi)
  34264 {
  34265     /* Make sure port module is initialized. */
  34266     PORT_INIT(unit); 
  34267 
  34268 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  34269     if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) {
  34270         return BCM_E_UNAVAIL;
  34271     }
  34272 #endif
  34273 
  34274     if (SOC_IS_TRIDENT3X(unit)) {
  34275         return BCM_E_UNAVAIL;
  34276     }
  34277 
  34278     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  34279 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \
  34280         || defined(BCM_TRX_SUPPORT)
  34281     if (soc_feature(unit, soc_feature_color_prio_map)) {
  34282         int index, int_pri_shift;
  34283         uint32     pri_unmap[SOC_MAX_MEM_FIELD_WORDS];
  34284         soc_mem_t  mem = EGR_PRI_CNG_MAPm;
  34285 
  34286         int_pri_shift = SOC_IS_TRX(unit) ? 4 : 3;
  34287         if ((internal_pri < 0 || internal_pri >= (1 << int_pri_shift)) ||
  34288             ((color != bcmColorGreen) && (color != bcmColorYellow) &&
  34289              (color != bcmColorRed))) {
  34290             return BCM_E_PARAM;
  34291         }
  34292         if (pkt_pri < 0 || pkt_pri > 7 || cfi < 0 || cfi > 1) {
  34293             return BCM_E_PARAM;
  34294         }
  34295 
  34296         /* EGR_PRI_CNG_MAP table is indexed with
  34297          * port[4:0] priority[2:0] CNG [1:0]
  34298          * port[5:0] priority[3:0] CNG [1:0] (TRX)
  34299          */
  34300         index = (port << (int_pri_shift + 2)) | (internal_pri << 2) |
  34301             _BCM_COLOR_ENCODING(unit, color);
  34302 
  34303         sal_memset(pri_unmap, 0, sizeof(pri_unmap));
  34304         soc_mem_field32_set(unit, mem, &pri_unmap, PRIf, pkt_pri);
  34305         soc_mem_field32_set(unit, mem, &pri_unmap, CFIf, cfi);
  34306         SOC_IF_ERROR_RETURN
  34307             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, &pri_unmap));
  34308 
  34309         if ((SOC_IS_TD_TT(unit) && !SOC_IS_TOMAHAWK3(unit)) ||
  34310             SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)) {
  34311             egr_map_mh_entry_t  egr_map;
  34312 
  34313             sal_memset(&egr_map, 0, sizeof(egr_map));
  34314             index = (port << int_pri_shift) | (internal_pri) ;
  34315             soc_mem_field32_set(unit, EGR_MAP_MHm, &egr_map, HG_TCf, internal_pri);
  34316             SOC_IF_ERROR_RETURN(WRITE_EGR_MAP_MHm(unit, MEM_BLOCK_ALL, index, &egr_map));
  34317         }
  34318 
  34319         return BCM_E_NONE;
  34320     }
  34321 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
  34322     return BCM_E_UNAVAIL;
  34323 }
  34324 
  34325 /*
  34326  * Function:
  34327  *      bcm_esw_port_vlan_priority_unmap_get
  34328  * Description:
  34329  *      Get the mapping of outgoing port, internal priority, and color to
  34330  *  outgoing packet priority and cfi bit.
  34331  * Parameters:
  34332  *      unit         - (IN) Device number
  34333  *      port         - (IN) Port number
  34334  *      internal_pri - (IN) Internal priority
  34335  *      color        - (IN) Color
  34336  *      pkt_pri      - (OUT) Packet priority
  34337  *      cfi          - (OUT) Packet CFI
  34338  * Return Value:
  34339  *      BCM_E_XXX
  34340  * Note:
  34341  *      This API programs only the mapping table.
  34342  */
  34343 int
  34344 bcm_esw_port_vlan_priority_unmap_get(int unit, bcm_port_t port,
  34345                                      int internal_pri, bcm_color_t color,
  34346                                      int *pkt_pri, int *cfi)
  34347 {
  34348     /* Make sure port module is initialized. */
  34349     PORT_INIT(unit); 
  34350 
  34351 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  34352     if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) {
  34353         return BCM_E_UNAVAIL;
  34354     }
  34355 #endif
  34356 
  34357     if (SOC_IS_TRIDENT3X(unit)) {
  34358         return BCM_E_UNAVAIL;
  34359     }
  34360 
  34361     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  34362 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \
  34363         || defined(BCM_TRX_SUPPORT)
  34364     if (soc_feature(unit, soc_feature_color_prio_map)) {
  34365         int index, int_pri_shift;
  34366         uint32     pri_unmap[SOC_MAX_MEM_FIELD_WORDS];
  34367         soc_mem_t  mem = EGR_PRI_CNG_MAPm;
  34368 
  34369         int_pri_shift = SOC_IS_TRX(unit) ? 4 : 3;
  34370         if ((internal_pri < 0 || internal_pri >= (1 << int_pri_shift)) ||
  34371             ((color != bcmColorGreen) && (color != bcmColorYellow) &&
  34372              (color != bcmColorRed))) {
  34373             return BCM_E_PARAM;
  34374         }
  34375 
  34376         /* EGR_PRI_CNG_MAP table is indexed with
  34377          * port[4:0] priority[2:0] CNG [1:0]
  34378          * port[5:0] priority[3:0] CNG [1:0] (TRX)
  34379          */
  34380         index = (port << (int_pri_shift + 2)) | (internal_pri << 2) |
  34381             _BCM_COLOR_ENCODING(unit, color);
  34382 
  34383         SOC_IF_ERROR_RETURN
  34384             (soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, pri_unmap));
  34385         *pkt_pri = soc_mem_field32_get(unit, mem, pri_unmap, PRIf);
  34386         *cfi = soc_mem_field32_get(unit, mem, pri_unmap, CFIf);
  34387         return BCM_E_NONE;
  34388     }
  34389 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
  34390     return BCM_E_UNAVAIL;
  34391 }
  34392 
  34393 /*
  34394  * Function:
  34395  *      bcm_esw_port_l3_modify_set
  34396  * Description:
  34397  *      Enable/Disable ingress port based L3 unicast packet operations.
  34398  * Parameters:
  34399  *      unit - Device number
  34400  *      port - Port number
  34401  *      flags - bitmap of the packet operations to be enabled or disabled.
  34402  * Return Value:
  34403  *      BCM_E_XXX
  34404  * Notes:
  34405  *      Available on XGS3 only.
  34406  */
  34407 int
  34408 bcm_esw_port_l3_modify_set(int unit, bcm_port_t port, uint32 flags)
  34409 {
  34410 #if defined(BCM_XGS3_SWITCH_SUPPORT) && defined(INCLUDE_L3)
  34411     uint64 r;
  34412     soc_reg_t reg;
  34413 
  34414     /* Make sure port module is initialized. */
  34415     PORT_INIT(unit);
  34416 
  34417     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  34418     if (SOC_IS_XGS3_SWITCH(unit)) {
  34419         reg = IS_ST_PORT(unit, port) ?
  34420             IEGR_PORT_L3UC_MODSr : EGR_PORT_L3UC_MODSr;
  34421     } else {
  34422         return BCM_E_UNAVAIL;
  34423     }
  34424 
  34425     if (!SOC_REG_IS_VALID(unit, reg)) {
  34426         return BCM_E_UNAVAIL;
  34427     }
  34428 
  34429     BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &r));
  34430 
  34431     soc_reg64_field32_set(unit, reg, &r, L3_UC_SA_DISABLEf,
  34432                           (flags & BCM_PORT_L3_MODIFY_NO_SRCMAC) ? 1 : 0);
  34433 
  34434     soc_reg64_field32_set(unit, reg, &r, L3_UC_DA_DISABLEf,
  34435                           (flags & BCM_PORT_L3_MODIFY_NO_DSTMAC) ? 1 : 0);
  34436 
  34437     soc_reg64_field32_set(unit, reg, &r, L3_UC_TTL_DISABLEf,
  34438                           (flags & BCM_PORT_L3_MODIFY_NO_TTL) ? 1 : 0);
  34439 
  34440     soc_reg64_field32_set(unit, reg, &r, L3_UC_VLAN_DISABLEf,
  34441                           (flags & BCM_PORT_L3_MODIFY_NO_VLAN) ? 1 : 0);
  34442 
  34443     return soc_reg_set(unit, reg, port, 0, r);
  34444 #endif /* BCM_XGS3_SWITCH_SUPPORT && INCLUDE_L3 */
  34445     return BCM_E_UNAVAIL;
  34446 }
  34447 
  34448 /*
  34449  * Function:
  34450  *      bcm_esw_port_l3_modify_get
  34451  * Description:
  34452  *      Get ingress port based L3 unicast packet operations status.
  34453  * Parameters:
  34454  *      unit - Device number
  34455  *      port - Port number
  34456  *      flags - (OUT) pointer to uint32 where bitmap of the current L3 packet
  34457  *              operations is returned.
  34458  * Return Value:
  34459  *      BCM_E_NONE
  34460  *      BCM_E_UNAVAIL - Functionality not available
  34461  * Notes:
  34462  *      Available on XGS3 only.
  34463  */
  34464 int
  34465 bcm_esw_port_l3_modify_get(int unit, bcm_port_t port, uint32 *flags)
  34466 {
  34467 #if defined(BCM_XGS3_SWITCH_SUPPORT) && defined(INCLUDE_L3)
  34468     uint64 r;
  34469     soc_reg_t reg;
  34470 
  34471     /* Make sure port module is initialized. */
  34472     PORT_INIT(unit);
  34473 
  34474     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  34475     if (SOC_IS_XGS3_SWITCH(unit)) {
  34476         reg = IS_ST_PORT(unit, port) ?
  34477             IEGR_PORT_L3UC_MODSr : EGR_PORT_L3UC_MODSr;
  34478     } else {
  34479         return BCM_E_UNAVAIL;
  34480     }
  34481 
  34482     if (!SOC_REG_IS_VALID(unit, reg)) {
  34483         return BCM_E_UNAVAIL;
  34484     }
  34485 
  34486     BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &r));
  34487 
  34488     *flags = 0;
  34489 
  34490     if (soc_reg64_field32_get(unit, reg, r, L3_UC_SA_DISABLEf)) {
  34491         *flags |= BCM_PORT_L3_MODIFY_NO_SRCMAC;
  34492     }
  34493 
  34494     if (soc_reg64_field32_get(unit, reg, r, L3_UC_DA_DISABLEf)) {
  34495         *flags |= BCM_PORT_L3_MODIFY_NO_DSTMAC;
  34496     }
  34497 
  34498     if (soc_reg64_field32_get(unit, reg, r, L3_UC_TTL_DISABLEf)) {
  34499         *flags |= BCM_PORT_L3_MODIFY_NO_TTL;
  34500     }
  34501 
  34502     if (soc_reg64_field32_get(unit, reg, r, L3_UC_VLAN_DISABLEf)) {
  34503         *flags |= BCM_PORT_L3_MODIFY_NO_VLAN;
  34504     }
  34505 
  34506     return BCM_E_NONE;
  34507 #endif /* BCM_XGS3_SWITCH_SUPPORT && INCLUDE_L3 */
  34508     return BCM_E_UNAVAIL;
  34509 }
  34510 
  34511 /*
  34512  * Function:
  34513  *      bcm_esw_port_ipmc_modify_set
  34514  * Description:
  34515  *      Enable/Disable ingress port based L3 multicast packet operations.
  34516  *      If the reg EGR_IPMC_CFG2r does not contain DISABLE_TTL_CHECKf field,
  34517  *         and if flag is set , then return E_PARAM.
  34518  *             if flag is not set, then donot  validate the field.
  34519  * Parameters:
  34520  *      unit - Device number
  34521  *      port - Port number
  34522  *      flags - bitmap of the packet operations to be enabled or disabled.
  34523  * Return Value:
  34524  *      BCM_E_XXX
  34525  * Notes:
  34526  *      Available on XGS3 only.
  34527  */
  34528 int
  34529 bcm_esw_port_ipmc_modify_set(int unit, bcm_port_t port, uint32 flags)
  34530 {
  34531 #if defined(INCLUDE_L3)
  34532     int          field_count;
  34533     soc_field_t  fields[]={DISABLE_SA_REPLACEf, DISABLE_TTL_DECREMENTf,
  34534                            DISABLE_TTL_CHECKf};
  34535     uint32       values[]={0, 0, 0};
  34536 
  34537     /* Make sure port module is initialized. */
  34538     PORT_INIT(unit);
  34539 
  34540     field_count = COUNTOF(fields);
  34541     if (!soc_feature(unit, soc_feature_ip_mcast)) {
  34542         return BCM_E_UNAVAIL;
  34543     }
  34544 
  34545     if (soc_feature(unit, soc_feature_no_egr_ipmc_cfg)) {
  34546         return BCM_E_UNAVAIL;
  34547     }
  34548 
  34549     if (!SOC_REG_IS_VALID(unit, EGR_IPMC_CFG2r) &&
  34550             !soc_feature(unit, soc_feature_egr_ipmc_cfg2_is_memory)) {
  34551         return BCM_E_UNAVAIL;
  34552     }
  34553     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  34554 
  34555 #if defined(BCM_RAPTOR1_SUPPORT)
  34556     if (SOC_IS_RAPTOR(unit)) {
  34557         return BCM_E_UNAVAIL;
  34558     }
  34559 #endif /* BCM_RAPTOR1_SUPPORT */
  34560 
  34561     values[0] = (flags & BCM_PORT_IPMC_MODIFY_NO_SRCMAC) ? 1 : 0;
  34562     values[1] = (flags & BCM_PORT_IPMC_MODIFY_NO_TTL)    ? 1 : 0;
  34563     values[2] = (flags & BCM_PORT_IPMC_CHECK_NO_TTL)     ? 1 : 0;
  34564 
  34565 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  34566     if (soc_feature(unit, soc_feature_egr_ipmc_cfg2_is_memory)) {
  34567         return soc_mem_fields32_modify(unit, EGR_IPMC_CFG2m, port,
  34568                 field_count, fields, values);
  34569     } else
  34570 #endif
  34571     {
  34572         if (values[2]) {
  34573             if (!SOC_REG_FIELD_VALID(unit, EGR_IPMC_CFG2r, DISABLE_TTL_CHECKf)) {
  34574                 return BCM_E_PARAM;
  34575             }
  34576         } else {
  34577             /* Donot include DISABLE_TTL_CHECKf for field validation in reg */
  34578             if (!SOC_REG_FIELD_VALID(unit, EGR_IPMC_CFG2r, DISABLE_TTL_CHECKf)) {
  34579                 field_count -= 1;
  34580             }
  34581         }
  34582 
  34583         return soc_reg_fields32_modify(unit, EGR_IPMC_CFG2r, port,
  34584                 field_count, fields, values);
  34585     }
  34586 #else /* INCLUDE_L3 */
  34587     return (BCM_E_UNAVAIL);
  34588 #endif /* INCLUDE_L3 */
  34589 }
  34590 
  34591 /*
  34592  * Function:
  34593  *      bcm_esw_port_ipmc_modify_get
  34594  * Description:
  34595  *      Enable/Disable ingress port based L3 multicast packet operations.
  34596  * Parameters:
  34597  *      unit - Device number
  34598  *      port - Port number
  34599  *      flags - (OUT) pointer to uint32 where bitmap of the current L3 packet
  34600  *              operations is returned.
  34601  * Return Value:
  34602  *      BCM_E_NONE
  34603  *      BCM_E_UNAVAIL - Functionality not available
  34604  * Notes:
  34605  *      Available on XGS3 only.
  34606  */
  34607 int
  34608 bcm_esw_port_ipmc_modify_get(int unit, bcm_port_t port, uint32 *flags)
  34609 {
  34610 #if defined(INCLUDE_L3)
  34611     uint32 reg_val;
  34612 
  34613     if (!soc_feature(unit, soc_feature_ip_mcast)) {
  34614         return BCM_E_UNAVAIL;
  34615     }
  34616 
  34617     if (soc_feature(unit, soc_feature_no_egr_ipmc_cfg)) {
  34618         return BCM_E_UNAVAIL;
  34619     }
  34620 
  34621     if (!SOC_REG_IS_VALID(unit, EGR_IPMC_CFG2r) &&
  34622             !soc_feature(unit, soc_feature_egr_ipmc_cfg2_is_memory)) {
  34623         return BCM_E_UNAVAIL;
  34624     }
  34625 
  34626 #if defined(BCM_RAPTOR1_SUPPORT)
  34627     if (SOC_IS_RAPTOR(unit)) {
  34628         return BCM_E_UNAVAIL;
  34629     }
  34630 #endif /* BCM_RAPTOR1_SUPPORT */
  34631 
  34632     /* Make sure port module is initialized. */
  34633     PORT_INIT(unit);
  34634 
  34635     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  34636     if (NULL == flags) {
  34637         return (BCM_E_PARAM);
  34638     }
  34639 
  34640 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  34641     if (soc_feature(unit, soc_feature_egr_ipmc_cfg2_is_memory)) {
  34642         BCM_IF_ERROR_RETURN(READ_EGR_IPMC_CFG2m(unit, MEM_BLOCK_ANY, port, &reg_val));
  34643         *flags = 0;
  34644         if (soc_mem_field32_get(unit, EGR_IPMC_CFG2m, &reg_val, DISABLE_SA_REPLACEf)) {
  34645             *flags |=  BCM_PORT_IPMC_MODIFY_NO_SRCMAC;
  34646         }
  34647         if (soc_mem_field32_get(unit, EGR_IPMC_CFG2m, &reg_val, DISABLE_TTL_DECREMENTf)) {
  34648             *flags |=  BCM_PORT_IPMC_MODIFY_NO_TTL;
  34649         }
  34650         if (soc_mem_field32_get(unit, EGR_IPMC_CFG2m, &reg_val, DISABLE_TTL_CHECKf)) {
  34651             *flags |=  BCM_PORT_IPMC_CHECK_NO_TTL;
  34652         }
  34653     } else
  34654 #endif
  34655     {
  34656         BCM_IF_ERROR_RETURN(READ_EGR_IPMC_CFG2r(unit, port, &reg_val));
  34657 
  34658         *flags = 0;
  34659         if (soc_reg_field_get(unit, EGR_IPMC_CFG2r, reg_val, DISABLE_SA_REPLACEf)) {
  34660             *flags |=  BCM_PORT_IPMC_MODIFY_NO_SRCMAC;
  34661         }
  34662         if (soc_reg_field_get(unit, EGR_IPMC_CFG2r, reg_val, DISABLE_TTL_DECREMENTf)) {
  34663             *flags |=  BCM_PORT_IPMC_MODIFY_NO_TTL;
  34664         }
  34665         if (SOC_REG_FIELD_VALID(unit, EGR_IPMC_CFG2r, DISABLE_TTL_CHECKf)) {
  34666             if (soc_reg_field_get(unit, EGR_IPMC_CFG2r, reg_val,
  34667                         DISABLE_TTL_CHECKf)) {
  34668                 *flags |=  BCM_PORT_IPMC_CHECK_NO_TTL;
  34669             }
  34670         }
  34671     }
  34672     return (BCM_E_NONE);
  34673 #else /* INCLUDE_L3 */
  34674     return (BCM_E_UNAVAIL);
  34675 #endif /* INCLUDE_L3 */
  34676 }
  34677 
  34678 /*
  34679  * Function:
  34680  *      _bcm_port_force_forward_linkscan_handler
  34681  * Description:
  34682  *      Called from linkscan handler when port toggles.
  34683  *      Adds/removes entry from LOCAL_SW_DISABLE_DEFAULT_PBM
  34684  * Parameters:
  34685  *      unit - Device number
  34686  *      info - port info
  34687  * Return Value:
  34688  *      BCM_E_XXX
  34689  */
  34690 void 
  34691 _bcm_port_force_forward_linkscan_handler(int unit, 
  34692                 bcm_port_t port, bcm_port_info_t *info)
  34693 {
  34694     bcm_port_t local_port; 
  34695     bcm_pbmp_t *sw_disable_pbmp_linkstate = 
  34696                             p_linkstate[unit].sw_disable_pbmp_linkstate;
  34697     int rv = BCM_E_NONE;
  34698 
  34699     if (!info) {
  34700         return;
  34701     }
  34702 
  34703     if (sw_disable_pbmp_linkstate == NULL) {
  34704         return;
  34705     }
  34706     if (p_linkstate[unit].num_pbmp_entry) {
  34707         PBMP_ALL_ITER(unit, local_port) {
  34708             if (BCM_PBMP_MEMBER(sw_disable_pbmp_linkstate[local_port],
  34709                                         port)) {
  34710                 if (info->linkstatus == BCM_PORT_LINK_STATUS_DOWN) {
  34711                     p_linkstate[unit].lock = 1;
  34712                     rv = bcm_esw_port_force_forward_mode_set(unit, local_port, 
  34713                                     port, BCM_PORT_FORCE_FORWARD_DISABLE);
  34714                     p_linkstate[unit].lock = 0;
  34715                 } else if (info->linkstatus == BCM_PORT_LINK_STATUS_UP) {
  34716                     p_linkstate[unit].lock = 1;
  34717                     rv = bcm_esw_port_force_forward_mode_set(unit, local_port, 
  34718                                     port, BCM_PORT_FORCE_FORWARD_ALL);
  34719                     p_linkstate[unit].lock = 0;
  34720                 }
  34721                 if (BCM_FAILURE(rv)) {
  34722                     LOG_WARN(BSL_LS_BCM_PORT,
  34723                             (BSL_META_U(unit,
  34724                         "bcm_esw_port_force_forward_mode_set failed for "
  34725                             "port %d, dest_port %d, link_state %d. rv = %d\n"),
  34726                             local_port, port, info->linkstatus, rv));
  34727                 }
  34728             }
  34729         }
  34730     }
  34731 }
  34732 
  34733 #if defined(BCM_TRIUMPH3_SUPPORT) 
  34734 /*
  34735  * Function:
  34736  *      _bcm_port_force_forward_init
  34737  * Purpose:
  34738  *      Initialize the port_forward entries
  34739  * Parameters:
  34740  *      unit  - SOC unit #
  34741  * Returns:
  34742  *      BCM_E_XXX
  34743  */
  34744 int
  34745 _bcm_port_force_forward_init(int unit) 
  34746 {
  34747     p_linkstate[unit].num_pbmp_entry = 0;
  34748     
  34749     if (p_linkstate[unit].sw_disable_pbmp_linkstate != NULL) {
  34750         sal_free(p_linkstate[unit].sw_disable_pbmp_linkstate);
  34751         p_linkstate[unit].sw_disable_pbmp_linkstate = NULL;
  34752     }
  34753 
  34754     p_linkstate[unit].sw_disable_pbmp_linkstate = (bcm_pbmp_t*) sal_alloc(
  34755                 sizeof(bcm_pbmp_t) * SOC_MAX_NUM_PORTS,
  34756                 "SW disable pbmp linkstate");
  34757     if (p_linkstate[unit].sw_disable_pbmp_linkstate == NULL) {
  34758         return BCM_E_MEMORY;
  34759     }
  34760     sal_memset(p_linkstate[unit].sw_disable_pbmp_linkstate, 0,
  34761                 sizeof(bcm_pbmp_t) * SOC_MAX_NUM_PORTS);
  34762     return BCM_E_NONE;
  34763 }
  34764 
  34765 /*
  34766  * Function:
  34767  *      _bcm_port_force_forward_deinit
  34768  * Purpose:
  34769  *      Uninitialize the port_forward entries
  34770  * Parameters:
  34771  *      unit  - SOC unit #
  34772  * Returns:
  34773  *      BCM_E_XXX
  34774  */
  34775 int
  34776 _bcm_port_force_forward_deinit(int unit) 
  34777 {
  34778     if (p_linkstate[unit].sw_disable_pbmp_linkstate != NULL) {
  34779         sal_free(p_linkstate[unit].sw_disable_pbmp_linkstate);
  34780         p_linkstate[unit].sw_disable_pbmp_linkstate = NULL;
  34781         p_linkstate[unit].num_pbmp_entry = 0;
  34782     }
  34783     return BCM_E_NONE;
  34784 }
  34785 
  34786 /*
  34787  * Function:
  34788  *      _bcm_port_force_forward_add
  34789  * Purpose:
  34790  *      Add/Deletes an entry into the port_forward DB.
  34791  * Parameters:
  34792  *      unit  - SOC unit #
  34793  *      local_port - Local port/Ingress port
  34794  *      egr_port - destination port. Set 0 to delete it.
  34795  * Returns:
  34796  *      BCM_E_XXX
  34797  */
  34798 int
  34799 _bcm_port_force_forward_add(int unit, bcm_port_t local_port, 
  34800                                         bcm_port_t egr_port)
  34801 {
  34802     bcm_pbmp_t *sw_disable_pbmp_linkstate = 
  34803                     p_linkstate[unit].sw_disable_pbmp_linkstate;
  34804     if (!sw_disable_pbmp_linkstate) {
  34805         return BCM_E_INTERNAL;
  34806     }
  34807     /* Lock is taken while calling bcm_esw_port_force_forward_mode_set
  34808      * from the linkscan handler. It is not taken when called by user.
  34809      * It is to ensure that only HW tables are written to and the 
  34810      * corresponding SW datastructure remains intact.
  34811      */
  34812     if (p_linkstate[unit].lock) {
  34813         return BCM_E_NONE;
  34814     }
  34815     BCM_PBMP_PORT_SET(sw_disable_pbmp_linkstate[local_port], egr_port);
  34816     p_linkstate[unit].num_pbmp_entry++;
  34817     return BCM_E_NONE;
  34818 }
  34819 
  34820 #ifdef BCM_WARM_BOOT_SUPPORT            
  34821 #define _BCM_PORT_WB_MAX_PBMP_V1_5 256
  34822 
  34823 /*
  34824  * Function:
  34825  *     _bcm_port_force_forward_sync
  34826  * Purpose:
  34827  *     Sync port_forward DB to scache.
  34828  * Parameters:
  34829  *     unit - Device unit number
  34830  *     scache_ptr - Scache pointer.
  34831  * Returns:
  34832  *     BCM_E_XXX
  34833  */
  34834 int
  34835 _bcm_port_force_forward_sync(int unit, uint8 **scache_ptr)
  34836 {
  34837     bcm_port_t local_port, dst_port;
  34838     bcm_pbmp_t *sw_disable_pbmp_linkstate = p_linkstate[unit].sw_disable_pbmp_linkstate;
  34839     int port_count = 0, iter = 0;
  34840     SHR_BITDCLNAME(port_bmp, _BCM_PORT_WB_MAX_PBMP_V1_5);
  34841 
  34842     if ((scache_ptr == NULL) || (*scache_ptr == NULL)) {
  34843         return BCM_E_INTERNAL;
  34844     }
  34845 
  34846     PBMP_ALL_ITER(unit, local_port) {
  34847         port_count = 0;
  34848         iter = 0;
  34849         sal_memset(&port_bmp, 0, sizeof(port_bmp));
  34850         BCM_PBMP_COUNT(sw_disable_pbmp_linkstate[local_port], port_count);
  34851         if (BCM_PBMP_NOT_NULL(sw_disable_pbmp_linkstate[local_port])) {
  34852             BCM_PBMP_ITER(sw_disable_pbmp_linkstate[local_port], dst_port) {
  34853                 if(_SHR_BITDCLSIZE(_BCM_PORT_WB_MAX_PBMP_V1_5) <
  34854                    _SHR_BITDCLSIZE(dst_port)) {
  34855                     /* coverity[dead_error_line] */
  34856                     continue;
  34857                 }
  34858                 /* coverity[overrun-local] */
  34859                 SHR_BITSET(port_bmp, dst_port);
  34860                 iter++;
  34861                 if (iter >= port_count) {
  34862                     break;
  34863                 }
  34864             }
  34865         }
  34866         sal_memcpy(*scache_ptr, port_bmp, sizeof(port_bmp));
  34867         *scache_ptr += sizeof(port_bmp);
  34868     }
  34869 
  34870     return BCM_E_NONE;
  34871 }
  34872 
  34873 /*
  34874  * Function:
  34875  *     _bcm_port_force_forward_reinit
  34876  * Purpose:
  34877  *     Retrieve port_forward from hardware and scache.
  34878  * Parameters:
  34879  *     unit - Device unit number
  34880  *     scache_ptr - Scache pointer.
  34881  * Returns:
  34882  *     BCM_E_XXX
  34883  */
  34884 int
  34885 _bcm_port_force_forward_reinit(int unit, uint8 **scache_ptr)
  34886 {
  34887     bcm_port_t local_port;
  34888     int idx;
  34889     bcm_pbmp_t *sw_disable_pbmp_linkstate = 
  34890                             p_linkstate[unit].sw_disable_pbmp_linkstate;
  34891     SHR_BITDCLNAME(port_bmp, _BCM_PORT_WB_MAX_PBMP_V1_5);
  34892 
  34893     p_linkstate[unit].num_pbmp_entry = 0;
  34894     if ((scache_ptr == NULL) || (*scache_ptr == NULL)) {
  34895         return BCM_E_PARAM;
  34896     }
  34897 
  34898     sal_memset(&port_bmp, 0, sizeof(port_bmp));
  34899     sal_memset(sw_disable_pbmp_linkstate, 0, sizeof(bcm_pbmp_t));
  34900     PBMP_ALL_ITER(unit, local_port) {
  34901         sal_memcpy(&port_bmp, *scache_ptr, sizeof(port_bmp));
  34902         *scache_ptr += sizeof(port_bmp);
  34903         if (!SHR_BITNULL_RANGE(port_bmp, 0, _BCM_PORT_WB_MAX_PBMP_V1_5)){
  34904             int bitcount = 0;
  34905             SHR_BITCOUNT_RANGE(port_bmp, bitcount, 0, _BCM_PORT_WB_MAX_PBMP_V1_5);
  34906             for(idx = 0; (idx < _BCM_PORT_WB_MAX_PBMP_V1_5) && (bitcount); idx++) {
  34907                 if(SHR_BITGET(port_bmp, idx)) {
  34908                     BCM_PBMP_PORT_ADD(sw_disable_pbmp_linkstate[local_port], idx);
  34909                     p_linkstate[unit].num_pbmp_entry++;
  34910                     bitcount--;
  34911                 }
  34912             }
  34913         }
  34914     }
  34915 
  34916     return BCM_E_NONE;
  34917 }
  34918 
  34919 /*
  34920  * Function:
  34921  *     _bcm_port_force_forward_scache_size
  34922  * Purpose:
  34923  *     Get the size of the port_forward for scache
  34924  * Parameters:
  34925  *     unit - Device unit number
  34926  *     size - size of scache
  34927  * Returns:
  34928  *     BCM_E_XXX
  34929  */
  34930 int
  34931 _bcm_port_force_forward_scache_size(int unit, int *size)
  34932 {
  34933     int port_forward_size;
  34934     int port_count = 0;
  34935     bcm_port_t local_port;
  34936 
  34937     if (!size) {
  34938         return BCM_E_PARAM;
  34939     }
  34940 
  34941     /* We prefer to use a predefined size of _BCM_PORT_WB_MAX_PBMP_V1_5
  34942      * for warmboot instead of bcm_pbmp_t. This is because of any future
  34943      * increase in max port count for new devices which may change the
  34944      * size of bcm_bcmp_t.
  34945      */
  34946     PBMP_ALL_ITER(unit, local_port) {
  34947         port_count++;
  34948     }
  34949     port_forward_size = SHR_BITALLOCSIZE(_BCM_PORT_WB_MAX_PBMP_V1_5) * port_count;
  34950 
  34951     *size = port_forward_size;
  34952     return BCM_E_NONE;
  34953 }
  34954 #endif /* BCM_WARM_BOOT_SUPPORT */
  34955 #endif /*defined(BCM_TRIUMPH3_SUPPORT)*/
  34956 
  34957 /*
  34958  * Function:
  34959  *      bcm_port_force_forward_mode_set
  34960  * Purpose:
  34961  *      Set egress override port mode.
  34962  * Parameters:
  34963  *      unit - (IN) Unit number.
  34964  *      port - (IN) Port number
  34965  *      egr_port - (IN) Egress port number
  34966  *      flags - (IN) Force forward flags from PORT_FORCE_FORWARD_*
  34967  * Returns:
  34968  *      BCM_E_xxx
  34969  * Notes:
  34970  */
  34971 int
  34972 bcm_esw_port_force_forward_mode_set(int unit, bcm_port_t port,
  34973                                     bcm_port_t egr_port, uint32 flags)
  34974 {
  34975     /* Make sure port module is initialized. */
  34976     PORT_INIT(unit);
  34977 
  34978 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) \
  34979     || defined(BCM_TRX_SUPPORT) || defined(BCM_RAVEN_SUPPORT)
  34980     if (soc_feature(unit, soc_feature_force_forward)) {
  34981 
  34982         int enable = FALSE;
  34983 
  34984         if ((0 != (flags & BCM_PORT_FORCE_FORWARD_LOCAL) &&
  34985              !SOC_IS_TRX(unit))) {
  34986             /* We don't support local only mode on pre-TRX devices */
  34987             return BCM_E_PARAM;
  34988         }
  34989 
  34990         if (0 != (flags & (BCM_PORT_FORCE_FORWARD_ALL |
  34991                            BCM_PORT_FORCE_FORWARD_LOCAL))) {
  34992             enable = TRUE;
  34993         }
  34994 
  34995         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  34996         if (enable) {
  34997             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, egr_port,
  34998                                                              &egr_port));
  34999         }
  35000 
  35001 #if defined(BCM_TRIUMPH_SUPPORT)
  35002         if (SOC_IS_TR_VL(unit)) {
  35003             pbmp_t pbmp;
  35004             uint64 val;
  35005             int cpu_hg_index = 0;
  35006 
  35007             COMPILER_64_SET(val, 0, 0);
  35008             SOC_PBMP_CLEAR(pbmp);
  35009             if (enable) {
  35010                 SOC_PBMP_PORT_SET(pbmp, egr_port);
  35011             }
  35012             if (soc_mem_is_valid(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm)) {
  35013                 local_sw_disable_default_pbm_entry_t entry;
  35014                 sal_memset(&entry, 0, sizeof(entry));
  35015                 soc_mem_pbmp_field_set(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm,
  35016                                        &entry, PORT_BITMAPf, &pbmp);
  35017                 BCM_IF_ERROR_RETURN
  35018                     (soc_mem_write(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm,
  35019                                    MEM_BLOCK_ANY, port, &entry));
  35020 
  35021                 cpu_hg_index = SOC_IS_KATANA2(unit) ?
  35022                                SOC_INFO(unit).cpu_hg_pp_port_index :
  35023                                SOC_INFO(unit).cpu_hg_index;
  35024                 if (IS_CPU_PORT(unit, port)) {
  35025                     BCM_IF_ERROR_RETURN
  35026                         (soc_mem_write(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm,
  35027                                        MEM_BLOCK_ANY, cpu_hg_index, &entry));
  35028                 }
  35029             } else {
  35030 #if defined(BCM_GREYHOUND2_SUPPORT)
  35031                 if (SOC_IS_GREYHOUND2(unit)) {
  35032                     uint64 val_hi, field_val;
  35033 
  35034                     COMPILER_64_SET(val_hi, 0, 0);
  35035                     COMPILER_64_SET(field_val,
  35036                         SOC_PBMP_WORD_GET(pbmp, 1), SOC_PBMP_WORD_GET(pbmp, 0));
  35037                     soc_reg64_field_set(unit, LOCAL_SW_DISABLE_DEFAULT_PBM_LOr,
  35038                         &val, PORT_BITMAP_LOf, field_val);
  35039 
  35040                     COMPILER_64_SET(field_val,
  35041                         0, SOC_PBMP_WORD_GET(pbmp, 2));
  35042                     soc_reg64_field_set(unit, LOCAL_SW_DISABLE_DEFAULT_PBM_HIr,
  35043                         &val_hi, PORT_BITMAP_LOf, field_val);
  35044 
  35045                     
  35046                     if (IS_ST_PORT(unit, port)) {
  35047                         BCM_IF_ERROR_RETURN
  35048                             (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_LOr(unit, port, val));
  35049                         BCM_IF_ERROR_RETURN
  35050                             (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_HIr(unit, port, val_hi));
  35051                     } else {
  35052                         BCM_IF_ERROR_RETURN
  35053                             (WRITE_LOCAL_SW_DISABLE_DEFAULT_PBM_LOr(unit, port, val));
  35054                         BCM_IF_ERROR_RETURN
  35055                             (WRITE_LOCAL_SW_DISABLE_DEFAULT_PBM_HIr(unit, port, val_hi));
  35056                         if (IS_CPU_PORT(unit, port)) {
  35057                             BCM_IF_ERROR_RETURN
  35058                                 (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_LOr(unit, port, val));
  35059                             BCM_IF_ERROR_RETURN
  35060                                 (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_HIr(unit, port, val_hi));
  35061                         }
  35062                     }
  35063                 } else
  35064 #endif /* BCM_GREYHOUND2_SUPPORT */
  35065                 {
  35066                 soc_reg64_field32_set(unit
  35067                                       , LOCAL_SW_DISABLE_DEFAULT_PBM_64r,
  35068                                       &val, PORT_BITMAP_LOf,
  35069                                       SOC_PBMP_WORD_GET(pbmp, 0));
  35070                 if(!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) &&
  35071                    !SOC_IS_GREYHOUND(unit)) {
  35072                     soc_reg64_field32_set(unit,
  35073                                           LOCAL_SW_DISABLE_DEFAULT_PBM_64r,
  35074                                           &val, PORT_BITMAP_HIf,
  35075                                           SOC_PBMP_WORD_GET(pbmp, 1));
  35076                 }
  35077                 
  35078                 if (IS_ST_PORT(unit, port)) {
  35079                     BCM_IF_ERROR_RETURN
  35080                         (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_64r(unit, port,
  35081                                                                  val));
  35082                 } else {
  35083                     BCM_IF_ERROR_RETURN
  35084                         (WRITE_LOCAL_SW_DISABLE_DEFAULT_PBM_64r(unit, port,
  35085                                                                 val));
  35086                     if (IS_CPU_PORT(unit, port)) {
  35087                         BCM_IF_ERROR_RETURN
  35088                             (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_64r(unit, port,
  35089                                                                      val));
  35090                     }
  35091                 }
  35092             }
  35093             }
  35094         }  else
  35095 #endif /* BCM_TRIUMPH_SUPPORT */
  35096         {
  35097 #if defined(BCM_FIREBOLT2_SUPPORT) ||  defined(BCM_RAVEN_SUPPORT)  || \
  35098             defined(BCM_SCORPION_SUPPORT)
  35099             if ((SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) ||
  35100                  SOC_IS_SC_CQ(unit)) && IS_ST_PORT(unit, port)) {
  35101                 BCM_IF_ERROR_RETURN
  35102                     (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBMr(unit, port,
  35103                                          (enable) ? 1 << egr_port : 0));
  35104             } else
  35105 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */
  35106             {
  35107                 BCM_IF_ERROR_RETURN
  35108                     (WRITE_LOCAL_SW_DISABLE_DEFAULT_PBMr(unit, port,
  35109                                     (enable) ? 1 << egr_port : 0));
  35110             }
  35111         }
  35112 
  35113 #if defined(BCM_TRIUMPH3_SUPPORT)
  35114         if (soc_feature(unit, soc_feature_epc_linkflap_recover)) {
  35115             int rv;
  35116             rv = _bcm_port_force_forward_add(unit, port,
  35117                             (enable) ? egr_port : 0);
  35118             if (BCM_FAILURE(rv)) {
  35119                 return rv;
  35120             }
  35121         }
  35122 #endif /*defined(BCM_TRIUMPH3_SUPPORT)*/
  35123 
  35124 #if defined(BCM_TRX_SUPPORT)
  35125         if (SOC_IS_TRX(unit)) {
  35126             uint32 mode;
  35127 
  35128             mode = (flags & BCM_PORT_FORCE_FORWARD_LOCAL) ?
  35129                 _BCM_TRX_PORT_FORCE_FORWARD_LOCAL :
  35130                 ((flags & BCM_PORT_FORCE_FORWARD_ALL) ?
  35131                  _BCM_TRX_PORT_FORCE_FORWARD_ALL :
  35132                  _BCM_TRX_PORT_FORCE_FORWARD_DISABLE);
  35133 
  35134             return soc_reg_field32_modify(unit, LOCAL_SW_DISABLE_CTRLr,
  35135                                           port, SW_MODEf, mode);
  35136         } else
  35137 #endif
  35138         {
  35139             return _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  35140                                          LOCAL_SW_DISABLEf,
  35141                                          (enable) ? 1 : 0);
  35142         }
  35143     }
  35144 #endif /* BCM_BRADLEY_SUPPORT || BCM_FIREBOLT2_SUPPORT \
  35145           || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
  35146     return BCM_E_UNAVAIL;
  35147 }
  35148 
  35149 /*
  35150  * Function:
  35151  *      bcm_port_force_forward_mode_get
  35152  * Purpose:
  35153  *      Get egress override port.
  35154  * Parameters:
  35155  *      unit - (IN) Unit number.
  35156  *      port - (IN) Port number
  35157  *      egr_port - (OUT) Egress port number
  35158  *      flags - (OUT) Force forward flags from PORT_FORCE_FORWARD_*
  35159  * Returns:
  35160  *      BCM_E_xxx
  35161  * Notes:
  35162  */
  35163 int
  35164 bcm_esw_port_force_forward_mode_get(int unit, bcm_port_t port,
  35165                                     bcm_port_t *egr_port, uint32 *flags)
  35166 {
  35167     /* Make sure port module is initialized. */
  35168     PORT_INIT(unit);
  35169 
  35170 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) \
  35171         || defined(BCM_TRX_SUPPORT) || defined(BCM_RAVEN_SUPPORT)
  35172     if (soc_feature(unit, soc_feature_force_forward)) {
  35173         pbmp_t pbmp;
  35174         uint32 egr_pbm;
  35175         int ep, enabled;
  35176 
  35177         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  35178 
  35179 #if defined(BCM_TRX_SUPPORT)
  35180         if (SOC_IS_TRX(unit)) {
  35181             uint32 val_32, mode;
  35182 
  35183             BCM_IF_ERROR_RETURN
  35184                 (READ_LOCAL_SW_DISABLE_CTRLr(unit, port, &val_32));
  35185             mode = soc_reg_field_get(unit, LOCAL_SW_DISABLE_CTRLr,
  35186                                          val_32, SW_MODEf);
  35187 
  35188             if (_BCM_TRX_PORT_FORCE_FORWARD_LOCAL == mode) {
  35189                 *flags = BCM_PORT_FORCE_FORWARD_LOCAL;
  35190             } else if (_BCM_TRX_PORT_FORCE_FORWARD_ALL == mode) {
  35191                 *flags = BCM_PORT_FORCE_FORWARD_ALL;
  35192             } else {
  35193                 *flags = BCM_PORT_FORCE_FORWARD_DISABLE;
  35194             }
  35195             enabled = (BCM_PORT_FORCE_FORWARD_DISABLE != mode);
  35196         } else
  35197 #endif
  35198         {
  35199             BCM_IF_ERROR_RETURN
  35200                 (_bcm_esw_port_tab_get(unit, port, LOCAL_SW_DISABLEf, &enabled));
  35201             *flags = enabled ? BCM_PORT_FORCE_FORWARD_ALL :
  35202                 BCM_PORT_FORCE_FORWARD_DISABLE;
  35203         }
  35204 
  35205         if (enabled) {
  35206             _bcm_gport_dest_t   dest;
  35207             bcm_module_t        modid;
  35208             int                 isGport = 0;
  35209 
  35210             _bcm_gport_dest_t_init(&dest);
  35211 #if defined(BCM_TRIUMPH_SUPPORT)
  35212             if (SOC_IS_TR_VL(unit)) {
  35213                 uint64 val;
  35214 
  35215                 if (soc_mem_is_valid(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm)) {
  35216                     local_sw_disable_default_pbm_entry_t entry;
  35217                     BCM_IF_ERROR_RETURN
  35218                         (soc_mem_read(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm,
  35219                                       MEM_BLOCK_ANY, port, &entry));
  35220                     soc_mem_pbmp_field_get(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm,
  35221                                            &entry, PORT_BITMAPf, &pbmp);
  35222                 } else {
  35223 #if defined(BCM_GREYHOUND2_SUPPORT)
  35224                     if (SOC_IS_GREYHOUND2(unit)) {
  35225                         BCM_IF_ERROR_RETURN
  35226                             (READ_LOCAL_SW_DISABLE_DEFAULT_PBM_LOr(unit, port, &val));
  35227 
  35228                         egr_pbm = soc_reg64_field32_get(unit,
  35229                                                   LOCAL_SW_DISABLE_DEFAULT_PBM_LOr,
  35230                                                   val, OVER_LOf);
  35231                         SOC_PBMP_CLEAR(pbmp);
  35232                         SOC_PBMP_WORD_SET(pbmp, 0, egr_pbm);
  35233 
  35234                         egr_pbm = soc_reg64_field32_get(unit,
  35235                                                   LOCAL_SW_DISABLE_DEFAULT_PBM_LOr,
  35236                                                   val, OVER_HIf);
  35237                         SOC_PBMP_WORD_SET(pbmp, 1, egr_pbm);
  35238 
  35239                         BCM_IF_ERROR_RETURN
  35240                             (READ_LOCAL_SW_DISABLE_DEFAULT_PBM_HIr(unit, port, &val));
  35241 
  35242                         egr_pbm = soc_reg64_field32_get(unit,
  35243                                                   LOCAL_SW_DISABLE_DEFAULT_PBM_HIr,
  35244                                                   val, OVER_LOf);
  35245                         SOC_PBMP_WORD_SET(pbmp, 2, egr_pbm);
  35246                     } else
  35247 #endif /* BCM_GREYHOUND2_SUPPORT */
  35248                     {
  35249                     BCM_IF_ERROR_RETURN
  35250                         (READ_LOCAL_SW_DISABLE_DEFAULT_PBM_64r(unit, port,
  35251                                                                &val));
  35252                     egr_pbm =
  35253                         soc_reg64_field32_get(unit,
  35254                                               LOCAL_SW_DISABLE_DEFAULT_PBM_64r,
  35255                                               val, PORT_BITMAP_LOf);
  35256                     SOC_PBMP_CLEAR(pbmp);
  35257                     SOC_PBMP_WORD_SET(pbmp, 0, egr_pbm);
  35258                     if ((egr_pbm == 0) &&
  35259                         (!SOC_IS_ENDURO(unit)) && (!SOC_IS_HURRICANEX(unit)) &&
  35260                         (!SOC_IS_GREYHOUND(unit))) {
  35261                         egr_pbm = soc_reg64_field32_get
  35262                             (unit,  LOCAL_SW_DISABLE_DEFAULT_PBM_64r,
  35263                              val, PORT_BITMAP_HIf);
  35264                         SOC_PBMP_WORD_SET(pbmp, 1, egr_pbm);
  35265                     }
  35266                 }
  35267                 }
  35268             } else
  35269 #endif /* BCM_TRIUMPH_SUPPORT */
  35270             if ((SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) ||
  35271                  SOC_IS_SC_CQ(unit)) && IS_ST_PORT(unit, port)) {
  35272                 BCM_IF_ERROR_RETURN
  35273                     (READ_ILOCAL_SW_DISABLE_DEFAULT_PBMr(unit, port, &egr_pbm));
  35274                 SOC_PBMP_CLEAR(pbmp);
  35275                 SOC_PBMP_WORD_SET(pbmp, 0, egr_pbm);
  35276             } else {
  35277                 BCM_IF_ERROR_RETURN
  35278                     (READ_LOCAL_SW_DISABLE_DEFAULT_PBMr(unit, port, &egr_pbm));
  35279                 SOC_PBMP_CLEAR(pbmp);
  35280                 SOC_PBMP_WORD_SET(pbmp, 0, egr_pbm);
  35281             }
  35282             if (SOC_PBMP_IS_NULL(pbmp)) {
  35283                 return BCM_E_INTERNAL;
  35284             }
  35285             /* Convert port bitmap into port number */
  35286             SOC_PBMP_ITER(pbmp, ep) {
  35287                 break;
  35288             }
  35289             BCM_IF_ERROR_RETURN
  35290                 (bcm_esw_switch_control_get(unit, bcmSwitchUseGport, &isGport));
  35291             if (isGport) {
  35292                 /* ignore return code to suport devices w/out modid assigned */
  35293                 (void)bcm_esw_stk_my_modid_get(unit, &modid);
  35294 
  35295                 if (BCM_MODID_INVALID == modid) {
  35296                     dest.gport_type = _SHR_GPORT_TYPE_DEVPORT;
  35297                 } else {
  35298                     dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
  35299                     dest.modid = modid;
  35300                 }
  35301                 dest.port = ep;
  35302 
  35303                 BCM_IF_ERROR_RETURN
  35304                     (_bcm_esw_gport_construct(unit, &dest, &ep));
  35305             }
  35306             *egr_port = ep;
  35307         }
  35308         return BCM_E_NONE;
  35309     }
  35310 #endif /* BCM_BRADLEY_SUPPORT || BCM_FIREBOLT2_SUPPORT \
  35311           || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */
  35312     return BCM_E_UNAVAIL;
  35313 }
  35314 
  35315 /*
  35316  * Function:
  35317  *      bcm_esw_port_force_forward_set
  35318  * Purpose:
  35319  *      This function allows packets to bypass the normal forwarding
  35320  *      logic and be sent out on a specific port instead.
  35321  * Parameters:
  35322  *      unit - Device number
  35323  *      port - Port number
  35324  *      egr_port - Egress port number
  35325  *      enable - Bypass switching logic and forward to egr_port
  35326  * Return Value:
  35327  *      BCM_E_NONE
  35328  *      BCM_E_UNAVAIL - Functionality not available
  35329  * Notes:
  35330  *      All normal ingress processing (table lookups etc.) is still
  35331  *      performed and used for contructing the Higig header if the
  35332  *      forced egress port is a Higig port.
  35333  */
  35334 int
  35335 bcm_esw_port_force_forward_set(int unit, bcm_port_t port,
  35336                                bcm_port_t egr_port, int enable)
  35337 {
  35338     return bcm_esw_port_force_forward_mode_set(unit, port, egr_port,
  35339                          enable ? BCM_PORT_FORCE_FORWARD_ALL :
  35340                                   BCM_PORT_FORCE_FORWARD_DISABLE);
  35341 }
  35342 
  35343 /*
  35344  * Function:
  35345  *      bcm_esw_port_force_forward_get
  35346  * Purpose:
  35347  *      Determine forced forwarding setting for a port.
  35348  * Parameters:
  35349  *      unit - Device number
  35350  *      port - Port number
  35351  *      egr_port - (OUT) Egress port number
  35352  *      enabled - (OUT) Forced forwarding enabled
  35353  * Return Value:
  35354  *      BCM_E_NONE
  35355  *      BCM_E_UNAVAIL - Functionality not available
  35356  * Notes:
  35357  *      If the value of enabled is zero, the value of egr_port should
  35358  *      be ignored.
  35359  */
  35360 int
  35361 bcm_esw_port_force_forward_get(int unit, bcm_port_t port,
  35362                                bcm_port_t *egr_port, int *enabled)
  35363 {
  35364     uint32 flags;
  35365 
  35366     /* Make sure port module is initialized. */
  35367     PORT_INIT(unit);
  35368 
  35369     BCM_IF_ERROR_RETURN
  35370         (bcm_esw_port_force_forward_mode_get(unit, port, egr_port, &flags));
  35371 
  35372     *enabled = (0 != (flags & (BCM_PORT_FORCE_FORWARD_ALL |
  35373                               BCM_PORT_FORCE_FORWARD_LOCAL)));
  35374     return BCM_E_NONE;
  35375 }
  35376 
  35377 #if defined(INCLUDE_L3)
  35378 /*
  35379  * Function:
  35380  *      _bcm_esw_port_ecmp_dlb_link_status_set
  35381  * Purpose:
  35382  *      Set ECMP DLB port link status.
  35383  * Parameters:
  35384  *      unit    - (IN) SOC unit number.
  35385  *      port    - (IN) Port, not Gport.
  35386  *      status  - (IN) ECMP DLB port link status.
  35387  * Returns:
  35388  *      BCM_E_xxx
  35389  */
  35390 int
  35391 _bcm_esw_port_ecmp_dlb_link_status_set(int unit, bcm_port_t port,
  35392                                        int status)
  35393 {
  35394     int rv = BCM_E_UNAVAIL;
  35395 
  35396 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  35397     if (soc_feature(unit, soc_feature_ecmp_dlb_optimized)) {
  35398         rv = _bcm_th2_l3_egress_ecmp_port_status_set(unit, port, status);
  35399     }
  35400 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT */
  35401 
  35402     return rv;
  35403 }
  35404 #endif /* INCLUDE_L3 */
  35405 
  35406 
  35407 #if defined(INCLUDE_L3)
  35408 /*
  35409  * Function:
  35410  *      _bcm_esw_port_ecmp_dlb_link_status_get
  35411  * Purpose:
  35412  *      Get ECMP DLB port link status.
  35413  * Parameters:
  35414  *      unit    - (IN) SOC unit number.
  35415  *      port    - (IN) Port, not Gport.
  35416  *      status  - (OUT) ECMP DLB port link status.
  35417  * Returns:
  35418  *      BCM_E_xxx
  35419  */
  35420 int
  35421 _bcm_esw_port_ecmp_dlb_link_status_get(int unit, bcm_port_t port,
  35422                                        int *status)
  35423 {
  35424     int rv = BCM_E_UNAVAIL;
  35425 
  35426     if (status == NULL) {
  35427         return BCM_E_PARAM;
  35428     }
  35429 
  35430 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  35431     if (soc_feature(unit, soc_feature_ecmp_dlb_optimized)) {
  35432        rv = _bcm_th2_l3_egress_ecmp_port_status_get(unit, port, status);
  35433     }
  35434 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT */
  35435 
  35436     return rv;
  35437 }
  35438 #endif /* INCLUDE_L3 */
  35439 
  35440 
  35441 
  35442 /*
  35443  * Function:
  35444  *      _bcm_esw_port_err_sym_detect_set
  35445  * Description:
  35446  *      Enable/Disable XAUI error symbol monitoring feature.
  35447  * Parameters:
  35448  *      unit - Device number
  35449  *      port - Port number
  35450  *      enable - TRUE, enable |E| monitoring feature on the port.
  35451  *               FALSE, disable |E| monitoring feature on the port.
  35452  * Return Value:
  35453  *      BCM_E_NONE
  35454  *      BCM_E_UNAVAIL - Functionality not available
  35455  */
  35456 #ifdef BCM_XGS3_SWITCH_SUPPORT
  35457 STATIC int
  35458 _bcm_esw_port_err_sym_detect_set(int unit, bcm_port_t port, int enable)
  35459 {
  35460     int rv;
  35461     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  35462 
  35463     LOG_INFO(BSL_LS_BCM_PORT,
  35464              (BSL_META_U(unit,
  35465                          "_bcm_esw_port_err_sym_detect_set: u=%d p=%d enable=%d\n"),
  35466               unit, port, enable));
  35467 
  35468     if (IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port)
  35469 #ifdef BCM_GXPORT_SUPPORT
  35470         || IS_GX_PORT(unit, port)
  35471 #endif /* BCM_GXPORT_SUPPORT */
  35472                                  ) {
  35473         PORT_LOCK(unit);
  35474         rv = soc_xaui_err_sym_detect_set(unit, port, enable);
  35475         PORT_UNLOCK(unit);
  35476     } else {
  35477         rv = BCM_E_UNAVAIL;
  35478     }
  35479 
  35480 
  35481     return rv;
  35482 }
  35483 #endif
  35484 
  35485 /*
  35486  * Function:
  35487  *      _bcm_esw_port_err_sym_detect_get
  35488  * Description:
  35489  *      Get the status of XAUI error symbol monitoring feature.
  35490  * Parameters:
  35491  *      unit - Device number
  35492  *      port - Port number
  35493  *      status - (OUT) TRUE, port is enabled, FALSE port is disabled.
  35494  * Return Value:
  35495  *      BCM_E_NONE
  35496  *      BCM_E_UNAVAIL - Functionality not available
  35497  */
  35498 #ifdef BCM_XGS3_SWITCH_SUPPORT
  35499 STATIC int
  35500 _bcm_esw_port_err_sym_detect_get(int unit, bcm_port_t port, int *status)
  35501 {
  35502     int rv;
  35503     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  35504 
  35505     if (IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port)
  35506 #ifdef BCM_GXPORT_SUPPORT
  35507         || IS_GX_PORT(unit, port)
  35508 #endif /* BCM_GXPORT_SUPPORT */
  35509                                  ) {
  35510         PORT_LOCK(unit);
  35511         rv = soc_xaui_err_sym_detect_get(unit, port, status);
  35512         PORT_UNLOCK(unit);
  35513     } else {
  35514         rv = BCM_E_UNAVAIL;
  35515     }
  35516 
  35517     LOG_INFO(BSL_LS_BCM_PORT,
  35518              (BSL_META_U(unit,
  35519                          "_bcm_esw_port_err_sym_detect_get: u=%d p=%d status=%d\n"),
  35520               unit, port, *status));
  35521 
  35522     return rv;
  35523 }
  35524 #endif
  35525 
  35526 /*
  35527  * Function:
  35528  *      _bcm_esw_port_err_sym_count_get
  35529  * Description:
  35530  *      Get the number of |E| symbol in XAUI lanes since last read.
  35531  *      The |E| symbol count is cleared on read.
  35532  * Parameters:
  35533  *      unit - Device number
  35534  *      port - Port number
  35535  *      count - (OUT) Number of |E| error since last read.
  35536  * Return Value:
  35537  *      BCM_E_NONE
  35538  *      BCM_E_UNAVAIL - Functionality not available
  35539  *      BCM_E_INIT    - Error symbol detect feature is not enabled
  35540  */
  35541 STATIC int
  35542 _bcm_esw_port_err_sym_count_get(int unit, bcm_port_t port, int *count)
  35543 {
  35544     int rv;
  35545     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  35546 
  35547     rv = BCM_E_UNAVAIL;
  35548 
  35549 #ifdef BCM_XGS3_SWITCH_SUPPORT
  35550 
  35551     if (IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port)
  35552 #ifdef BCM_GXPORT_SUPPORT
  35553         || IS_GX_PORT(unit, port)
  35554 #endif /* BCM_GXPORT_SUPPORT */
  35555                                  ) {
  35556         PORT_LOCK(unit);
  35557         rv = soc_xaui_err_sym_count(unit, port, count);
  35558         PORT_UNLOCK(unit);
  35559     }
  35560 #endif
  35561 
  35562     LOG_INFO(BSL_LS_BCM_PORT,
  35563              (BSL_META_U(unit,
  35564                          "_bcm_esw_port_err_sym_count_get: u=%d p=%d count=%d\n"),
  35565               unit, port, *count));
  35566 
  35567     return rv;
  35568 }
  35569 
  35570 STATIC int
  35571 _bcm_esw_port_control_bridge_set(int unit, bcm_port_t port, int value)
  35572 {
  35573     int rv = BCM_E_UNAVAIL;
  35574 
  35575 #ifdef BCM_TRIUMPH_SUPPORT
  35576     if (SOC_IS_TR_VL(unit)) {
  35577         bcm_pbmp_t  pbmp;            /* Port bitmap to update.*/
  35578 
  35579         if (IS_E_PORT(unit, port)
  35580             || IS_CPU_PORT(unit, port)
  35581             || IS_HG_PORT(unit, port)) {
  35582             if (SOC_MEM_IS_VALID(unit, PORT_BRIDGE_BMAPm)) {
  35583                 port_bridge_bmap_entry_t entry;
  35584 
  35585                 SOC_IF_ERROR_RETURN(soc_mem_read(unit, PORT_BRIDGE_BMAPm,
  35586                             MEM_BLOCK_ANY, 0, &entry));
  35587                 soc_mem_pbmp_field_get(unit, PORT_BRIDGE_BMAPm, &entry,
  35588                         BITMAPf, &pbmp);
  35589                 if (value && !SOC_PBMP_MEMBER(pbmp, port)) {
  35590                     SOC_PBMP_PORT_ADD(pbmp, port);
  35591                 } else if (!value && SOC_PBMP_MEMBER(pbmp, port)) {
  35592                     SOC_PBMP_PORT_REMOVE(pbmp, port);
  35593                 } else {
  35594                     return BCM_E_NONE;
  35595                 }
  35596                 soc_mem_pbmp_field_set(unit, PORT_BRIDGE_BMAPm, &entry,
  35597                         BITMAPf, &pbmp);
  35598                 SOC_IF_ERROR_RETURN(soc_mem_write(unit, PORT_BRIDGE_BMAPm,
  35599                             MEM_BLOCK_ANY, 0, &entry));
  35600             }
  35601             if (SOC_REG_IS_VALID(unit, PORT_BRIDGE_BMAP_64r)) {
  35602                 uint64      buf64;           /* Buffer for reg64 value. */
  35603                 SOC_PBMP_CLEAR(pbmp);
  35604 
  35605                 BCM_IF_ERROR_RETURN
  35606                     (READ_PORT_BRIDGE_BMAP_64r(unit, &buf64));
  35607 
  35608                 /* Set l3 port bitmap. */
  35609                 SOC_PBMP_WORD_SET(pbmp, 0,
  35610                         soc_reg64_field32_get(unit, PORT_BRIDGE_BMAP_64r,
  35611                             buf64, BITMAP_LOf));
  35612                 if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) &&
  35613                         !SOC_IS_GREYHOUND(unit) && !SOC_IS_GREYHOUND2(unit)) {
  35614                     SOC_PBMP_WORD_SET(pbmp, 1,
  35615                             soc_reg64_field32_get(unit, PORT_BRIDGE_BMAP_64r,
  35616                                     buf64, BITMAP_HIf));
  35617                 }
  35618 
  35619                 if (SOC_PBMP_MEMBER(pbmp, port) && value) {
  35620                     return BCM_E_NONE;
  35621                 }
  35622                 if (!SOC_PBMP_MEMBER(pbmp, port) && !value) {
  35623                     return BCM_E_NONE;
  35624                 }
  35625                 if (!SOC_PBMP_MEMBER(pbmp, port) && value) {
  35626                     SOC_PBMP_PORT_ADD(pbmp, port);
  35627                 } else if (SOC_PBMP_MEMBER(pbmp, port) && !value) {
  35628                     SOC_PBMP_PORT_REMOVE(pbmp, port);
  35629                 }
  35630 
  35631                 soc_reg64_field32_set(unit, PORT_BRIDGE_BMAP_64r,
  35632                         &buf64, BITMAP_LOf,
  35633                         SOC_PBMP_WORD_GET(pbmp, 0));
  35634                 if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) &&
  35635                         !SOC_IS_GREYHOUND(unit)) {
  35636                     soc_reg64_field32_set(unit, PORT_BRIDGE_BMAP_64r,
  35637                             &buf64, BITMAP_HIf,
  35638                             SOC_PBMP_WORD_GET(pbmp, 1));
  35639                 }
  35640 
  35641                 BCM_IF_ERROR_RETURN
  35642                     (WRITE_PORT_BRIDGE_BMAP_64r(unit, buf64));
  35643             } else if (SOC_REG_IS_VALID(unit, PORT_BRIDGE_BMAP_LO_64r)) {
  35644                 /* 
  35645                  * Both PORT_BRIDGE_BMAP_LO_64r and PORT_BRIDGE_BMAP_HI_64r 
  35646                  * are expected been valid here.
  35647                  */
  35648                 
  35649                 uint64      fval64, rval64;
  35650                 uint32      t_port;
  35651                 soc_reg_t   reg;
  35652                 pbmp_t      curr_pbmp;
  35653         
  35654                 BCM_PBMP_CLEAR(curr_pbmp);
  35655                 COMPILER_64_ZERO(fval64);
  35656                 COMPILER_64_ZERO(rval64);
  35657                 
  35658         
  35659                 if (port < 64) {
  35660                     reg = PORT_BRIDGE_BMAP_LO_64r;
  35661                     t_port = port;
  35662                 } else {
  35663                     reg = PORT_BRIDGE_BMAP_HI_64r;
  35664                     t_port = port - 64;
  35665                 }
  35666                 rv = soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64);
  35667                 if (BCM_SUCCESS(rv)) {
  35668                     fval64 = soc_reg64_field_get(unit, reg, 
  35669                                                     rval64, BITMAPf);
  35670                     SOC_PBMP_WORD_SET(curr_pbmp, 0, 
  35671                                         COMPILER_64_LO(fval64));
  35672                     SOC_PBMP_WORD_SET(curr_pbmp, 1, 
  35673                                         COMPILER_64_HI(fval64));
  35674         
  35675                     if (value && !SOC_PBMP_MEMBER(curr_pbmp, t_port)) {
  35676                         SOC_PBMP_PORT_ADD(curr_pbmp, t_port);
  35677                     } else if (!value && SOC_PBMP_MEMBER(curr_pbmp, t_port)) {
  35678                         SOC_PBMP_PORT_REMOVE(curr_pbmp, t_port);
  35679                     } else {
  35680                         return BCM_E_NONE;
  35681                     }
  35682                         
  35683                     COMPILER_64_SET(fval64,
  35684                                     SOC_PBMP_WORD_GET(curr_pbmp, 1),
  35685                                     SOC_PBMP_WORD_GET(curr_pbmp, 0));
  35686                     soc_reg64_field_set(unit, reg, &rval64, 
  35687                                         BITMAPf, fval64);
  35688                     rv = soc_reg_set(unit, reg, 
  35689                                         REG_PORT_ANY, 0, rval64);
  35690                 }
  35691             }
  35692 
  35693         }
  35694         if (IS_HG_PORT(unit, port)) {
  35695 
  35696             if (SOC_MEM_IS_VALID(unit, PORT_BRIDGE_MIRROR_BMAPm)) {
  35697                 port_bridge_mirror_bmap_entry_t entry;
  35698 
  35699                 SOC_IF_ERROR_RETURN(soc_mem_read(unit, PORT_BRIDGE_MIRROR_BMAPm,
  35700                             MEM_BLOCK_ANY, 0, &entry));
  35701                 soc_mem_pbmp_field_get(unit, PORT_BRIDGE_MIRROR_BMAPm, &entry,
  35702                         BITMAPf, &pbmp);
  35703                 /* it might be different to port_tab, so don't return */
  35704                 if (value && !SOC_PBMP_MEMBER(pbmp, port)) {
  35705                     SOC_PBMP_PORT_ADD(pbmp, port);
  35706                 } else if (!value && SOC_PBMP_MEMBER(pbmp, port)) {
  35707                     SOC_PBMP_PORT_REMOVE(pbmp, port);
  35708                 }
  35709                 soc_mem_pbmp_field_set(unit, PORT_BRIDGE_MIRROR_BMAPm, &entry,
  35710                         BITMAPf, &pbmp);
  35711                 SOC_IF_ERROR_RETURN(soc_mem_write(unit, PORT_BRIDGE_MIRROR_BMAPm,
  35712                             MEM_BLOCK_ANY, 0, &entry));
  35713             }
  35714 
  35715             if (SOC_REG_IS_VALID(unit, PORT_BRIDGE_MIRROR_BMAP_64r)) {
  35716                 uint64      buf64;           /* Buffer for reg64 value. */
  35717                 SOC_PBMP_CLEAR(pbmp);
  35718 
  35719                 BCM_IF_ERROR_RETURN
  35720                     (READ_PORT_BRIDGE_MIRROR_BMAP_64r(unit, &buf64));
  35721 
  35722                 /* Set port bitmap. */
  35723                 SOC_PBMP_WORD_SET(pbmp, 0,
  35724                         soc_reg64_field32_get(unit, PORT_BRIDGE_MIRROR_BMAP_64r,
  35725                             buf64, BITMAP_LOf));
  35726                 if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) &&
  35727                         !SOC_IS_GREYHOUND(unit) && !SOC_IS_GREYHOUND2(unit)) {
  35728                     SOC_PBMP_WORD_SET(pbmp, 1,
  35729                             soc_reg64_field32_get(unit, PORT_BRIDGE_MIRROR_BMAP_64r,
  35730                                     buf64, BITMAP_HIf));
  35731                 }
  35732 
  35733                 if (!SOC_PBMP_MEMBER(pbmp, port) && value) {
  35734                     SOC_PBMP_PORT_ADD(pbmp, port);
  35735                 } else if (SOC_PBMP_MEMBER(pbmp, port) && !value) {
  35736                     SOC_PBMP_PORT_REMOVE(pbmp, port);
  35737                 } else {
  35738                     return BCM_E_NONE;
  35739                 }
  35740 
  35741                 soc_reg64_field32_set(unit, PORT_BRIDGE_MIRROR_BMAP_64r,
  35742                         &buf64, BITMAP_LOf, SOC_PBMP_WORD_GET(pbmp, 0));
  35743                 if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) &&
  35744                         !SOC_IS_GREYHOUND(unit) && !SOC_IS_GREYHOUND2(unit)) {
  35745                     soc_reg64_field32_set(unit, PORT_BRIDGE_MIRROR_BMAP_64r,
  35746                             &buf64, BITMAP_HIf, SOC_PBMP_WORD_GET(pbmp, 1));
  35747                 }
  35748 
  35749                 BCM_IF_ERROR_RETURN
  35750                     (WRITE_PORT_BRIDGE_MIRROR_BMAP_64r(unit, buf64));
  35751             } else if (SOC_REG_IS_VALID(unit, PORT_BRIDGE_MIRROR_BMAP_LOr)) {
  35752                 /* 
  35753                  * Both PORT_BRIDGE_MIRROR_BMAP_LOr and PORT_BRIDGE_MIRROR_BMAP_HIr 
  35754                  * are expected been valid here.
  35755                  */
  35756                 
  35757                 uint64      fval64, rval64;
  35758                 uint32      t_port;
  35759                 soc_reg_t   reg;
  35760                 pbmp_t      curr_pbmp;
  35761         
  35762                 BCM_PBMP_CLEAR(curr_pbmp);
  35763                 COMPILER_64_ZERO(fval64);
  35764                 COMPILER_64_ZERO(rval64);
  35765                 
  35766         
  35767                 if (port < 64) {
  35768                     reg = PORT_BRIDGE_MIRROR_BMAP_LOr;
  35769                     t_port = port;
  35770                 } else {
  35771                     reg = PORT_BRIDGE_MIRROR_BMAP_HIr;
  35772                     t_port = port - 64;
  35773                 }
  35774                 rv = soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64);
  35775                 if (BCM_SUCCESS(rv)) {
  35776                     fval64 = soc_reg64_field_get(unit, reg, 
  35777                                                     rval64, BITMAPf);
  35778                     SOC_PBMP_WORD_SET(curr_pbmp, 0, 
  35779                                         COMPILER_64_LO(fval64));
  35780                     SOC_PBMP_WORD_SET(curr_pbmp, 1, 
  35781                                         COMPILER_64_HI(fval64));
  35782         
  35783                     if (value && !SOC_PBMP_MEMBER(curr_pbmp, t_port)) {
  35784                         SOC_PBMP_PORT_ADD(curr_pbmp, t_port);
  35785                     } else if (!value && SOC_PBMP_MEMBER(curr_pbmp, t_port)) {
  35786                         SOC_PBMP_PORT_REMOVE(curr_pbmp, t_port);
  35787                     } else {
  35788                         return BCM_E_NONE;
  35789                     }
  35790                         
  35791                     COMPILER_64_SET(fval64,
  35792                                     SOC_PBMP_WORD_GET(curr_pbmp, 1),
  35793                                     SOC_PBMP_WORD_GET(curr_pbmp, 0));
  35794                     soc_reg64_field_set(unit, reg, &rval64, 
  35795                                         BITMAPf, fval64);
  35796                     rv = soc_reg_set(unit, reg, 
  35797                                         REG_PORT_ANY, 0, rval64);
  35798                 }
  35799             }
  35800         }
  35801 
  35802         /* Allow to set bridging on higig ports as well */
  35803         return _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  35804                 PORT_BRIDGEf, (value) ? 1 : 0);
  35805     }
  35806 #endif /* BCM_TRIUMPH_SUPPORT */
  35807 
  35808     if (SOC_IS_XGS3_SWITCH(unit)) {
  35809         /* Allow to set bridging on higig ports as well */
  35810         rv =_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  35811                 PORT_BRIDGEf, (value) ? 1 : 0);
  35812         BCM_IF_ERROR_RETURN(rv);
  35813 
  35814         if (IS_E_PORT(unit, port) || IS_CPU_PORT(unit, port)) {
  35815 
  35816 #if defined(BCM_RAPTOR_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \
  35817             defined(BCM_SCORPION_SUPPORT)
  35818             if (soc_feature(unit, soc_feature_src_trunk_port_bridge)) {
  35819                 bcm_pbmp_t  pbmp;            /* Port bitmap to update.*/
  35820                 uint32      port_bridge_map;
  35821 #if defined (BCM_RAPTOR_SUPPORT)
  35822                 uint32 port_bridge_map_hi;
  35823 #endif
  35824 
  35825                 SOC_PBMP_CLEAR(pbmp);
  35826                 BCM_IF_ERROR_RETURN
  35827                     (READ_PORT_BRIDGE_BMAPr(unit, &port_bridge_map));
  35828 
  35829                 SOC_PBMP_WORD_SET(pbmp, 0,
  35830                         soc_reg_field_get(unit, PORT_BRIDGE_BMAPr,
  35831                             port_bridge_map, BITMAPf));
  35832 #if defined (BCM_RAPTOR_SUPPORT)
  35833                 if (soc_feature(unit, soc_feature_register_hi)) {
  35834                     BCM_IF_ERROR_RETURN
  35835                         (READ_PORT_BRIDGE_BMAP_HIr(unit,
  35836                                                    &port_bridge_map_hi));
  35837                     SOC_PBMP_WORD_SET(pbmp, 1,
  35838                             soc_reg_field_get(unit, PORT_BRIDGE_BMAP_HIr,
  35839                                 port_bridge_map_hi, BITMAPf));
  35840                 }
  35841 #endif
  35842                 if (!SOC_PBMP_MEMBER(pbmp, port) && value) {
  35843                     SOC_PBMP_PORT_ADD(pbmp, port);
  35844                     soc_reg_field_set(unit, PORT_BRIDGE_BMAPr,
  35845                             &port_bridge_map, BITMAPf,
  35846                             SOC_PBMP_WORD_GET(pbmp, 0));
  35847                     BCM_IF_ERROR_RETURN
  35848                         (WRITE_PORT_BRIDGE_BMAPr(unit, port_bridge_map));
  35849 #if defined (BCM_RAPTOR_SUPPORT)
  35850 
  35851                     if (soc_feature(unit, soc_feature_register_hi)) {
  35852                         soc_reg_field_set(unit, PORT_BRIDGE_BMAP_HIr,
  35853                                 &port_bridge_map_hi, BITMAPf,
  35854                                 SOC_PBMP_WORD_GET(pbmp, 1));
  35855                         BCM_IF_ERROR_RETURN
  35856                             (WRITE_PORT_BRIDGE_BMAP_HIr(unit,
  35857                                                         port_bridge_map_hi));
  35858                     }
  35859 #endif
  35860                 } else if (SOC_PBMP_MEMBER(pbmp, port) && !value) {
  35861                     SOC_PBMP_PORT_REMOVE(pbmp, port);
  35862                     soc_reg_field_set(unit, PORT_BRIDGE_BMAPr,
  35863                             &port_bridge_map, BITMAPf,
  35864                             SOC_PBMP_WORD_GET(pbmp, 0));
  35865                     BCM_IF_ERROR_RETURN
  35866                         (WRITE_PORT_BRIDGE_BMAPr(unit, port_bridge_map));
  35867 #if defined (BCM_RAPTOR_SUPPORT)
  35868                     if (soc_feature(unit, soc_feature_register_hi)) {
  35869                         soc_reg_field_set(unit, PORT_BRIDGE_BMAP_HIr,
  35870                                 &port_bridge_map_hi, BITMAPf,
  35871                                 SOC_PBMP_WORD_GET(pbmp, 1));
  35872                         BCM_IF_ERROR_RETURN
  35873                             (WRITE_PORT_BRIDGE_BMAP_HIr(unit,
  35874                                                         port_bridge_map_hi));
  35875                     }
  35876 #endif
  35877                 }
  35878             }
  35879 #endif /* BCM_RAPTOR_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  35880 
  35881         } else if (IS_HG_PORT(unit, port)) {
  35882 #ifdef BCM_SCORPION_SUPPORT
  35883             if (SOC_REG_IS_VALID(unit, PORT_BRIDGE_MIRROR_BMAPr)) {
  35884                 bcm_pbmp_t  pbmp;            /* Port bitmap to update.*/
  35885                 uint32      port_bridge_mirror_map;
  35886 
  35887                 SOC_PBMP_CLEAR(pbmp);
  35888                 BCM_IF_ERROR_RETURN(READ_PORT_BRIDGE_MIRROR_BMAPr(unit,
  35889                             &port_bridge_mirror_map));
  35890                 SOC_PBMP_WORD_SET(pbmp, 0,
  35891                         soc_reg_field_get(unit, PORT_BRIDGE_MIRROR_BMAPr,
  35892                             port_bridge_mirror_map, BITMAPf));
  35893 
  35894                 if (!SOC_PBMP_MEMBER(pbmp, port) && value) {
  35895                     SOC_PBMP_PORT_ADD(pbmp, port);
  35896                 } else if (SOC_PBMP_MEMBER(pbmp, port) && !value) {
  35897                     SOC_PBMP_PORT_REMOVE(pbmp, port);
  35898                 } else {
  35899                     return BCM_E_NONE;
  35900                 }
  35901 
  35902                 soc_reg_field_set(unit, PORT_BRIDGE_MIRROR_BMAPr,
  35903                         &port_bridge_mirror_map, BITMAPf,
  35904                         SOC_PBMP_WORD_GET(pbmp, 0));
  35905                 BCM_IF_ERROR_RETURN(WRITE_PORT_BRIDGE_MIRROR_BMAPr(unit,
  35906                             port_bridge_mirror_map));
  35907             }
  35908 #endif /* BCM_SCORPION_SUPPORT */
  35909         }
  35910     }
  35911     return rv;
  35912 }
  35913 
  35914 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_REGEX)
  35915 STATIC int
  35916 _bcm_esw_port_regex_control_set(int unit, bcm_gport_t gport,
  35917                                 int udp, int tcp, int enable)
  35918 {
  35919     int vp = -1;
  35920     bcm_port_t local_port;
  35921     source_vp_entry_t svp_entry;
  35922     source_trunk_map_table_entry_t stm_entry;
  35923     ft_dst_port_config_entry_t ftdcfg;
  35924     bcm_module_t my_modid;
  35925     int index;
  35926     int rv;
  35927 
  35928     if (!soc_feature(unit, soc_feature_regex)) {
  35929         return BCM_E_UNAVAIL;
  35930     }
  35931 
  35932     enable = !!enable;
  35933 
  35934     if (BCM_GPORT_IS_MIM_PORT(gport)) {
  35935         vp = BCM_GPORT_MIM_PORT_ID_GET(gport);
  35936         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
  35937             return BCM_E_NOT_FOUND;
  35938         }
  35939     } else if (BCM_GPORT_IS_MPLS_PORT(gport)) {
  35940         vp = BCM_GPORT_MPLS_PORT_ID_GET(gport);
  35941         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
  35942             return BCM_E_NOT_FOUND;
  35943         }
  35944     } else if (BCM_GPORT_IS_WLAN_PORT(gport)) {
  35945         vp = BCM_GPORT_WLAN_PORT_ID_GET(gport);
  35946     }
  35947 
  35948     if (vp >= 0) {
  35949         SOC_IF_ERROR_RETURN
  35950             (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
  35951         if (tcp) {
  35952             soc_SOURCE_VPm_field32_set(unit, &svp_entry,
  35953                                        DPI_TCP_CREATE_ENf, enable);
  35954             tcp = enable;
  35955         } else {
  35956             tcp = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
  35957                                              DPI_TCP_CREATE_ENf);
  35958         }
  35959         if (udp) {
  35960             soc_SOURCE_VPm_field32_set(unit, &svp_entry,
  35961                                        DPI_UDP_CREATE_ENf, enable);
  35962             udp = enable;
  35963         } else {
  35964             udp = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
  35965                                              DPI_UDP_CREATE_ENf);
  35966         }
  35967         if (tcp + udp) {
  35968             soc_SOURCE_VPm_field32_set(unit, &svp_entry, DPI_ENABLEf, 1);
  35969         } else {
  35970             soc_SOURCE_VPm_field32_set(unit, &svp_entry, DPI_ENABLEf, 0);
  35971         }
  35972         BCM_IF_ERROR_RETURN(WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry));
  35973     } else {
  35974         BCM_IF_ERROR_RETURN(
  35975             _bcm_esw_port_gport_validate(unit, gport, &local_port));
  35976         /* Port sanity check. */
  35977         if (!SOC_PORT_ADDRESSABLE(unit, local_port)) {
  35978             return (BCM_E_PORT);
  35979         }
  35980 
  35981         /* Get local module id. */
  35982         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
  35983 
  35984         soc_mem_lock(unit, SOURCE_TRUNK_MAP_TABLEm);
  35985 
  35986         /* Calculate table index. */
  35987         rv = _bcm_esw_src_mod_port_table_index_get(unit, my_modid,
  35988                                                    local_port, &index);
  35989 
  35990         if(BCM_FAILURE(rv)) {
  35991             soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm);
  35992             return rv;
  35993         }
  35994 
  35995         rv = READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY,
  35996                                          index, &stm_entry);
  35997         if(BCM_FAILURE(rv)) {
  35998             soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm);
  35999             return rv;
  36000         }
  36001 
  36002         if (tcp) {
  36003             soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry,
  36004                                                     DPI_TCP_CREATE_ENf, enable);
  36005             tcp = enable;
  36006         } else {
  36007             tcp = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, &stm_entry,
  36008                                                           DPI_TCP_CREATE_ENf);
  36009         }
  36010         if (udp) {
  36011             soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry,
  36012                                                     DPI_UDP_CREATE_ENf, enable);
  36013             udp = enable;
  36014         } else {
  36015             udp = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, &stm_entry,
  36016                                                           DPI_UDP_CREATE_ENf);
  36017         }
  36018         if (tcp + udp) {
  36019             soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry, DPI_ENABLEf, 1);
  36020         } else {
  36021             soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry, DPI_ENABLEf, 0);
  36022         }
  36023 
  36024         rv = WRITE_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ALL,
  36025                                           index, &stm_entry);
  36026 
  36027         soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm);
  36028         if(BCM_FAILURE(rv)) {
  36029             return rv;
  36030         }
  36031 
  36032         SOC_IF_ERROR_RETURN(READ_FT_DST_PORT_CONFIGm(unit, MEM_BLOCK_ANY,
  36033                                                      local_port, &ftdcfg));
  36034         soc_FT_DST_PORT_CONFIGm_field32_set(unit, &ftdcfg,
  36035                                             DPI_TCP_CREATE_ENf, !!tcp);
  36036         soc_FT_DST_PORT_CONFIGm_field32_set(unit, &ftdcfg,
  36037                                             DPI_UDP_CREATE_ENf, !!udp);
  36038         if (tcp + udp) {
  36039             soc_FT_DST_PORT_CONFIGm_field32_set(unit, &ftdcfg, DPI_ENABLEf, 1);
  36040         } else {
  36041             soc_FT_DST_PORT_CONFIGm_field32_set(unit, &ftdcfg, DPI_ENABLEf, 0);
  36042         }
  36043         SOC_IF_ERROR_RETURN(WRITE_FT_DST_PORT_CONFIGm(unit, MEM_BLOCK_ANY,
  36044                                                       local_port, &ftdcfg));
  36045     }
  36046     return BCM_E_NONE;
  36047 }
  36048 
  36049 STATIC int _bcm_esw_port_regex_control_get(int unit, bcm_gport_t gport,
  36050                                            int *udp, int *tcp, int *enable)
  36051 {
  36052     int vp = -1;
  36053     bcm_port_t local_port;
  36054     source_vp_entry_t svp_entry;
  36055     source_trunk_map_table_entry_t stm_entry;
  36056     ft_dst_port_config_entry_t ftdcfg;
  36057     bcm_module_t my_modid;
  36058     int index;
  36059 
  36060     if (!soc_feature(unit, soc_feature_regex)) {
  36061         return BCM_E_UNAVAIL;
  36062     }
  36063 
  36064     if (BCM_GPORT_IS_MIM_PORT(gport)) {
  36065         vp = BCM_GPORT_MIM_PORT_ID_GET(gport);
  36066         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
  36067             return BCM_E_NOT_FOUND;
  36068         }
  36069     } else if (BCM_GPORT_IS_MPLS_PORT(gport)) {
  36070         vp = BCM_GPORT_MPLS_PORT_ID_GET(gport);
  36071         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
  36072             return BCM_E_NOT_FOUND;
  36073         }
  36074     } else if (BCM_GPORT_IS_WLAN_PORT(gport)) {
  36075         vp = BCM_GPORT_WLAN_PORT_ID_GET(gport);
  36076     }
  36077 
  36078     if (vp >= 0) {
  36079         SOC_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry));
  36080         *tcp    = soc_SOURCE_VPm_field32_get(unit, &svp_entry, DPI_TCP_CREATE_ENf);
  36081         *udp    = soc_SOURCE_VPm_field32_get(unit, &svp_entry, DPI_UDP_CREATE_ENf);
  36082         *enable = soc_SOURCE_VPm_field32_get(unit, &svp_entry, DPI_ENABLEf);
  36083     } else {
  36084         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, gport, &local_port));
  36085         /* Port sanity check. */
  36086         if (!SOC_PORT_ADDRESSABLE(unit, local_port)) {
  36087             return (BCM_E_PORT);
  36088         }
  36089 
  36090         /* Get local module id. */
  36091         BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
  36092 
  36093         /* Calculate table index. */
  36094         BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, my_modid,
  36095                                                                   local_port, &index));
  36096 
  36097         BCM_IF_ERROR_RETURN(READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY,
  36098                                                          index, &stm_entry));
  36099         *tcp = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, &stm_entry,
  36100                                                        DPI_TCP_CREATE_ENf);
  36101         *udp = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, &stm_entry,
  36102                                                        DPI_UDP_CREATE_ENf);
  36103         SOC_IF_ERROR_RETURN(READ_FT_DST_PORT_CONFIGm(unit, MEM_BLOCK_ANY,
  36104                                                      local_port, &ftdcfg));
  36105         *enable = soc_FT_DST_PORT_CONFIGm_field32_get(unit, &ftdcfg, DPI_ENABLEf);
  36106     }
  36107     return BCM_E_NONE;
  36108 }
  36109 #endif
  36110 
  36111 #if defined(BCM_SHADOW_SUPPORT)
  36112 STATIC int
  36113 _bcm_port_type_shadow_support (int unit, bcm_port_t port,
  36114                                     bcm_port_control_t type)
  36115 {
  36116     LOG_INFO(BSL_LS_BCM_PORT,
  36117              (BSL_META_U(unit,
  36118                          "_bcm_port_type_shadow_support : u=%d p=%d type=%d\n"),
  36119               unit, port, (int)type));
  36120 
  36121     switch (type)
  36122     {
  36123         /* Shadoow supported port control types */
  36124         case bcmPortControlManagementPacketIp6Reserved:
  36125         case bcmPortControlManagementPacketIp4Reserved:
  36126         case bcmPortControlManagementPacketLinkConstrained:
  36127         case bcmPortControlManagementPacketGarp:
  36128         case bcmPortControlManagementPacketCos:
  36129         case bcmPortControlManagementPacketColor:
  36130         case bcmPortControlTaggedL3PacketPktPri:
  36131         case bcmPortControlTaggedMPLSPacketPktPri:
  36132         case bcmPortControlTaggedMPLSL3PacketPktPri:
  36133         case bcmPortControlRxEnable:
  36134         case bcmPortControlTxEnable:
  36135         case bcmPortControlPFCEthertype:
  36136         case bcmPortControlPFCOpcode:
  36137         case bcmPortControlPFCReceive:
  36138         case bcmPortControlPFCTransmit:
  36139         case bcmPortControlPFCClasses:
  36140         case bcmPortControlPFCPassFrames:
  36141         case bcmPortControlPFCDestMacOui:
  36142         case bcmPortControlPFCDestMacNonOui:
  36143         case bcmPortControlPFCRefreshTime:
  36144         case bcmPortControlPFCXOffTime:
  36145         case bcmPortControlEEETransmitWakeTime:
  36146         case bcmPortControlEEEReceiveWakeTime:
  36147         case bcmPortControlEEETransmitSleepTime:
  36148         case bcmPortControlEEEReceiveSleepTime:
  36149         case bcmPortControlEEETransmitQuietTime:
  36150         case bcmPortControlEEEReceiveQuietTime:
  36151         case bcmPortControlEEETransmitRefreshTime:
  36152         case bcmPortControlEEEEnable:
  36153         case bcmPortControlEEETransmitIdleTime:
  36154         case bcmPortControlEEETransmitEventCount:
  36155         case bcmPortControlEEETransmitDuration:
  36156         case bcmPortControlEEEReceiveEventCount:
  36157         case bcmPortControlEEEReceiveDuration:
  36158         case bcmPortControlEEETransmitIdleTimeHund:
  36159         case bcmPortControlEEETransmitWakeTimeHund:
  36160         case bcmPortControlEEETransmitMinLPITime:
  36161         case bcmPortControlEEETransmitMinLPITimeHund:
  36162             if (IS_IL_PORT(unit, port)) { /* No support for IL port type */
  36163                 return FALSE;
  36164             }
  36165             /* Fall through */
  36166         case bcmPortControlPrbsMode:
  36167         case bcmPortControlPrbsPolynomial:
  36168         case bcmPortControlPrbsTxEnable:
  36169         case bcmPortControlPrbsRxEnable:
  36170         case bcmPortControlPrbsTxInvertData:
  36171         case bcmPortControlPrbsRxStatus:
  36172         case bcmPortControlLanes:
  36173             return TRUE;
  36174 
  36175         default:
  36176             return FALSE;
  36177     }
  36178 }
  36179 #endif /* BCM_SHADOW_SUPPORT */
  36180 
  36181 static int
  36182 _bcm_esw_mac_rx_control(int unit, bcm_port_t port, uint8 optype, int *enable)
  36183 {
  36184     int rv = BCM_E_NONE;
  36185 
  36186     if (SOC_USE_PORTCTRL(unit)) {
  36187         return(bcmi_esw_portctrl_mac_rx_control(unit, port, optype, enable));
  36188     } else {
  36189         PORT_LOCK(unit);
  36190         if (optype) { /* get */
  36191             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  36192                                  SOC_MAC_CONTROL_RX_SET, enable);
  36193         } else { /* set */
  36194              rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  36195                                   SOC_MAC_CONTROL_RX_SET, *enable);
  36196         }
  36197         PORT_UNLOCK(unit);
  36198     }
  36199     return rv;
  36200 }
  36201 /*
  36202  * Function:
  36203  *     bcm_esw_port_enqueue_set
  36204  * Description:
  36205  *      This function enable and disable the enqueuing
  36206  *      packets on a port
  36207  * Parameters:
  36208  *      unit      - (IN) Device number
  36209  *      port      - (IN) Port to resolve
  36210  *      enable    - (IN) TRUE to enable enqueuing
  36211  *                       FALSE to disable enqueuing
  36212  * Return Value:
  36213  *      BCM_E_XXX
  36214  */
  36215 
  36216 static int
  36217 bcm_esw_port_enqueue_set(int unit, bcm_port_t port,int enable)
  36218 {
  36219     int rv = BCM_E_NONE;
  36220 
  36221     /* Make sure port module is initialized. */
  36222     PORT_INIT(unit);
  36223 #ifdef BCM_HELIX5_SUPPORT
  36224     if (SOC_IS_HELIX5(unit)) {
  36225         BCM_IF_ERROR_RETURN
  36226             (_bcm_hx5_port_enqueue_set(unit, port, enable));
  36227     } else
  36228 #endif
  36229 #ifdef BCM_TRIDENT3_SUPPORT
  36230     if (SOC_IS_TRIDENT3X(unit)) {
  36231         int link;
  36232         rv = bcm_esw_port_link_status_get(unit, port, &link);
  36233         if (BCM_FAILURE(rv)) {
  36234             return rv;
  36235         }
  36236         if (link == BCM_PORT_LINK_STATUS_UP) {
  36237             /* FALSE to disable enqueuing and MMU cells drain */
  36238             PORT_LOCK(unit);
  36239             if (SOC_USE_PORTCTRL(unit)) {
  36240                 rv = bcmi_esw_portctrl_mac_enable_set(unit, port, enable);
  36241             } else {
  36242                 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, enable);
  36243             }
  36244             if (BCM_FAILURE(rv)) {
  36245                 PORT_UNLOCK(unit);
  36246                 return rv;
  36247             }
  36248             PORT_UNLOCK(unit);
  36249         }
  36250     } else
  36251 #endif
  36252 #ifdef BCM_TOMAHAWK_SUPPORT
  36253     if (SOC_IS_TOMAHAWKX(unit)) {
  36254         int link;
  36255         rv = bcm_esw_port_link_status_get(unit, port, &link);
  36256         if (BCM_FAILURE(rv)) {
  36257             return rv;
  36258         }
  36259         if (link == BCM_PORT_LINK_STATUS_UP || SOC_FAST_REBOOT(unit)) {
  36260             /* FALSE to disable enqueuing and MMU cells drain */
  36261             PORT_LOCK(unit);
  36262             if (SOC_USE_PORTCTRL(unit)) {
  36263                 rv = bcmi_esw_portctrl_mac_enable_set(unit, port, enable);
  36264             } else {
  36265                 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, enable);
  36266             }
  36267             if (BCM_FAILURE(rv)) {
  36268                 PORT_UNLOCK(unit);
  36269                 return rv;
  36270             }
  36271             PORT_UNLOCK(unit);
  36272         }
  36273     } else
  36274 #endif
  36275 #ifdef BCM_MONTEREY_SUPPORT
  36276     if (SOC_IS_MONTEREY(unit)) {
  36277         BCM_IF_ERROR_RETURN
  36278             (_bcm_mn_port_enqueue_set(unit,port,enable));
  36279     } else
  36280 #endif
  36281 #ifdef BCM_APACHE_SUPPORT
  36282     if (SOC_IS_APACHE(unit)) {
  36283         BCM_IF_ERROR_RETURN
  36284             (_bcm_ap_port_enqueue_set(unit,port,enable));
  36285     } else
  36286 #endif
  36287 #ifdef BCM_TRIDENT2_SUPPORT
  36288     if (SOC_IS_TD2_TT2(unit)) {
  36289         BCM_IF_ERROR_RETURN
  36290             (_bcm_td2_port_enqueue_set(unit,port,enable));
  36291     } else
  36292 #endif
  36293 #ifdef BCM_TRIDENT_SUPPORT
  36294     if (SOC_IS_TD_TT(unit)) {
  36295         BCM_IF_ERROR_RETURN
  36296             (_bcm_td_port_enqueue_set(unit,port,enable));
  36297     } else
  36298 #endif
  36299 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT)
  36300     if (SOC_IS_TRIUMPH3(unit) || SOC_IS_HELIX4(unit)) {
  36301          BCM_IF_ERROR_RETURN
  36302             (_bcm_tr3_port_enqueue_set(unit,port,enable));
  36303     } else
  36304 #endif /* BCM_TRIUMPH3_SUPPORT */
  36305 #ifdef BCM_KATANA2_SUPPORT
  36306     if (SOC_IS_KATANA2(unit)) {
  36307         BCM_IF_ERROR_RETURN
  36308             (_bcm_kt2_port_enqueue_set(unit,port,enable));
  36309     } else
  36310 #endif
  36311     {
  36312         return BCM_E_UNAVAIL;
  36313     }
  36314     return rv;
  36315 }
  36316 
  36317 /*
  36318  * Function:
  36319  *     bcm_esw_port_enqueue_get
  36320  * Description:
  36321  *      This function get enqueuing state
  36322  *      packets on a port
  36323  * Parameters:
  36324  *      unit      - (IN) Device number
  36325  *      port      - (IN) Port to resolve
  36326  *      enable    - (OUT) TRUE to when enqueuing is enabled
  36327  *                       FALSE to when enqueuing is disabled
  36328  * Return Value:
  36329  *      BCM_E_XXX
  36330  */
  36331 static int
  36332 bcm_esw_port_enqueue_get(int unit, bcm_port_t port, int *enable)
  36333 {
  36334     int rv = BCM_E_NONE;
  36335 
  36336     /* Make sure port module is initialized. */
  36337     PORT_INIT(unit);
  36338 #ifdef BCM_HELIX5_SUPPORT
  36339     if (SOC_IS_HELIX5(unit)) {
  36340         BCM_IF_ERROR_RETURN
  36341             (_bcm_hx5_port_enqueue_get(unit, port, enable));
  36342     } else
  36343 #endif
  36344 #ifdef BCM_TRIDENT3_SUPPORT
  36345     if (SOC_IS_TRIDENT3X(unit)) {
  36346         return BCM_E_UNAVAIL;
  36347     } else
  36348 #endif
  36349 #ifdef BCM_TOMAHAWK_SUPPORT
  36350     if (SOC_IS_TOMAHAWKX(unit)) {
  36351         BCM_IF_ERROR_RETURN
  36352             (_bcm_th_port_enqueue_get(unit, port, enable));
  36353     } else
  36354 #endif
  36355 #ifdef BCM_APACHE_SUPPORT
  36356     if (SOC_IS_APACHE(unit)) {
  36357         BCM_IF_ERROR_RETURN
  36358             (_bcm_ap_port_enqueue_get(unit,port,enable));
  36359     } else
  36360 #endif
  36361 #ifdef BCM_TRIDENT2_SUPPORT
  36362     if (SOC_IS_TD2_TT2(unit)) {
  36363         BCM_IF_ERROR_RETURN
  36364             (_bcm_td2_port_enqueue_get(unit,port,enable));
  36365     } else
  36366 #endif
  36367 #ifdef BCM_TRIDENT_SUPPORT
  36368     if (SOC_IS_TD_TT(unit)) {
  36369         BCM_IF_ERROR_RETURN
  36370             (_bcm_td_port_enqueue_get(unit,port,enable));
  36371     }  else
  36372 #endif
  36373     {
  36374         return BCM_E_UNAVAIL;
  36375     }
  36376     return rv;
  36377 }
  36378 
  36379 /*
  36380  * Function:
  36381  *     bcm_esw_port_drain_cells
  36382  * Description:i
  36383  *      This function will drains the MMU cells which the port
  36384  *      is holding
  36385  * Parameters:
  36386  *      unit      - (IN) Device number
  36387  *      port      - (IN) Port to resolve
  36388  *      value     - (IN) TRUE to drain the cells
  36389  *                       FALSE to just ignore
  36390  * Return Value:
  36391  *      BCM_E_XXX
  36392  */
  36393 static int
  36394 bcm_esw_port_drain_cells(int unit, bcm_port_t port, int value)
  36395 {
  36396     int rv = BCM_E_NONE;
  36397 
  36398     /* Make sure port module is initialized. */
  36399     PORT_INIT(unit);
  36400     if (value == FALSE ) {
  36401         return rv;
  36402     }
  36403 #ifdef BCM_TRIDENT3_SUPPORT
  36404     if (SOC_IS_TRIDENT3X(unit)) {
  36405         if (IS_CPU_PORT(unit, port)) {
  36406             return BCM_E_PORT;
  36407         }
  36408         /* MMU cells were drained when enqueuing is disabled */
  36409         return rv;
  36410     } else
  36411 #endif
  36412 #ifdef BCM_TOMAHAWK_SUPPORT
  36413     if (SOC_IS_TOMAHAWKX(unit)) {
  36414         if (IS_CPU_PORT(unit, port)) {
  36415             return BCM_E_PORT;
  36416         }
  36417         /* MMU cells were drained when enqueuing is disabled */
  36418         return rv;
  36419 
  36420     } else
  36421 #endif
  36422 #ifdef BCM_MONTEREY_SUPPORT
  36423     if (SOC_IS_MONTEREY(unit)) {
  36424         BCM_IF_ERROR_RETURN
  36425             (bcm_monterey_port_drain_cells(unit, port));
  36426     } else
  36427 #endif
  36428 #ifdef BCM_APACHE_SUPPORT
  36429     if (SOC_IS_APACHE(unit)) {
  36430         BCM_IF_ERROR_RETURN
  36431             (bcm_apache_port_drain_cells(unit, port));
  36432     } else
  36433 #endif
  36434 #ifdef BCM_TRIDENT2_SUPPORT
  36435     if (SOC_IS_TD2_TT2(unit)) {
  36436         BCM_IF_ERROR_RETURN
  36437             (bcm_td2_port_drain_cells(unit, port));
  36438     } else
  36439 #endif
  36440 #ifdef BCM_TRIDENT_SUPPORT
  36441     if (SOC_IS_TD_TT(unit)) {
  36442         BCM_IF_ERROR_RETURN
  36443             (bcm_td_port_drain_cells(unit, port));
  36444     } else
  36445 #endif
  36446 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT)
  36447         if (SOC_IS_TRIUMPH3(unit) || SOC_IS_HELIX4(unit)) {
  36448         BCM_IF_ERROR_RETURN
  36449             (bcm_tr3_port_drain_cells(unit, port));
  36450         } else
  36451 #endif /* BCM_TRIUMPH3_SUPPORT */
  36452 #ifdef BCM_KATANA2_SUPPORT
  36453     if (SOC_IS_KATANA2(unit)) {
  36454         BCM_IF_ERROR_RETURN
  36455             (bcm_kt2_port_drain_cells(unit, port));
  36456     } else
  36457 #endif
  36458 
  36459     {
  36460         return BCM_E_UNAVAIL;
  36461     }
  36462     return rv;
  36463 }
  36464 
  36465 /*
  36466  * Function:
  36467  *     _bcm_esw_port_llfc_set
  36468  * Description:
  36469  *      This function will set the LLFC_RX/TX_ENABLE field,
  36470  *       and LLFC_EN field can possibly be set accordingly.
  36471  * Parameters:
  36472  *      unit - (IN) Device number
  36473  *      port - (IN) Port to resolve
  36474  *      type - (IN) Enum value of the feature
  36475  *      value - (IN) Value to be set
  36476  * Return Value:
  36477  *      BCM_E_XXX
  36478  */
  36479 STATIC int
  36480 _bcm_esw_port_llfc_set(int unit, bcm_port_t port, bcm_port_control_t type, int value)
  36481 {
  36482     int rv = BCM_E_UNAVAIL;
  36483     soc_reg_t port_config;
  36484     int llfc_enable;
  36485 #ifdef BCM_TRIDENT2_SUPPORT
  36486     uint32 rval;
  36487 #endif
  36488 
  36489     if(SOC_USE_PORTCTRL(unit)) {
  36490         return(bcmi_esw_portctrl_llfc_set(unit,port, type, value));
  36491     }
  36492 
  36493     switch(type) {
  36494     case bcmPortControlLLFCReceive:
  36495 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  36496     case bcmPortControlSAFCReceive:
  36497 #endif
  36498 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  36499         if (SOC_IS_XGS3_SWITCH(unit)) {
  36500 
  36501             if (!SOC_PORT_VALID(unit, port)) {
  36502                 return BCM_E_PORT;
  36503             }
  36504 
  36505             BCM_IF_ERROR_RETURN
  36506                 (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  36507                                  SOC_MAC_CONTROL_LLFC_RX_ENABLE, value));
  36508             if (value == 0) {
  36509                 BCM_IF_ERROR_RETURN
  36510                     (MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  36511                                      SOC_MAC_CONTROL_LLFC_TX_ENABLE,
  36512                                      &llfc_enable));
  36513             } else {
  36514                 llfc_enable = TRUE;
  36515             }
  36516 
  36517             if (SOC_REG_FIELD_VALID(unit, XLPORT_CONFIGr, LLFC_ENf)) {
  36518                 port_config = XLPORT_CONFIGr;
  36519             } else if (SOC_REG_FIELD_VALID(unit, XPORT_CONFIGr, LLFC_ENf)) {
  36520                 port_config = XPORT_CONFIGr;
  36521             } else if (SOC_REG_FIELD_VALID(unit, PORT_CONFIGr, LLFC_ENf)) {
  36522                 port_config = PORT_CONFIGr;
  36523             } else {
  36524                 port_config = INVALIDr;
  36525             }
  36526 
  36527             if (port_config != INVALIDr){
  36528                 BCM_IF_ERROR_RETURN
  36529                     (soc_reg_field32_modify(unit, port_config, port, LLFC_ENf,
  36530                                             llfc_enable ? 1 : 0));
  36531             }
  36532 
  36533             rv = BCM_E_NONE;
  36534         }
  36535 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  36536         break;
  36537     case bcmPortControlLLFCTransmit:
  36538 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  36539     case bcmPortControlSAFCTransmit:
  36540 #endif
  36541 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  36542         if (SOC_IS_XGS3_SWITCH(unit)) {
  36543             if (!SOC_PORT_VALID(unit, port)) {
  36544                 return BCM_E_PORT;
  36545             }
  36546 
  36547             BCM_IF_ERROR_RETURN
  36548                 (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  36549                                  SOC_MAC_CONTROL_LLFC_TX_ENABLE, value));
  36550             if (value == 0) {
  36551                 BCM_IF_ERROR_RETURN
  36552                     (MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  36553                                      SOC_MAC_CONTROL_LLFC_RX_ENABLE,
  36554                                      &llfc_enable));
  36555             } else {
  36556                 llfc_enable = TRUE;
  36557             }
  36558 
  36559             if (SOC_REG_FIELD_VALID(unit, XLPORT_CONFIGr, LLFC_ENf)) {
  36560                 port_config = XLPORT_CONFIGr;
  36561             } else if (SOC_REG_FIELD_VALID(unit, XPORT_CONFIGr, LLFC_ENf)) {
  36562                 port_config = XPORT_CONFIGr;
  36563             } else if (SOC_REG_FIELD_VALID(unit, PORT_CONFIGr, LLFC_ENf)) {
  36564                 port_config = PORT_CONFIGr;
  36565             } else {
  36566                 port_config = INVALIDr;
  36567             }
  36568 
  36569             if (port_config != INVALIDr){
  36570                 BCM_IF_ERROR_RETURN
  36571                     (soc_reg_field32_modify(unit, port_config, port, LLFC_ENf,
  36572                                             llfc_enable ? 1 : 0));
  36573             }
  36574 
  36575 #ifdef BCM_TRIDENT2_SUPPORT
  36576             if (SOC_IS_TD2_TT2(unit)) {
  36577                 SOC_IF_ERROR_RETURN
  36578                     (soc_reg32_get(unit, THDI_INPUT_PORT_XON_ENABLESr,
  36579                                    port, 0, &rval));
  36580                 
  36581                 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
  36582                                   PORT_PRI_XON_ENABLEf,
  36583                                   value ? 0xffff : 0);
  36584                 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
  36585                                   PORT_PAUSE_ENABLEf, value ? 0 : 1);
  36586                 
  36587                 SOC_IF_ERROR_RETURN
  36588                     (soc_reg32_set(unit, THDI_INPUT_PORT_XON_ENABLESr,
  36589                                    port, 0, rval));
  36590             }
  36591 #endif
  36592             
  36593             rv = BCM_E_NONE;
  36594         }
  36595 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  36596         break;
  36597     default:
  36598         break;
  36599     }
  36600 
  36601     return rv;
  36602 }
  36603 
  36604 /*
  36605  * Function:
  36606  *     _bcm_esw_port_llfc_get
  36607  * Description:
  36608  *      This function will get the LLFC_TX/RX_ENABLE field.
  36609  * Parameters:
  36610  *      unit - (IN) Device number
  36611  *      port - (IN) Port to resolve
  36612  *      type - (IN) Enum value of the feature
  36613  *      value - (OUT) Current value of the port feature
  36614  * Return Value:
  36615  *      BCM_E_XXX
  36616  */
  36617 STATIC int
  36618 _bcm_esw_port_llfc_get(int unit, bcm_port_t port, bcm_port_control_t type, int *value)
  36619 {
  36620     int rv = BCM_E_UNAVAIL;
  36621 
  36622     if(SOC_USE_PORTCTRL(unit)) {
  36623         return(bcmi_esw_portctrl_llfc_get(unit,port, type, value));
  36624     }    
  36625 
  36626     switch(type) {
  36627     case bcmPortControlLLFCReceive:
  36628 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  36629     case bcmPortControlSAFCReceive:
  36630 #endif
  36631 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  36632         if (SOC_IS_XGS3_SWITCH(unit)) {
  36633             if (!SOC_PORT_VALID(unit, port)) {
  36634                 return BCM_E_PORT;
  36635             }
  36636             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  36637                                  SOC_MAC_CONTROL_LLFC_RX_ENABLE, value);
  36638         }
  36639 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  36640         break;
  36641     case bcmPortControlLLFCTransmit:
  36642 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  36643     case bcmPortControlSAFCTransmit:
  36644 #endif
  36645 #if defined(BCM_XGS3_SWITCH_SUPPORT)
  36646         if (SOC_IS_XGS3_SWITCH(unit)) {
  36647             if (!SOC_PORT_VALID(unit, port)) {
  36648                 return BCM_E_PORT;
  36649             }
  36650             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  36651                                  SOC_MAC_CONTROL_LLFC_TX_ENABLE, value);
  36652         }
  36653 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  36654         break;
  36655     default:
  36656         break;
  36657     }
  36658 
  36659     return rv;
  36660 }
  36661 
  36662 #ifdef BCM_TRIUMPH3_SUPPORT
  36663 STATIC int
  36664 _bcm_tr3_port_lanes_set(int unit, bcm_port_t port, int value)
  36665 {
  36666     int i, incr = 1, ports = 3, okay;
  36667     int rv = BCM_E_NONE, rv1, old_value;
  36668     int retry_count = 0, mode_change = -1;
  36669     uint16 phy;
  36670     uint32 flags;
  36671     soc_info_t *si = &SOC_INFO(unit);
  36672     int phy_port = -1;
  36673     int old_port[4];
  36674     if (!SOC_PORT_VALID(unit, port)) {
  36675         return BCM_E_PORT;
  36676     }
  36677 
  36678     /* coverity[overrun-local : FALSE] */
  36679     phy_port = si->port_l2p_mapping[port];
  36680     for (i = 0; i < 4; i++) {
  36681         old_port[i] = si->flex_port_p2l_mapping[phy_port+i];
  36682     }
  36683 
  36684 _reconfig:
  36685     rv = soc_tr3_port_lanes_set(unit, port, value, &old_value, &mode_change);
  36686     if (rv != SOC_E_NONE) {
  36687         return rv;
  36688     }
  36689     if (value == 1) {
  36690 #ifdef BCM_HELIX4_SUPPORT
  36691         /* coverity[overrun-local : FALSE] */
  36692         if (SOC_IS_HELIX4(unit) && ((_tr3_port_config_id[unit] == 410) &&
  36693                 (si->port_l2p_mapping[port] == 57 || si->port_l2p_mapping[port] == 61))){
  36694             ports = 1;
  36695         }else if(SOC_IS_HELIX4(unit) && (((_tr3_port_config_id[unit] == 463) ||
  36696                (_tr3_port_config_id[unit] == 413)) && (si->port_l2p_mapping[port] == 57 ||
  36697                si->port_l2p_mapping[port] == 61))){
  36698            ports = 2;
  36699         }
  36700         else
  36701 #endif
  36702         /* coverity[overrun-local : FALSE] */
  36703         if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit) &&
  36704             ((_tr3_port_config_id[unit] == 112 || _tr3_port_config_id[unit] == 12) &&
  36705             (si->port_l2p_mapping[port] == 73 || si->port_l2p_mapping[port] == 77))) {
  36706             ports = 1;
  36707         } else {
  36708             ports = 4;
  36709         }
  36710     } else if (value == 2) {
  36711 #ifdef BCM_HELIX4_SUPPORT
  36712     if(SOC_IS_HELIX4(unit) &&((_tr3_port_config_id[unit] == 463) ||
  36713            _tr3_port_config_id[unit] == 413) && (si->port_l2p_mapping[port] == 57 ||
  36714            si->port_l2p_mapping[port] == 61)){
  36715            ports = 1;
  36716         incr = 2;
  36717        }
  36718        else
  36719 #endif
  36720        {
  36721            incr = 2;
  36722        }
  36723     } else if (value == 4) {
  36724         ports = 1;
  36725     }
  36726     if (value == 2 && old_value == 1) {
  36727 #ifdef BCM_HELIX4_SUPPORT
  36728     if(SOC_IS_HELIX4(unit) && (((_tr3_port_config_id[unit] == 463) ||
  36729         (_tr3_port_config_id[unit] == 413)) && (si->port_l2p_mapping[port] == 57 ||
  36730          si->port_l2p_mapping[port] == 61))){
  36731         SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, si->port_p2l_mapping[si->port_l2p_mapping[port] + 1]));
  36732       }else
  36733 #endif
  36734       {
  36735         SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 1));
  36736         SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 3));
  36737       }
  36738     } else if (value == 4 && old_value == 1) {
  36739         if ((SOC_IS_HELIX4(unit) && (_tr3_port_config_id[unit] == 410)) ||
  36740             (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit) &&
  36741             (_tr3_port_config_id[unit] == 112 || _tr3_port_config_id[unit] == 12))){
  36742             if (old_port[1] > 0) {
  36743                 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, old_port[1]));
  36744             }
  36745             if (old_port[2] > 0) {
  36746                 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, old_port[2]));
  36747             }
  36748             if (old_port[3] > 0) {
  36749                 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, old_port[3]));
  36750             }
  36751         } else {
  36752             SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 1));
  36753             SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 2));
  36754             SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 3));
  36755         }
  36756     } else if (value == 4 && old_value == 2) {
  36757         SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 2));
  36758     }
  36759     for (i = 0; i < ports; i+=incr) {
  36760         flags = 0;
  36761         phy = soc_property_port_get(unit, port + i, spn_FLEX_PORT_PHY_ADDR, 0);
  36762         if (!phy) {
  36763             SOC_IF_ERROR_RETURN(soc_tr3_phy_addr_get(unit, port + i, &phy));
  36764             flags = _SHR_PORT_PHY_INTERNAL;
  36765         }
  36766         SOC_IF_ERROR_RETURN(soc_phy_cfg_addr_set(unit, port + i, flags, phy));
  36767         BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port + i, &okay));
  36768         LOG_VERBOSE(BSL_LS_BCM_PORT,
  36769                     (BSL_META_U(unit,
  36770                                 "Port %d probe: %d\n"), port + i, okay));
  36771         if (!okay) {
  36772             return BCM_E_INTERNAL;
  36773         }
  36774         BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port + i, TRUE));
  36775     }
  36776 #ifdef BCM_WARM_BOOT_SUPPORT
  36777     if (SOC_WARM_BOOT(unit)) {
  36778         return rv;
  36779     }
  36780 #endif /* BCM_WARM_BOOT_SUPPORT */
  36781 
  36782     for (i = 0; i < ports; i+=incr) {
  36783         if (SOC_PBMP_MEMBER(si->port.disabled_bitmap, port+i)) {
  36784             continue;
  36785         }
  36786         rv1 = _bcm_tr3_port_ur_chk(unit, ports, port + i);
  36787         if (rv1 == BCM_E_PORT) {
  36788             /* Error encountered in the newly created flex ports.
  36789                Lets revert back to old mode and retry if retry count not exceeded */
  36790             if (++retry_count > _BCM_TR3_PORT_UR_RETRY_MAX) {
  36791                 return BCM_E_INTERNAL;
  36792             }
  36793             rv = soc_tr3_port_lanes_set(unit, port, old_value, &old_value, &mode_change);
  36794             if (rv != SOC_E_NONE) {
  36795                 return rv;
  36796             }
  36797             goto _reconfig;
  36798         }
  36799         if (rv1 != BCM_E_NONE) {
  36800             return rv1;
  36801         }
  36802     }
  36803 
  36804     /* Note: Following is currently a brute force solution */
  36805     for (i = 0; i < ports; i+=incr) {
  36806         if (mode_change == BCM_PORT_ENCAP_HIGIG) {
  36807             /* coverity[overrun-call : FALSE] */
  36808             BCM_IF_ERROR_RETURN
  36809                 (_bcm_port_encap_xport_set(unit, port + i, BCM_PORT_ENCAP_HIGIG,
  36810                                            TRUE));
  36811         } else if (mode_change == BCM_PORT_ENCAP_IEEE) {
  36812             /* coverity[overrun-call : FALSE] */
  36813             BCM_IF_ERROR_RETURN
  36814                 (_bcm_port_encap_xport_set(unit, port + i, BCM_PORT_ENCAP_IEEE,
  36815                                            TRUE));
  36816         }
  36817     }
  36818     return rv;
  36819 }
  36820 
  36821 STATIC int
  36822 _bcm_tr3_port_lanes_get(int unit, bcm_port_t port, int *value)
  36823 {
  36824     int rv = BCM_E_NONE;
  36825     if (!SOC_PORT_VALID(unit, port)) {
  36826         return BCM_E_PORT;
  36827     }
  36828     rv = soc_tr3_port_lanes_get(unit, port, value);
  36829     return rv;
  36830 }
  36831 #endif /* BCM_TRIUMPH3_SUPPORT */
  36832 
  36833 #ifdef BCM_TRIDENT_SUPPORT
  36834 STATIC int
  36835 _bcm_td_port_lanes_set(int unit, bcm_port_t port, int value)
  36836 {
  36837     soc_info_t *si;
  36838     int rv, okay, i;
  36839     uint32 rval, phy_mode, core_mode;
  36840     uint32 reset_status;
  36841     bcm_port_t phy_port;
  36842 
  36843     rv = READ_XLPORT_MODE_REGr(unit, port, &rval);
  36844     if (BCM_SUCCESS(rv)) {
  36845         phy_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval,
  36846                                      PHY_PORT_MODEf);
  36847         core_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval,
  36848                                      CORE_PORT_MODEf);
  36849         if (phy_mode == 0) { /* single mode */
  36850             /* Case of 40G port --> 10G XFI */
  36851             if (value == 1) {
  36852                 SOC_INFO(unit).port_speed_max[port]=10000;
  36853             }
  36854         } else if (phy_mode == 1) { /* dual mode */
  36855             if (value != 2 && value != 4) {
  36856                 rv = BCM_E_PARAM;
  36857             } else if (value == 4) {
  36858                 core_mode = 0;
  36859                 soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, CORE_PORT_MODEf, core_mode);
  36860                 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MODE_REGr(unit, port, rval));
  36861             }
  36862         } else {  /* phy_mode == 2 */
  36863             if (value == 4) {
  36864                 /* 10G XFI --> 10G XAUI or 10G XFI --> 40G */
  36865                 if (core_mode == 0) {
  36866                     /* 10GXFI --> 40G */
  36867                     SOC_INFO(unit).port_speed_max[port]=40000;
  36868                 }
  36869             }
  36870         }
  36871     }
  36872     if (BCM_SUCCESS(rv)) {
  36873         si = &SOC_INFO(unit);
  36874         phy_port = si->port_l2p_mapping[port];
  36875         for (i = 0; i < value; i++) {
  36876             if ((si->port_p2l_mapping[phy_port + i]) == -1) {
  36877                 continue;
  36878             }
  36879             rv = soc_phyctrl_detach
  36880                 (unit, si->port_p2l_mapping[phy_port + i]);
  36881             if (BCM_FAILURE(rv)) {
  36882                 break;
  36883             }
  36884         }
  36885     }
  36886     if (BCM_SUCCESS(rv)) {
  36887         si = &SOC_INFO(unit);
  36888         si->port_num_lanes[port] = value;
  36889         if (BCM_SUCCESS(rv)) {
  36890             rv = _bcm_port_phy_probe(unit, port, &okay);
  36891         }
  36892     }
  36893 
  36894     /* Do XMAC reset when port mode is changed */
  36895     SOC_IF_ERROR_RETURN(READ_XLPORT_XMAC_CONTROLr(unit, port, &rval));
  36896     reset_status = soc_reg_field_get(unit, XLPORT_XMAC_CONTROLr, rval, XMAC_RESETf);
  36897     if (reset_status != 1) {
  36898         soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 1);
  36899         SOC_IF_ERROR_RETURN(WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval));
  36900         sal_udelay(10);
  36901         soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 0);
  36902         SOC_IF_ERROR_RETURN(WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval));
  36903     }
  36904 
  36905     return rv;
  36906 }
  36907 #endif /* BCM_TRIDENT_SUPPORT */
  36908 
  36909 #ifdef BCM_TRIDENT2_SUPPORT
  36910 STATIC int
  36911 _bcm_td2_port_lanes_set(int unit, bcm_port_t port_base, int lanes)
  36912 {
  36913     soc_info_t *si = &SOC_INFO(unit);
  36914     soc_td2_port_lanes_t lanes_ctrl;
  36915     int port, i;
  36916     int enable, okay;
  36917     soc_control_t *soc = SOC_CONTROL(unit);
  36918 
  36919     if(SOC_USE_PORTCTRL(unit)) {
  36920         return(bcmi_esw_td2_portctrl_lanes_set(unit, port_base, lanes));
  36921     }
  36922 
  36923     sal_memset(&lanes_ctrl, 0, sizeof(lanes_ctrl));
  36924     lanes_ctrl.port_base = port_base;
  36925     lanes_ctrl.lanes = lanes;
  36926     SOC_IF_ERROR_RETURN
  36927         (soc_trident2_port_lanes_validate(unit, &lanes_ctrl));
  36928 
  36929     if (lanes_ctrl.lanes == lanes_ctrl.cur_lanes) {
  36930         return BCM_E_NONE;
  36931     }
  36932 
  36933     /* All existing ports are required to be disasbled */
  36934     SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port_base, &enable));
  36935     if (enable) {
  36936         return BCM_E_BUSY;
  36937     }
  36938     if (lanes_ctrl.lanes > lanes_ctrl.cur_lanes) { /* port(s) to be removed */
  36939         for (i = 0; i < lanes_ctrl.phy_ports_len; i++) {
  36940             port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]];
  36941             SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &enable));
  36942             if (enable) {
  36943                 return BCM_E_BUSY;
  36944             }
  36945         }
  36946     }
  36947 
  36948     SOC_IF_ERROR_RETURN
  36949         (soc_trident2_port_lanes_set(unit, &lanes_ctrl));
  36950 
  36951     /* Detach PHY on all existing port(s) */
  36952     SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port_base));
  36953     if (lanes_ctrl.lanes > lanes_ctrl.cur_lanes) { /* port(s) to be removed */
  36954         for (i = 0; i < lanes_ctrl.phy_ports_len; i++) {
  36955             port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]];
  36956             SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port));
  36957             COUNTER_LOCK(unit);
  36958             SOC_PBMP_PORT_REMOVE(soc->counter_pbmp, port);
  36959             COUNTER_UNLOCK(unit);
  36960         }
  36961     }
  36962     /* Probe PHY on all port(s) after conversion */
  36963     BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port_base, &okay));
  36964     BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port_base, FALSE));
  36965     if (lanes_ctrl.lanes < lanes_ctrl.cur_lanes) { /* port(s) to be added */
  36966         for (i = 0; i < lanes_ctrl.phy_ports_len; i++) {
  36967             port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]];
  36968             BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port, &okay));
  36969             BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port, FALSE));
  36970             COUNTER_LOCK(unit);
  36971             SOC_PBMP_PORT_ADD(soc->counter_pbmp, port);
  36972             COUNTER_UNLOCK(unit);
  36973         }
  36974     }
  36975 
  36976     return BCM_E_NONE;
  36977 }
  36978 #endif /* BCM_TRIDENT2_SUPPORT */
  36979 
  36980 #ifdef BCM_TOMAHAWK_SUPPORT
  36981 STATIC int
  36982 _bcm_th_port_lanes_set(int unit, bcm_port_t port_base, int lanes)
  36983 {
  36984     soc_info_t *si = &SOC_INFO(unit);
  36985     soc_control_t *soc = SOC_CONTROL(unit);
  36986     soc_th_port_lanes_t lanes_ctrl;
  36987     int port, i;
  36988     int enable, okay;
  36989     int speed;
  36990 
  36991     sal_memset(&lanes_ctrl, 0, sizeof(lanes_ctrl));
  36992     lanes_ctrl.port_base = port_base;
  36993     lanes_ctrl.lanes = lanes;
  36994 
  36995     /* All existing ports are required to be disabled */
  36996     SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port_base, &enable));
  36997     if (enable) {
  36998         return BCM_E_PORT;
  36999     }
  37000     SOC_IF_ERROR_RETURN
  37001         (soc_tomahawk_port_lanes_validate(unit, &lanes_ctrl));
  37002     if (lanes_ctrl.lanes == lanes_ctrl.cur_lanes) {
  37003         return BCM_E_NONE;
  37004     }
  37005 
  37006     if (lanes_ctrl.lanes > lanes_ctrl.cur_lanes) { /* port(s) to be removed */
  37007         for (i = 0; i < lanes_ctrl.phy_ports_len; i++) {
  37008             port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]];
  37009             SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &enable));
  37010             if (enable) {
  37011                 return BCM_E_PORT;
  37012             }
  37013         }
  37014     }
  37015 
  37016     SOC_IF_ERROR_RETURN
  37017         (soc_tomahawk_port_lanes_set(unit, &lanes_ctrl));
  37018     SOC_IF_ERROR_RETURN
  37019         (soc_tomahawk_port_lanes_consolidation(unit, &lanes_ctrl));
  37020 
  37021     /* Detach PHY on all existing port(s) */
  37022     SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port_base));
  37023     if (lanes_ctrl.lanes > lanes_ctrl.cur_lanes) { /* port(s) to be removed */
  37024         for (i = 0; i < lanes_ctrl.phy_ports_len; i++) {
  37025             port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]];
  37026             SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port));
  37027             COUNTER_LOCK(unit);
  37028             SOC_PBMP_PORT_REMOVE(soc->counter_pbmp, port);
  37029             COUNTER_UNLOCK(unit);
  37030         }
  37031     }
  37032 
  37033     /* Probe PHY on all port(s) after conversion */
  37034     BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port_base, &okay));
  37035     BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port_base, FALSE));
  37036     if (lanes_ctrl.lanes < lanes_ctrl.cur_lanes) { /* port(s) to be added */
  37037         for (i = 0; i < lanes_ctrl.phy_ports_len; i++) {
  37038             port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]];
  37039             BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port, &okay));
  37040             BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port, FALSE));
  37041             COUNTER_LOCK(unit);
  37042             SOC_PBMP_PORT_ADD(soc->counter_pbmp, port);
  37043             COUNTER_UNLOCK(unit);
  37044         }
  37045     }
  37046 
  37047     /* Update port ASF setting to SAF */
  37048     /* Base Port */
  37049     speed = si->port_init_speed[port_base];
  37050     BCM_IF_ERROR_RETURN(soc_th_port_asf_mode_set
  37051                             (unit, port_base, speed, _SOC_TH_ASF_MODE_SAF));
  37052     /* Newly added ports */
  37053     if (lanes_ctrl.lanes < lanes_ctrl.cur_lanes) { /* port(s) to be added */
  37054         for (i = 0; i < lanes_ctrl.phy_ports_len; i++) {
  37055             port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]];
  37056             speed = si->port_init_speed[port];
  37057             BCM_IF_ERROR_RETURN(soc_th_port_asf_mode_set
  37058                                     (unit, port, speed, _SOC_TH_ASF_MODE_SAF));
  37059         }
  37060     }
  37061 
  37062     return BCM_E_NONE;
  37063 }
  37064 #endif /* BCM_TOMAHAWK_SUPPORT */
  37065 
  37066 #ifdef BCM_HURRICANE2_SUPPORT
  37067 STATIC int
  37068 _bcm_hu2_port_lanes_set(int unit, bcm_port_t port_base, int lanes)
  37069 {
  37070     soc_info_t *si = &SOC_INFO(unit);
  37071     int cur_lanes;
  37072     int port, phy_ports[3], phy_ports_len, i;
  37073     int okay;
  37074 
  37075     SOC_IF_ERROR_RETURN
  37076         (soc_hurricane2_port_lanes_set(unit, port_base, lanes, &cur_lanes,
  37077                                      phy_ports, &phy_ports_len));
  37078     if (lanes == cur_lanes) {
  37079         return BCM_E_NONE;
  37080     }
  37081 
  37082     if (lanes > cur_lanes) { /* port(s) to be removed */
  37083         for (i = 0; i < phy_ports_len; i++) {
  37084             port = si->port_p2l_mapping[phy_ports[i]];
  37085             SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port));
  37086         }
  37087     }
  37088 
  37089     /* The specified port */
  37090     BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port_base, &okay));
  37091     BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port_base, TRUE));
  37092 
  37093     if (lanes < cur_lanes) { /* port(s) to be added */
  37094         for (i = 0; i < phy_ports_len; i++) {
  37095             port = si->port_p2l_mapping[phy_ports[i]];
  37096             BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port, &okay));
  37097             BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port, TRUE));
  37098         }
  37099     }
  37100 
  37101     return BCM_E_NONE;
  37102 }
  37103 #endif
  37104 
  37105 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  37106 int
  37107 _bcm_sc_tr_port_pfc_tx_set(int unit, bcm_port_t port, uint32 pri_bmp)
  37108 {
  37109     int pfc_enable;
  37110     uint32 rval;
  37111     int value, val_count = 0;
  37112     soc_reg_t reg;
  37113     uint32 values[2];
  37114     int chk_gx_port = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  37115                        SOC_IS_VALKYRIE2(unit) || SOC_IS_SCORPION(unit));
  37116     soc_field_t fields[] = {PFC_ENABLEf, LLFC_ENf};
  37117 
  37118     if (!soc_feature(unit, soc_feature_priority_flow_control)) {
  37119         return BCM_E_UNAVAIL;
  37120     }
  37121     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  37122     if (chk_gx_port && !IS_GX_PORT(unit, port)) { /* IS_GX_PORT == IS_XL_PORT */
  37123         return BCM_E_PORT;
  37124     }
  37125     if (pri_bmp >= (1U << 16)) {
  37126         return  BCM_E_PARAM;
  37127     }
  37128 
  37129     value = (pri_bmp == 0)? 0 : 1;
  37130     BCM_IF_ERROR_RETURN
  37131         (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  37132                          SOC_MAC_CONTROL_PFC_TX_ENABLE, value));
  37133     if (value == 0) {
  37134         BCM_IF_ERROR_RETURN
  37135             (MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  37136                              SOC_MAC_CONTROL_PFC_RX_ENABLE,
  37137                              &pfc_enable));
  37138     } else {
  37139         pfc_enable = TRUE;
  37140     }
  37141 
  37142     if (!soc_feature(unit, soc_feature_mmu_config_property)) {
  37143         rval = 0;
  37144         if (SOC_REG_IS_VALID(unit,PORT_PRI_XON_ENABLEr)) {
  37145            if (value) {
  37146               soc_reg_field_set(unit, PORT_PRI_XON_ENABLEr, &rval,
  37147                                 PORT_PRI_XON_ENABLEf, 0xff);
  37148               if (soc_reg_field_valid(unit, PORT_PRI_XON_ENABLEr,
  37149                                       PORT_PG7PAUSE_DISABLEf)) {
  37150                   soc_reg_field_set(unit, PORT_PRI_XON_ENABLEr, &rval,
  37151                                     PORT_PG7PAUSE_DISABLEf, 1);
  37152               }
  37153            }
  37154            BCM_IF_ERROR_RETURN
  37155               (WRITE_PORT_PRI_XON_ENABLEr(unit, port, rval));
  37156         }
  37157     } else if (SOC_IS_TRIDENT(unit)) {
  37158        rval = 0;
  37159        if (SOC_REG_IS_VALID(unit,PORT_PRI_XON_ENABLEr)) {
  37160            if(value) {
  37161                /* Get flow_control_enable info from mmu config
  37162                 * property for each priority group, and enable
  37163                 * generation of XON/XOFF for priority group
  37164                 * accordingly. */
  37165                int idx = 0, prifc_en = 0, fval = 0;
  37166                char suffix;
  37167                for(idx = 0; idx < 8; idx ++) {
  37168                    /* By default, enable generation of XON and XOFF
  37169                     * LLFC messages for priority 7 */
  37170                    prifc_en = (idx == 7) ? 1 : 0;
  37171                    prifc_en = soc_property_port_obj_attr_get(unit,
  37172                                         port, spn_BUF, spn_PRIGROUP,
  37173                                         idx, spn_FLOW_CONTROL_ENABLE,
  37174                                         0, &suffix, prifc_en);
  37175                    if(prifc_en != 0) {
  37176                        fval |= (1 << idx);
  37177                    }
  37178                }
  37179                soc_reg_field_set(unit, PORT_PRI_XON_ENABLEr, &rval,
  37180                                    PORT_PRI_XON_ENABLEf, fval);
  37181            }
  37182            /* When disable PFC on port, generation of XON/XOFF
  37183             * for all priority groups must be disabled also. */
  37184            BCM_IF_ERROR_RETURN
  37185                  (WRITE_PORT_PRI_XON_ENABLEr(unit, port, rval));
  37186         }
  37187     }
  37188 
  37189     /* Port config settings */
  37190     values[0] = pfc_enable ? 1 : 0;
  37191     values[1] = 0;
  37192 
  37193     if (SOC_IS_TD2_TT2(unit)) {
  37194 #ifdef BCM_TOMAHAWK3_SUPPORT
  37195         if(SOC_IS_TOMAHAWK3(unit)) {
  37196             SOC_IF_ERROR_RETURN
  37197                 (bcm_th3_mmu_pfc_tx_config_set(unit, port,
  37198                                         pfc_enable, pri_bmp));
  37199         } else
  37200 #endif
  37201         {
  37202             SOC_IF_ERROR_RETURN
  37203                 (soc_reg32_get(unit, THDI_INPUT_PORT_XON_ENABLESr,
  37204                                port, 0, &rval));
  37205             soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
  37206                               PORT_PRI_XON_ENABLEf,
  37207                               pfc_enable ? pri_bmp : 0);
  37208 
  37209             soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
  37210                               PORT_PAUSE_ENABLEf, pfc_enable ? 0 : 1);
  37211             SOC_IF_ERROR_RETURN
  37212                 (soc_reg32_set(unit, THDI_INPUT_PORT_XON_ENABLESr,
  37213                                port, 0, rval));
  37214         }
  37215 #ifdef BCM_TOMAHAWK_SUPPORT
  37216         if (SOC_IS_TOMAHAWKX(unit) && IS_CL_PORT(unit, port)) {
  37217             soc_info_t *si;
  37218             uint64 rval64;
  37219             int phy_port_base, phy_port, lane, block_idx, pipe, clport, obm;
  37220             static const soc_reg_t obm_fc_config_regs[] = {
  37221                 IDB_OBM0_FLOW_CONTROL_CONFIGr, IDB_OBM1_FLOW_CONTROL_CONFIGr,
  37222                 IDB_OBM2_FLOW_CONTROL_CONFIGr, IDB_OBM3_FLOW_CONTROL_CONFIGr,
  37223                 IDB_OBM4_FLOW_CONTROL_CONFIGr, IDB_OBM5_FLOW_CONTROL_CONFIGr,
  37224                 IDB_OBM6_FLOW_CONTROL_CONFIGr, IDB_OBM7_FLOW_CONTROL_CONFIGr,
  37225 #ifdef BCM_TOMAHAWK2_SUPPORT
  37226                 IDB_OBM8_FLOW_CONTROL_CONFIGr, IDB_OBM9_FLOW_CONTROL_CONFIGr,
  37227                 IDB_OBM10_FLOW_CONTROL_CONFIGr, IDB_OBM11_FLOW_CONTROL_CONFIGr,
  37228                 IDB_OBM12_FLOW_CONTROL_CONFIGr, IDB_OBM13_FLOW_CONTROL_CONFIGr,
  37229                 IDB_OBM14_FLOW_CONTROL_CONFIGr, IDB_OBM15_FLOW_CONTROL_CONFIGr
  37230 #endif
  37231             };
  37232 
  37233             COMPILER_64_ZERO(rval64);
  37234             si = &SOC_INFO(unit);
  37235             phy_port = si->port_l2p_mapping[port];
  37236             phy_port_base = PORT_BLOCK_BASE_PORT(port);
  37237             lane = (phy_port - phy_port_base) & 3;
  37238             block_idx = SOC_PORT_IDX_BLOCK(unit, phy_port_base, 0);
  37239             pipe = si->port_pipe[port];
  37240             clport = SOC_BLOCK_NUMBER(unit, block_idx);
  37241             if (SOC_IS_TOMAHAWK(unit)) {
  37242             /* obm number is reversed (mirrored) in odd pipe */
  37243                 obm = pipe & 1 ? (7- (clport & 7)) : (clport & 7);
  37244             } else {
  37245                 obm = clport & 15;
  37246             }
  37247             reg = SOC_REG_UNIQUE_ACC(unit, obm_fc_config_regs[obm])[pipe];
  37248             SOC_IF_ERROR_RETURN
  37249                 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64));
  37250             soc_reg64_field32_set(unit, reg, &rval64, FC_TYPEf, pfc_enable);
  37251             SOC_IF_ERROR_RETURN
  37252                 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64));
  37253         }
  37254 #endif /* BCM_TOMAHAWK_SUPPORT */
  37255         reg = INVALIDr;
  37256     } else if (SOC_IS_TD_TT(unit)) {
  37257         int mmu_port;
  37258         uint64 r64val;
  37259         soc_info_t *si;
  37260         
  37261         /* disable pause if pfc is enabled, vice versa */
  37262         si = &SOC_INFO(unit);
  37263         mmu_port = si->port_p2m_mapping[si->port_l2p_mapping[port]];
  37264         reg = (mmu_port < 33) ? PORT_PAUSE_ENABLE0_64r : PORT_PAUSE_ENABLE1_64r;
  37265         mmu_port = (mmu_port < 33) ? mmu_port : mmu_port - 33;
  37266         SOC_IF_ERROR_RETURN(
  37267             soc_reg_get(unit, reg, REG_PORT_ANY, 0, &r64val));
  37268         if (value) {
  37269             COMPILER_64_BITCLR(r64val, mmu_port);
  37270         } else {
  37271             COMPILER_64_BITSET(r64val, mmu_port);
  37272         }
  37273         SOC_IF_ERROR_RETURN(
  37274             soc_reg_set(unit, reg, REG_PORT_ANY, 0, r64val));
  37275         
  37276         reg = XLPORT_CONFIGr;
  37277         val_count=2;
  37278     } else if (SOC_IS_SHADOW(unit)) {
  37279         reg = XLPORT_CONFIGr;
  37280         val_count=2;
  37281     } else if (SOC_IS_TRIUMPH3(unit)) {
  37282         reg = PORT_CONFIGr;
  37283         val_count=2;
  37284     }  else if (SOC_IS_SABER2(unit)) {
  37285         /* No port level config required */
  37286         reg = INVALIDr;
  37287         val_count = 0;
  37288     } else if (SOC_IS_KATANAX(unit)) {
  37289         reg = XPORT_CONFIGr;
  37290         val_count=2;
  37291     } else {
  37292         reg = INVALIDr;
  37293     }
  37294 
  37295     if (val_count > 0) {
  37296         BCM_IF_ERROR_RETURN
  37297             (soc_reg_fields32_modify(unit, reg, port,
  37298                                      COUNTOF(values), fields, values));
  37299     } else if (SOC_IS_SC_CQ(unit) || SOC_IS_TR_VL(unit)) {
  37300         if (SOC_REG_IS_VALID(unit, PPFC_ENr)) {
  37301             BCM_IF_ERROR_RETURN
  37302               (soc_reg_field32_modify(unit, PPFC_ENr, port,
  37303                                       PPFC_FEATURE_ENf,
  37304                                       pfc_enable ? 1 : 0));
  37305         }
  37306         if (soc_reg_field_valid(unit, XPORT_CONFIGr, PPP_ENABLEf)) {
  37307             BCM_IF_ERROR_RETURN
  37308                 (soc_reg_field32_modify(unit, XPORT_CONFIGr, port,
  37309                                         PPP_ENABLEf,
  37310                                         pfc_enable ? 1 : 0));
  37311         }
  37312     }
  37313 
  37314     /* Stats enable */
  37315     BCM_IF_ERROR_RETURN
  37316         (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  37317                          SOC_MAC_CONTROL_PFC_STATS_ENABLE,
  37318                          pfc_enable ? 1 : 0));
  37319 
  37320     return BCM_E_NONE;
  37321 }
  37322 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  37323 
  37324 
  37325 /*
  37326  * Function:
  37327  *      bcm_esw_port_control_wlan_validate
  37328  * Description:
  37329  *      Checks that port control is valid for a WLAN GPORT.
  37330  *      Resolves port to expected port value for the given port control type.
  37331  * Parameters:
  37332  *      port      - (IN) Port to resolve
  37333  *      type      - (IN) Port control type
  37334  *      port_out  - (OUT) Returns port (gport or BCM format) that
  37335  *                  is expected for corresponding port control type.
  37336  * Return Value:
  37337  *      BCM_E_XXX
  37338  */
  37339 STATIC int
  37340 bcm_esw_port_control_wlan_validate(bcm_port_t port,
  37341                                    bcm_port_control_t type,
  37342                                    bcm_port_t *port_out)
  37343 {
  37344     int rv = BCM_E_PORT;
  37345     int support = FALSE;
  37346 
  37347     switch (type) {
  37348     case bcmPortControlBridge:
  37349     case bcmPortControlTrunkHashSet:
  37350     case bcmPortControlFabricTrunkHashSet:
  37351     case bcmPortControlECMPHashSet:
  37352     case bcmPortControlLoadBalanceHashSet:
  37353     case bcmPortControlLoadBalancingNumber:
  37354     case bcmPortControlIP4:
  37355     case bcmPortControlIP6:
  37356     case bcmPortControlIP4Mcast:
  37357     case bcmPortControlIP6Mcast:
  37358     case bcmPortControlMpls:
  37359     case bcmPortControlMacInMac:
  37360     case bcmPortControlSrcBmacMissToCpu:
  37361     case bcmPortControlIP4McastL2:
  37362     case bcmPortControlIP6McastL2:
  37363     case bcmPortControlFilterLookup:
  37364     case bcmPortControlFilterIngress:
  37365     case bcmPortControlPreservePacketPriority:
  37366     case bcmPortControlLearnClassEnable:
  37367     case bcmPortControlTrustIncomingVlan:
  37368     case bcmPortControlDoNotCheckVlan:
  37369     case bcmPortControlIEEE8021ASEnableIngress:
  37370     case bcmPortControlIpfixRate:
  37371     case bcmPortControlForwardStaticL2MovePkt:
  37372     case bcmPortControlTrillHashSelect:
  37373     case bcmPortControlFabricSourceKnockout:
  37374     case bcmPortControlL2GreEnable:
  37375     case bcmPortControlL2GreTunnelbasedVpnId:
  37376     case bcmPortControlL2GreDefaultTunnelEnable:
  37377     case bcmPortControlVxlanEnable:
  37378     case bcmPortControlVxlanTunnelbasedVnId:
  37379     case bcmPortControlVxlanDefaultTunnelEnable:
  37380     case bcmPortControlRegex:
  37381     case bcmPortControlRegexTcp:
  37382     case bcmPortControlRegexUdp:
  37383         support = TRUE;
  37384         break;
  37385     default:
  37386         support = FALSE;
  37387         break;
  37388     }
  37389 
  37390     if (support) {
  37391         *port_out = port;
  37392         rv = BCM_E_NONE;
  37393     }
  37394 
  37395     return rv;
  37396 }
  37397 
  37398 /*
  37399  * Function:
  37400  *      bcm_esw_port_control_proxy_validate
  37401  * Description:
  37402  *      Checks that port control is valid for a PROXY GPORT.
  37403  *      Resolves port to expected port value for the given port control type.
  37404  * Parameters:
  37405  *      unit      - (IN) Device number
  37406  *      port      - (IN) Port to resolve
  37407  *      type      - (IN) Port control type
  37408  *      port_out  - (OUT) Returns port (gport or BCM format) that
  37409  *                  is expected for corresponding port control type.
  37410  * Return Value:
  37411  *      BCM_E_XXX
  37412  */
  37413 STATIC int
  37414 bcm_esw_port_control_proxy_validate(int unit, bcm_port_t port,
  37415                                     bcm_port_control_t type,
  37416                                     bcm_port_t *port_out)
  37417 {
  37418     int rv = BCM_E_PORT;
  37419     int support = FALSE;
  37420 
  37421     /* Make sure port module is initialized. */
  37422     PORT_INIT(unit);
  37423 
  37424     if (!soc_feature(unit, soc_feature_proxy_port_property)) {
  37425         return BCM_E_PORT;
  37426     }
  37427 
  37428     switch(type) {
  37429     case bcmPortControlBridge:
  37430     case bcmPortControlTrunkHashSet:
  37431     case bcmPortControlFabricTrunkHashSet:
  37432     case bcmPortControlECMPHashSet:
  37433     case bcmPortControlLoadBalanceHashSet:
  37434     case bcmPortControlLoadBalancingNumber:
  37435     case bcmPortControlIP4:
  37436     case bcmPortControlIP6:
  37437     case bcmPortControlIP4Mcast:
  37438     case bcmPortControlIP6Mcast:
  37439     case bcmPortControlMpls:
  37440     case bcmPortControlMacInMac:
  37441     case bcmPortControlSrcBmacMissToCpu:
  37442     case bcmPortControlIP4McastL2:
  37443     case bcmPortControlIP6McastL2:
  37444     case bcmPortControlFilterLookup:
  37445     case bcmPortControlFilterIngress:
  37446     case bcmPortControlPreservePacketPriority:
  37447     case bcmPortControlLearnClassEnable:
  37448     case bcmPortControlTrustIncomingVlan:
  37449     case bcmPortControlDoNotCheckVlan:
  37450     case bcmPortControlIEEE8021ASEnableIngress:
  37451     case bcmPortControlIpfixRate:
  37452     case bcmPortControlOAMEnable:
  37453     case bcmPortControlForwardStaticL2MovePkt:
  37454     case bcmPortControlTrill:
  37455     case bcmPortControlTrillAllow:
  37456     case bcmPortControlNonTrillAllow:
  37457     case bcmPortControlTrillCoreISISToCPU:
  37458     case bcmPortControlTrillHashSelect:
  37459     case bcmPortControlNivNonVntagDrop:
  37460     case bcmPortControlNonEtagDrop:
  37461     case bcmPortControlNivVntagDrop:
  37462     case bcmPortControlEtagDrop:
  37463     case bcmPortControlNivNonVntagAdd:
  37464     case bcmPortControlNonEtagAdd:
  37465     case bcmPortControlNivVntagIngressReplace:
  37466     case bcmPortControlEtagIngressReplace:
  37467     case bcmPortControlNivVntagIngressDelete:
  37468     case bcmPortControlEtagIngressDelete:
  37469     case bcmPortControlNivRpfCheck:
  37470     case bcmPortControlExtenderRpfCheck:
  37471     case bcmPortControlNivNameSpace:
  37472     case bcmPortControlExtenderNameSpace:
  37473     case bcmPortControlUseEtagPri:
  37474     case bcmPortControlProhibitedDot1p:
  37475     case bcmPortControlFabricSourceKnockout:
  37476     case bcmPortControlMplsEntropyHashSet:
  37477     case bcmPortControlL2GreEnable:
  37478     case bcmPortControlL2GreTunnelbasedVpnId:
  37479     case bcmPortControlL2GreDefaultTunnelEnable:
  37480     case bcmPortControlVxlanEnable:
  37481     case bcmPortControlVxlanTunnelbasedVnId:
  37482     case bcmPortControlVxlanDefaultTunnelEnable:
  37483         support = TRUE;
  37484         break;
  37485     default:
  37486         support = FALSE;
  37487         break;
  37488     }
  37489 
  37490     if (support) {
  37491         *port_out = port;
  37492         rv = BCM_E_NONE;
  37493     }
  37494 
  37495     return rv;
  37496 }
  37497 
  37498 /*
  37499  * Function:
  37500  *      bcm_esw_port_control_scheduler_validate
  37501  * Description:
  37502  *      Checks that port control is valid for a SCHEDULER GPORT.
  37503  *      Resolves port to expected port value for the given port control type.
  37504  * Parameters:
  37505  *      unit      - (IN) Device number
  37506  *      port      - (IN) Port to resolve
  37507  *      type      - (IN) Port control type
  37508  *      port_out  - (OUT) Returns port (gport or BCM format) that
  37509  *                  is expected for corresponding port control type.
  37510  * Return Value:
  37511  *      BCM_E_XXX
  37512  */
  37513 STATIC int
  37514 bcm_esw_port_control_scheduler_validate(int unit, bcm_port_t port,
  37515                                         bcm_port_control_t type,
  37516                                         bcm_port_t *port_out)
  37517 {
  37518     int rv = BCM_E_PORT;
  37519     int support = FALSE;
  37520 
  37521     switch (type) {
  37522     case bcmPortControlWredDropCountUpdateEnableQueueMask:
  37523     case bcmPortControlWredDropCountUpdateEnableColorMask:
  37524         support = TRUE;
  37525         break;
  37526     default:
  37527         support = FALSE;
  37528         break;
  37529     }
  37530 
  37531     if (support) {
  37532         *port_out = port;
  37533         rv = BCM_E_NONE;
  37534     }
  37535 
  37536     return rv;
  37537 }
  37538 
  37539 /*
  37540  * Function:
  37541  *      bcm_esw_port_control_local_port_validate
  37542  * Description:
  37543  *      Checks that port control is valid for a BCM local physical port.
  37544  *      Resolves port to expected port value for the given port control type.
  37545  * Parameters:
  37546  *      unit      - (IN) Device number
  37547  *      port      - (IN) Port to resolve
  37548  *      type      - (IN) Port control type
  37549  *      port_out  - (OUT) Returns port (gport or BCM format) that
  37550  *                  is expected for corresponding port control type.
  37551  * Return Value:
  37552  *      BCM_E_XXX
  37553  *
  37554  *      Unlike the other similar routines
  37555  *      (i.e. bcm_esw_port_control_wlan_support), note that the default
  37556  *      support is VALID and checks for INVALID types, since most
  37557  *      port controls are valid for this type of port.
  37558  */
  37559 STATIC int
  37560 bcm_esw_port_control_local_port_validate(int unit, bcm_port_t port,
  37561                                          bcm_port_control_t type,
  37562                                          bcm_port_t *port_out)
  37563 {
  37564     int rv = BCM_E_PORT;
  37565     int support = TRUE;
  37566     bcm_port_t local_port;
  37567 
  37568     /* Make sure port module is initialized. */
  37569     PORT_INIT(unit);
  37570 
  37571     /* Check for valid BCM local physical port */
  37572     BCM_IF_ERROR_RETURN
  37573         (_bcm_esw_port_gport_validate(unit, port, &local_port));
  37574 
  37575     if (IS_ST_PORT(unit, local_port)) {
  37576         switch(type) {
  37577         case bcmPortControlIP4:
  37578         case bcmPortControlIP6:
  37579         case bcmPortControlIP4Mcast:
  37580         case bcmPortControlIP6Mcast:
  37581         case bcmPortControlMpls:
  37582         case bcmPortControlMacInMac:
  37583         case bcmPortControlIP4McastL2:
  37584         case bcmPortControlIP6McastL2:
  37585         case bcmPortControlIPMC4Ucast:
  37586         case bcmPortControlIPMC6Ucast:
  37587             support = FALSE;
  37588             break;
  37589         default:
  37590             support = TRUE;
  37591             break;
  37592         }
  37593     }
  37594 
  37595     if (support) {
  37596         if (!IS_E_PORT(unit, local_port)) {
  37597             switch(type) {
  37598             case bcmPortControlEEEEnable:
  37599             case bcmPortControlEEETransmitIdleTime:
  37600             case bcmPortControlEEEStatisticsClear:
  37601             case bcmPortControlEEETransmitRefreshTime:
  37602             case bcmPortControlEEETransmitSleepTime:
  37603             case bcmPortControlEEETransmitQuietTime:
  37604             case bcmPortControlEEETransmitWakeTime:
  37605             case bcmPortControlEEEReceiveSleepTime:
  37606             case bcmPortControlEEEReceiveQuietTime:
  37607             case bcmPortControlEEEReceiveWakeTime:
  37608             case bcmPortControlEEEEventCountSymmetric:
  37609             case bcmPortControlEEELinkActiveDuration:
  37610             case bcmPortControlEEEReceiveDuration:
  37611             case bcmPortControlEEETransmitEventCount:
  37612             case bcmPortControlEEETransmitDuration:
  37613             case bcmPortControlEEEReceiveEventCount:
  37614                 support = FALSE;
  37615                 break;
  37616             default:
  37617                 support = TRUE;
  37618                 break;
  37619             }
  37620         }
  37621     }
  37622 
  37623     if (support) {
  37624         *port_out = local_port;
  37625         rv = BCM_E_NONE;
  37626     }
  37627 
  37628     return rv;
  37629 }
  37630 
  37631 /*
  37632  * Function:
  37633  *      bcm_esw_port_control_validate
  37634  * Description:
  37635  *      Checks that port is valid and that control is supported
  37636  *      for the given port type.  Resolves port to expected
  37637  *      port value for the given port control type.
  37638  *      Current valid port types are:
  37639  *          GPORT WLAN
  37640  *          GPORT PROXY
  37641  *          GPORT (various types) that resolves to local physical port
  37642  *          BCM port (non-gport)
  37643  * Parameters:
  37644  *      unit      - (IN) Device number
  37645  *      port      - (IN) Port to resolve
  37646  *      type      - (IN) Port control type
  37647  *      port_out  - (OUT) Returns port (gport or BCM format) that
  37648  *                  is expected for corresponding port control type.
  37649  * Return Value:
  37650  *      BCM_E_XXX
  37651  */
  37652 STATIC int
  37653 bcm_esw_port_control_validate(int unit, bcm_port_t port,
  37654                               bcm_port_control_t type,
  37655                               bcm_port_t *port_out)
  37656 {
  37657     int rv = BCM_E_PORT;
  37658 
  37659     /* Make sure port module is initialized. */
  37660     PORT_INIT(unit);
  37661 
  37662     if (BCM_GPORT_IS_WLAN_PORT(port)) {
  37663         rv = bcm_esw_port_control_wlan_validate(port, type, port_out);
  37664     } else if (BCM_GPORT_IS_PROXY(port)) {
  37665         rv = bcm_esw_port_control_proxy_validate(unit, port, type, port_out);
  37666     } else if (BCM_GPORT_IS_SCHEDULER(port)) {
  37667         rv = bcm_esw_port_control_scheduler_validate(unit, port,
  37668                                                      type, port_out);
  37669     } else {
  37670         rv = bcm_esw_port_control_local_port_validate(unit, port, type,
  37671                                                       port_out);
  37672     }
  37673 
  37674     return rv;
  37675 }
  37676 
  37677 
  37678 int
  37679 _bcm_esw_port_vrf_set(int unit, bcm_port_t port, int value)
  37680 {
  37681     int rv = BCM_E_UNAVAIL;
  37682 #if defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_HURRICANE_SUPPORT)
  37683         if (SOC_IS_HAWKEYE(unit) || SOC_IS_HURRICANEX(unit) ||
  37684             !soc_feature(unit, soc_feature_l3))  {
  37685             return BCM_E_UNAVAIL;
  37686         }
  37687 #endif /* BCM_HAWKEYE_SUPPORT || BCM_HURRICANE_SUPPORT */
  37688         if (soc_mem_field_valid(unit, PORT_TABm, VRF_IDf)) {
  37689             if ((value > 0 ) && (value < SOC_VRF_MAX(unit) )) {
  37690                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  37691                                            VRF_IDf, value);
  37692                 BCM_IF_ERROR_RETURN(rv);
  37693                 if (soc_mem_field_valid(unit, PORT_TABm, VRF_PORT_ENABLEf)) {
  37694                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  37695                                                VRF_PORT_ENABLEf, 0x1);
  37696                 }
  37697             } else {
  37698                 if (soc_mem_field_valid(unit, PORT_TABm, VRF_PORT_ENABLEf)) {
  37699                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  37700                                                VRF_PORT_ENABLEf, 0x0);
  37701                     BCM_IF_ERROR_RETURN(rv);
  37702                 }
  37703                 if (soc_mem_field_valid(unit, PORT_TABm, VRF_IDf)) {
  37704                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  37705                                                VRF_IDf, 0x0);
  37706                 }
  37707             }
  37708         }
  37709 
  37710 #if defined(BCM_TRIUMPH_SUPPORT)
  37711         else {
  37712             if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, VRF_IDf)) {
  37713                 if  ((value > 0 ) && (value < SOC_VRF_MAX(unit) )) {
  37714 #if defined(BCM_KATANA2_SUPPORT)
  37715                     if (SOC_IS_KATANA2(unit)) {
  37716                         rv = _bcm_kt2_source_trunk_map_set(unit, port,
  37717                                 VRF_IDf, value);
  37718                     } else
  37719 #endif
  37720                     {
  37721                         rv = _bcm_trx_source_trunk_map_set(unit, port,
  37722                                 VRF_IDf, value);
  37723                     }
  37724                     BCM_IF_ERROR_RETURN(rv);
  37725                     if (soc_mem_field_valid(unit, PORT_TABm,
  37726                                             PORT_OPERATIONf) ||
  37727                         SOC_IS_TRIDENT3X(unit)) {
  37728                         rv = _bcm_esw_port_tab_set(unit, port,
  37729                                                    _BCM_CPU_TABS_BOTH,
  37730                                                    PORT_OPERATIONf, 0x3);
  37731                     }
  37732                 } else {
  37733                     if (soc_mem_field_valid(unit, PORT_TABm,
  37734                                             PORT_OPERATIONf) ||
  37735                         SOC_IS_TRIDENT3X(unit)) {
  37736                         rv = _bcm_esw_port_tab_set(unit, port,
  37737                                                    _BCM_CPU_TABS_BOTH,
  37738                                                    PORT_OPERATIONf, 0x0);
  37739                     }
  37740                 }
  37741             }
  37742         }
  37743 #endif  /* BCM_TRIUMPH_SUPPORT */
  37744     return rv;
  37745 }
  37746 
  37747 int
  37748 _bcm_esw_port_vrf_get(int unit, bcm_port_t port, int *value)
  37749 {
  37750     int rv = BCM_E_UNAVAIL;
  37751 #if defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_HURRICANE_SUPPORT)
  37752     if (SOC_IS_HAWKEYE(unit) || SOC_IS_HURRICANEX(unit) ||
  37753         !soc_feature(unit, soc_feature_l3)) {
  37754         return BCM_E_UNAVAIL;
  37755     }
  37756 #endif /* BCM_HAWKEYE_SUPPORT || BCM_HURRICANE_SUPPORT */
  37757     if (soc_mem_field_valid(unit, PORT_TABm, VRF_PORT_ENABLEf)) {
  37758         rv = _bcm_esw_port_tab_get(unit, port, VRF_PORT_ENABLEf, value);
  37759 
  37760         if ((*value == 0x1 ) && (soc_mem_field_valid(unit, PORT_TABm,
  37761                                                      VRF_IDf ))) {
  37762               rv = _bcm_esw_port_tab_get(unit, port, VRF_IDf, value);
  37763         } else {
  37764               *value = 0;
  37765         }
  37766     } else if (soc_mem_field_valid(unit, PORT_TABm, VRF_IDf)) {
  37767         rv = _bcm_esw_port_tab_get(unit, port, VRF_IDf, value);
  37768     }
  37769 
  37770 #if defined(BCM_TRIUMPH_SUPPORT)
  37771     else {
  37772         *value = 0;
  37773         if (soc_mem_field_valid(unit, PORT_TABm, PORT_OPERATIONf) ||
  37774             SOC_IS_TRIDENT3X(unit)) {
  37775             rv = _bcm_esw_port_tab_get(unit, port, PORT_OPERATIONf, value);
  37776             BCM_IF_ERROR_RETURN(rv);
  37777         }
  37778         if ((*value == 0x3) &&
  37779             (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm,
  37780                                      VRF_IDf))) {
  37781 #if defined(BCM_KATANA2_SUPPORT)
  37782             if (SOC_IS_KATANA2(unit)) {
  37783                 rv = _bcm_kt2_source_trunk_map_get(unit, port, VRF_IDf,
  37784                                            (uint32 *)value);
  37785             } else
  37786 #endif
  37787             {
  37788                 rv = _bcm_trx_source_trunk_map_get(unit, port, VRF_IDf,
  37789                                            (uint32 *)value);
  37790             }
  37791         }
  37792     }
  37793 
  37794 #endif /* BCM_TRIUMPH_SUPPORT */
  37795     return rv;
  37796 }
  37797 
  37798 #ifdef BCM_TRIDENT2_SUPPORT
  37799 STATIC void
  37800 _bcm_flex_port_phy_control_software_rx_los_get(int unit, bcm_port_t control_port) {
  37801     int        rv = BCM_E_NONE;
  37802     bcm_pbmp_t ancillary_pbmp;
  37803     bcm_port_t ancillary_port;
  37804     uint32     rx_los;
  37805 
  37806     rv = bcm_esw_port_subsidiary_ports_get(unit, control_port, &ancillary_pbmp);
  37807     if (BCM_FAILURE(rv)) {
  37808         return;
  37809     }
  37810     PBMP_ITER(ancillary_pbmp, ancillary_port) {
  37811         rv = bcm_esw_port_phy_control_get(unit, ancillary_port, BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS, &rx_los);
  37812         if (BCM_SUCCESS(rv)) {
  37813             PORT_INFO_RX_LOS_SET(unit, ancillary_port, BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS, rx_los);
  37814         }
  37815     }
  37816     return;
  37817 }
  37818 #endif
  37819 
  37820 /*
  37821  * Function:
  37822  *      _bcm_esw_port_eee_stat_clear
  37823  * Description:
  37824  *      Clear EEE statistics directly by 
  37825  *      writing EEE counter register to 0
  37826  * Parameters:
  37827  *      unit - Device number
  37828  *      port - Port number
  37829  * Return Value:
  37830  *      BCM_E_XXX
  37831  */
  37832 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) || \
  37833     defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT)
  37834 STATIC int
  37835 _bcm_esw_port_eee_stat_clear(int unit, bcm_port_t port)
  37836 {
  37837     int idx;
  37838     uint64 val64;
  37839     soc_reg_t def_regs[] = {
  37840         RX_EEE_LPI_DURATION_COUNTERr,
  37841         RX_EEE_LPI_EVENT_COUNTERr,
  37842         TX_EEE_LPI_DURATION_COUNTERr,
  37843         TX_EEE_LPI_EVENT_COUNTERr
  37844     };
  37845     soc_reg_t ge_regs[] = {
  37846         GRX_EEE_LPI_DURATION_COUNTERr,
  37847         GRX_EEE_LPI_EVENT_COUNTERr,
  37848         GTX_EEE_LPI_DURATION_COUNTERr,
  37849         GTX_EEE_LPI_EVENT_COUNTERr
  37850     };
  37851     soc_reg_t *regs = def_regs;
  37852 
  37853     COMPILER_64_ZERO(val64);
  37854 
  37855     if (IS_GE_PORT(unit, port) && !IS_XL_PORT(unit, port)) {
  37856         regs = ge_regs;
  37857     }
  37858 
  37859     for (idx = 0; idx < sizeof(def_regs) / sizeof(def_regs[0]); idx++) {
  37860         SOC_IF_ERROR_RETURN(soc_counter_set(unit, port, regs[idx], 0, val64));
  37861     }
  37862 
  37863     return BCM_E_NONE;
  37864 }
  37865 #endif
  37866 
  37867 /*
  37868  * Function:
  37869  *      bcm_esw_port_control_set
  37870  * Description:
  37871  *      Enable/Disable specified port feature.
  37872  * Parameters:
  37873  *      unit - Device number
  37874  *      port - Port number
  37875  *      type - Enum value of the feature
  37876  *      value - value to be set
  37877  * Return Value:
  37878  *      BCM_E_NONE
  37879  *      BCM_E_UNAVAIL - Functionality not available
  37880  */
  37881 int
  37882 bcm_esw_port_control_set(int unit, bcm_port_t port,
  37883                          bcm_port_control_t type, int value)
  37884 {
  37885     int rv = BCM_E_UNAVAIL;
  37886     int valid = 0;
  37887 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  37888     soc_reg_t egr_port_reg;
  37889 #endif
  37890 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  37891     int chk_gx_port = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  37892                        SOC_IS_VALKYRIE2(unit) || SOC_IS_SCORPION(unit));
  37893 #endif
  37894 #if defined(BCM_GREYHOUND_SUPPORT)
  37895     int cur_val = 0;
  37896 #endif
  37897 #if defined (BCM_METROLITE_SUPPORT)
  37898     bcm_pbmp_t pbm;
  37899 #endif
  37900 #if defined(BCM_TOMAHAWK3_SUPPORT)
  37901 int_turnaround_en_bmap_entry_t int_turnaround_en_bmap_entry;
  37902 bcm_pbmp_t  pbmp;
  37903 #endif
  37904 
  37905     LOG_INFO(BSL_LS_BCM_PORT,
  37906              (BSL_META_U(unit,
  37907                          "bcm_port_control_set: u=%d p=%d rv=%d : %d\n"),
  37908               unit, port, value, (int)type));
  37909 
  37910     /* Make sure port module is initialized. */
  37911     PORT_INIT(unit);
  37912 
  37913     if(bcm_common_oamp_port_enable_get(unit, port) &&
  37914             (type != bcmPortControlSatEnable)) {
  37915         /* Only bcmPortControlSatEnable is permitted on oamp port */
  37916         LOG_ERROR(BSL_LS_BCM_PORT,
  37917                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  37918                    port));
  37919         return BCM_E_PARAM;
  37920     }
  37921 
  37922     /* Call Port Control module */
  37923     if (SOC_USE_PORTCTRL(unit)) {
  37924         /*
  37925          * Check that port control feature is valid in Port Control.
  37926          * If valid, call Port Control routine to handle feature; otherwise
  37927          * continue with rest of logic.
  37928          */
  37929         BCM_IF_ERROR_RETURN
  37930             (bcmi_esw_portctrl_control_validate(unit, type, &valid));
  37931         if (valid) {
  37932             return bcmi_esw_portctrl_control_set(unit, port, type, value);
  37933         }
  37934     }
  37935 
  37936 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  37937     egr_port_reg = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  37938                     SOC_IS_VALKYRIE2(unit)|| SOC_IS_GREYHOUND(unit) ||
  37939                     SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ?
  37940                     EGR_PORT_64r : EGR_PORTr;
  37941 #endif
  37942 
  37943 #if defined(BCM_SHADOW_SUPPORT)
  37944     if (SOC_IS_SHADOW(unit)) {
  37945         /*  If unsupported port control type, return unavail */
  37946         if (!_bcm_port_type_shadow_support (unit, port, type)) {
  37947             return BCM_E_UNAVAIL;
  37948         }
  37949     }
  37950 #endif /* BCM_SHADOW_SUPPORT */
  37951 
  37952     if (type == bcmPortControlEsmEligibility) {
  37953 #ifdef BCM_TRIUMPH3_SUPPORT
  37954         /* For bcmPortControlEsmEligibility, a non-local port
  37955          * is accepted. For other port controls, a non-local
  37956          * port is not accepted. Hence, bcmPortControlEsmEligibility
  37957          * is implemented here, before the _bcm_esw_port_gport_validate
  37958          * procedure below.
  37959          */
  37960         return bcm_tr3_port_esm_eligible_set(unit, port, value);
  37961 #endif /* BCM_TRIUMPH3_SUPPORT */
  37962     }
  37963 
  37964 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
  37965     if (
  37966 #ifdef BCM_HGPROXY_COE_SUPPORT
  37967         (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  37968          _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port) &&
  37969          ((type == bcmPortControlVlanVpGroupIngress) ||
  37970           (type == bcmPortControlVlanVpGroupEgress))) ||
  37971 #endif
  37972         BCM_GPORT_IS_TRUNK(port) ||
  37973         BCM_GPORT_IS_VLAN_PORT(port) ||
  37974         BCM_GPORT_IS_NIV_PORT(port) ||
  37975         BCM_GPORT_IS_VXLAN_PORT(port) ||
  37976         BCM_GPORT_IS_MIM_PORT(port) ||
  37977         BCM_GPORT_IS_MPLS_PORT(port) ||
  37978         BCM_GPORT_IS_L2GRE_PORT(port) ||
  37979         BCM_GPORT_IS_FLOW_PORT(port) ||
  37980         BCM_GPORT_IS_EXTENDER_PORT(port)) {
  37981         return bcm_td_vp_control_set(unit, port, type, value);
  37982     } else
  37983 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  37984 #if defined(BCM_KATANA2_SUPPORT)
  37985     if ((BCM_GPORT_IS_MIM_PORT(port) || BCM_GPORT_IS_MPLS_PORT(port))
  37986          && SOC_IS_KATANA2(unit)) {
  37987         rv = BCM_E_NONE;
  37988     } else
  37989 #endif /* BCM_KATANA2_SUPPORT */
  37990     if ((BCM_GPORT_IS_LOCAL_CPU_IEEE(port)) || 
  37991         (BCM_GPORT_IS_LOCAL_CPU_HIGIG(port))) {
  37992         rv = BCM_E_NONE;
  37993     } else
  37994 #ifdef BCM_HGPROXY_COE_SUPPORT
  37995     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  37996         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  37997         rv = BCM_E_NONE;
  37998     } else
  37999 #endif
  38000     {
  38001         rv = bcm_esw_port_control_validate(unit, port, type, &port);
  38002     }
  38003     BCM_IF_ERROR_RETURN(rv);
  38004     rv = BCM_E_UNAVAIL;
  38005 
  38006     /*
  38007      * At this point, 'port' can be:
  38008      *    GPORT WLAN
  38009      *    GPORT PROXY
  38010      *    BCM valid local port
  38011      *
  38012      * Some switch cases only handles 'port' in BCM port format
  38013      * (non-gport).  Corresponding checks must be added in those
  38014      * cases to ensure that 'port' is not a gport.
  38015      */
  38016     switch (type) {
  38017     case bcmPortControlBridge:
  38018         if (BCM_GPORT_IS_SET(port)) {
  38019             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38020                                        PORT_BRIDGEf, value);
  38021         } else {
  38022             PORT_LOCK(unit);
  38023             rv = _bcm_esw_port_control_bridge_set(unit, port, value);
  38024             PORT_UNLOCK(unit);
  38025         }
  38026         break;
  38027     case bcmPortControlTrunkHashSet:
  38028 #if defined(BCM_TRIUMPH3_SUPPORT)
  38029         if (SOC_IS_TRIUMPH3(unit)) {
  38030             return BCM_E_UNAVAIL;
  38031         } else
  38032 #endif /* BCM_TRIUMPH3_SUPPORT */
  38033         {
  38034 #if defined(BCM_BRADLEY_SUPPORT)
  38035             if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) {
  38036                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38037                                            RTAG7_HASH_CFG_SEL_TRUNKf,
  38038                                            (value) ? 1 : 0);
  38039             }
  38040 #endif /* BCM_BRADLEY_SUPPORT */
  38041         }
  38042         break;
  38043     case bcmPortControlFabricTrunkHashSet:
  38044 #if defined(BCM_TRIUMPH3_SUPPORT)
  38045         if (SOC_IS_TRIUMPH3(unit)) {
  38046             return BCM_E_UNAVAIL;
  38047         } else
  38048 #endif /* BCM_TRIUMPH3_SUPPORT */
  38049         {
  38050 #if defined(BCM_BRADLEY_SUPPORT)
  38051             if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) {
  38052                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38053                                            RTAG7_HASH_CFG_SEL_HIGIG_TRUNKf,
  38054                                            (value) ? 1 : 0);
  38055             }
  38056 #endif /* BCM_BRADLEY_SUPPORT */
  38057         }
  38058         break;
  38059     case bcmPortControlECMPHashSet:
  38060 #if defined(BCM_TRIUMPH3_SUPPORT)
  38061         if (SOC_IS_TRIUMPH3(unit)) {
  38062             return BCM_E_UNAVAIL;
  38063         } else
  38064 #endif /* BCM_TRIUMPH3_SUPPORT */
  38065         {
  38066 #if defined(BCM_BRADLEY_SUPPORT)
  38067             if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) {
  38068                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38069                                            RTAG7_HASH_CFG_SEL_ECMPf,
  38070                                            (value) ? 1 : 0);
  38071             }
  38072 #endif /* BCM_BRADLEY_SUPPORT */
  38073         }
  38074         break;
  38075     case bcmPortControlLoadBalanceHashSet:
  38076 #if defined(BCM_TRIUMPH3_SUPPORT)
  38077         if (SOC_IS_TRIUMPH3(unit)) {
  38078             return BCM_E_UNAVAIL;
  38079         } else
  38080 #endif /* BCM_TRIUMPH3_SUPPORT */
  38081         {
  38082 #if defined(BCM_BRADLEY_SUPPORT)
  38083             if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) {
  38084                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38085                                            RTAG7_HASH_CFG_SEL_LBIDf,
  38086                                            (value) ? 1 : 0);
  38087             }
  38088 #endif /* BCM_BRADLEY_SUPPORT */
  38089         }
  38090         break;
  38091     case bcmPortControlLoadBalancingNumber:
  38092 #if defined(BCM_BRADLEY_SUPPORT)
  38093         if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) {
  38094 #if defined(BCM_TOMAHAWK3_SUPPORT)
  38095             if (SOC_IS_TOMAHAWK3(unit)) {
  38096                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38097                                        RTAG7_PORT_LBNf,
  38098                                        (value) & 0x3f);
  38099             } else
  38100 #endif /* BCM_TOMAHAWK3_SUPPORT */
  38101             {
  38102                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38103                                        RTAG7_PORT_LBNf,
  38104                                        (value) & 0xf);
  38105             }
  38106         }
  38107 #endif /* BCM_BRADLEY_SUPPORT */
  38108         break;
  38109     case bcmPortControlErrorSymbolDetect:
  38110 #if defined(BCM_GREYHOUND_SUPPORT)
  38111         if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  38112             SOC_IS_GREYHOUND2(unit)) {
  38113             rv = BCM_E_UNAVAIL;
  38114         } else
  38115 #endif /* BCM_GREYHOUND_SUPPORT */
  38116         {
  38117 #ifdef BCM_XGS3_SWITCH_SUPPORT
  38118             if (SOC_IS_XGS3_SWITCH(unit)) {
  38119                 rv = _bcm_esw_port_err_sym_detect_set(unit, port, value);
  38120             }
  38121 #endif
  38122         }
  38123         break;
  38124     case bcmPortControlErrorSymbolCount:
  38125 #if defined(BCM_GREYHOUND_SUPPORT)
  38126         if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  38127             SOC_IS_GREYHOUND2(unit)) {
  38128             rv = BCM_E_UNAVAIL;
  38129         } else
  38130 #endif /* BCM_GREYHOUND_SUPPORT */
  38131         {
  38132 #ifdef BCM_XGS3_SWITCH_SUPPORT
  38133             if (SOC_IS_XGS3_SWITCH(unit)) {
  38134              int temp = 0;
  38135                 /* Error symbol count is read only and cleared on read. */
  38136                 rv = _bcm_esw_port_err_sym_count_get(unit, port, &temp);
  38137             }
  38138 #endif
  38139         }
  38140         break;
  38141 #if defined(INCLUDE_L3)
  38142     case bcmPortControlIP4:
  38143         if (SOC_IS_XGS3_SWITCH(unit)) {
  38144             if (BCM_GPORT_LOCAL_CPU_IEEE == port) {
  38145                 rv = _bcm_esw_port_tab_set(unit, CMIC_PORT(unit), _BCM_CPU_TABS_ETHER,
  38146                                            V4L3_ENABLEf, (value) ? 1 : 0);
  38147             } else if (BCM_GPORT_LOCAL_CPU_HIGIG == port) {
  38148                 rv = _bcm_esw_port_tab_set(unit, CMIC_PORT(unit), _BCM_CPU_TABS_HIGIG,
  38149                                            V4L3_ENABLEf, (value) ? 1 : 0);
  38150             } else {
  38151                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  38152                                            V4L3_ENABLEf, (value) ? 1 : 0);
  38153             }
  38154 
  38155 #if defined(BCM_TRIUMPH_SUPPORT)
  38156             if (BCM_SUCCESS(rv) &&
  38157                 soc_feature(unit, soc_feature_esm_support)) {
  38158                 if (SOC_IS_TRIUMPH3(unit)) { 
  38159                     break;
  38160                 }
  38161                 if (!BCM_GPORT_IS_SET(port)) {
  38162                     rv = _bcm_tr_l3_enable(unit, port, 0, (value) ? 1 : 0);
  38163                 }
  38164             }
  38165 #endif /* BCM_TRIUMPH_SUPPORT */
  38166         }
  38167         break;
  38168     case bcmPortControlIP6:
  38169         if (SOC_IS_XGS3_SWITCH(unit)) {
  38170             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  38171                                        V6L3_ENABLEf, (value) ? 1 : 0);
  38172 #if defined(BCM_TRIUMPH_SUPPORT)
  38173             if (BCM_SUCCESS(rv) &&
  38174                 soc_feature(unit, soc_feature_esm_support)) {
  38175                 if (SOC_IS_TRIUMPH3(unit)) { 
  38176                     break;
  38177                 }
  38178                 if (!BCM_GPORT_IS_SET(port)) {
  38179                     rv = _bcm_tr_l3_enable(unit, port, BCM_L3_IP6,
  38180                                            (value) ? 1 : 0);
  38181                 }
  38182             }
  38183 #endif /* BCM_TRIUMPH_SUPPORT */
  38184         }
  38185         break;
  38186     case bcmPortControlIP4Mcast:
  38187         if (SOC_IS_XGS3_SWITCH(unit)) {
  38188             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  38189                                        V4IPMC_ENABLEf, (value) ? 1 : 0);
  38190         }
  38191         break;
  38192     case bcmPortControlIP6Mcast:
  38193         if (SOC_IS_XGS3_SWITCH(unit)) {
  38194             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  38195                                        V6IPMC_ENABLEf, (value) ? 1 : 0);
  38196         }
  38197         break;
  38198     case bcmPortControlIPMC4Ucast:
  38199         if (soc_feature(unit, soc_feature_ipmc_unicast)) {
  38200             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  38201                     IPMCV4_UNICAST_MACDA_ENABLEf, (value) ? 1 : 0);
  38202         }
  38203         break;
  38204     case bcmPortControlIPMC6Ucast:
  38205         if (soc_feature(unit, soc_feature_ipmc_unicast)) {
  38206             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  38207                     IPMCV6_UNICAST_MACDA_ENABLEf, (value) ? 1 : 0);
  38208         }
  38209         break;
  38210     case bcmPortControlMpls:
  38211 #if defined(BCM_TRIUMPH_SUPPORT)
  38212         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  38213                                    MPLS_ENABLEf, (value) ? 1 : 0);
  38214 #endif
  38215         break;
  38216     case bcmPortControlMacInMac:
  38217         if (!soc_feature(unit, soc_feature_mim)) {
  38218             break;
  38219         }
  38220 #if defined(BCM_TRIUMPH2_SUPPORT)
  38221         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  38222                                    MIM_TERM_ENABLEf, (value) ? 1 : 0);
  38223         if(rv == BCM_E_NONE) {
  38224 #if defined(BCM_TRIDENT3_SUPPORT)
  38225             if(SOC_IS_TRIDENT3X(unit)) {
  38226                 int app = 0;
  38227                 if (0x0 != value)  {
  38228                     app = CANCUN_APP__PORT_TABLE__MIM_MC_TERM_ENABLE;
  38229                 } else {
  38230                     app = CANCUN_APP__PORT_TABLE__MIM_MC_TERM_DISABLE;
  38231                 }
  38232                 rv = soc_cancun_app_dest_entry_set (unit,
  38233                     PORT_TABm, port, PORT_TYPEf, app, 0x0);
  38234                 if (BCM_E_NONE != rv ) {
  38235                     LOG_ERROR(BSL_LS_BCM_L2,
  38236                         (BSL_META_U(unit,
  38237                         "MIM_MC_TERM_ENABLE cfg error\n")));
  38238                 }
  38239             } else
  38240 #endif
  38241             {
  38242             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  38243                                        MIM_MC_TERM_ENABLEf, (value) ? 1 : 0);
  38244         }
  38245         }
  38246 #endif
  38247         break;
  38248 
  38249     case bcmPortControlMimUcastTermEnable:
  38250         if (!soc_feature(unit, soc_feature_mim)) {
  38251             break;
  38252         }
  38253 #if defined(BCM_TRIUMPH2_SUPPORT)
  38254         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  38255                                    MIM_TERM_ENABLEf, (value) ? 1 : 0);
  38256 #endif
  38257         break;
  38258 
  38259     case bcmPortControlMimMcastTermEnable:
  38260         if (!soc_feature(unit, soc_feature_mim)) {
  38261             break;
  38262         }
  38263 #if defined(BCM_TRIUMPH2_SUPPORT)
  38264         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  38265                                        MIM_MC_TERM_ENABLEf, (value) ? 1 : 0);
  38266 #endif
  38267         break;
  38268 
  38269     case bcmPortControlSrcBmacMissToCpu:
  38270 #ifdef BCM_TRIUMPH2_SUPPORT
  38271         if (SOC_IS_TRIDENT3X(unit)) { /* see SDK-124007 */
  38272             return BCM_E_UNAVAIL;
  38273         }
  38274         if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  38275             SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit) ||
  38276             SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) ||
  38277             SOC_IS_KATANA(unit)) {
  38278             /* 0x2: ToCPU 0x1: Drop(default) */
  38279             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  38280                                        CML_BMAC_NEWf, (value) ? 0x2 : 0x1);
  38281         }
  38282 #endif /* BCM_TRIUMPH2_SUPPORT */
  38283         break;
  38284 
  38285     case bcmPortControlQosRemarkResolution:
  38286 #ifdef BCM_TRIDENT3_SUPPORT
  38287         if (SOC_IS_TRIDENT3X(unit)) {
  38288             /* Two resolution supported by TD3 hardware:
  38289              * 1: Serial resolution.
  38290              * 3: Layered resolution.
  38291              * Default is Layered resolution
  38292              */
  38293             if (value == BCM_PORT_QOS_SERIAL_RESOLUTION) {
  38294                 value = 1;
  38295             } else if (value == BCM_PORT_QOS_LAYERED_RESOLUTION) {
  38296                 value = 3;
  38297             } else {
  38298                 return BCM_E_PARAM;
  38299             }
  38300             rv = _bcm_esw_egr_port_tab_set(unit, port, QOS_CTRL_IDf, value);
  38301         }
  38302 #endif /* BCM_TRIDENT3_SUPPORT */
  38303         break;
  38304 
  38305     case bcmPortControlFabricQueue:
  38306 #if defined(BCM_TRIUMPH2_SUPPORT)
  38307         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  38308 #if defined(BCM_TRIDENT3_SUPPORT)
  38309         if (SOC_IS_TRIDENT3X(unit) &&
  38310             soc_feature(unit, soc_feature_egr_lport_tab_profile)) {
  38311             rv = bcm_esw_port_egr_lport_field_set(
  38312                   unit, port, EGR_LPORT_PROFILEm, EH_EXT_HDR_ENABLEf,
  38313                   (value) ? 1 : 0);
  38314             BCM_IF_ERROR_RETURN(rv);
  38315         }
  38316 #endif
  38317         if (IS_ST_PORT(unit, port)) {
  38318             if (SOC_REG_FIELD_VALID(unit, EGR_PORT_64r, EH_EXT_HDR_ENABLEf)) {
  38319                 rv = soc_reg_field32_modify(unit, EGR_PORT_64r, port,
  38320                                             EH_EXT_HDR_ENABLEf,(value) ? 1 : 0);
  38321             }
  38322             else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EH_EXT_HDR_ENABLEf)){
  38323                 rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  38324                                             EH_EXT_HDR_ENABLEf,(value) ? 1 : 0 );
  38325             }
  38326         } else {
  38327 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  38328             /* Allow CPU port on TD2+ to add extended header */
  38329             if (SOC_IS_TRIDENT2PLUS(unit) && IS_CPU_PORT(unit, port)) {
  38330                 rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  38331                                             EH_EXT_HDR_ENABLEf,(value) ? 1 : 0 );
  38332             }
  38333 #endif
  38334 #if defined(BCM_TOMAHAWK_SUPPORT)
  38335             if (SOC_IS_TOMAHAWKX(unit) && IS_CPU_PORT(unit, port)) {
  38336                 rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  38337                                             EH_EXT_HDR_ENABLEf,(value) ? 1 : 0 );
  38338             }
  38339 #endif
  38340         }
  38341 #endif
  38342         break;
  38343 #endif /* INCLUDE_L3 */
  38344     case bcmPortControlIP4McastL2:
  38345 #if defined(BCM_TRX_SUPPORT)
  38346         if (SOC_IS_TD2_TT2(unit) &&
  38347                 soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm,
  38348                                                  IPMCV4_L2_ENABLEf)) {
  38349             rv = _bcm_trx_source_trunk_map_set(unit, port,
  38350                                   IPMCV4_L2_ENABLEf, (value) ? 1 : 0);
  38351         } else {
  38352             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  38353                                     V4IPMC_L2_ENABLEf, (value) ? 1 : 0);
  38354         }
  38355 #endif /* BCM_TRX_SUPPORT */
  38356         break;
  38357     case bcmPortControlIP6McastL2:
  38358 #if defined(BCM_TRX_SUPPORT)
  38359         if (SOC_IS_TD2_TT2(unit) &&
  38360                 soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm,
  38361                                                  IPMCV6_L2_ENABLEf)) {
  38362             rv = _bcm_trx_source_trunk_map_set(unit, port,
  38363                                   IPMCV6_L2_ENABLEf, (value) ? 1 : 0);
  38364         } else {
  38365             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  38366                                        V6IPMC_L2_ENABLEf, (value) ? 1 : 0);
  38367         }
  38368 #endif /* BCM_TRX_SUPPORT */
  38369         break;
  38370     case bcmPortControlPassControlFrames:
  38371         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  38372 #ifdef BCM_XGS3_SWITCH_SUPPORT
  38373         if (SOC_IS_XGS3_SWITCH(unit) && IS_E_PORT(unit, port)) {
  38374             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE,
  38375                                        PASS_CONTROL_FRAMESf,
  38376                                        (value) ? 1 : 0);
  38377         }
  38378 #endif
  38379 #ifdef BCM_XGS_SWITCH_SUPPORT
  38380         if (IS_XE_PORT(unit, port) || IS_CE_PORT(unit, port) ||
  38381             (IS_GE_PORT(unit, port)
  38382              && soc_feature(unit, soc_feature_unified_port)) ||
  38383             (SOC_IS_KATANAX(unit) && IS_MXQ_PORT(unit, port))) {
  38384             /* Enable Control Frames in BigMAC */
  38385             if(soc_feature(unit, soc_feature_pgw_mac_control_frame)) {
  38386                 uint32 rval32 = 0;
  38387                 PORT_LOCK(unit);
  38388                 rv = READ_PGW_MAC_RSV_MASKr(unit, port, &rval32);
  38389                 if (BCM_SUCCESS(rv)) {
  38390                     /* PGW_MAC_RSV_MASK: Bit 11 Control Frame recieved
  38391                      * Enable  Control Frame : Set 0. Packet go through
  38392                      * Disable Control Frame : Set 1. Packet is purged.
  38393                      */
  38394                     if(value) {
  38395                         rval32 &= ~(1 << 11);
  38396                     } else {
  38397                         rval32 |= (1 << 11);
  38398                     }
  38399                     rv = WRITE_PGW_MAC_RSV_MASKr(unit, port, rval32);
  38400                 }
  38401                 PORT_UNLOCK(unit);
  38402             } else {
  38403                 PORT_LOCK(unit);
  38404 
  38405                 if (SOC_IS_SABER2(unit)) {
  38406                     if (IS_MXQ_PORT(unit, port)) {
  38407                         rv = soc_reg_field32_modify(unit, XPORT_CONFIGr, port,
  38408                                                    PASS_PAUSE_FRAMEf, value ? 1 : 0);
  38409                         if (rv == SOC_E_NONE) 
  38410                             rv = soc_reg_field32_modify(unit, XPORT_CONFIGr, port,
  38411                                                    PASS_CONTROL_FRAMEf, value ? 1 : 0);
  38412                     } else {
  38413                         rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port,
  38414                                                    PASS_PAUSE_FRAMEf, value ? 1 : 0);
  38415                         if (rv == SOC_E_NONE) 
  38416                             rv = soc_reg_field32_modify(unit,  IECELL_CONFIGr, port,
  38417                                                    PASS_CONTROL_FRAMEf, value ? 1 : 0);
  38418                     }
  38419                 }   
  38420                 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  38421                                      SOC_MAC_PASS_CONTROL_FRAME, value);
  38422                 PORT_UNLOCK(unit);
  38423             }
  38424         }
  38425 #endif
  38426         break;
  38427 #ifdef BCM_XGS3_SWITCH_SUPPORT
  38428     case bcmPortControlFilterLookup:
  38429 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  38430         value = value ? 1 : 0;
  38431             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38432                                        VFP_ENABLEf, value);
  38433 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  38434         break;
  38435     case bcmPortControlFilterIngress:
  38436         value = value ? 1 : 0;
  38437             /* Enable/disable ingress filtering. */
  38438         if (BCM_GPORT_LOCAL_CPU_IEEE == port) {
  38439             rv = _bcm_esw_port_tab_set(unit, CMIC_PORT(unit), _BCM_CPU_TABS_ETHER,
  38440                                        FILTER_ENABLEf, value);
  38441         } else if (BCM_GPORT_LOCAL_CPU_HIGIG == port) {
  38442             rv = _bcm_esw_port_tab_set(unit, CMIC_PORT(unit), _BCM_CPU_TABS_HIGIG,
  38443                                        FILTER_ENABLEf, value);
  38444         } else {
  38445             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38446                                        FILTER_ENABLEf, value);
  38447         }
  38448 
  38449         break;
  38450     case bcmPortControlFilterEgress:
  38451 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  38452         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  38453         value = value ? 1 : 0;
  38454         /* Enable/disable egress filtering. */
  38455         if (SOC_REG_FIELD_VALID(unit, egr_port_reg, EFP_FILTER_ENABLEf)) {
  38456             rv = soc_reg_field32_modify(unit, egr_port_reg, port,
  38457                                         EFP_FILTER_ENABLEf, value);
  38458         } else {
  38459             rv = _bcm_esw_egr_port_tab_set(unit, port,
  38460                                         EFP_FILTER_ENABLEf, value);
  38461         }
  38462 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  38463         break;
  38464     case bcmPortControlFrameSpacingStretch:
  38465         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  38466         rv = (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  38467                               SOC_MAC_CONTROL_FRAME_SPACING_STRETCH,
  38468                               value));
  38469         break;
  38470     case bcmPortControlPreservePacketPriority:
  38471 #if ((defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)) \
  38472     || defined(BCM_RAVEN_SUPPORT))
  38473         if (SOC_IS_TRIUMPH3(unit)) {
  38474             /* Triumph3 has unity mapping to ING_OUTER_DOT1P_MAPPING_TABLE */
  38475             if (value) {
  38476                 /* Remap pointer to default dot1p profile */
  38477                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38478                                            DOT1P_REMAP_POINTERf, 0);
  38479             }
  38480         } else {
  38481             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38482                                        USE_INCOMING_DOT1Pf, (value) ? 1 : 0);
  38483         }
  38484 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || defined(BCM_RAVEN_SUPPORT) */
  38485 #if defined(BCM_SHADOW_SUPPORT)
  38486         if (SOC_IS_SHADOW(unit)) {
  38487             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  38488             rv = soc_reg_field32_modify(unit, PRIORITY_MAPPING_SELECTr, port,
  38489                                         USE_INPUT_PRIORIYf, 1 );
  38490         }
  38491 #endif
  38492         break;
  38493     case bcmPortControlLearnClassEnable:
  38494 #if defined(BCM_TRX_SUPPORT)
  38495         if (soc_feature(unit, soc_feature_class_based_learning)) {
  38496             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38497                                        CLASS_BASED_SM_ENABLEf, value ? 1 : 0);
  38498         }
  38499 #endif /* BCM_TRX_SUPPORT */
  38500           break;
  38501     case bcmPortControlTrustIncomingVlan:
  38502 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_TRX_SUPPORT)
  38503         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38504                                    TRUST_INCOMING_VIDf, (value) ? 1 : 0);
  38505 #endif /* BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
  38506           break;
  38507     case bcmPortControlDoNotCheckVlan:
  38508 #if defined(BCM_TRX_SUPPORT)
  38509 #if defined(BCM_TRIDENT3_SUPPORT)
  38510         if (SOC_IS_TRIDENT3X(unit)) {
  38511             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38512                                        DISABLE_VLAN_CHECKSf, (value) ? 1 : 0);
  38513             BCM_IF_ERROR_RETURN(rv);
  38514         }
  38515 #endif
  38516         if (soc_mem_field_valid(unit, PORT_TABm, DISABLE_VLAN_CHECKSf)) {
  38517             if (CMIC_PORT(unit) == port) {
  38518                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_HIGIG,
  38519                                            DISABLE_VLAN_CHECKSf, (value) ? 1 : 0);
  38520             } else {
  38521                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38522                                            DISABLE_VLAN_CHECKSf, (value) ? 1 : 0);
  38523             }
  38524         } else if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm,
  38525                     DISABLE_VLAN_CHECKSf)) {
  38526 #if defined(BCM_KATANA2_SUPPORT)
  38527             if (SOC_IS_KATANA2(unit)) {
  38528                 rv = _bcm_kt2_source_trunk_map_set(unit, port,
  38529                         DISABLE_VLAN_CHECKSf, (value) ? 1 : 0);
  38530             } else
  38531 #endif
  38532             {
  38533                 rv = _bcm_trx_source_trunk_map_set(unit, port,
  38534                         DISABLE_VLAN_CHECKSf, (value) ? 1 : 0);
  38535             }
  38536         }
  38537 #endif /* BCM_TRX_SUPPORT */
  38538         break;
  38539     case bcmPortControlDoNotCheckVlanFromCpu:
  38540 #if defined(BCM_TRX_SUPPORT)
  38541 #if defined(BCM_TRIDENT3_SUPPORT)
  38542         if (CMIC_PORT(unit) == port) {
  38543             if (SOC_IS_TRIDENT3X(unit)) {
  38544                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  38545                                        DISABLE_VLAN_CHECKSf, (value) ? 1 : 0);
  38546                 BCM_IF_ERROR_RETURN(rv);
  38547             }
  38548         }
  38549 #endif
  38550         if (CMIC_PORT(unit) == port) {
  38551             if (soc_mem_field_valid(unit, PORT_TABm, DISABLE_VLAN_CHECKSf)) {
  38552                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  38553                                        DISABLE_VLAN_CHECKSf, (value) ? 1 : 0);
  38554             } else if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm,
  38555                         DISABLE_VLAN_CHECKSf)) {
  38556                 rv = _bcm_trx_source_trunk_map_set(unit, port,
  38557                     DISABLE_VLAN_CHECKSf, (value) ? 1 : 0);
  38558             }
  38559         } else {
  38560             rv = BCM_E_PORT;
  38561         }
  38562 #endif /* BCM_TRX_SUPPORT */
  38563         break;
  38564     case bcmPortControlIEEE8021ASEnableIngress:
  38565         if (soc_feature(unit, soc_feature_rx_timestamp)) {
  38566             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38567                                        IEEE_802_1AS_ENABLEf, (value) ? 1 : 0);
  38568         }
  38569         break;
  38570     case bcmPortControlIEEE8021ASEnableEgress:
  38571 #if defined(BCM_HAWKEYE_SUPPORT)
  38572         if (SOC_IS_HAWKEYE(unit)) {
  38573             rv = soc_reg_field32_modify(unit, EGR_PORTr, port,
  38574                                         IEEE_802_1AS_ENABLEf, (value) ? 1 : 0);
  38575         }
  38576 #endif /* BCM_HAWKEYE_SUPPORT */
  38577         break;
  38578     case bcmPortControlEgressVlanPriUsesPktPri:
  38579 #if defined(BCM_TRX_SUPPORT)
  38580         if (SOC_IS_TRX(unit) && !SOC_IS_SHADOW(unit)) {
  38581 #if defined (BCM_HGPROXY_COE_SUPPORT)
  38582             if (!(soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  38583                 BCM_GPORT_IS_SUBPORT_PORT(port)))
  38584 #endif
  38585             {
  38586                 BCM_IF_ERROR_RETURN(
  38587                     _bcm_esw_port_gport_validate(unit, port, &port));
  38588             }
  38589 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  38590             if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
  38591                 if (soc_feature(unit, soc_feature_egr_all_profile)) {
  38592                     rv = bcm_esw_port_egr_lport_field_set(unit,
  38593                         port, EGR_VLAN_CONTROL_1m, REMARK_OUTER_DOT1Pf,
  38594                         value ? 0 : 1);
  38595                 } else {
  38596 #if defined (BCM_HGPROXY_COE_SUPPORT)
  38597                     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  38598                         BCM_GPORT_IS_SUBPORT_PORT(port)) {
  38599                         rv = bcm_esw_port_egr_lport_field_set(
  38600                                 unit, port, EGR_VLAN_CONTROL_1m,
  38601                                 REMARK_OUTER_DOT1Pf, value ? 0 : 1);
  38602                     } else
  38603 #endif
  38604                     {
  38605                         rv = soc_mem_field32_modify(
  38606                                 unit, EGR_VLAN_CONTROL_1m, port,
  38607                                 REMARK_OUTER_DOT1Pf, value ? 0 : 1);
  38608                     }
  38609                 }
  38610             } else
  38611 #endif
  38612             {
  38613                 rv = soc_reg_field32_modify(unit, EGR_VLAN_CONTROL_1r, port,
  38614                                             REMARK_OUTER_DOT1Pf,
  38615                                             value ? 0 : 1);
  38616 #if defined(BCM_GREYHOUND_SUPPORT)
  38617                 if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) {
  38618                     if (BCM_FAILURE(rv)) {
  38619                         return rv;
  38620                     }
  38621                     /*
  38622                      * Make sure TREAT_PKTPRI_AS_DOT1P bit is set for
  38623                      * Egress VLAN internal priority mapping.
  38624                      */
  38625                     rv = bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update
  38626                              (unit, (value) ? 1 : -1);
  38627                 }
  38628 #endif /* BCM_GREYHOUND_SUPPORT */
  38629             }
  38630         }
  38631 #endif /* BCM_TRX_SUPPORT */
  38632         break;
  38633     case bcmPortControlEgressModifyDscp:
  38634 #if defined(BCM_TRX_SUPPORT)
  38635         if (SOC_IS_TRX(unit) && !SOC_IS_SHADOW(unit)) {
  38636             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  38637 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  38638             if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
  38639                 if (soc_feature(unit, soc_feature_egr_all_profile)) {
  38640                     rv = bcm_esw_port_egr_lport_field_set(unit,
  38641                         port, EGR_VLAN_CONTROL_1m, REMARK_OUTER_DSCPf,
  38642                         value ? 1 : 0);
  38643                 } else {
  38644                     rv = soc_mem_field32_modify(unit,
  38645                         EGR_VLAN_CONTROL_1m, port, REMARK_OUTER_DSCPf,
  38646                         value ? 1 : 0);
  38647                 }
  38648             } else
  38649 #endif
  38650             {
  38651                 rv = soc_reg_field32_modify(unit, EGR_VLAN_CONTROL_1r, port,
  38652                                             REMARK_OUTER_DSCPf,
  38653                                             value ? 1 : 0);
  38654             }
  38655         }
  38656 #endif /* BCM_TRX_SUPPORT */
  38657         break;
  38658     case bcmPortControlIpfixRate:
  38659 #ifdef BCM_TRIUMPH2_SUPPORT
  38660         if (soc_feature(unit, soc_feature_ipfix_rate)) {
  38661             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38662                                        IPFIX_FLOW_METER_IDf, value);
  38663         }
  38664 #endif /* BCM_TRIUMPH2_SUPPORT */
  38665         break;
  38666     case bcmPortControlCustomerQueuing:
  38667         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  38668 #ifdef BCM_ENDURO_SUPPORT
  38669         if (SOC_IS_ENDURO(unit) && !IS_HG_PORT(unit, port)) {
  38670             return BCM_E_UNAVAIL;
  38671         }
  38672 #endif
  38673 #ifdef BCM_HELIX5_SUPPORT
  38674         if (SOC_IS_HELIX5(unit)) {
  38675             uint64 rval64, rval64_tmp, rval64_reset_tmp;
  38676             soc_reg_t reg;
  38677             uint32 phy_port;
  38678             uint32 mmu_port;
  38679             soc_info_t *si = &SOC_INFO(unit);
  38680 
  38681             if (value < 0 || value > 1) {
  38682                 return BCM_E_PARAM;
  38683             }
  38684 
  38685             COMPILER_64_ZERO(rval64);
  38686             COMPILER_64_ZERO(rval64_tmp);
  38687             COMPILER_64_ZERO(rval64_reset_tmp);
  38688             rv = soc_reg_get(unit, ING_COS_MODEr, port, 0, &rval64);
  38689             BCM_IF_ERROR_RETURN(rv);
  38690             soc_reg64_field32_set(unit, ING_COS_MODEr, &rval64, COS_MODEf,
  38691                     value);
  38692             rv = soc_reg_set(unit, ING_COS_MODEr, port, 0, rval64);
  38693             BCM_IF_ERROR_RETURN(rv);
  38694 
  38695             phy_port = si->port_l2p_mapping[port];
  38696             mmu_port = si->port_p2m_mapping[phy_port];
  38697             mmu_port &= (SOC_HX5_MMU_PORT_STRIDE - 1);
  38698 
  38699             if (mmu_port < 16) {
  38700                 reg = COS_MODE_SPLIT0r;  /* 2 bits per Port 0-15 */
  38701                 COMPILER_64_SET(rval64_tmp, 0, (1 << (mmu_port * 2)));
  38702                 COMPILER_64_SET(rval64_reset_tmp, 0, (3 << (mmu_port * 2)));
  38703             } else {
  38704                 reg = COS_MODE_64_SPLIT1r; /* 1 bit per Port 16-71 */
  38705                 mmu_port -= 16;
  38706                 if (mmu_port < 32) {
  38707                     COMPILER_64_SET(rval64_tmp, 0, (1 << mmu_port));
  38708                 } else {
  38709                     COMPILER_64_SET(rval64_tmp, (1 << (mmu_port - 32)), 0);
  38710                 }
  38711                 COMPILER_64_COPY(rval64_reset_tmp, rval64_tmp);
  38712             }
  38713 
  38714             SOC_IF_ERROR_RETURN
  38715                 (soc_trident3_xpe_reg_get(unit, reg, -1, si->port_pipe[port],
  38716                                           0, &rval64));
  38717             if (value) {
  38718                 COMPILER_64_OR(rval64, rval64_tmp);
  38719             } else {
  38720                 COMPILER_64_NOT(rval64_reset_tmp);
  38721                 COMPILER_64_AND(rval64, rval64_reset_tmp);
  38722             }
  38723             SOC_IF_ERROR_RETURN
  38724                 (soc_trident3_xpe_reg_set(unit, reg, -1, si->port_pipe[port],
  38725                                           0, rval64));
  38726             rv = BCM_E_NONE;
  38727             break;
  38728         }
  38729 #endif /* BCM_HELIX5_SUPPORT */
  38730 #ifdef BCM_TRIDENT3_SUPPORT
  38731         if (SOC_IS_TRIDENT3X(unit)) {
  38732             uint64 rval64, rval64_tmp;
  38733             soc_reg_t reg;
  38734             uint32 pipe_portNum;
  38735             soc_info_t *si = &SOC_INFO(unit);
  38736 
  38737             if (value < 0 || value > 1) {
  38738                 return BCM_E_PARAM;
  38739             }
  38740 
  38741             COMPILER_64_ZERO(rval64);
  38742             COMPILER_64_ZERO(rval64_tmp);
  38743             rv = soc_reg_get(unit, ING_COS_MODEr, port, 0, &rval64);
  38744             BCM_IF_ERROR_RETURN(rv);
  38745             soc_reg64_field32_set(unit, ING_COS_MODEr, &rval64, COS_MODEf,
  38746                                   value);
  38747             rv = soc_reg_set(unit, ING_COS_MODEr, port, 0, rval64);
  38748             BCM_IF_ERROR_RETURN(rv);
  38749 
  38750             pipe_portNum = port % _TD3_PORTS_PER_PIPE;
  38751             if (pipe_portNum < 64) {
  38752                 reg = COS_MODE_64_SPLIT0r;
  38753             } else {
  38754                 reg = COS_MODE_SPLIT1r;
  38755             }
  38756 
  38757             if (pipe_portNum < 32) {
  38758                 COMPILER_64_SET(rval64_tmp, 0, (1 << pipe_portNum));
  38759             } else {
  38760                 COMPILER_64_SET(rval64_tmp, (1 << (pipe_portNum - 32)), 0);
  38761             }
  38762 
  38763             SOC_IF_ERROR_RETURN
  38764                 (soc_trident3_xpe_reg_get(unit, reg, -1, si->port_pipe[port],
  38765                                           0, &rval64));
  38766             if (value) {
  38767                 COMPILER_64_OR(rval64, rval64_tmp);
  38768             } else {
  38769                 COMPILER_64_NOT(rval64_tmp);
  38770                 COMPILER_64_AND(rval64, rval64_tmp);
  38771             }
  38772 
  38773             SOC_IF_ERROR_RETURN
  38774                 (soc_trident3_xpe_reg_set(unit, reg, -1, si->port_pipe[port],
  38775                                           0, rval64));
  38776             rv = BCM_E_NONE;
  38777             break;
  38778         }
  38779 #endif /* BCM_TRIDENT3_SUPPORT */
  38780 #ifdef BCM_TOMAHAWK_SUPPORT
  38781         if (SOC_IS_TOMAHAWKX(unit)) {
  38782             uint64 rval64, rval64_tmp;
  38783             int pipe, phy_port, mmu_port;
  38784             soc_info_t *si;
  38785 
  38786             if (SOC_REG_IS_VALID(unit, ING_COS_MODEr)) {
  38787 
  38788                 if (value < 0 || value > 1) {
  38789                     return BCM_E_PARAM;
  38790                 }
  38791 
  38792                 COMPILER_64_ZERO(rval64);
  38793                 COMPILER_64_ZERO(rval64_tmp);
  38794 
  38795                 rv = soc_reg_get(unit, ING_COS_MODEr, port, 0, &rval64);
  38796                 BCM_IF_ERROR_RETURN(rv);
  38797                 soc_reg64_field32_set(unit, ING_COS_MODEr, &rval64, COS_MODEf,
  38798                                       value);
  38799                 rv = soc_reg_set(unit, ING_COS_MODEr, port, 0, rval64);
  38800                 BCM_IF_ERROR_RETURN(rv);
  38801 
  38802                 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, port, &pipe));
  38803                 si = &SOC_INFO(unit);
  38804                 phy_port = si->port_l2p_mapping[port];
  38805                 mmu_port = si->port_p2m_mapping[phy_port];
  38806                 mmu_port &= (SOC_TH_MMU_PORT_STRIDE - 1);
  38807 
  38808                 COMPILER_64_SET(rval64_tmp, 0, (1 << mmu_port));
  38809                 COMPILER_64_ZERO(rval64);
  38810                 SOC_IF_ERROR_RETURN
  38811                     (soc_tomahawk_xpe_reg_get(unit, COS_MODE_64r, -1, pipe, 0,
  38812                                               &rval64));
  38813                 if (value) {
  38814                     COMPILER_64_OR(rval64, rval64_tmp);
  38815                 } else {
  38816                     COMPILER_64_NOT(rval64_tmp);
  38817                     COMPILER_64_AND(rval64, rval64_tmp);
  38818                 }
  38819 
  38820                 SOC_IF_ERROR_RETURN
  38821                     (soc_tomahawk_xpe_reg_set(unit, COS_MODE_64r, -1, pipe, 0,
  38822                                               rval64));
  38823                 rv = BCM_E_NONE;
  38824             }
  38825             break;
  38826         }
  38827 #endif /* BCM_TOMAHAWK_SUPPORT */
  38828 
  38829 #ifdef BCM_TRIDENT2_SUPPORT
  38830         if (SOC_IS_TD2_TT2(unit)) {
  38831             uint32 fval = 0;
  38832             uint64 rval;
  38833 
  38834             if (value <= 4) {
  38835                 fval = value;
  38836             }
  38837 
  38838             if (!SOC_REG_FIELD_VALID(unit, ING_COS_MODE_64r, QUEUE_MODEf)) {
  38839                 return BCM_E_UNAVAIL;
  38840             }
  38841 
  38842             rv = READ_ING_COS_MODE_64r(unit, port, &rval);
  38843             BCM_IF_ERROR_RETURN(rv);
  38844  
  38845             soc_reg64_field32_set(unit, ING_COS_MODE_64r, &rval,
  38846                                   QUEUE_MODEf, fval);
  38847             rv = WRITE_ING_COS_MODE_64r(unit, port, rval);
  38848             break;
  38849         }
  38850 #endif /* BCM_TRIDENT2_SUPPORT */
  38851 #ifdef BCM_TRIUMPH2_SUPPORT
  38852         if (soc_feature(unit, soc_feature_vlan_queue_map)) {
  38853             uint32 fval = 0;
  38854             if (SOC_IS_TRIUMPH3(unit)) {
  38855                 if (value <= 4) {
  38856                     fval = value;
  38857                 }
  38858             } else {
  38859             if (value) {
  38860                 fval = 3;
  38861             } else {
  38862                 fval = 0;
  38863             }
  38864             }
  38865 
  38866             rv = BCM_E_UNAVAIL;
  38867 
  38868             if (SOC_REG_IS_VALID(unit, ING_COS_MODEr)) {
  38869                 if (SOC_REG_FIELD_VALID(unit, ING_COS_MODEr, SELECTf)) {
  38870                     rv = soc_reg_field32_modify(unit, ING_COS_MODEr, port,
  38871                                                 SELECTf, fval);
  38872                 }
  38873                 if (SOC_REG_FIELD_VALID(unit, ING_COS_MODEr, QUEUE_MODEf)) {
  38874                     rv = soc_reg_field32_modify(unit, ING_COS_MODEr, port,
  38875                                                 QUEUE_MODEf, fval);
  38876                     /* 0 - COS1 port COS, 1 - COS2 vlan COS */
  38877                     rv = soc_reg_field32_modify(unit, ING_COS_MODEr, port,
  38878                                                 COS_MODEf, 1);
  38879 
  38880                 }
  38881             }
  38882             if (SOC_REG_IS_VALID(unit, COS_MODEr)) {
  38883                 if (SOC_REG_FIELD_VALID(unit, COS_MODEr, SELECTf)) {
  38884                     rv = soc_reg_field32_modify(unit, COS_MODEr, REG_PORT_ANY,
  38885                                                 SELECTf, fval);
  38886                 }
  38887             }
  38888 
  38889         }
  38890 #endif /* BCM_TRIUMPH2_SUPPORT */
  38891 #ifdef BCM_KATANA_SUPPORT
  38892         if (SOC_IS_KATANAX(unit)) {
  38893             uint32 ing_cos_mode ;
  38894             uint32 rqe_cos_mode;
  38895             uint32      rval = 0;
  38896 /*
  38897  * If custom queueing is enabled the ing_cos_mode is set to 1 but 1 is not
  38898  * valid for rqe_cos_mode
  38899  * setting it to 0 if the ing_cos_mode is 1.
  38900  * if value is 4 that means configure service queuing only for unicast
  38901  * traffic. i.e if value = 4 then ing_cos_mode = 3 and rqe_cos_mode 0 or 2.
  38902  */         if (value == 4) {
  38903                 ing_cos_mode = 3;
  38904             } else {
  38905             ing_cos_mode = (value <= 3 ? value : 0);
  38906             }
  38907             if (IS_HG_PORT(unit, port)) {
  38908                 rqe_cos_mode = ((ing_cos_mode == 1) || (value == 4)) ? 2 : ing_cos_mode;
  38909             } else {
  38910                 rqe_cos_mode = ((ing_cos_mode == 1) || (value == 4)) ? 0 : ing_cos_mode;
  38911             }
  38912 
  38913             if (SOC_REG_FIELD_VALID(unit, ING_COS_MODEr, COS_MODEf)) {
  38914                 rv = soc_reg_field32_modify(unit, ING_COS_MODEr, port,
  38915                                             COS_MODEf, ing_cos_mode);
  38916             }
  38917 
  38918             if (SOC_IS_KATANA(unit)) {
  38919                 SOC_IF_ERROR_RETURN(READ_RQE_PORT_CONFIGr(unit, port, &rval));
  38920                 soc_reg_field_set(unit, RQE_PORT_CONFIGr, &rval, COS_MODEf,
  38921                                   rqe_cos_mode);
  38922                 SOC_IF_ERROR_RETURN(WRITE_RQE_PORT_CONFIGr(unit, port, rval));
  38923             } else {
  38924 #if defined(BCM_KATANA2_SUPPORT)
  38925                 if (SOC_IS_KATANA2(unit)) {
  38926                     SOC_IF_ERROR_RETURN(READ_RQE_PP_PORT_CONFIGr(unit, port, &rval));
  38927                     soc_reg_field_set(unit, RQE_PP_PORT_CONFIGr, &rval, COS_MODEf,
  38928                                       rqe_cos_mode);
  38929                     SOC_IF_ERROR_RETURN(WRITE_RQE_PP_PORT_CONFIGr(unit, port, rval));
  38930                 }
  38931 #endif
  38932             }
  38933         }
  38934 #endif /* BCM_KATANA_SUPPORT */
  38935         break;
  38936 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  38937 
  38938 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_APOLLO_SUPPORT)
  38939     case bcmPortControlOAMEnable:
  38940         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  38941                                    OAM_ENABLEf, value ? 1 : 0);
  38942 #if defined(BCM_KATANA2_SUPPORT)
  38943         if (SOC_IS_KATANA2(unit)) {
  38944             rv = _bcm_esw_egr_port_tab_set(unit, port,
  38945                                    OAM_ENABLEf, value ? 1 : 0);
  38946         }
  38947 #endif
  38948         break;
  38949 #endif /* defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_APOLLO_SUPPORT) */
  38950 
  38951 #if defined(BCM_OLP_SUPPORT)
  38952     case bcmPortControlOlpEnable:
  38953 
  38954         if (soc_feature(unit, soc_feature_olp)) {
  38955             ing_en_efilter_bitmap_entry_t efilter_entry;
  38956             bcm_module_t module_id = 0;
  38957             bcm_module_t my_modid;
  38958             bcm_port_t port_id;
  38959             bcm_trunk_t trunk_id = BCM_TRUNK_INVALID;
  38960             int         local_id;
  38961             uint32      olp_enable;
  38962             pbmp_t      pbmp;
  38963 
  38964             olp_enable = value ? 1 : 0;
  38965 
  38966             BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
  38967 
  38968             if (BCM_GPORT_IS_SET(port)) {
  38969                 SOC_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, &module_id, 
  38970                             &port_id, &trunk_id, &local_id));
  38971 
  38972 #if defined(BCM_KATANA2_SUPPORT) 
  38973                 if (SOC_IS_KATANA2(unit) && 
  38974                         (BCM_GPORT_IS_SUBPORT_PORT(port)) &&
  38975                         ((_BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) ||
  38976                          (_BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port)))) {
  38977 
  38978                     LOG_ERROR(BSL_LS_BCM_L2,
  38979                             (BSL_META_U(unit,
  38980                                         "OLP is not allowed on SUBPORT. \
  38981                                         \n")));
  38982                     return BCM_E_PARAM;
  38983                 }
  38984 #endif        
  38985             } else { 
  38986                 port_id = port;
  38987             }
  38988             if ((module_id == 0) || (module_id == my_modid)) {
  38989 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  38990                 if(SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) {
  38991                     iarb_ing_port_table_entry_t entry;
  38992                     port_tab_entry_t            port_entry;
  38993                     uint64                      mac;
  38994                     int                         prefix_check = 0;
  38995 
  38996                     SOC_IF_ERROR_RETURN(soc_mem_read(unit, IARB_ING_PORT_TABLEm, 
  38997                                         MEM_BLOCK_ANY, port_id, &entry));
  38998                     soc_IARB_ING_PORT_TABLEm_field32_set(unit, &entry, 
  38999                                                           OLP_ENABLEf, olp_enable);
  39000                     SOC_IF_ERROR_RETURN(soc_mem_write(unit, IARB_ING_PORT_TABLEm, 
  39001                                          MEM_BLOCK_ALL, port_id, &entry));
  39002 
  39003 
  39004                     /* Enable/Disable the prefix checking on the OLP port
  39005                      * If OLP is being enabled  - Disable prefix checking
  39006                      * If OLP is being disabled - Enable prefix checking if it
  39007                      *                            is configured.
  39008                      */
  39009                     prefix_check = 0;
  39010                     if (0 == olp_enable) {
  39011                         SOC_IF_ERROR_RETURN(READ_ING_OLP_CONFIG_0_64r(unit, &mac));
  39012                         if (!COMPILER_64_IS_ZERO(mac)) {
  39013                             prefix_check = 1;
  39014                         }
  39015                     }
  39016                     SOC_IF_ERROR_RETURN(READ_PORT_TABm(unit,
  39017                                                        MEM_BLOCK_ANY,
  39018                                                        port_id,
  39019                                                        &port_entry));
  39020                     soc_PORT_TABm_field32_set(unit,
  39021                                               &port_entry,
  39022                                               OLP_MAC_DA_PREFIX_CHECK_ENABLEf,
  39023                                               prefix_check);
  39024 
  39025                     SOC_IF_ERROR_RETURN(WRITE_PORT_TABm(unit,
  39026                                                         MEM_BLOCK_ALL,
  39027                                                         port_id,
  39028                                                         &port_entry));
  39029                 } else 
  39030 #endif
  39031                 {
  39032                     iarb_ing_physical_port_entry_t  entry;
  39033                     ing_physical_port_table_entry_t port_entry;
  39034                     uint64                          mac;
  39035                     int                             prefix_check = 0;
  39036 
  39037                     SOC_IF_ERROR_RETURN(soc_mem_read(unit, IARB_ING_PHYSICAL_PORTm, 
  39038                                          MEM_BLOCK_ANY, port_id, &entry));
  39039                     soc_IARB_ING_PHYSICAL_PORTm_field32_set(unit, &entry, 
  39040                                          OLP_ENABLEf, olp_enable);
  39041                     SOC_IF_ERROR_RETURN(soc_mem_write(unit, IARB_ING_PHYSICAL_PORTm, 
  39042                                          MEM_BLOCK_ALL, port_id, &entry));
  39043 
  39044                     /* Enable/Disable the prefix checking on the OLP port
  39045                      * If OLP is being enabled  - Disable prefix checking
  39046                      * If OLP is being disabled - Enable prefix checking if it
  39047                      *                            is configured.
  39048                      */
  39049                     prefix_check = 0;
  39050                     if (0 == olp_enable) {
  39051                         SOC_IF_ERROR_RETURN(READ_ING_OLP_CONFIG_0_64r(unit, &mac));
  39052                         if (!COMPILER_64_IS_ZERO(mac)) {
  39053                             prefix_check = 1;
  39054                         }
  39055                     }
  39056                     SOC_IF_ERROR_RETURN(
  39057                                    READ_ING_PHYSICAL_PORT_TABLEm(unit,
  39058                                                                  MEM_BLOCK_ANY,
  39059                                                                  port_id,
  39060                                                                  &port_entry));
  39061 
  39062                     soc_ING_PHYSICAL_PORT_TABLEm_field32_set(unit,
  39063                                                              &port_entry,
  39064                                                              OLP_MAC_DA_PREFIX_CHECK_ENABLEf,
  39065                                                              prefix_check);
  39066                     SOC_IF_ERROR_RETURN(
  39067                                    WRITE_ING_PHYSICAL_PORT_TABLEm(unit,
  39068                                                                   MEM_BLOCK_ALL,
  39069                                                                   port_id,
  39070                                                                   &port_entry));
  39071                 }
  39072                 /* Disable EFILTER */
  39073                 SOC_IF_ERROR_RETURN(soc_mem_read(unit, ING_EN_EFILTER_BITMAPm, 
  39074                                        MEM_BLOCK_ANY, 0, &efilter_entry));
  39075                 soc_mem_pbmp_field_get(unit, ING_EN_EFILTER_BITMAPm,
  39076                                        &efilter_entry, BITMAPf, &pbmp);
  39077                 if (olp_enable) {
  39078                     SOC_PBMP_PORT_REMOVE(pbmp, port_id);
  39079                 } else {
  39080                     SOC_PBMP_PORT_ADD(pbmp, port_id);
  39081                 }
  39082                 soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm,
  39083                         &efilter_entry, BITMAPf, &pbmp);
  39084                 SOC_IF_ERROR_RETURN(soc_mem_write(unit, ING_EN_EFILTER_BITMAPm, 
  39085                             MEM_BLOCK_ALL, 0, &efilter_entry));
  39086             }
  39087             rv = BCM_E_NONE;
  39088         }
  39089         break;
  39090 #endif /* BCM_OLP_SUPPORT */
  39091 
  39092 #if defined(BCM_KATANA2_SUPPORT) || defined (BCM_APACHE_SUPPORT)
  39093     case bcmPortControlPortMacOui:
  39094     case bcmPortControlPortMacNonOui:
  39095 
  39096         /*
  39097          * In case of KT2, SB2 and TD2+ NONTCAM STATION related to OAM, OLP, XGS can be programmed
  39098          * by either of bcm_l2_station_xxx API or  bcm_switch_olp_l2_addr_xxx
  39099          *
  39100          * Use either of two set of APIs
  39101          */
  39102 
  39103         if (_BCM_SWITCH_OLP_APIV(unit) == _BCM_SWITCH_OLP_L2_STATION_API) {
  39104             LOG_VERBOSE(BSL_LS_BCM_L2,
  39105                         (BSL_META_U(unit,
  39106                                     "use bcm_l2_station_xxx API\n")));
  39107             return BCM_E_UNAVAIL;
  39108         }
  39109         _BCM_SWITCH_OLP_APIV_SET(unit, _BCM_SWITCH_OLP_TRUE_API);
  39110 
  39111 #if defined(BCM_KATANA2_SUPPORT)
  39112         if (SOC_IS_KATANA2(unit) &&
  39113                  (soc_feature(unit, soc_feature_oam)  ||
  39114                   soc_feature(unit, soc_feature_sat))) {
  39115             uint32 val_lo, val_hi;
  39116             uint64 mac_field;
  39117 
  39118             PORT_LOCK(unit);
  39119 
  39120             rv = _bcm_kt2_port_mac_get(unit, port, &mac_field);
  39121 
  39122             if (BCM_FAILURE(rv)) {
  39123                 PORT_UNLOCK(unit);
  39124                 return (rv);
  39125             }
  39126 
  39127             COMPILER_64_TO_32_LO(val_lo, mac_field);
  39128             COMPILER_64_TO_32_HI(val_hi, mac_field);
  39129 
  39130             switch (type) {
  39131                 case bcmPortControlPortMacOui:
  39132                     val_lo = (val_lo & 0xffffff) | ((value & 0xff) << 24);
  39133                     val_hi = (value >> 8) & 0xffff;
  39134                     COMPILER_64_SET(mac_field, val_hi, val_lo);
  39135                     break;
  39136 
  39137                 case bcmPortControlPortMacNonOui:
  39138                     val_lo = (val_lo & 0xff000000) | (value & 0xffffff);
  39139                     COMPILER_64_SET(mac_field, val_hi, val_lo);
  39140                     break;
  39141 
  39142                 default:
  39143                      break;
  39144             }
  39145 
  39146             rv = _bcm_kt2_port_mac_set(unit, port, mac_field);
  39147             PORT_UNLOCK(unit);
  39148         }
  39149 #endif /* BCM_KATANA2_SUPPORT */
  39150 
  39151 #if defined(BCM_MONTEREY_SUPPORT)
  39152         if (SOC_IS_MONTEREY(unit)) {
  39153             PORT_LOCK(unit);
  39154             rv = _bcm_monterey_port_mac_set(unit,
  39155                                           port,
  39156                                           type == bcmPortControlPortMacOui,
  39157                                           value);
  39158             PORT_UNLOCK(unit);
  39159         }
  39160 #endif /* BCM_MONTEREY_SUPPORT */
  39161 #if defined(BCM_APACHE_SUPPORT)
  39162         if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
  39163             PORT_LOCK(unit);
  39164             rv = _bcm_apache_port_mac_set(unit,
  39165                                           port,
  39166                                           type == bcmPortControlPortMacOui,
  39167                                           value);
  39168             PORT_UNLOCK(unit);
  39169         }
  39170 #endif /* BCM_APACHE_SUPPORT */
  39171         break;
  39172 #endif /* BCM_KATANA2_SUPPORT || BCM_APACHE_SUPPORT */
  39173 #ifdef BCM_TRX_SUPPORT
  39174     case bcmPortControlOamLoopback:
  39175         if (SOC_IS_TRX(unit) && !SOC_IS_HURRICANE(unit)
  39176             && !SOC_IS_SHADOW(unit)) {
  39177             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  39178 
  39179             if (soc_reg_field_valid(unit,ING_MISC_PORT_CONFIGr,
  39180                                     OAM_DO_NOT_MODIFYf)) {
  39181 
  39182                 rv = soc_reg_field32_modify(unit, ING_MISC_PORT_CONFIGr, port,
  39183                                             OAM_DO_NOT_MODIFYf, value ? 1 : 0);
  39184             } else {
  39185                 return BCM_E_UNAVAIL;
  39186             }
  39187         }
  39188 
  39189         break;
  39190 #endif /* BCM_TRX_SUPPORT */
  39191 
  39192     case bcmPortControlLanes:
  39193         if (soc_feature(unit, soc_feature_flexport_no_legacy)) {
  39194             return BCM_E_UNAVAIL;
  39195         }
  39196 #if defined(BCM_TRIUMPH2_SUPPORT)
  39197         if (soc_feature(unit, soc_feature_flex_port)) {
  39198             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  39199 #ifdef BCM_TRIDENT_SUPPORT
  39200             if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
  39201                 bcm_port_t phy_port;
  39202                 int bindex;
  39203 
  39204                 if (!SOC_PORT_VALID(unit, port)) {
  39205                     return BCM_E_PORT;
  39206                 }
  39207                 if (value != 1 && value != 2 && value != 4) {
  39208                     return BCM_E_PARAM;
  39209                 }
  39210                 /* coverity[overrun-local : FALSE] */
  39211                 phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  39212                 bindex = SOC_PORT_BINDEX(unit, phy_port);
  39213                 if (bindex & (value - 1)) { /* port alignment check */
  39214                     return BCM_E_PARAM;
  39215                 }
  39216             }
  39217 #endif /* BCM_TRIDENT_SUPPORT */
  39218             _bcm_esw_port_mirror_lock(unit);
  39219 
  39220 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT
  39221             if (soc_feature(unit, soc_feature_xgs5_flexport_legacy_mode)) {
  39222                 rv = bcmi_xgs5_port_lanes_set(unit, port, value);
  39223             }
  39224 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT */
  39225 #if defined(BCM_ENDURO_SUPPORT)
  39226             if (SOC_IS_ENDURO(unit)) {
  39227                 rv = _bcm_en_port_lanes_set(unit, port, value);
  39228             } else
  39229 #endif
  39230 #if defined(BCM_HURRICANE1_SUPPORT)
  39231             if (SOC_IS_HURRICANE(unit)) {
  39232                 rv = _bcm_hu_port_lanes_set(unit, port, value);
  39233             } else
  39234 #endif
  39235 #if defined(BCM_HURRICANE2_SUPPORT)
  39236             if (SOC_IS_HURRICANE2(unit)) {
  39237                 rv = _bcm_hu2_port_lanes_set(unit, port, value);
  39238             } else
  39239 #endif
  39240 #ifdef BCM_TOMAHAWK_SUPPORT
  39241             if (SOC_IS_TOMAHAWK(unit) || SOC_IS_TRIDENT3X(unit)) {
  39242                 /* coverity[overrun-call : FALSE] */
  39243                 rv = _bcm_th_port_lanes_set(unit, port, value);
  39244             } else
  39245 #endif
  39246 #if defined(BCM_MONTEREY_SUPPORT)
  39247             if (SOC_IS_MONTEREY(unit)) {
  39248                 rv = bcmi_monterey_port_lanes_set(unit, port, value);
  39249             } else
  39250 #endif
  39251 #if defined(BCM_APACHE_SUPPORT)
  39252             if (SOC_IS_APACHE(unit)) {
  39253                 rv = bcmi_apache_port_lanes_set(unit, port, value);
  39254             } else
  39255 #endif
  39256 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  39257             if (SOC_IS_TD2P_TT2P(unit)) {
  39258                 rv = bcmi_td2p_port_lanes_set(unit, port, value);
  39259             } else
  39260 #endif
  39261 #ifdef BCM_TRIDENT2_SUPPORT
  39262             if (SOC_IS_TD2_TT2(unit)) {
  39263                 rv = _bcm_td2_port_lanes_set(unit, port, value);
  39264                 _bcm_flex_port_phy_control_software_rx_los_get(unit, port);
  39265             } else
  39266 #endif
  39267 #ifdef BCM_TRIDENT_SUPPORT
  39268             if (SOC_IS_TD_TT(unit)) {
  39269                 /* coverity[overrun-call : FALSE] */
  39270                 rv = _bcm_td_port_lanes_set(unit, port, value);
  39271             } else
  39272 #endif /* BCM_TRIDENT_SUPPORT */
  39273 #ifdef BCM_SHADOW_SUPPORT
  39274             if (SOC_IS_SHADOW(unit)) {
  39275                 soc_info_t *si = NULL;
  39276                 int okay;
  39277                 int i;
  39278 
  39279                 rv = _bcm_shadow_port_lanes_set(unit, port, value);
  39280                 if (BCM_SUCCESS(rv)) {
  39281                     si = &SOC_INFO(unit);
  39282                     if (value == 1) { /* Probe other ports */
  39283                         for (i = port; i < port+4; i++) {
  39284                             rv = soc_phyctrl_detach(unit, i);
  39285                             if (SOC_FAILURE(rv)) {
  39286                                 _bcm_esw_port_mirror_unlock(unit);
  39287                                 return (rv);
  39288                             }
  39289                         }
  39290                         for (i = port; i < port+4; i++) {
  39291                             /* coverity[overrun-local : FALSE] */
  39292                             si->port_num_lanes[i] = value;
  39293                             rv = _bcm_port_probe(unit, i, &okay);
  39294                         }
  39295                     } else if (value == 4) { /* Probe other ports */
  39296                         si = &SOC_INFO(unit);
  39297                         for (i = port; i < port+4; i++) {
  39298                             rv = soc_phyctrl_detach(unit, i);
  39299                             if (SOC_FAILURE(rv)) {
  39300                                 _bcm_esw_port_mirror_unlock(unit);
  39301                                 return (rv);
  39302                             }
  39303                         }
  39304                         /* coverity[overrun-local : FALSE] */
  39305                         si->port_num_lanes[port] = value;
  39306                         rv = _bcm_port_probe(unit, port, &okay);
  39307                     }
  39308                 }
  39309             } else
  39310 #endif /* BCM_SHADOW_SUPPORT */
  39311 #ifdef BCM_TRIUMPH3_SUPPORT
  39312             if (SOC_IS_TRIUMPH3(unit)) {
  39313                 if (!SOC_IS_HELIX4(unit) && (_tr3_port_config_id[unit] == 112 ||
  39314                     _tr3_port_config_id[unit] == 12)&&
  39315                     (port == 54 || port == 55)) {
  39316                     return BCM_E_PARAM;
  39317                 }
  39318                 COUNTER_LOCK(unit);
  39319                 rv = _bcm_tr3_port_lanes_set(unit, port, value);
  39320                 COUNTER_UNLOCK(unit);
  39321             } else
  39322 #endif /* BCM_TRIUMPH3_SUPPORT */
  39323 #ifdef  BCM_METROLITE_SUPPORT
  39324              if (SOC_IS_METROLITE(unit)) {
  39325                  COUNTER_LOCK(unit);
  39326                  SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit));
  39327                  rv = _bcm_ml_port_lanes_set(unit, port, value);
  39328                 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit));
  39329                  COUNTER_UNLOCK(unit);
  39330             } else
  39331 #endif /* BCM_METROLITE_SUPPORT */
  39332 #ifdef BCM_SABER2_SUPPORT
  39333             if (SOC_IS_SABER2(unit)) {
  39334                 COUNTER_LOCK(unit);
  39335                 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit));
  39336                 rv = _bcm_sb2_port_lanes_set(unit, port, value);
  39337                 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit));
  39338                 COUNTER_UNLOCK(unit);
  39339             } else 
  39340 #endif /* BCM_SABER2_SUPPORT */
  39341 #ifdef BCM_KATANA2_SUPPORT
  39342             if (SOC_IS_KATANA2(unit)) {
  39343                 COUNTER_LOCK(unit);
  39344                 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit));
  39345                 rv = _bcm_kt2_port_lanes_set(unit, port, value);
  39346                 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit));
  39347                 COUNTER_UNLOCK(unit);
  39348             } else
  39349 #endif /* BCM_KATANA2_SUPPORT */
  39350             {
  39351                 rv = _bcm_tr2_port_lanes_set(unit, port, value);
  39352             }
  39353             _bcm_esw_port_mirror_unlock(unit);
  39354 #ifdef  BCM_METROLITE_SUPPORT
  39355             if (BCM_SUCCESS(rv) && SOC_IS_METROLITE(unit)) {
  39356                 COUNTER_LOCK(unit);
  39357                 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit));
  39358                 rv = _bcm_ml_port_lanes_set_post_operation(unit, port);
  39359                 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit));
  39360                 COUNTER_UNLOCK(unit);
  39361             } else
  39362 #endif /* BCM_METROLITE_SUPPORT */
  39363 #ifdef BCM_SABER2_SUPPORT
  39364             if (BCM_SUCCESS(rv) && SOC_IS_SABER2(unit)) {
  39365                 COUNTER_LOCK(unit);
  39366                 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit));
  39367                 rv = _bcm_sb2_port_lanes_set_post_operation(unit, port);
  39368                 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit));
  39369                 COUNTER_UNLOCK(unit);
  39370             } else
  39371 #endif
  39372 #ifdef BCM_KATANA2_SUPPORT
  39373             /* Dead Lock (with port lock) so calling separately */
  39374             if (BCM_SUCCESS(rv) && SOC_IS_KATANA2(unit)) {
  39375                 COUNTER_LOCK(unit);
  39376                 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit));
  39377                 rv = _bcm_kt2_port_lanes_set_post_operation(unit, port);
  39378                 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit));
  39379                 COUNTER_UNLOCK(unit);
  39380             }
  39381 #endif
  39382         }
  39383 #endif
  39384         break;
  39385 
  39386     case bcmPortControlPFCEthertype:
  39387 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  39388         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  39389             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  39390             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  39391                 /* IS_GX_PORT == IS_XL_PORT */
  39392                 return BCM_E_PORT;
  39393             }
  39394             if (value < 0 || value > 0xffff) {
  39395                 return BCM_E_PARAM;
  39396             }
  39397             rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  39398                                  SOC_MAC_CONTROL_PFC_TYPE, value);
  39399         }
  39400 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  39401         break;
  39402 
  39403     case bcmPortControlPFCOpcode:
  39404 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  39405         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  39406             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  39407             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  39408                 /* IS_GX_PORT == IS_XL_PORT */
  39409                 return BCM_E_PORT;
  39410             }
  39411             if (value < 0 || value > 0xffff) {
  39412                 return BCM_E_PARAM;
  39413             }
  39414             rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  39415                                  SOC_MAC_CONTROL_PFC_OPCODE, value);
  39416         }
  39417 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  39418         break;
  39419 
  39420     case bcmPortControlPFCReceive:
  39421 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  39422         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  39423         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  39424             int pfc_enable;
  39425             int val_count = 0;
  39426             soc_reg_t reg;
  39427             uint32 values[2];
  39428             soc_field_t fields[] = {PFC_ENABLEf, LLFC_ENf};
  39429 
  39430             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  39431                 /* IS_GX_PORT == IS_XL_PORT */
  39432                 return BCM_E_PORT;
  39433             }
  39434 
  39435             BCM_IF_ERROR_RETURN
  39436                 (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  39437                                  SOC_MAC_CONTROL_PFC_RX_ENABLE, value));
  39438             if (value == 0) {
  39439                 BCM_IF_ERROR_RETURN
  39440                     (MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  39441                                      SOC_MAC_CONTROL_PFC_TX_ENABLE,
  39442                                      &pfc_enable));
  39443             } else {
  39444                 pfc_enable = TRUE;
  39445             }
  39446 
  39447             if (SOC_IS_SC_CQ(unit)) {
  39448                 BCM_IF_ERROR_RETURN
  39449                     (soc_reg_field32_modify(unit, MMU_LLFC_RX_CONFIGr,
  39450                                             port, RX_ENABLEf, value ? 1 : 0));
  39451             }
  39452 
  39453             if (value == 0) {
  39454                 /* Disabling RX, flush MMU XOFF state */
  39455                 BCM_IF_ERROR_RETURN
  39456                     (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  39457                                      SOC_MAC_CONTROL_PFC_FORCE_XON, 1));
  39458                 BCM_IF_ERROR_RETURN
  39459                     (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  39460                                      SOC_MAC_CONTROL_PFC_FORCE_XON, 0));
  39461             }
  39462 
  39463             /* Port config settings */
  39464             values[0] = pfc_enable ? 1 : 0;
  39465             values[1] = 0;
  39466 
  39467             if (SOC_IS_TD2_TT2(unit)) {
  39468                 reg = INVALIDr;
  39469             } else if (SOC_IS_TD_TT(unit) || SOC_IS_SHADOW(unit)) {
  39470                 reg = XLPORT_CONFIGr;
  39471                 val_count=2;
  39472             } else if (SOC_IS_TRIUMPH3(unit)) {
  39473                 reg = PORT_CONFIGr;
  39474                 val_count=2;
  39475             } else if (SOC_IS_SABER2(unit)) {
  39476                 /* No port level config required */
  39477                 reg = INVALIDr;
  39478                 val_count = 0;
  39479             } else if (SOC_IS_KATANAX(unit)) {
  39480                 reg = XPORT_CONFIGr;
  39481                 val_count=2;
  39482             } else {
  39483                 reg = INVALIDr;
  39484             }
  39485 
  39486             if (val_count > 0) {
  39487                 BCM_IF_ERROR_RETURN
  39488                     (soc_reg_fields32_modify(unit, reg, port,
  39489                                              COUNTOF(values), fields, values));
  39490             } else if (SOC_IS_TD2_TT2(unit)) {
  39491                 ;
  39492             } else if (SOC_IS_SC_CQ(unit) || SOC_IS_TR_VL(unit)) {
  39493                 if (SOC_REG_IS_VALID(unit, PPFC_ENr)) {
  39494                     /* Feature enable */
  39495                     BCM_IF_ERROR_RETURN
  39496                         (soc_reg_field32_modify(unit, PPFC_ENr, port,
  39497                                                 PPFC_FEATURE_ENf,
  39498                                                 pfc_enable ? 1 : 0));
  39499                 }
  39500                 if (soc_reg_field_valid(unit, XPORT_CONFIGr, PPP_ENABLEf)) {
  39501                     BCM_IF_ERROR_RETURN
  39502                         (soc_reg_field32_modify(unit, XPORT_CONFIGr,
  39503                                                 port, PPP_ENABLEf,
  39504                                                 pfc_enable ? 1 : 0));
  39505                 }
  39506             }
  39507 
  39508             /* Stats enable */
  39509             rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  39510                                  SOC_MAC_CONTROL_PFC_STATS_ENABLE,
  39511                                  pfc_enable ? 1 : 0);
  39512 
  39513             if (SOC_REG_IS_VALID(unit, XPORT_TO_MMU_BKPr) && pfc_enable == 0) {
  39514                 BCM_IF_ERROR_RETURN(WRITE_XPORT_TO_MMU_BKPr(unit, port, 0));
  39515             }
  39516         }
  39517 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  39518         break;
  39519 
  39520     case bcmPortControlPFCTransmit:
  39521 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  39522         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  39523             rv = _bcm_sc_tr_port_pfc_tx_set(unit, port, (value)? 0xffff : 0);
  39524         }
  39525 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  39526         break;
  39527 
  39528     case bcmPortControlPFCClasses:
  39529 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  39530         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  39531             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  39532             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  39533                 /* IS_GX_PORT == IS_XL_PORT */
  39534                 return BCM_E_PORT;
  39535             }
  39536             rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  39537                                  SOC_MAC_CONTROL_PFC_CLASSES, value);
  39538         }
  39539 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  39540         break;
  39541 
  39542     case bcmPortControlPFCPassFrames:
  39543 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  39544         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  39545             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  39546             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  39547                 /* IS_GX_PORT == IS_XL_PORT */
  39548                 return BCM_E_PORT;
  39549             }
  39550             if(soc_feature(unit, soc_feature_pgw_mac_pfc_frame)) {
  39551                 uint32 rval32 = 0;
  39552                 soc_reg_t reg = INVALIDr;
  39553                 if(SOC_REG_IS_VALID(unit, PGW_MAC_RSV_MASKr)) {
  39554                     reg = PGW_MAC_RSV_MASKr;
  39555                 } else if(IS_CL_PORT(unit, port) &&
  39556                           SOC_REG_IS_VALID(unit, CLPORT_MAC_RSV_MASKr)) {
  39557                     reg = CLPORT_MAC_RSV_MASKr;
  39558                 } else if(IS_XL_PORT(unit, port) &&
  39559                           SOC_REG_IS_VALID(unit, XLPORT_MAC_RSV_MASKr)) {
  39560                     reg = XLPORT_MAC_RSV_MASKr;
  39561                 } else {
  39562                     reg = INVALIDr;
  39563                 }
  39564 
  39565                 if (reg != INVALIDr) {
  39566                 PORT_LOCK(unit);
  39567                     rv = soc_reg32_get(unit, reg, port, 0, &rval32);
  39568                 if (BCM_SUCCESS(rv)) {
  39569                         /* xxx_MAC_RSV_MASK: Bit 18 PFC frame detected
  39570                      * Enable  PFC Frame : Set 0. Go through
  39571                      * Disable PFC Frame : Set 1. Purged.
  39572                      */
  39573                     if(value) {
  39574                         rval32 &= ~(1 << 18);
  39575                     } else {
  39576                         rval32 |= (1 << 18);
  39577                     }
  39578                         rv = soc_reg32_set(unit, reg, port, 0, rval32);
  39579                 }
  39580                 PORT_UNLOCK(unit);
  39581             } else {
  39582                     rv = BCM_E_UNAVAIL;
  39583                 }
  39584             } else {
  39585                 PORT_LOCK(unit);
  39586                 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  39587                                      SOC_MAC_CONTROL_PFC_RX_PASS, value);
  39588                 PORT_UNLOCK(unit);
  39589             }
  39590         }
  39591 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  39592         break;
  39593 
  39594     case bcmPortControlPFCDestMacOui:
  39595 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  39596         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  39597             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  39598             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  39599                 /* IS_GX_PORT == IS_XL_PORT */
  39600                 return BCM_E_PORT;
  39601             }
  39602             if (value < 0 || value > 0xffffff) {
  39603                 return BCM_E_PARAM;
  39604             }
  39605             rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  39606                                  SOC_MAC_CONTROL_PFC_MAC_DA_OUI, value);
  39607         }
  39608 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  39609         break;
  39610 
  39611     case bcmPortControlPFCDestMacNonOui:
  39612 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  39613         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  39614             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  39615             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  39616                 /* IS_GX_PORT == IS_XL_PORT */
  39617                 return BCM_E_PORT;
  39618             }
  39619             if (value < 0 || value > 0xffffff) {
  39620                 return BCM_E_PARAM;
  39621             }
  39622             rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  39623                                  SOC_MAC_CONTROL_PFC_MAC_DA_NONOUI, value);
  39624         }
  39625 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  39626         break;
  39627 
  39628     case bcmPortControlPFCRefreshTime:
  39629 #if defined(BCM_TRIDENT_SUPPORT)||defined(BCM_GREYHOUND_SUPPORT)
  39630         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  39631             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  39632             if (value < 0 || value > 0xffff) {
  39633                 return BCM_E_PARAM;
  39634             }
  39635             rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  39636                                  SOC_MAC_CONTROL_PFC_REFRESH_TIME, value);
  39637         }
  39638 #endif /* BCM_TRIDENT_SUPPORT */
  39639         break;
  39640 
  39641     case bcmPortControlPFCXOffTime:
  39642 #if defined(BCM_TRIDENT_SUPPORT)||defined(BCM_GREYHOUND_SUPPORT)
  39643         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  39644             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  39645             if (value < 0 || value > 0xffff) {
  39646                 return BCM_E_PARAM;
  39647             }
  39648             rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  39649                                  SOC_MAC_CONTROL_PFC_XOFF_TIME, value);
  39650         }
  39651 #endif /* BCM_TRIDENT_SUPPORT */
  39652         break;
  39653 
  39654     case bcmPortControlVrf:
  39655         rv = _bcm_esw_port_vrf_set(unit, port, value);
  39656         break;
  39657 
  39658     case bcmPortControlL3Ingress:
  39659 #if defined(BCM_TRIUMPH_SUPPORT)
  39660         if (!soc_feature(unit, soc_feature_l3_ingress_interface)) {
  39661             return BCM_E_UNAVAIL;
  39662         }
  39663 
  39664         if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, L3_IIFf)) {
  39665             if ((value >= 1) && (value < soc_mem_index_count(unit, L3_IIFm))) {
  39666 #if defined(BCM_KATANA2_SUPPORT)
  39667                 if (SOC_IS_KATANA2(unit)) {
  39668                     rv = _bcm_kt2_source_trunk_map_set(unit, port, L3_IIFf, value);
  39669                 } else
  39670 #endif
  39671                 {
  39672                     rv = _bcm_trx_source_trunk_map_set(unit, port, L3_IIFf, value);
  39673                 }
  39674                 BCM_IF_ERROR_RETURN(rv);
  39675                 if (soc_mem_field_valid(unit, PORT_TABm, PORT_OPERATIONf) ||
  39676                     SOC_IS_TRIDENT3X(unit)) {
  39677                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  39678                                                PORT_OPERATIONf, 0x2);
  39679                 }
  39680             } else {
  39681 #if defined(BCM_KATANA2_SUPPORT)
  39682                 if (SOC_IS_KATANA2(unit)) {
  39683                     rv = _bcm_kt2_source_trunk_map_set(unit, port, L3_IIFf, 0);
  39684                 } else
  39685 #endif
  39686                 {
  39687                     rv = _bcm_trx_source_trunk_map_set(unit, port, L3_IIFf, 0);
  39688                 }
  39689                 BCM_IF_ERROR_RETURN(rv);
  39690                 if (soc_mem_field_valid(unit, PORT_TABm, PORT_OPERATIONf)) {
  39691                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  39692                                                PORT_OPERATIONf, 0x0);
  39693                 }
  39694             }
  39695         }
  39696 #endif  /* BCM_TRIUMPH_SUPPORT */
  39697         break;
  39698 
  39699     case bcmPortControlL2Learn:
  39700 #if defined(BCM_TRX_SUPPORT)
  39701         if (SOC_IS_TRX(unit)) {
  39702             uint32 hw_val = 0;
  39703             bcm_port_cfg_t port_cfg;
  39704 
  39705             BCM_IF_ERROR_RETURN(
  39706                 _bcm_trx_port_cml_flags2hw(unit, value, &hw_val));
  39707             BCM_IF_ERROR_RETURN(mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &port_cfg));
  39708             port_cfg.pc_cml = hw_val;
  39709             rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &port_cfg);
  39710         }
  39711 #endif /* BCM_TRX_SUPPORT */
  39712           break;
  39713 
  39714     case bcmPortControlL2Move:
  39715 #if defined(BCM_TRX_SUPPORT)
  39716         if (SOC_IS_TRX(unit)) {
  39717             uint32 hw_val = 0;
  39718             bcm_port_cfg_t port_cfg;
  39719 
  39720             BCM_IF_ERROR_RETURN(
  39721                 _bcm_trx_port_cml_flags2hw(unit, value, &hw_val));
  39722             BCM_IF_ERROR_RETURN(mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &port_cfg));
  39723             port_cfg.pc_cml_move = hw_val;
  39724             rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &port_cfg);
  39725         }
  39726 #endif /* BCM_TRX_SUPPORT */
  39727           break;
  39728 
  39729     case bcmPortControlForwardStaticL2MovePkt:
  39730 #if defined(BCM_TRX_SUPPORT)
  39731         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  39732                                    DISABLE_STATIC_MOVE_DROPf, value ? 1 : 0);
  39733 #endif /* BCM_TRX_SUPPORT */
  39734         break;
  39735 
  39736     case bcmPortControlPrbsMode:
  39737         if (value != 0) {
  39738             return BCM_E_PARAM;
  39739         }
  39740         rv = BCM_E_NONE;
  39741         break;
  39742 
  39743     case bcmPortControlPrbsPolynomial:
  39744         /*prbs polynomial value check*/
  39745         if((value < BCM_PORT_PRBS_POLYNOMIAL_X7_X6_1)
  39746             || (value > BCM_PORT_PRBS_POLYNOMIAL_PAM4_13Q))
  39747         {
  39748             return BCM_E_PARAM;
  39749         }
  39750         PORT_LOCK(unit);
  39751         rv = soc_phyctrl_control_set(unit, port,
  39752                                      SOC_PHY_CONTROL_PRBS_POLYNOMIAL, value);
  39753         PORT_UNLOCK(unit);
  39754         break;
  39755     case bcmPortControlPrbsTxEnable:
  39756         PORT_LOCK(unit);
  39757         rv = soc_phyctrl_control_set(unit, port,
  39758                                      SOC_PHY_CONTROL_PRBS_TX_ENABLE, value);
  39759         PORT_UNLOCK(unit);
  39760         break;
  39761 
  39762     case bcmPortControlPrbsRxEnable:
  39763         PORT_LOCK(unit);
  39764         rv = soc_phyctrl_control_set(unit, port,
  39765                                      SOC_PHY_CONTROL_PRBS_RX_ENABLE, value);
  39766         PORT_UNLOCK(unit);
  39767         break;
  39768 
  39769     case bcmPortControlPrbsTxInvertData:
  39770         PORT_LOCK(unit);
  39771         rv = soc_phyctrl_control_set(unit, port,
  39772                                      SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA,
  39773                                      value);
  39774         PORT_UNLOCK(unit);
  39775         break;
  39776 
  39777     case bcmPortControlLinkFaultLocalEnable:
  39778         rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  39779                              SOC_MAC_CONTROL_FAULT_LOCAL_ENABLE, value);
  39780         break;
  39781     case bcmPortControlLinkFaultRemoteEnable:
  39782         rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  39783                              SOC_MAC_CONTROL_FAULT_REMOTE_ENABLE, value);
  39784         break;
  39785     case bcmPortControlSerdesDriverTune:
  39786         PORT_LOCK(unit);
  39787         rv = soc_phyctrl_control_set(unit, port,
  39788                 SOC_PHY_CONTROL_SERDES_DRIVER_TUNE, value);
  39789         PORT_UNLOCK(unit);
  39790         break;
  39791     case bcmPortControlLinkdownTransmit:
  39792         PORT_LOCK(unit);
  39793         rv = soc_phyctrl_control_set(unit, port,
  39794                 SOC_PHY_CONTROL_LINKDOWN_TRANSMIT, value);
  39795         PORT_UNLOCK(unit);
  39796         /* Most of PHYs have nothing to configure and simply return UNAVAIL*/
  39797         if ((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL)) {
  39798             BCM_IF_ERROR_RETURN(_bcm_esw_link_down_tx_set(unit, port, value));
  39799 #if defined(BCM_TRIUMPH3_SUPPORT)
  39800             if (SOC_REG_PORT_VALID(unit, XMAC_RX_LSS_CTRLr, port)) {
  39801                 rv = soc_reg_field32_modify(unit, XMAC_RX_LSS_CTRLr,
  39802                          port, LOCAL_FAULT_DISABLEf, (value ? 1 : 0));
  39803             } else if (SOC_REG_PORT_VALID(unit, XLMAC_RX_LSS_CTRLr, port)) {
  39804                 rv = soc_reg_field32_modify(unit, XLMAC_RX_LSS_CTRLr,
  39805                          port, LOCAL_FAULT_DISABLEf, (value ? 1 : 0));
  39806             }
  39807 #endif
  39808         }
  39809         break;
  39810     case bcmPortControlSerdesTuneMarginMode:
  39811         PORT_LOCK(unit);
  39812         rv = soc_phyctrl_control_set(unit, port,
  39813                 SOC_PHY_CONTROL_SERDES_TUNE_MARGIN_MODE, value);
  39814         PORT_UNLOCK(unit);
  39815         break;
  39816     case bcmPortControlSerdesTuneMarginValue:
  39817         PORT_LOCK(unit);
  39818         rv = soc_phyctrl_control_set(unit, port,
  39819                 SOC_PHY_CONTROL_SERDES_TUNE_MARGIN_VALUE, value);
  39820         PORT_UNLOCK(unit);
  39821         break;
  39822     case bcmPortControlStatOversize:
  39823         rv = _bcm_esw_stat_ovr_threshold_set(unit, port, value);
  39824         break;
  39825 
  39826     case bcmPortControlStatOversizeIsError:
  39827         rv = _bcm_esw_stat_ovr_error_control_set(unit, port, value);
  39828         break;
  39829 
  39830     case bcmPortControlTimestampEnable:
  39831 #if defined(BCM_HAWKEYE_SUPPORT)
  39832         if (SOC_IS_HAWKEYE(unit)) {
  39833             uint32 rval;
  39834             if (!SOC_PORT_VALID(unit, port)) {
  39835                 return BCM_E_PORT;
  39836             }
  39837             SOC_IF_ERROR_RETURN(READ_EAV_ENABLE_BMAPr(unit, &rval));
  39838             if (value) {
  39839                 /* coverity[BAD_SHIFT: FALSE] */
  39840                 rval |= (port >= 32 ? 0 : (1 << port));
  39841             } else {
  39842                 /* coverity[BAD_SHIFT: FALSE] */
  39843                 rval &= ~(port >= 32 ? 0 : (1 << port));
  39844             }
  39845             SOC_IF_ERROR_RETURN(WRITE_EAV_ENABLE_BMAPr(unit, rval));
  39846 
  39847             /* Enable MMU */
  39848             SOC_IF_ERROR_RETURN(WRITE_MMUEAVENABLEr(unit, rval));
  39849 
  39850             /* Program EGR_PORT register */
  39851             SOC_IF_ERROR_RETURN(READ_EGR_PORTr(unit, port, &rval));
  39852             soc_reg_field_set(unit, EGR_PORTr, &rval, EAV_CAPABLEf, value);
  39853             SOC_IF_ERROR_RETURN(WRITE_EGR_PORTr(unit, port, rval));
  39854 
  39855             rv = BCM_E_NONE;
  39856         } else
  39857 #endif /* BCM_HAWKEYE_SUPPORT */
  39858         if (soc_feature (unit, soc_feature_xlmac_timestamp_disable)) {
  39859             if (IS_XL_PORT(unit, port)) {
  39860                 /* Enable/disable timesatmp on XLMAC */
  39861                 uint32 rval;
  39862                 SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit,
  39863                                                              port, &rval));
  39864                 soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval,
  39865                                   XLMAC_TS_DISABLEf, (value) ? 0 : 1);
  39866                 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit,
  39867                                                               port, rval));
  39868                 rv = BCM_E_NONE;
  39869             }
  39870         }
  39871         break;
  39872 
  39873     case bcmPortControlEEEEnable:
  39874         if (!SOC_PORT_VALID(unit, port)) {
  39875             return BCM_E_PORT;
  39876         }
  39877 
  39878         PORT_LOCK(unit);
  39879 
  39880 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \
  39881         || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \
  39882         || defined(BCM_HURRICANE2_SUPPORT)
  39883         if (soc_feature (unit, soc_feature_eee)) {
  39884             int mac_val;
  39885             uint32 phy_val;
  39886 
  39887             if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  39888                                  SOC_MAC_CONTROL_EEE_ENABLE,
  39889                                  &mac_val) != SOC_E_UNAVAIL) &&
  39890                 (soc_phyctrl_control_get(unit, port,
  39891                                          BCM_PORT_PHY_CONTROL_EEE,
  39892                                          &phy_val) != SOC_E_UNAVAIL)) {
  39893 
  39894                 /* If MAC/Switch is EEE aware (Native EEE mode is supported)
  39895                  * and PHY also supports Native EEE mode
  39896                  */
  39897 
  39898                 /* a. Disable AutoGrEEEn mode by PHY if applicable */
  39899                 rv = (soc_phyctrl_control_get(unit, port,
  39900                                               BCM_PORT_PHY_CONTROL_EEE_AUTO,
  39901                                               &phy_val));
  39902 
  39903                 if ((rv != SOC_E_UNAVAIL) && (phy_val != 0)) {
  39904                     rv = soc_phyctrl_control_set(unit, port,
  39905                                                  BCM_PORT_PHY_CONTROL_EEE_AUTO,
  39906                                                  0);
  39907                 }
  39908 
  39909                 /* b. Enable/Disable Native EEE in PHY */
  39910                 rv = soc_phyctrl_control_set (unit, port,
  39911                         BCM_PORT_PHY_CONTROL_EEE, value ? 1 : 0);
  39912 
  39913                 if (SOC_SUCCESS(rv)) {
  39914                     /* EEE standard compliance Work Around:
  39915                      * Store the software copy of eee value in eee_cfg flag
  39916                      */
  39917                     eee_cfg[unit][port] = value;
  39918                     /* If (value==1), EEE will be enabled in MAC after 1 sec.
  39919                      * during linkscan update*/
  39920                     if (value == 0) {
  39921                         /* Disable EEE in MAC immediately*/
  39922                         rv = MAC_CONTROL_SET(PORT(unit, port).p_mac,
  39923                                              unit, port,
  39924                                              SOC_MAC_CONTROL_EEE_ENABLE, 0);
  39925                     }
  39926 
  39927                     /* Notify Int-PHY to bypass LPI for native EEE mode.
  39928                      *
  39929                      * Note :
  39930                      *  1. Not all internal SerDes support the setting to
  39931                      *     enable/disable bypass LPI signal.
  39932                      *  2. Int-PHY to bypass LPI will sync with Ext-PHY's EEE
  39933                      *     enabling status for Native EEE mode.
  39934                      */
  39935                     (void)soc_phyctrl_notify(unit, port,
  39936                                             phyEventLpiBypass, value? 1: 0);
  39937                 }
  39938 
  39939             } else {
  39940                 /* If native EEE mode is not supported,
  39941                  * set PHY in AutoGrEEEn mode.
  39942                  */
  39943 
  39944                 /* a. Disable Native EEE mode in PHY if applicable */
  39945                 rv = (soc_phyctrl_control_get(unit, port,
  39946                                               BCM_PORT_PHY_CONTROL_EEE,
  39947                                               &phy_val));
  39948 
  39949                 if ((rv != SOC_E_UNAVAIL) && (phy_val != 0)) {
  39950                     rv = soc_phyctrl_control_set (unit, port,
  39951                                                   BCM_PORT_PHY_CONTROL_EEE,
  39952                                                   0);
  39953                 }
  39954 
  39955                 /* b. Enable/Disable AutoGrEEEn in PHY.
  39956                  * If PHY does not support AutoGrEEEn mode,
  39957                  * rv will be assigned SOC_E_UNAVAIL.
  39958                  */
  39959                 rv = soc_phyctrl_control_set (unit, port,
  39960                                               BCM_PORT_PHY_CONTROL_EEE_AUTO,
  39961                                               value ? 1 : 0);
  39962                 if (SOC_SUCCESS(rv)) {
  39963                     eee_cfg[unit][port] = value;
  39964                 }
  39965             }
  39966         } else
  39967 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT ||
  39968           BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */
  39969 
  39970         {
  39971             /* For legacy devices that don't support native EEE,
  39972              * set PHY in AutoGrEEEn mode.
  39973              */
  39974             uint32 phy_val;
  39975 
  39976             /* a. Disable Native EEE mode in PHY if applicable */
  39977             rv = (soc_phyctrl_control_get(unit, port,
  39978                                           BCM_PORT_PHY_CONTROL_EEE,
  39979                                           &phy_val));
  39980 
  39981             if ((rv != SOC_E_UNAVAIL) && (phy_val != 0)) {
  39982                 rv = soc_phyctrl_control_set (unit, port,
  39983                                               BCM_PORT_PHY_CONTROL_EEE, 0);
  39984             }
  39985 
  39986             /* b. Enable/Disable AutoGrEEEn in PHY.
  39987              * If PHY does not support AutoGrEEEn mode,
  39988              * rv will be assigned BCM_E_UNAVAIL.
  39989              */
  39990             rv = soc_phyctrl_control_set (unit, port,
  39991                                           BCM_PORT_PHY_CONTROL_EEE_AUTO,
  39992                                           value ? 1 : 0);
  39993         }
  39994 
  39995         PORT_UNLOCK(unit);
  39996 
  39997         break;
  39998 
  39999     case bcmPortControlEEEStatisticsClear:
  40000         if (!SOC_PORT_VALID(unit, port)) {
  40001             return BCM_E_PORT;
  40002         }
  40003         if (!IS_E_PORT(unit, port)) {
  40004             return BCM_E_UNAVAIL;
  40005         }
  40006 
  40007         PORT_LOCK(unit);
  40008 
  40009 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) ||\
  40010     defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT)
  40011         if (soc_feature(unit, soc_feature_eee)) {
  40012             uint32 val = 0;
  40013             uint64 val64;
  40014             int mac_val;
  40015             uint32 phy_val;
  40016 
  40017             COMPILER_64_ZERO(val64);
  40018             if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  40019                                  SOC_MAC_CONTROL_EEE_ENABLE, &mac_val)
  40020                  != SOC_E_UNAVAIL) &&
  40021                 (soc_phyctrl_control_get(unit, port,
  40022                                          BCM_PORT_PHY_CONTROL_EEE, &phy_val)
  40023                  != SOC_E_UNAVAIL)) {
  40024 
  40025                 if (soc_feature(unit, soc_feature_eee_stat_clear_directly) || 
  40026                     SOC_IS_TD2_TT2(unit)) {
  40027                     rv = _bcm_esw_port_eee_stat_clear(unit, port);
  40028 
  40029                     PORT_UNLOCK (unit);
  40030                     break;
  40031                 }
  40032 
  40033                 /* MAC/Switch is EEE aware (Native EEE mode is supported) */
  40034                 if (soc_feature(unit, soc_feature_unified_port)) {
  40035                     if (SOC_REG_IS_VALID(unit,PORT_XGXS_COUNTER_MODEr)) {
  40036                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40037                             (READ_PORT_XGXS_COUNTER_MODEr(unit, port, &val));
  40038                         soc_reg_field_set(unit, PORT_XGXS_COUNTER_MODEr, &val,
  40039                                           CNT_MODEf, 0);
  40040                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40041                             (WRITE_PORT_XGXS_COUNTER_MODEr(unit, port, val));
  40042                     }
  40043                 } else {
  40044                     if (SOC_REG_IS_VALID(unit,GE0_EEE_CONFIGr)) {
  40045                         /*set counter rollover bit to 0*/
  40046                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  40047                             READ_GE0_EEE_CONFIGr(unit, port, &val));
  40048                         soc_reg_field_set(unit, GE0_EEE_CONFIGr, &val,
  40049                             COUNTER_ROLLOVERf, 0);
  40050                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40051                                 (WRITE_GE0_EEE_CONFIGr(unit, port, val));
  40052                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40053                                 (WRITE_GE1_EEE_CONFIGr(unit, port, val));
  40054                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40055                                 (WRITE_GE2_EEE_CONFIGr(unit, port, val));
  40056                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40057                                 (WRITE_GE3_EEE_CONFIGr(unit, port, val));
  40058                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40059                                 (WRITE_GE4_EEE_CONFIGr(unit, port, val));
  40060                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40061                                 (WRITE_GE5_EEE_CONFIGr(unit, port, val));
  40062                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40063                                 (WRITE_GE6_EEE_CONFIGr(unit, port, val));
  40064                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40065                                 (WRITE_GE7_EEE_CONFIGr(unit, port, val));
  40066                     }
  40067                 }
  40068 
  40069                 /*Read counters to clear them*/
  40070                 if (IS_GE_PORT(unit, port) && !IS_XL_PORT(unit, port) &&
  40071                     (SOC_IS_HURRICANE2(unit) || SOC_IS_HURRICANE3(unit) ||
  40072                      SOC_IS_GREYHOUND(unit))) {
  40073                     _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40074                         (READ_GRX_EEE_LPI_DURATION_COUNTERr(unit, port, &val));
  40075                     _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40076                         (READ_GRX_EEE_LPI_EVENT_COUNTERr(unit, port, &val));
  40077                     _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40078                         (READ_GTX_EEE_LPI_DURATION_COUNTERr(unit, port, &val));
  40079                     _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40080                         (READ_GTX_EEE_LPI_EVENT_COUNTERr(unit, port, &val));
  40081 #ifdef BCM_GREYHOUND2_SUPPORT
  40082                 } else if (SOC_IS_GREYHOUND2(unit)) {
  40083                     
  40084                     if (IS_CL_PORT(unit, port)) {
  40085                         /* for port with CLMAC */
  40086                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40087                             (READ_CLMIB_RX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64));
  40088                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40089                             (READ_CLMIB_RX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64));
  40090                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40091                             (READ_CLMIB_TX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64));
  40092                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40093                             (READ_CLMIB_TX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64));
  40094                     } else if (IS_XL_PORT(unit, port)) {
  40095                         /* for port with XLMAC */
  40096                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40097                             (READ_XLMIB_RX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64));
  40098                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40099                             (READ_XLMIB_RX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64));
  40100                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40101                             (READ_XLMIB_TX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64));
  40102                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40103                             (READ_XLMIB_TX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64));
  40104 
  40105                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40106                             (READ_XLPMIB_RX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64));
  40107                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40108                             (READ_XLPMIB_RX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64));
  40109                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40110                             (READ_XLPMIB_TX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64));
  40111                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40112                             (READ_XLPMIB_TX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64));
  40113                     } else {
  40114                         /* for port with UniMAC */
  40115                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40116                             (READ_GRX_EEE_LPI_DURATION_COUNTERr(unit, port, &val));
  40117                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40118                             (READ_GRX_EEE_LPI_EVENT_COUNTERr(unit, port, &val));
  40119                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40120                             (READ_GTX_EEE_LPI_DURATION_COUNTERr(unit, port, &val));
  40121                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40122                             (READ_GTX_EEE_LPI_EVENT_COUNTERr(unit, port, &val));
  40123                     }
  40124 #endif
  40125                 } else {
  40126                     _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40127                         (READ_RX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64));
  40128                     _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40129                         (READ_RX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64));
  40130                     _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40131                         (READ_TX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64));
  40132                     _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40133                         (READ_TX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64));
  40134                 }
  40135 
  40136                 /*set counter rollover bit to 1*/
  40137                 if (soc_feature(unit, soc_feature_unified_port)) {
  40138                     if (SOC_REG_IS_VALID(unit,PORT_XGXS_COUNTER_MODEr)) {
  40139                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40140                             (READ_PORT_XGXS_COUNTER_MODEr(unit, port, &val));
  40141                         soc_reg_field_set(unit, PORT_XGXS_COUNTER_MODEr, &val,
  40142                                           CNT_MODEf, 1);
  40143                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40144                             (WRITE_PORT_XGXS_COUNTER_MODEr(unit, port, val));
  40145                     }
  40146                 } else {
  40147                     if (SOC_REG_IS_VALID(unit,GE0_EEE_CONFIGr)) {
  40148                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  40149                             READ_GE0_EEE_CONFIGr(unit, port, &val));
  40150                         soc_reg_field_set(unit, GE0_EEE_CONFIGr, &val,
  40151                             COUNTER_ROLLOVERf, 1);
  40152                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40153                                 (WRITE_GE0_EEE_CONFIGr(unit, port, val));
  40154                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40155                                 (WRITE_GE1_EEE_CONFIGr(unit, port, val));
  40156                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40157                                 (WRITE_GE2_EEE_CONFIGr(unit, port, val));
  40158                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40159                                 (WRITE_GE3_EEE_CONFIGr(unit, port, val));
  40160                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40161                                 (WRITE_GE4_EEE_CONFIGr(unit, port, val));
  40162                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40163                                 (WRITE_GE5_EEE_CONFIGr(unit, port, val));
  40164                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40165                                 (WRITE_GE6_EEE_CONFIGr(unit, port, val));
  40166                         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  40167                                 (WRITE_GE7_EEE_CONFIGr(unit, port, val));
  40168                     }
  40169                 }
  40170                 rv = BCM_E_NONE;
  40171             } else {
  40172                 /* native EEE mode is not supported, */
  40173                 rv = soc_phyctrl_control_set
  40174                     (unit, port,
  40175                      BCM_PORT_PHY_CONTROL_EEE_STATISTICS_CLEAR, value);
  40176             }
  40177         } else
  40178 #endif /* BCM_HURRICANE_SUPPORT || BCM_TRIDENT_SUPPORT
  40179           || BCM_HAWKEYE_SUPPORT*/
  40180         {
  40181             /* On legacy devices that don't support native EEE,
  40182              * get counter value from PHY. If PHY does not support
  40183              * EEE counters, rv will be assigned BCM_E_UNAVAIL.
  40184              */
  40185             rv = soc_phyctrl_control_set
  40186                 (unit, port,
  40187                  BCM_PORT_PHY_CONTROL_EEE_STATISTICS_CLEAR, value);
  40188         }
  40189         PORT_UNLOCK (unit);
  40190         break;
  40191 
  40192 
  40193  /**********************      EEE Mode Overview    ************************
  40194  *                      |DET|                              |  WT |
  40195  *   Signalling   |idles|   |------------------------------|     | idles   |
  40196  *   from Tx MAC  | or  |   |   Low Power Idle (LPI)       |idles|  or     |
  40197  *   to local PHY |data |   |------------------------------|     | data    |
  40198  *                          *                              *
  40199  *                          *                              *
  40200  *                          *  -------LPI state------------*
  40201  *   Local PHY    |         |  |      |  |       |  |      |   |           |
  40202  *   signaling    |   Active|Ts|  Tq  |Tr|  Tq   |Tr|  Tq  |Tw |Active     |
  40203  *   on MDI       |         |  |      |  |       |  |      |   |           |
  40204  *                          *------------------------------*
  40205  *                          *                              *
  40206  *                          *                               *
  40207  *   Signaling    |   idles |-------------------------------|id| PHY is    |
  40208  *   from LP PHY  |     or  |  Low Power Idle (LPI)         |le| ready     |
  40209  *   to Rx MAC    |   data  |-------------------------------|s | for data  |
  40210  *
  40211  *   where DET = Delay Entry Timer    WT = Tx MAC Wake Timer
  40212  */
  40213     case bcmPortControlEEETransmitIdleTime:
  40214         /* DET = Time (in microsecs) for which condition to move to LPI state
  40215          * is satisfied, at the end of which MAC TX transitions to LPI state */
  40216         if (!SOC_PORT_VALID(unit, port)) {
  40217             return BCM_E_PORT;
  40218         }
  40219 
  40220         PORT_LOCK(unit);
  40221 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT)     \
  40222     || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT)     \
  40223     || defined (BCM_HURRICANE2_SUPPORT)
  40224         if (soc_feature (unit, soc_feature_eee)) {
  40225             rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  40226                                  SOC_MAC_CONTROL_EEE_TX_IDLE_TIME, value);
  40227         } else
  40228 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT ||
  40229           BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */
  40230         {
  40231             rv = BCM_E_UNAVAIL;
  40232         }
  40233         PORT_UNLOCK(unit);
  40234         break;
  40235 
  40236     case bcmPortControlEEETransmitRefreshTime:
  40237         if (!SOC_PORT_VALID(unit, port)) {
  40238             return BCM_E_PORT;
  40239         }
  40240 
  40241         PORT_LOCK(unit);
  40242         rv = soc_phyctrl_control_set(unit, port,
  40243                 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_REFRESH_TIME, value);
  40244         PORT_UNLOCK (unit);
  40245         break;
  40246 
  40247     case bcmPortControlEEETransmitSleepTime:
  40248         if (!SOC_PORT_VALID(unit, port)) {
  40249             return BCM_E_PORT;
  40250         }
  40251         PORT_LOCK (unit);
  40252         rv = soc_phyctrl_control_set(unit, port,
  40253                 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_SLEEP_TIME, value);
  40254         PORT_UNLOCK (unit);
  40255         break;
  40256 
  40257     case bcmPortControlEEETransmitQuietTime:
  40258         if (!SOC_PORT_VALID(unit, port)) {
  40259             return BCM_E_PORT;
  40260         }
  40261         PORT_LOCK(unit);
  40262         rv = soc_phyctrl_control_set(unit, port,
  40263                 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_QUIET_TIME, value);
  40264         PORT_UNLOCK (unit);
  40265         break;
  40266 
  40267     case bcmPortControlEEETransmitWakeTime:
  40268         /* Time(in microsecs) to wait before transmitter can leave LPI State*/
  40269         if (!SOC_PORT_VALID(unit, port)) {
  40270             return BCM_E_PORT;
  40271         }
  40272 
  40273         PORT_LOCK (unit);
  40274 
  40275 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \
  40276         || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \
  40277         || defined(BCM_HURRICANE2_SUPPORT)
  40278             if (soc_feature (unit, soc_feature_eee)) {
  40279                 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  40280                         SOC_MAC_CONTROL_EEE_TX_WAKE_TIME, value);
  40281             }
  40282 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT || BCM_TRIDENT_SUPPORT ||
  40283          BCM_SHADOW_SUPPORT */
  40284 
  40285         PORT_UNLOCK (unit);
  40286         break;
  40287 
  40288      case bcmPortControlEEEReceiveSleepTime:
  40289         if (!SOC_PORT_VALID(unit, port)) {
  40290             return BCM_E_PORT;
  40291         }
  40292         PORT_LOCK (unit);
  40293         rv = soc_phyctrl_control_set(unit, port,
  40294                 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_SLEEP_TIME, value);
  40295         PORT_UNLOCK (unit);
  40296         break;
  40297 
  40298     case bcmPortControlEEEReceiveQuietTime:
  40299         if (!SOC_PORT_VALID(unit, port)) {
  40300             return BCM_E_PORT;
  40301         }
  40302         PORT_LOCK(unit);
  40303         rv = soc_phyctrl_control_set(unit, port,
  40304                 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_QUIET_TIME, value);
  40305         PORT_UNLOCK(unit);
  40306         break;
  40307 
  40308     case bcmPortControlEEEReceiveWakeTime:
  40309         if (!SOC_PORT_VALID(unit, port)) {
  40310             return BCM_E_PORT;
  40311         }
  40312         if (!IS_E_PORT(unit, port)) {
  40313             return BCM_E_UNAVAIL;
  40314         }
  40315         PORT_LOCK(unit);
  40316 
  40317         rv = soc_phyctrl_control_set (unit, port,
  40318                 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_WAKE_TIME, value);
  40319         PORT_UNLOCK(unit);
  40320         break;
  40321 
  40322     case bcmPortControlEEEEventCountSymmetric:
  40323         if (!SOC_PORT_VALID(unit, port)) {
  40324             return BCM_E_PORT;
  40325         }
  40326         if (!IS_E_PORT(unit, port)) {
  40327             return BCM_E_UNAVAIL;
  40328         }
  40329 #if defined(BCM_HURRICANE2_SUPPORT)
  40330         if (SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  40331             SOC_IS_GREYHOUND2(unit)) {
  40332             soc_reg_t   reg;
  40333 
  40334             if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) {
  40335                 reg = IS_XL_PORT(unit, port) ? XLPORT_EEE_COUNTER_MODEr : 
  40336                                                CLPORT_EEE_COUNTER_MODEr;
  40337 
  40338                 if (SOC_REG_FIELD_VALID(unit, reg, MODE_BITf)) {
  40339                     rv = soc_reg_field32_modify(unit, reg, port, 
  40340                         MODE_BITf, (value) ? 1 : 0);
  40341                 } else {
  40342                     return BCM_E_INTERNAL;
  40343                 }
  40344             } else {
  40345                 return BCM_E_PORT;
  40346             }
  40347         } else
  40348 #endif
  40349         {
  40350 #if defined(BCM_TRIUMPH3_SUPPORT)
  40351             if (SOC_REG_FIELD_VALID(unit, PORT_EEE_COUNTER_MODEr, MODE_BITf)) {
  40352                 rv = soc_reg_field32_modify(unit, PORT_EEE_COUNTER_MODEr, port,
  40353                                             MODE_BITf, (value) ? 1 : 0);
  40354             }
  40355 #endif
  40356         }
  40357         break;
  40358 
  40359     case bcmPortControlEEELinkActiveDuration:
  40360         if (!SOC_PORT_VALID(unit, port)) {
  40361             return BCM_E_PORT;
  40362         }
  40363         if (!IS_E_PORT(unit, port)) {
  40364             return BCM_E_UNAVAIL;
  40365         }
  40366 #if defined(BCM_HURRICANE2_SUPPORT)
  40367         if (SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) ||
  40368             SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  40369             soc_reg_t   reg;
  40370 
  40371             if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) {
  40372                 reg = IS_XL_PORT(unit, port) ? XLMAC_EEE_1_SEC_LINK_STATUS_TIMERr : 
  40373                                                CLMAC_EEE_1_SEC_LINK_STATUS_TIMERr;
  40374                 if (SOC_REG_FIELD_VALID(unit, reg, ONE_SECOND_TIMERf)) {
  40375                     if (value >= (1 << soc_reg_field_length(unit,
  40376                                                             reg, 
  40377                         ONE_SECOND_TIMERf))) {
  40378                         return BCM_E_PARAM;
  40379                     }
  40380                     rv = soc_reg_field32_modify(unit,
  40381                                                 reg, 
  40382                                                 port,
  40383                                                 ONE_SECOND_TIMERf, 
  40384                                                 value);
  40385                 }
  40386             } else {
  40387                 return BCM_E_PORT;
  40388             }
  40389         } else
  40390 #endif
  40391         {
  40392 #if defined(BCM_TRIUMPH3_SUPPORT)
  40393             {
  40394                 soc_reg_t reg;
  40395 
  40396                 reg = IS_C_PORT(unit, port) ?
  40397                     CMAC_EEE_1_SEC_LINK_STATUS_TIMERr :
  40398                     XMAC_EEE_1_SEC_LINK_STATUS_TIMERr;
  40399                 if (SOC_REG_FIELD_VALID(unit, reg, ONE_SECOND_TIMERf)) {
  40400                     if (value >= (1 << soc_reg_field_length(unit, reg,
  40401                                                      ONE_SECOND_TIMERf))) {
  40402                         return BCM_E_PARAM;
  40403                     }
  40404                     rv = soc_reg_field32_modify(unit, reg, port,
  40405                                                 ONE_SECOND_TIMERf, value);
  40406                 }
  40407             }
  40408 #endif
  40409         }
  40410         break;
  40411 
  40412     case bcmPortControlRemoteCpuEnable:
  40413         if (soc_feature(unit, soc_feature_rcpu_1)) {
  40414            bcm_pbmp_t   pbmp;
  40415            uint32       rval;
  40416 
  40417            rval = 0;
  40418            if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTSr)) {
  40419                READ_CMIC_PKT_PORTSr(unit, &rval);
  40420            } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_0r)) {
  40421                READ_CMIC_PKT_PORTS_0r(unit, &rval);
  40422            }
  40423            SOC_PBMP_WORD_SET(pbmp, 0, rval);
  40424            if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_HIr)) {
  40425                READ_CMIC_PKT_PORTS_HIr(unit, &rval);
  40426                SOC_PBMP_WORD_SET(pbmp, 1, rval);
  40427            } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_1r)) {
  40428                READ_CMIC_PKT_PORTS_1r(unit, &rval);
  40429                SOC_PBMP_WORD_SET(pbmp, 1, rval);
  40430            }
  40431 
  40432            if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_HI_2r)) {
  40433                READ_CMIC_PKT_PORTS_HI_2r(unit, &rval);
  40434                SOC_PBMP_WORD_SET(pbmp, 2, rval);
  40435            } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_2r)) {
  40436                READ_CMIC_PKT_PORTS_2r(unit, &rval);
  40437                SOC_PBMP_WORD_SET(pbmp, 2, rval);
  40438            }
  40439 
  40440            if (value) {
  40441                SOC_PBMP_PORT_ADD(pbmp, port);
  40442            } else {
  40443                SOC_PBMP_PORT_REMOVE(pbmp, port);
  40444            }
  40445            rval = 0;
  40446 
  40447            if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTSr)) {
  40448                soc_reg_field_set(unit, CMIC_PKT_PORTSr, &rval, PORTSf,
  40449                                  SOC_PBMP_WORD_GET(pbmp, 0));
  40450                 (void) WRITE_CMIC_PKT_PORTSr(unit, rval);
  40451             } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_0r)) {
  40452                soc_reg_field_set(unit, CMIC_PKT_PORTS_0r, &rval, PORTSf,
  40453                                  SOC_PBMP_WORD_GET(pbmp, 0));
  40454                 (void) WRITE_CMIC_PKT_PORTS_0r(unit, rval);
  40455             }
  40456 
  40457            if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_HIr)) {
  40458                rval = 0;
  40459                soc_reg_field_set(unit, CMIC_PKT_PORTS_HIr, &rval, PORTS_HIf,
  40460                              SOC_PBMP_WORD_GET(pbmp, 1));
  40461                (void) WRITE_CMIC_PKT_PORTS_HIr(unit, rval);
  40462            } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_1r)) {
  40463                rval = 0;
  40464                soc_reg_field_set(unit, CMIC_PKT_PORTS_1r, &rval, PORTS_HIf,
  40465                              SOC_PBMP_WORD_GET(pbmp, 1));
  40466                (void) WRITE_CMIC_PKT_PORTS_1r(unit, rval);
  40467            }
  40468 
  40469            if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_HI_2r)) {
  40470                rval = 0;
  40471                soc_reg_field_set(unit, CMIC_PKT_PORTS_HI_2r, &rval, PORTS_HIf,
  40472                              SOC_PBMP_WORD_GET(pbmp, 2));
  40473                (void) WRITE_CMIC_PKT_PORTS_HI_2r(unit, rval);
  40474            } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_2r)) {
  40475                rval = 0;
  40476                soc_reg_field_set(unit, CMIC_PKT_PORTS_2r, &rval, PORTS_HIf,
  40477                              SOC_PBMP_WORD_GET(pbmp, 2));
  40478                (void) WRITE_CMIC_PKT_PORTS_2r(unit, rval);
  40479            }
  40480 
  40481            rv = BCM_E_NONE;
  40482         } else {
  40483             rv = BCM_E_UNAVAIL;
  40484         }
  40485         break;
  40486 
  40487     case bcmPortControlRemoteCpuTcMapping:
  40488         if (soc_feature(unit, soc_feature_rcpu_tc_mapping)) {
  40489             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40490                                        REMOTE_CPU_ENf, (value) ? 1 : 0);
  40491             /* If BCM port, then set property in LPORT table too */
  40492             if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) {
  40493                 rv = bcm_esw_port_lport_field_set(unit, port,
  40494                                                   LPORT_PROFILE_LPORT_TAB,
  40495                                                   REMOTE_CPU_ENf,
  40496                                                   (value) ? 1 : 0);
  40497             }
  40498         } else {
  40499             rv = BCM_E_UNAVAIL;
  40500         }
  40501         break;
  40502 
  40503     case bcmPortControlTrill:
  40504 #if defined(BCM_TRIDENT_SUPPORT)
  40505         if (soc_feature(unit, soc_feature_trill)) {
  40506             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40507                                        TRILL_ENABLEf, (value) ? 1 : 0);
  40508             if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) {
  40509                 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, TRILL_ENABLEf)) {
  40510                     rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  40511                                                 TRILL_ENABLEf,
  40512                                                 (value) ? 1 : 0);
  40513                 }
  40514             }
  40515         }
  40516 #endif /* BCM_TRIDENT_SUPPORT */
  40517        break;
  40518 
  40519     case bcmPortControlTrillAllow:
  40520 #if defined(BCM_TRIDENT_SUPPORT)
  40521          if (soc_feature(unit, soc_feature_trill)) {
  40522              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40523                                         ALLOW_TRILL_FRAMESf,
  40524                                         (value) ? 1 : 0);
  40525              if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) {
  40526                  if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm,
  40527                                          ALLOW_TRILL_FRAMESf)) {
  40528                      rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  40529                                                  ALLOW_TRILL_FRAMESf,
  40530                                                  (value) ? 1 : 0);
  40531                  }
  40532              }
  40533          }
  40534 #endif /* BCM_TRIDENT_SUPPORT */
  40535          break;
  40536 
  40537     case bcmPortControlNonTrillAllow:
  40538 #if defined(BCM_TRIDENT_SUPPORT)
  40539          if (soc_feature(unit, soc_feature_trill)) {
  40540              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40541                                         ALLOW_NON_TRILL_FRAMESf,
  40542                                         (value) ? 1 : 0);
  40543              if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) {
  40544                  if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm,
  40545                                          ALLOW_NON_TRILL_FRAMESf)) {
  40546                      rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  40547                                                  ALLOW_NON_TRILL_FRAMESf,
  40548                                                  (value) ? 1 : 0);
  40549                  }
  40550              }
  40551          }
  40552 #endif /* BCM_TRIDENT_SUPPORT */
  40553          break;
  40554 
  40555     case bcmPortControlTrillCoreISISToCPU:
  40556 #if defined(BCM_TRIDENT_SUPPORT)
  40557          if (soc_feature(unit, soc_feature_trill)) {
  40558              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40559                                         COPY_CORE_IS_IS_TO_CPUf,
  40560                                         (value) ? 1 : 0);
  40561          }
  40562 #endif /* BCM_TRIDENT_SUPPORT */
  40563          break;
  40564 
  40565     case bcmPortControlTrillHashSelect:
  40566 #if defined(BCM_TRIUMPH3_SUPPORT)
  40567         if (SOC_IS_TRIUMPH3(unit)) {
  40568             return BCM_E_UNAVAIL;
  40569         } else
  40570 #endif /* BCM_TRIUMPH3_SUPPORT */
  40571         {
  40572 #if defined(BCM_TRIDENT_SUPPORT)
  40573              if (soc_feature(unit, soc_feature_trill)) {
  40574                    rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40575                             RTAG7_HASH_CFG_SEL_TRILL_ECMPf, (value) ? 1 : 0);
  40576              }
  40577 #endif /* BCM_TRIDENT_SUPPORT */
  40578         }
  40579          break;
  40580 
  40581     case bcmPortControlNivAccessVirtualInterfaceId:
  40582     case bcmPortControlExtendedPortVid:
  40583 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  40584          if (soc_feature(unit, soc_feature_niv) ||
  40585                  soc_feature(unit, soc_feature_port_extension)) {
  40586              int mod_port_index;
  40587 
  40588              if ((value < 0) || (value > 0xfff)) {
  40589                  return BCM_E_PARAM;
  40590              }
  40591             BCM_IF_ERROR_RETURN(
  40592                  _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40593                                        NIV_VIF_IDf, value));
  40594             BCM_IF_ERROR_RETURN(
  40595                 _bcm_esw_src_mod_port_table_index_get_from_port(
  40596                     unit, port, &mod_port_index));
  40597             SOC_IF_ERROR_RETURN(
  40598                 soc_mem_field32_modify(unit, EGR_GPP_ATTRIBUTESm, mod_port_index,
  40599                      SRC_NIV_VIF_IDf, value));
  40600 
  40601             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  40602                 SOC_IS_GREYHOUND2(unit)) {
  40603                 uint64 val64;
  40604 
  40605                 rv = READ_EGR_PORT_64r(unit, port, &val64);
  40606                 if (BCM_SUCCESS(rv)) {
  40607                     soc_reg64_field32_set(unit, EGR_PORT_64r,
  40608                         &val64,
  40609                         NIV_VIF_IDf, value);
  40610                 }
  40611                 rv = WRITE_EGR_PORT_64r(unit, port, val64);
  40612             } else {
  40613                  rv = _bcm_esw_egr_port_tab_set(unit, port, NIV_VIF_IDf, value);
  40614             }
  40615          }
  40616 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  40617          break;
  40618 
  40619     case bcmPortControlNivNonVntagDrop:
  40620     case bcmPortControlNonEtagDrop:
  40621 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  40622          if (soc_feature(unit, soc_feature_niv) ||
  40623              soc_feature(unit, soc_feature_port_extension)) {
  40624              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40625                      DISCARD_IF_VNTAG_NOT_PRESENTf, (value) ? 1 : 0);
  40626          }
  40627 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT*/
  40628          break;
  40629 
  40630     case bcmPortControlNivVntagDrop:
  40631     case bcmPortControlEtagDrop:
  40632 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  40633          if (soc_feature(unit, soc_feature_niv) ||
  40634              soc_feature(unit, soc_feature_port_extension)) {
  40635              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40636                      DISCARD_IF_VNTAG_PRESENTf, (value) ? 1 : 0);
  40637          }
  40638 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  40639          break;
  40640 
  40641     case bcmPortControlSubportPktTagDrop:
  40642 #if defined(BCM_KATANA2_SUPPORT)
  40643         if (soc_feature(unit, soc_feature_lltag)) {
  40644             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40645                      DISCARD_IF_LLTAG_PRESENTf, (value) ? 1 : 0);
  40646         }
  40647 #endif  /* BCM_KATANA2_SUPPORT */
  40648         break;
  40649 
  40650     case bcmPortControlNoSubportPktTagDrop:
  40651 #if defined(BCM_KATANA2_SUPPORT)
  40652         if (soc_feature(unit, soc_feature_lltag)) {
  40653             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40654                      DISCARD_IF_LLTAG_NOT_PRESENTf, (value) ? 1 : 0);
  40655         }
  40656 #endif  /* BCM_KATANA2_SUPPORT */
  40657         break;
  40658 
  40659     case bcmPortControlNivNonVntagAdd:
  40660     case bcmPortControlNonEtagAdd:
  40661 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  40662          if (soc_feature(unit, soc_feature_niv) ||
  40663                  soc_feature(unit, soc_feature_port_extension)) {
  40664              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40665                      VNTAG_ACTIONS_IF_NOT_PRESENTf,
  40666                      (value) ?
  40667                      ((type == bcmPortControlNonEtagAdd) ? 2 : VNTAG_ADD) :
  40668                      VNTAG_NOOP);
  40669          }
  40670 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  40671          break;
  40672 
  40673     case bcmPortControlNivVntagIngressReplace:
  40674     case bcmPortControlEtagIngressReplace:
  40675 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  40676          if (soc_feature(unit, soc_feature_niv) ||
  40677                  soc_feature(unit, soc_feature_port_extension)) {
  40678              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40679                      VNTAG_ACTIONS_IF_PRESENTf,
  40680                      (value) ? VNTAG_REPLACE : VNTAG_NOOP);
  40681          }
  40682 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  40683          break;
  40684 
  40685     case bcmPortControlNivVntagEgressReplace:
  40686     case bcmPortControlEtagEgressReplace:
  40687 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  40688          if (soc_feature(unit, soc_feature_niv) ||
  40689                  soc_feature(unit, soc_feature_port_extension)) {
  40690             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  40691                 SOC_IS_GREYHOUND2(unit)) {
  40692                 uint64 val64;
  40693 
  40694                 if (type == bcmPortControlEtagEgressReplace) {
  40695                     return BCM_E_UNAVAIL;
  40696                 }
  40697 
  40698                 rv = READ_EGR_PORT_64r(unit, port, &val64);
  40699                 if (BCM_SUCCESS(rv)) {
  40700                     soc_reg64_field32_set(unit, EGR_PORT_64r,
  40701                         &val64,
  40702                         VNTAG_ACTIONS_IF_PRESENTf,
  40703                         (value) ? VNTAG_REPLACE : VNTAG_NOOP);
  40704                 }
  40705                 rv = WRITE_EGR_PORT_64r(unit, port, val64);
  40706             } else {
  40707                  rv = _bcm_esw_egr_port_tab_set(
  40708                           unit, port, VNTAG_ACTIONS_IF_PRESENTf,
  40709                      (value) ? VNTAG_REPLACE : VNTAG_NOOP);
  40710             }
  40711          }
  40712 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  40713          break;
  40714 
  40715     case bcmPortControlNivVntagIngressDelete:
  40716     case bcmPortControlEtagIngressDelete:
  40717 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  40718          if (soc_feature(unit, soc_feature_niv) ||
  40719                  soc_feature(unit, soc_feature_port_extension)) {
  40720              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40721                      VNTAG_ACTIONS_IF_PRESENTf,
  40722                      (value) ? VNTAG_DELETE : VNTAG_NOOP);
  40723          }
  40724 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  40725          break;
  40726 
  40727     case bcmPortControlNivVntagEgressDelete:
  40728     case bcmPortControlEtagEgressDelete:
  40729 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  40730          if (soc_feature(unit, soc_feature_niv) ||
  40731                  soc_feature(unit, soc_feature_port_extension)) {
  40732             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  40733                 SOC_IS_GREYHOUND2(unit)) {
  40734                 uint64 val64;
  40735                 rv = READ_EGR_PORT_64r(unit, port, &val64);
  40736                 if (BCM_SUCCESS(rv)) {
  40737                     soc_reg64_field32_set(unit, EGR_PORT_64r,
  40738                         &val64,
  40739                         VNTAG_ACTIONS_IF_PRESENTf,
  40740                         (value) ? VNTAG_DELETE : VNTAG_NOOP);
  40741                 }
  40742                 rv = WRITE_EGR_PORT_64r(unit, port, val64);
  40743             } else {
  40744                 rv = _bcm_esw_egr_port_tab_set(
  40745                          unit, port, VNTAG_ACTIONS_IF_PRESENTf,
  40746                      (value) ? VNTAG_DELETE: VNTAG_NOOP);
  40747             }
  40748          }
  40749 #endif /* BCM_TRIDENT_SUPPORT  || BCM_GREYHOUND_SUPPORT */
  40750          break;
  40751 
  40752     case bcmPortControlNivRpfCheck:
  40753     case bcmPortControlExtenderRpfCheck:
  40754 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  40755          if (soc_feature(unit, soc_feature_niv) ||
  40756                  soc_feature(unit, soc_feature_port_extension)) {
  40757              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40758                      NIV_RPF_CHECK_ENABLEf, (value) ? 1 : 0);
  40759          }
  40760 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  40761          break;
  40762 
  40763     case bcmPortControlNivSourceKnockout:
  40764     case bcmPortControlExtenderSourceKnockout:
  40765 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  40766          if (soc_feature(unit, soc_feature_niv) ||
  40767                  soc_feature(unit, soc_feature_port_extension)) {
  40768             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  40769                 SOC_IS_GREYHOUND2(unit)) {
  40770                 uint64 val64;
  40771                 rv = READ_EGR_PORT_64r(unit, port, &val64);
  40772                 if (BCM_SUCCESS(rv)) {
  40773                     soc_reg64_field32_set(unit, EGR_PORT_64r,
  40774                         &val64,
  40775                         NIV_PRUNE_ENABLEf,
  40776                         (value) ? 1 : 0);
  40777                 }
  40778                 rv = WRITE_EGR_PORT_64r(unit, port, val64);
  40779             } else {
  40780                  rv = _bcm_esw_egr_port_tab_set(unit, port, NIV_PRUNE_ENABLEf,
  40781                                                 (value) ? 1 : 0);
  40782             }
  40783          }
  40784 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  40785          break;
  40786 
  40787     case bcmPortControlNivForwardPort:
  40788     case bcmPortControlExtenderForwardPort:
  40789 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  40790          if (soc_feature(unit, soc_feature_niv) ||
  40791                  soc_feature(unit, soc_feature_port_extension)) {
  40792              int mod_port_index;
  40793              bcm_module_t mod_out;
  40794              bcm_port_t port_out;
  40795              bcm_trunk_t trunk_out;
  40796              int id_out;
  40797              int tx_dest_port;
  40798 
  40799              if (value == -1) {
  40800                  BCM_IF_ERROR_RETURN
  40801                      (_bcm_esw_port_tab_set(unit, port,
  40802                                             _BCM_CPU_TABS_ETHER,
  40803                                             NIV_UPLINK_PORTf, 1));
  40804                 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  40805                     SOC_IS_GREYHOUND2(unit)) {
  40806                     uint64 val64;
  40807                     rv = READ_EGR_PORT_64r(unit, port, &val64);
  40808                     if (BCM_SUCCESS(rv)) {
  40809                         soc_reg64_field32_set(unit, EGR_PORT_64r,
  40810                             &val64,
  40811                             NIV_UPLINK_PORTf, 1);
  40812                     }
  40813                     rv = WRITE_EGR_PORT_64r(unit, port, val64);
  40814                 } else {
  40815                     BCM_IF_ERROR_RETURN(
  40816                         _bcm_esw_egr_port_tab_set(unit, port,
  40817                                                   NIV_UPLINK_PORTf, 1));
  40818                     BCM_IF_ERROR_RETURN(
  40819                         _bcm_esw_src_mod_port_table_index_get_from_port(
  40820                             unit, port, &mod_port_index));
  40821                     SOC_IF_ERROR_RETURN(
  40822                         soc_mem_field32_modify(unit, EGR_GPP_ATTRIBUTESm,
  40823                                              mod_port_index,
  40824                                              SRC_IS_NIV_UPLINK_PORTf, 1));
  40825                  }
  40826                  rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40827                                             NIV_VIF_LOOKUP_ENABLEf, 1);
  40828              } else {
  40829                  BCM_IF_ERROR_RETURN
  40830                      (_bcm_esw_gport_resolve(unit, value, &mod_out, &port_out,
  40831                                              &trunk_out, &id_out));
  40832                  if (id_out != -1) {
  40833                      return BCM_E_PARAM;
  40834                 }
  40835 
  40836                 if (soc_feature(unit, soc_feature_generic_dest)) {
  40837                     uint32 dval;
  40838                     if (trunk_out != -1) {
  40839                         dval = _soc_mem_dest_value_construct(unit,
  40840                                     SOC_MEM_FIF_DEST_LAG, trunk_out);
  40841                     } else {
  40842                         dval = _soc_mem_dest_value_construct(unit,
  40843                                     SOC_MEM_FIF_DEST_DGPP,
  40844                                     mod_out << SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS | port_out);
  40845                     }
  40846                     BCM_IF_ERROR_RETURN
  40847                         (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40848                                                DESTINATIONf, dval));
  40849                 } else {
  40850                     if (trunk_out != -1) {
  40851                      tx_dest_port = (1 << SOC_TRUNK_BIT_POS(unit)) + trunk_out;
  40852                  } else {
  40853 #if defined(BCM_METROLITE_SUPPORT)
  40854                    /* Metrolite DGLP still uses 7 bits for ports like saber2 */
  40855                    if (SOC_IS_METROLITE(unit)) {
  40856                        tx_dest_port = ((mod_out << 7) | (port_out));
  40857                    } else
  40858 #endif
  40859                      tx_dest_port = mod_out * (SOC_PORT_ADDR_MAX(unit) + 1) +
  40860                                     port_out;
  40861                  }
  40862 
  40863                  BCM_IF_ERROR_RETURN
  40864                      (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40865                                             TX_DEST_PORTf, tx_dest_port));
  40866                 }
  40867                  rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40868                                             TX_DEST_PORT_ENABLEf, 1);
  40869              }
  40870          }
  40871 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  40872          break;
  40873 
  40874     case bcmPortControlNivType:
  40875         if (soc_feature(unit, soc_feature_niv)) {
  40876              if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  40877                 SOC_IS_GREYHOUND2(unit)) {
  40878 #if defined(BCM_GREYHOUND_SUPPORT)
  40879                  rv = bcm_gh_port_niv_type_set(unit, port, value);
  40880 #endif /* BCM_GREYHOUND_SUPPORT */
  40881             } else {
  40882 #if defined(BCM_TRIDENT_SUPPORT)
  40883                  rv = bcm_td_port_niv_type_set(unit, port, value);
  40884 #endif /* BCM_TRIDENT_SUPPORT */
  40885             }
  40886         }
  40887          break;
  40888 
  40889     case bcmPortControlExtenderType:
  40890         if (soc_feature(unit, soc_feature_port_extension)) {
  40891             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  40892                 SOC_IS_GREYHOUND2(unit)) {
  40893 #if defined(BCM_GREYHOUND_SUPPORT)
  40894                  rv = bcm_gh_port_extender_type_set(unit, port, value);
  40895 #endif /* BCM_GREYHOUND_SUPPORT */
  40896             } else {
  40897 #if defined(BCM_TRIUMPH3_SUPPORT)
  40898                  rv = bcm_tr3_port_extender_type_set(unit, port, value);
  40899 #endif /* BCM_TRIUMPH3_SUPPORT */
  40900             }
  40901         }
  40902          break;
  40903 
  40904     case bcmPortControlNivNameSpace:
  40905     case bcmPortControlExtenderNameSpace:
  40906 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  40907          if (soc_feature(unit, soc_feature_niv) ||
  40908                  soc_feature(unit, soc_feature_port_extension)) {
  40909              if ((value < 0) || (value > 0xfff)) {
  40910                  return BCM_E_PARAM;
  40911              }
  40912              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40913                      NIV_NAMESPACEf, value);
  40914          }
  40915 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  40916          break;
  40917 
  40918     case bcmPortControlEtagPcpDeSelect:
  40919 #if defined(INCLUDE_L3)
  40920         if (soc_feature(unit, soc_feature_port_extension)) {
  40921             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  40922                 SOC_IS_GREYHOUND2(unit)) {
  40923 #if defined(BCM_GREYHOUND_SUPPORT)
  40924                 rv = bcm_gh_port_etag_pcp_de_source_set(unit, port, value);
  40925 #endif /* BCM_GREYHOUND_SUPPORT */
  40926             } else {
  40927 #if defined(BCM_TRIUMPH3_SUPPORT)
  40928                 rv = bcm_tr3_port_etag_pcp_de_source_set(unit, port, value);
  40929 #endif /* BCM_TRIUMPH3_SUPPORT */
  40930             }
  40931         }
  40932 #endif /* INCLUDE_L3 */
  40933          break;
  40934 
  40935     case bcmPortControlEtagPcp:
  40936 #if defined(BCM_TRIUMPH3_SUPPORT)
  40937          if (soc_feature(unit, soc_feature_port_extension)) {
  40938              if ((value < 0) || (value > 7)) {
  40939                  return BCM_E_PARAM;
  40940              }
  40941              if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, ETAG_PCPf)) {
  40942                  BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit,
  40943                                      EGR_ING_PORTm, port,
  40944                                      ETAG_PCPf, value));
  40945              }
  40946              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40947                      ETAG_PCPf, value);
  40948          }
  40949 #endif /* BCM_TRIUMPH3_SUPPORT */
  40950 #if defined(BCM_GREYHOUND_SUPPORT)
  40951         if (soc_feature(unit, soc_feature_port_extension)) {
  40952             if ((value < 0) || (value > 7)) {
  40953                 return BCM_E_PARAM;
  40954             }
  40955             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40956                     ETAG_PCPf, value);
  40957         }
  40958 #endif /* BCM_GREYHOUND_SUPPORT */
  40959          break;
  40960 
  40961     case bcmPortControlEtagDe:
  40962 #if defined(BCM_TRIUMPH3_SUPPORT)
  40963          if (soc_feature(unit, soc_feature_port_extension)) {
  40964              if ((value < 0) || (value > 1)) {
  40965                  return BCM_E_PARAM;
  40966              }
  40967              if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, ETAG_DEf)) {
  40968                  BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit,
  40969                                      EGR_ING_PORTm, port,
  40970                                      ETAG_DEf, value));
  40971              }
  40972              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40973                      ETAG_DEf, value);
  40974          }
  40975 #endif /* BCM_TRIUMPH3_SUPPORT */
  40976 #if defined(BCM_GREYHOUND_SUPPORT)
  40977          if (soc_feature(unit, soc_feature_port_extension)) {
  40978             if ((value < 0) || (value > 1)) {
  40979                 return BCM_E_PARAM;
  40980             }
  40981             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40982                            ETAG_DEf, value);
  40983          }
  40984 #endif /* BCM_GREYHOUND_SUPPORT */
  40985          break;
  40986 
  40987     case bcmPortControlUseEtagPri:
  40988 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  40989          if (soc_feature(unit, soc_feature_port_extension)) {
  40990             if ((value < 0) || (value > 1)) {
  40991                 return BCM_E_PARAM;
  40992             }
  40993             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  40994                      PHB_FROM_ETAGf, value);
  40995 #if defined(BCM_GREYHOUND_SUPPORT)
  40996             if(soc_feature(unit,soc_feature_pktpri_as_dot1p)){
  40997                 if (BCM_FAILURE(rv)) {
  40998                         return rv;
  40999                     }
  41000                 /*
  41001                  * Make sure TREAT_PKTPRI_AS_DOT1P bit is set for
  41002                  * ETAG internal priority mapping.
  41003                  */
  41004                 rv = bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update
  41005                          (unit, (value) ? 1 : -1);
  41006             }
  41007 #endif /* BCM_GREYHOUND_SUPPORT */
  41008         } 
  41009 #endif /* BCM_TRIUMPH3_SUPPORT||BCM_GREYHOUND_SUPPORT */
  41010          break;
  41011 
  41012     case bcmPortControlUseSubportPktTagPri:
  41013 #if defined(BCM_KATANA2_SUPPORT)
  41014          if (soc_feature(unit, soc_feature_lltag)) {
  41015              rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41016                      PHB_FROM_LLTAGf, value);
  41017          }
  41018 #endif /* BCM_KATANA2_SUPPORT */
  41019          break;
  41020 
  41021     case bcmPortControlProhibitedDot1p:
  41022 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  41023          rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41024                  PROHIBITED_DOT1Pf, value);
  41025 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  41026          break;
  41027 
  41028     case bcmPortControlFabricSourceKnockout:
  41029         if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, REMOVE_HG_HDR_SRC_PORTf) ||
  41030             SOC_IS_TRIDENT3X(unit)) {
  41031             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  41032                                 REMOVE_HG_HDR_SRC_PORTf, (value) ? 1 : 0);
  41033 
  41034             if (!SOC_IS_TOMAHAWK3(unit)) {
  41035                 /* If BCM port, then set property in LPORT table too */
  41036                 if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) {
  41037                     rv = bcm_esw_port_lport_field_set(unit, port,
  41038                                                   LPORT_PROFILE_LPORT_TAB,
  41039                                                   ALLOW_SRC_MODf, value);
  41040                 }
  41041             }
  41042         }
  41043         break;
  41044     case bcmPortControlRxEnable:
  41045         rv = _bcm_esw_mac_rx_control(unit, port, 0, &value);
  41046         break;
  41047     case bcmPortControlTxEnable:
  41048 
  41049         if (SOC_REG_IS_VALID(unit, COSMASKr)) {
  41050             /* Use egress scheduling control if available */
  41051             uint32 val;
  41052             if (value > 0) {
  41053                 if (!(PORT(unit, port).flags & _PORT_INFO_STOP_TX)) {
  41054                     /* Port tx was never stopped */
  41055                     rv = BCM_E_NONE;
  41056                     break;
  41057                 }
  41058                 /* Restore values */
  41059                 val = PORT(unit, port).cosmask;
  41060                 rv =  soc_reg_field32_modify(unit, COSMASKr, port,
  41061                                              COSMASKf, val);
  41062                 /* clear flag */
  41063                 PORT(unit, port).flags &= ~_PORT_INFO_STOP_TX;
  41064             } else {
  41065                 uint32 rval;
  41066                 /* Read and save current values */
  41067                 SOC_IF_ERROR_RETURN(READ_COSMASKr(unit, port, &rval));
  41068                 PORT(unit, port).cosmask = soc_reg_field_get(unit, COSMASKr,
  41069                                                              rval, COSMASKf);
  41070                 /* set flag */
  41071                 PORT(unit, port).flags |= _PORT_INFO_STOP_TX;
  41072                 /* Disable Tx */
  41073                 val = (1 << soc_reg_field_length(unit, COSMASKr,
  41074                                                  COSMASKf)) - 1;
  41075                 rv =  soc_reg_field32_modify(unit, COSMASKr, port,
  41076                                              COSMASKf, val);
  41077             }
  41078 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT)
  41079         } else if  (SOC_IS_HELIX4(unit) || SOC_IS_TRIUMPH3(unit)) {
  41080             rv = BCM_E_NONE;
  41081             if (value > 0 ) {
  41082                 if (!(PORT(unit, port).flags & _PORT_INFO_STOP_TX)) {
  41083                     /* Port tx already enabled */
  41084                     break;
  41085                 }
  41086                 PORT(unit, port).flags &= ~_PORT_INFO_STOP_TX;
  41087                 BCM_IF_ERROR_RETURN(_bcm_tr3_port_tx_set(unit, port, 1));
  41088             } else {
  41089                 if ((PORT(unit, port).flags & _PORT_INFO_STOP_TX)) {
  41090                     /* Port tx already disabled */
  41091                     break;
  41092                 }
  41093                 PORT(unit, port).flags |= _PORT_INFO_STOP_TX;
  41094                 BCM_IF_ERROR_RETURN(_bcm_tr3_port_tx_set(unit, port, 0));
  41095             }
  41096             break;
  41097 #endif
  41098         } else if ((SOC_REG_IS_VALID(unit, EGRMETERINGCONFIGr)) ||
  41099                     (SOC_REG_IS_VALID(unit, EGRMETERINGBUCKETr))) { /* Use egress metering control if available */
  41100             uint32 rval1 = 0, rval2 = 0;
  41101             if (value > 0 ) {
  41102                 if (!(PORT(unit, port).flags & _PORT_INFO_STOP_TX)) {
  41103                     /* Port tx was never stopped */
  41104                     break;
  41105                 }
  41106                 /* Restore values */
  41107                 BCM_IF_ERROR_RETURN(READ_EGRMETERINGCONFIGr(unit, port,
  41108                                                             &rval1));
  41109                 BCM_IF_ERROR_RETURN(READ_EGRMETERINGBUCKETr(unit, port,
  41110                                                             &rval2));
  41111                 soc_reg_field_set(unit, EGRMETERINGCONFIGr, &rval1,
  41112                                   REFRESHf, PORT(unit, port).m_info.refresh);
  41113                 soc_reg_field_set(unit, EGRMETERINGCONFIGr, &rval1,
  41114                                   THD_SELf, PORT(unit, port).m_info.threshold);
  41115                 soc_reg_field_set(unit, EGRMETERINGBUCKETr, &rval2,
  41116                                   BUCKETf, PORT(unit, port).m_info.bucket);
  41117                 soc_reg_field_set(unit, EGRMETERINGBUCKETr, &rval2,
  41118                                   IN_PROFILE_FLAGf,
  41119                                   PORT(unit, port).m_info.in_profile);
  41120                 BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGCONFIGr(unit, port,
  41121                                                              rval1));
  41122                 BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGBUCKETr(unit, port,
  41123                                                              rval2));
  41124                 /* clear flag */
  41125                 PORT(unit, port).flags &= ~_PORT_INFO_STOP_TX;
  41126                 rv = BCM_E_NONE;
  41127 
  41128             } else {
  41129                 /* Read and save current values */
  41130                 BCM_IF_ERROR_RETURN(READ_EGRMETERINGCONFIGr(unit, port,
  41131                                                             &rval1));
  41132                 PORT(unit, port).m_info.refresh =
  41133                     soc_reg_field_get(unit, EGRMETERINGCONFIGr, rval1,
  41134                                       REFRESHf);
  41135                 PORT(unit, port).m_info.threshold =
  41136                     soc_reg_field_get(unit, EGRMETERINGCONFIGr, rval1,
  41137                                       THD_SELf);
  41138                 BCM_IF_ERROR_RETURN(READ_EGRMETERINGBUCKETr(unit, port,
  41139                                                             &rval2));
  41140                 PORT(unit, port).m_info.bucket =
  41141                     soc_reg_field_get(unit, EGRMETERINGBUCKETr, rval2,
  41142                                       BUCKETf);
  41143                 PORT(unit, port).m_info.in_profile =
  41144                     soc_reg_field_get(unit, EGRMETERINGBUCKETr, rval2,
  41145                                       IN_PROFILE_FLAGf);
  41146                 /* set flag */
  41147                 PORT(unit, port).flags |= _PORT_INFO_STOP_TX;
  41148                 /* Disable Tx */
  41149                 soc_reg_field_set(unit, EGRMETERINGCONFIGr, &rval1,
  41150                                   REFRESHf, 0);
  41151                 soc_reg_field_set(unit, EGRMETERINGCONFIGr, &rval1,
  41152                                   THD_SELf, 1);
  41153                 soc_reg_field_set(unit, EGRMETERINGBUCKETr, &rval2,
  41154                                   BUCKETf, 0x100000);
  41155                 soc_reg_field_set(unit, EGRMETERINGBUCKETr, &rval2,
  41156                                   IN_PROFILE_FLAGf, 1);
  41157                 BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGCONFIGr(unit, port,
  41158                                                              rval1));
  41159                 BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGBUCKETr(unit, port,
  41160                                                              rval2));
  41161                 rv = BCM_E_NONE;
  41162             }
  41163         } else {
  41164             int (*port_tx_enable_set) (int, soc_port_t, int);
  41165 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) 
  41166             if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_TRIDENT2(unit)) {
  41167                 port_tx_enable_set = soc_td2_port_traffic_egr_enable_set;
  41168             } else 
  41169 #endif
  41170 #if defined(BCM_TRIDENT3_SUPPORT)
  41171             if (SOC_IS_TRIDENT3X(unit)) {
  41172                 port_tx_enable_set = soc_td3_port_traffic_egr_enable_set;
  41173             } else
  41174 #endif
  41175 #if defined(BCM_MONTEREY_SUPPORT)
  41176             if (SOC_IS_MONTEREY(unit)) {
  41177                 port_tx_enable_set = soc_monterey_port_traffic_egr_enable_set;
  41178             } else  
  41179 #endif
  41180 #if defined(BCM_APACHE_SUPPORT)
  41181             if (SOC_IS_APACHE(unit)) {
  41182                 port_tx_enable_set = soc_apache_port_traffic_egr_enable_set;
  41183             } else  
  41184 #endif
  41185 #if defined(BCM_TOMAHAWK_SUPPORT)
  41186             if (SOC_IS_TOMAHAWKX(unit)) {
  41187                 port_tx_enable_set = soc_tomahawk_port_traffic_egr_enable_set;
  41188             } else
  41189 #endif
  41190             { 
  41191                 port_tx_enable_set = NULL;
  41192             }
  41193             if (port_tx_enable_set != NULL ) { 
  41194                 rv = BCM_E_NONE;
  41195                 if (value > 0 ) {
  41196                     if (!(PORT(unit, port).flags & _PORT_INFO_STOP_TX)) {
  41197                         /* Port tx was never stopped */
  41198                         break;
  41199                     }
  41200                     PORT(unit, port).flags &= ~_PORT_INFO_STOP_TX;
  41201                     BCM_IF_ERROR_RETURN(((*port_tx_enable_set)(unit, port, 1)));
  41202                 } else {
  41203                     if ((PORT(unit, port).flags & _PORT_INFO_STOP_TX)) {
  41204                         /* Port tx alrady enabled */
  41205                         break;
  41206                     }
  41207                     PORT(unit, port).flags |= _PORT_INFO_STOP_TX;
  41208                     BCM_IF_ERROR_RETURN(((*port_tx_enable_set)(unit, port, 0)));
  41209                 }
  41210                 break;
  41211             } else {
  41212                 rv = BCM_E_UNAVAIL;
  41213             }
  41214         }
  41215         break;
  41216     case bcmPortControlMplsEntropyHashSet:
  41217 #if defined(BCM_TRIUMPH3_SUPPORT)
  41218         if (SOC_IS_TRIUMPH3(unit)) {
  41219             return BCM_E_UNAVAIL;
  41220         } else
  41221 #endif /* BCM_TRIUMPH3_SUPPORT */
  41222 #if defined(BCM_KATANA2_SUPPORT)
  41223         if (SOC_IS_KATANA2(unit)) {
  41224             return BCM_E_UNAVAIL;
  41225         } else
  41226 #endif /* BCM_KATANA2_SUPPORT */
  41227         {
  41228 #if defined(BCM_KATANA_SUPPORT)
  41229             if (soc_feature(unit, soc_feature_mpls)) {
  41230                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41231                                            RTAG7_HASH_CFG_SEL_ENTROPY_LABELf,
  41232                                            (value) ? 1 : 0);
  41233             }
  41234 #endif /* BCM_KATANA_SUPPORT */
  41235         }
  41236         break;
  41237 
  41238     case bcmPortControlL2GreEnable:
  41239 #if defined(BCM_TRIUMPH3_SUPPORT)
  41240         if (soc_feature(unit, soc_feature_l2gre)
  41241 #if defined(BCM_TRIDENT3_SUPPORT)
  41242             || soc_feature(unit, soc_feature_flex_flow)
  41243 #endif
  41244             ) {
  41245             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41246                                        L2GRE_TERMINATION_ALLOWEDf,
  41247                                        (value) ? 1 : 0);
  41248         }
  41249 #endif /* BCM_TRIUMPH3_SUPPORT */
  41250        break;
  41251 
  41252     case bcmPortControlL2GreTunnelbasedVpnId:
  41253 #if defined(BCM_TRIUMPH3_SUPPORT)
  41254         if (soc_feature(unit, soc_feature_l2gre)
  41255 #if defined(BCM_TRIDENT3_SUPPORT)
  41256             || soc_feature(unit, soc_feature_flex_flow)
  41257 #endif
  41258             ) {
  41259             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41260                                        L2GRE_VPNID_LOOKUP_KEY_TYPEf,
  41261                                        (value) ? 1 : 0);
  41262 
  41263             if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) {
  41264                 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm,
  41265                                         L2GRE_VFI_LOOKUP_KEY_TYPEf)) {
  41266                     rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  41267                                                 L2GRE_VFI_LOOKUP_KEY_TYPEf,
  41268                                                 (value) ? 1 : 0);
  41269                 }
  41270             }
  41271         }
  41272 #endif /* BCM_TRIUMPH3_SUPPORT */
  41273        break;
  41274 
  41275     case bcmPortControlL2GreDefaultTunnelEnable:
  41276 #if defined(BCM_TRIUMPH3_SUPPORT)
  41277         if (soc_feature(unit, soc_feature_l2gre)
  41278 #if defined(BCM_TRIDENT3_SUPPORT)
  41279             || soc_feature(unit, soc_feature_flex_flow)
  41280 #endif
  41281             ) {
  41282             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41283                                        L2GRE_DEFAULT_SVP_ENABLEf,
  41284                                        (value) ? 1 : 0);
  41285         }
  41286 #endif /* BCM_TRIUMPH3_SUPPORT */
  41287        break;
  41288 
  41289     case bcmPortControlVxlanEnable:
  41290 #if defined(BCM_TRIDENT2_SUPPORT)
  41291         if ((soc_feature(unit, soc_feature_vxlan)) ||
  41292             (soc_feature(unit, soc_feature_flex_flow))) {
  41293             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41294                                        VXLAN_TERMINATION_ALLOWEDf,
  41295                                        (value) ? 1 : 0);
  41296         }
  41297 #endif /* BCM_TRIDENT2_SUPPORT */
  41298        break;
  41299 
  41300     case bcmPortControlVxlanTunnelbasedVnId:
  41301 #if defined(BCM_TRIDENT2_SUPPORT)
  41302         if ((soc_feature(unit, soc_feature_vxlan)) ||
  41303             (soc_feature(unit, soc_feature_flex_flow))) {
  41304             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41305                                        VXLAN_VN_ID_LOOKUP_KEY_TYPEf,
  41306                                        (value) ? 1 : 0);
  41307             if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) {
  41308                 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm,
  41309                                         VXLAN_VFI_LOOKUP_KEY_TYPEf)) {
  41310                     rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  41311                                                 VXLAN_VFI_LOOKUP_KEY_TYPEf,
  41312                                                 (value) ? 1 : 0);
  41313                 }
  41314             }
  41315 #if defined(BCM_TRIDENT3_SUPPORT) && defined(CANCUN_SUPPORT)
  41316             if (BCM_SUCCESS(rv) && SOC_IS_TRIDENT3X(unit)) {
  41317                 rv = _bcm_esw_td3_port_cmh_ctrl_set(unit, port, type, value);
  41318             }
  41319 #endif
  41320         }
  41321 #endif /* BCM_TRIDENT2_SUPPORT */
  41322     break;
  41323     case bcmPortControlVxlanVpnAssignmentCriteria:
  41324 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  41325         if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) {
  41326             if ((value < bcmPortVxlanVpnAssignOnVnid) 
  41327                 || (value > bcmPortVxlanVpnAssignOnVnidOuterVlanSrcIp)) {
  41328                 return BCM_E_PARAM;
  41329             }
  41330             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41331                                        VXLAN_VN_ID_LOOKUP_KEY_TYPEf, value);
  41332         }
  41333 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  41334     break;
  41335     case bcmPortControlVxlanTerminationMatchCriteria:
  41336 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  41337         if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) {
  41338             if ((value < bcmPortVxlanTerminationMatchDstIp)
  41339                 || (value > bcmPortVxlanTerminationMatchOuterVlanDstIp)) {
  41340                 return BCM_E_PARAM;
  41341             }
  41342             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41343                                        VXLAN_TERMINATION_LOOKUP_TYPEf, value);
  41344         }
  41345 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  41346     break;
  41347     case bcmPortControlVxlanGportAssignmentCriteria:
  41348 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  41349         if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) {
  41350             if ((value < bcmPortVxlanGportAssignOnSrcIp)
  41351                 || (value > bcmPortVxlanGportAssignOnOuterVlanSrcIp)) {
  41352                 return BCM_E_PARAM;
  41353             }
  41354             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41355                                        VXLAN_SVP_ASSIGNMENT_KEY_TYPEf, value);
  41356         }
  41357 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  41358     break;
  41359     case bcmPortControlVxlanDefaultTunnelEnable:
  41360 #if defined(BCM_TRIDENT2_SUPPORT)
  41361         if ((soc_feature(unit, soc_feature_vxlan)) ||
  41362             (soc_feature(unit, soc_feature_flex_flow))) {
  41363             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  41364                                        VXLAN_DEFAULT_SVP_ENABLEf,
  41365                                        (value) ? 1 : 0);
  41366         }
  41367 #endif /* BCM_TRIDENT2_SUPPORT */
  41368     break;
  41369 
  41370 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_REGEX)
  41371     case bcmPortControlRegex:
  41372         if (!SOC_IS_TRIUMPH3(unit)) {
  41373             return BCM_E_UNAVAIL;
  41374         }
  41375         rv = _bcm_esw_port_regex_control_set(unit, port, 1, 1, !!value);
  41376         break;
  41377     case bcmPortControlRegexTcp:
  41378         if (!SOC_IS_TRIUMPH3(unit)) {
  41379             return BCM_E_UNAVAIL;
  41380         }
  41381         rv = _bcm_esw_port_regex_control_set(unit, port, 0, 1, !!value);
  41382         break;
  41383     case bcmPortControlRegexUdp:
  41384         if (!SOC_IS_TRIUMPH3(unit)) {
  41385             return BCM_E_UNAVAIL;
  41386         }
  41387         rv = _bcm_esw_port_regex_control_set(unit, port, 1, 0, !!value);
  41388         break;
  41389 #endif
  41390 #ifdef BCM_SHADOW_SUPPORT
  41391     case bcmPortControlManagementPacketIp6Reserved:
  41392         if (!SOC_IS_SHADOW(unit)) {
  41393             return BCM_E_UNAVAIL;
  41394         }
  41395         PORT_LOCK(unit);
  41396         if (value == 0) {
  41397             /* Clear the MGMT Frame classification */
  41398             rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port,
  41399                                         IPV6_RESVf, 0);
  41400         } else {
  41401             rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port,
  41402                                         IPV6_RESVf, 1);
  41403         }
  41404         PORT_UNLOCK(unit);
  41405         break;
  41406     case bcmPortControlManagementPacketIp4Reserved:
  41407         if (!SOC_IS_SHADOW(unit)) {
  41408             return BCM_E_UNAVAIL;
  41409         }
  41410         PORT_LOCK(unit);
  41411         if (value == 0) {
  41412             /* Clear the MGMT Frame classification */
  41413             rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port,
  41414                                         IPV6_RESVf, 0);
  41415         } else {
  41416             rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port,
  41417                                         IPV4_RESVf, 1);
  41418         }
  41419         PORT_UNLOCK(unit);
  41420         break;
  41421     case bcmPortControlManagementPacketLinkConstrained:
  41422         if (!SOC_IS_SHADOW(unit)) {
  41423             return BCM_E_UNAVAIL;
  41424         }
  41425         PORT_LOCK(unit);
  41426         if (value == 0) {
  41427             /* Clear the MGMT Frame classification */
  41428             rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port,
  41429                                         LINK_CONSTf, 0);
  41430         } else {
  41431             rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port,
  41432                                         LINK_CONSTf, 1);
  41433         }
  41434         PORT_UNLOCK(unit);
  41435         break;
  41436     case bcmPortControlManagementPacketGarp:
  41437         if (!SOC_IS_SHADOW(unit)) {
  41438             return BCM_E_UNAVAIL;
  41439         }
  41440         PORT_LOCK(unit);
  41441         if (value == 0) {
  41442             /* Clear the MGMT Frame classification */
  41443             rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port,
  41444                                         DOT1D_GARPf, 0);
  41445         } else {
  41446             rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port,
  41447                                         DOT1D_GARPf, 1);
  41448         }
  41449         PORT_UNLOCK(unit);
  41450         break;
  41451     case bcmPortControlManagementPacketCos:
  41452         if (!SOC_IS_SHADOW(unit)) {
  41453             return BCM_E_UNAVAIL;
  41454         }
  41455         PORT_LOCK(unit);
  41456         if ((value >= 0) && (value <= 7)) {
  41457             /* Clear the MGMT Frame classification */
  41458             rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port,
  41459                                         MGMT_FRAME_COSf, value);
  41460         } else {
  41461             rv = BCM_E_PARAM;
  41462         }
  41463         PORT_UNLOCK(unit);
  41464         break;
  41465     case bcmPortControlManagementPacketColor:
  41466         rv = BCM_E_UNAVAIL;
  41467         break;
  41468     case bcmPortControlTaggedL3PacketPktPri:
  41469         if (!SOC_IS_SHADOW(unit)) {
  41470             return BCM_E_UNAVAIL;
  41471         }
  41472         PORT_LOCK(unit);
  41473         switch ((bcm_port_cos_remap_t)value) {
  41474         case BCM_PORT_COS_REMAP_VLAN_PRI:
  41475             /* Clear the MGMT Frame classification */
  41476             rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port,
  41477                                         SELECT5f, 0);
  41478         break;
  41479         case BCM_PORT_COS_REMAP_DSCP:
  41480             /* Clear the MGMT Frame classification */
  41481             rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port,
  41482                                         SELECT5f, 2);
  41483         break;
  41484         default:
  41485             rv = BCM_E_PARAM;
  41486         }
  41487         PORT_UNLOCK(unit);
  41488         break;
  41489     case bcmPortControlTaggedMPLSPacketPktPri:
  41490         if (!SOC_IS_SHADOW(unit)) {
  41491             return BCM_E_UNAVAIL;
  41492         }
  41493         PORT_LOCK(unit);
  41494         switch ((bcm_port_cos_remap_t)value) {
  41495         case BCM_PORT_COS_REMAP_VLAN_PRI:
  41496             /* Clear the MGMT Frame classification */
  41497             rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port,
  41498                                         SELECT3f, 0);
  41499         break;
  41500         case BCM_PORT_COS_REMAP_EXP:
  41501             /* Clear the MGMT Frame classification */
  41502             rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port,
  41503                                         SELECT3f, 1);
  41504         break;
  41505         default:
  41506             rv = BCM_E_PARAM;
  41507         }
  41508         PORT_UNLOCK(unit);
  41509         break;
  41510     case bcmPortControlTaggedMPLSL3PacketPktPri:
  41511         if (!SOC_IS_SHADOW(unit)) {
  41512             return BCM_E_UNAVAIL;
  41513         }
  41514         PORT_LOCK(unit);
  41515         switch(value) {
  41516         case BCM_PORT_COS_REMAP_VLAN_PRI:
  41517             /* Clear the MGMT Frame classification */
  41518             rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port,
  41519                                         SELECT7f, 0);
  41520         break;
  41521         case BCM_PORT_COS_REMAP_DSCP:
  41522             /* Clear the MGMT Frame classification */
  41523             rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port,
  41524                                         SELECT7f, 2);
  41525         break;
  41526         case BCM_PORT_COS_REMAP_EXP:
  41527             /* Clear the MGMT Frame classification */
  41528             rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port,
  41529                                         SELECT7f, 1);
  41530         break;
  41531         default:
  41532             rv = BCM_E_PARAM;
  41533         }
  41534         PORT_UNLOCK(unit);
  41535         break;
  41536 
  41537 #endif
  41538 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  41539     case bcmPortControlFieldEgressClassSelect:
  41540 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  41541         if (soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) {
  41542             rv = _bcm_td2p_port_control_egress_class_select_set(unit, port, value);
  41543         } else
  41544 #endif
  41545         {
  41546         rv = _bcm_trx_port_control_egress_class_select_set(unit, port, value);
  41547         }
  41548         break;
  41549 #endif
  41550 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  41551     case bcmPortControlFieldHiGigClassSelect:
  41552 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  41553         if (soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) {
  41554             rv = _bcm_td2p_port_control_higig_class_select_set(unit, port, value);
  41555         } else
  41556 #endif
  41557         {
  41558         rv = _bcm_trx_port_control_higig_class_select_set(unit, port, value);
  41559         }
  41560         break;
  41561 #endif
  41562     case bcmPortControlSubportTagEnable:
  41563 
  41564 #if defined (BCM_HGPROXY_COE_SUPPORT)
  41565         if(soc_feature(unit, soc_feature_hgproxy_subtag_coe)) {
  41566             rv = bcmi_xgs5_port_control_subtag_status_set(unit, port, value);
  41567         }
  41568 #endif 
  41569 #if defined (BCM_KATANA2_SUPPORT)
  41570         if (soc_feature(unit, soc_feature_subtag_coe)) {
  41571             if (SOC_IS_KATANA2(unit)) {
  41572                 rv = bcm_kt2_port_control_subtag_status_set(unit, port, value);
  41573             }
  41574 #if defined (BCM_METROLITE_SUPPORT)
  41575             /*In Metrolite physical port PP port is [re]used for the subports
  41576              * to achieve the MAX number of streams.*/
  41577             if((soc_feature(unit, soc_feature_discontinuous_pp_port)) && (rv == BCM_E_NONE)){
  41578                 BCM_PBMP_CLEAR(pbm);
  41579                 BCM_PBMP_PORT_ADD(pbm, port);
  41580                 if(value){
  41581                     bcm_esw_vlan_port_remove(unit, BCM_VLAN_DEFAULT, pbm);
  41582                 }else{
  41583                     bcm_esw_vlan_port_add(unit, BCM_VLAN_DEFAULT, pbm, pbm);
  41584                 }
  41585             }
  41586 #endif
  41587         }
  41588 #endif
  41589         break;
  41590 
  41591     case bcmPortControlLinkPhyEnable:
  41592 #if defined (BCM_KATANA2_SUPPORT)
  41593         if (soc_feature(unit, soc_feature_linkphy_coe)) {
  41594             if (SOC_IS_KATANA2(unit)) {
  41595                 rv = bcm_kt2_port_control_linkphy_status_set(unit, port, value);
  41596             }
  41597 #if defined (BCM_METROLITE_SUPPORT)
  41598             /*In Metrolite physical port PP port is [re]used for the subports
  41599              * to achieve the MAX number of streams.*/
  41600             if((soc_feature(unit, soc_feature_discontinuous_pp_port)) && (rv == BCM_E_NONE)){
  41601                 BCM_PBMP_CLEAR(pbm);
  41602                 BCM_PBMP_PORT_ADD(pbm, port);
  41603                 if(value){
  41604                     bcm_esw_vlan_port_remove(unit, BCM_VLAN_DEFAULT, pbm);
  41605                 }else{
  41606                     bcm_esw_vlan_port_add(unit, BCM_VLAN_DEFAULT, pbm, pbm);
  41607                 }
  41608             }
  41609 #endif
  41610         }
  41611 #endif
  41612         break;
  41613 
  41614 #if defined(BCM_TRIDENT2_SUPPORT)
  41615 
  41616     case bcmPortControlFcoeRouteEnable:
  41617         if (soc_feature(unit, soc_feature_fcoe)) {
  41618 #ifdef BCM_TRIDENT3_SUPPORT
  41619             if (SOC_IS_TRIDENT3X(unit)) {
  41620                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  41621                                            FCOE_ROUTE_ENABLEf,
  41622                                            (value) ? 1 : 0);
  41623                 if ((rv == BCM_E_NONE) &&
  41624                     SOC_MEM_IS_VALID(unit, EGR_PORTm) &&
  41625                     SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_ROUTE_ENABLEf)) {
  41626                     rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  41627                                                 FCOE_ROUTE_ENABLEf,
  41628                                                 (value) ? 1 : 0);
  41629                 }
  41630             } else 
  41631 #endif
  41632             {
  41633             if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_ROUTE_ENABLEf)) {
  41634                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  41635                                            FCOE_ROUTE_ENABLEf,
  41636                                            (value) ? 1 : 0);
  41637             }
  41638             if ((rv == BCM_E_NONE) &&
  41639                 SOC_MEM_IS_VALID(unit, EGR_PORTm) &&
  41640                 SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_ROUTE_ENABLEf)) {
  41641                 rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  41642                                             FCOE_ROUTE_ENABLEf,
  41643                                             (value) ? 1 : 0);
  41644             }
  41645         }
  41646         }
  41647         break;
  41648 
  41649     case bcmPortControlFcoeVftEnable:
  41650         if (soc_feature(unit, soc_feature_fcoe)) {
  41651             if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VFT_ENABLEf)) {
  41652                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  41653                                            FCOE_VFT_ENABLEf, (value) ? 1 : 0);
  41654             }
  41655         }
  41656         break;
  41657 
  41658     case bcmPortControlFcoeZoneCheckEnable:
  41659         if (soc_feature(unit, soc_feature_fcoe)) {
  41660             if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_FIELD_VALID(unit, PORT_TABm,
  41661                                     FCOE_ZONE_CHECK_ENABLEf))) {
  41662                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  41663                                            FCOE_ZONE_CHECK_ENABLEf,
  41664                                            (value) ? 1 : 0);
  41665             }
  41666         }
  41667         break;
  41668 
  41669     case bcmPortControlFcoeSourceBindCheckEnable:
  41670         if (soc_feature(unit, soc_feature_fcoe)) {
  41671             if (SOC_MEM_FIELD_VALID(unit, PORT_TABm,
  41672                                     FCOE_SRC_BIND_CHECK_ENABLEf)) {
  41673                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  41674                                            FCOE_SRC_BIND_CHECK_ENABLEf,
  41675                                            (value) ? 1 : 0);
  41676             }
  41677         }
  41678         break;
  41679 
  41680     case bcmPortControlFcoeFpmaPrefixCheckEnable:
  41681         if (soc_feature(unit, soc_feature_fcoe)) {
  41682             if (SOC_MEM_FIELD_VALID(unit, PORT_TABm,
  41683                                     FCOE_SRC_FPMA_PREFIX_CHECK_ENABLEf)) {
  41684                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  41685                                            FCOE_SRC_FPMA_PREFIX_CHECK_ENABLEf,
  41686                                            (value) ? 1 : 0);
  41687             }
  41688         }
  41689         break;
  41690 
  41691     case bcmPortControlFcoeDoNotLearn:
  41692         if (soc_feature(unit, soc_feature_fcoe)) {
  41693             if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_DO_NOT_LEARNf))) {
  41694                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  41695                                            FCOE_DO_NOT_LEARNf,
  41696                                            (value) ? 1 : 0);
  41697             }
  41698         }
  41699         break;
  41700 
  41701     case bcmPortControlFcoeNetworkPort:
  41702         if (soc_feature(unit, soc_feature_fcoe)) {
  41703             if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_NETWORK_PORTf))) {
  41704                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  41705                                            FCOE_NETWORK_PORTf,
  41706                                            (value) ? 1 : 0);
  41707             }
  41708         }
  41709         break;
  41710 
  41711     case bcmPortControlFcoeFabricSel:
  41712         if (soc_feature(unit, soc_feature_fcoe)) {
  41713             if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_SELf)) {
  41714                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  41715                                            FCOE_FABRIC_SELf, value);
  41716             }
  41717         }
  41718         break;
  41719 
  41720     case bcmPortControlFcoeFabricId:
  41721         if (soc_feature(unit, soc_feature_fcoe)) {
  41722 #ifdef BCM_TRIDENT3_SUPPORT
  41723             if (SOC_IS_TRIDENT3X(unit)) {
  41724                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  41725                                                FCOE_FABRIC_IDf, value);
  41726             } else
  41727 #endif
  41728             {
  41729             if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_IDf)) {
  41730                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  41731                                            FCOE_FABRIC_IDf, value);
  41732             }
  41733         }
  41734         }
  41735         break;
  41736 
  41737     case bcmPortControlFcoeFabricPri:
  41738         if (soc_feature(unit, soc_feature_fcoe)) {
  41739 #ifdef BCM_TRIDENT3_SUPPORT
  41740             if (SOC_IS_TRIDENT3X(unit)) {
  41741                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  41742                                                FCOE_FABRIC_PRIf, value);
  41743             } else
  41744 #endif
  41745             {
  41746             if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_PRIf)) {
  41747                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  41748                                            FCOE_FABRIC_PRIf, value);
  41749             }
  41750         }
  41751         }
  41752         break;
  41753 
  41754     case bcmPortControlFcoeFcCrcAction:
  41755         if (soc_feature(unit, soc_feature_fcoe)) {
  41756             if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm,
  41757                                     FCOE_FC_CRC_ACTIONf)) {
  41758                 /* 2 bits but only 0,1 are valid */
  41759                 rv = soc_mem_field32_modify(unit, EGR_ING_PORTm, port,
  41760                                             FCOE_FC_CRC_ACTIONf, value);
  41761             }
  41762         }
  41763         break;
  41764 
  41765     case bcmPortControlFcoeFcCrcRecompute:
  41766         if (soc_feature(unit, soc_feature_fcoe)) {
  41767             if (SOC_MEM_IS_VALID(unit, EGR_PORTm) &&
  41768                 SOC_MEM_FIELD_VALID(unit, EGR_PORTm,
  41769                                     FCOE_FC_CRC_RECOMPUTEf)) {
  41770                 rv = soc_mem_field32_modify(unit, EGR_PORTm, port,
  41771                                             FCOE_FC_CRC_RECOMPUTEf, value);
  41772             }
  41773         }
  41774         break;
  41775 
  41776     case bcmPortControlFcoeFcEofIgnore:
  41777         if (soc_feature(unit, soc_feature_fcoe)) {
  41778             if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm,
  41779                                     FCOE_FC_EOF_IGNOREf)) {
  41780                 rv = soc_mem_field32_modify(unit, EGR_ING_PORTm, port,
  41781                                             FCOE_FC_EOF_IGNOREf,
  41782                                             (value) ? 1 : 0);
  41783             }
  41784         }
  41785         break;
  41786 
  41787     case bcmPortControlFcoeTranslateKeyFirst:
  41788     case bcmPortControlFcoeTranslateKeySecond:
  41789         if (soc_feature(unit, soc_feature_fcoe)) {
  41790 
  41791             /* first, translate value to HW value */
  41792             int key_type = 0;
  41793             int key_type_value;
  41794             int use_port = 0;
  41795 
  41796             switch (value) {
  41797                 case bcmFcoeVsanTranslateKeyPortDouble:
  41798                 use_port = 1; /* fall thru */
  41799                 case bcmFcoeVsanTranslateKeyDouble:
  41800                     key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID;
  41801                     break;
  41802                 case bcmFcoeVsanTranslateKeyPortOuterTag:
  41803                 use_port = 1; /* fall thru */
  41804                 case bcmFcoeVsanTranslateKeyOuterTag:
  41805                     key_type = VLXLT_HASH_KEY_TYPE_OTAG;
  41806                     break;
  41807                 case bcmFcoeVsanTranslateKeyPortInnerTag:
  41808                 use_port = 1; /* fall thru */
  41809                 case bcmFcoeVsanTranslateKeyInnerTag:
  41810                     key_type = VLXLT_HASH_KEY_TYPE_ITAG;
  41811                     break;
  41812                 case bcmFcoeVsanTranslateKeyPortOuter:
  41813                 use_port = 1; /* fall thru */
  41814                 case bcmFcoeVsanTranslateKeyOuter:
  41815                     key_type = VLXLT_HASH_KEY_TYPE_OVID;
  41816                     break;
  41817                 case bcmFcoeVsanTranslateKeyPortInner:
  41818                 use_port = 1; /* fall thru */
  41819                 case bcmFcoeVsanTranslateKeyInner:
  41820                     key_type = VLXLT_HASH_KEY_TYPE_IVID;
  41821                     break;
  41822                 case bcmFcoeVsanTranslateKeyPortOuterPri:
  41823                 use_port = 1; /* fall thru */
  41824                 case bcmFcoeVsanTranslateKeyOuterPri:
  41825                     key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI;
  41826                     break;
  41827                 case bcmFcoeVsanTranslateKeyPortDoubleVsan:
  41828                 use_port = 1; /* fall thru */
  41829                 case bcmFcoeVsanTranslateKeyDoubleVsan:
  41830                     key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN;
  41831                     break;
  41832                 case bcmFcoeVsanTranslateKeyPortInnerVsan:
  41833                 use_port = 1; /* fall thru */
  41834                 case bcmFcoeVsanTranslateKeyInnerVsan:
  41835                     key_type = VLXLT_HASH_KEY_TYPE_IVID_VSAN;
  41836                     break;
  41837                 case bcmFcoeVsanTranslateKeyPortOuterVsan:
  41838                 use_port = 1; /* fall thru */
  41839                 case bcmFcoeVsanTranslateKeyOuterVsan:
  41840                     key_type = VLXLT_HASH_KEY_TYPE_OVID_VSAN;
  41841                     break;
  41842                 default:
  41843                     return BCM_E_PARAM;
  41844             }
  41845 
  41846             BCM_IF_ERROR_RETURN(
  41847                 _bcm_esw_vlan_xlate_key_type_value_get(unit, key_type,
  41848                                                        &key_type_value));
  41849 
  41850             if (type == bcmPortControlFcoeTranslateKeyFirst) {
  41851                 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VT_KEY_TYPE_1f)) {
  41852                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  41853                                                FCOE_VT_KEY_TYPE_1f,
  41854                                                key_type_value);
  41855                 }
  41856                 if (BCM_SUCCESS(rv)) {
  41857                     rv = _bcm_esw_port_config_set(unit, port,
  41858                                                   _bcmPortVTKeyPortFirst,
  41859                                                   use_port);
  41860                 }
  41861             } else {
  41862                 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VT_KEY_TYPE_2f)) {
  41863                     rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  41864                                                FCOE_VT_KEY_TYPE_2f,
  41865                                                key_type_value);
  41866                 }
  41867                 if (BCM_SUCCESS(rv)) {
  41868                     rv = _bcm_esw_port_config_set(unit, port,
  41869                                                   _bcmPortVTKeyPortSecond,
  41870                                                   use_port);
  41871                 }
  41872             }
  41873         }
  41874         break;
  41875 
  41876     case bcmPortControlFcoeTranslateKeyFirstEgress:
  41877     case bcmPortControlFcoeTranslateKeySecondEgress:
  41878         if (soc_feature(unit, soc_feature_fcoe)) {
  41879 
  41880             /* first, translate value to HW value */
  41881             int key_type_value = 0;
  41882 
  41883             switch (value) {
  41884                 case bcmFcoeVsanTranslateKeyEgressDoubleVsan:
  41885                     key_type_value = EGR_VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN;
  41886                     break;
  41887                 case bcmFcoeVsanTranslateKeyEgressVsan:
  41888                     key_type_value = EGR_VLXLT_HASH_KEY_TYPE_VSAN;
  41889                     break;
  41890                 case bcmFcoeVsanTranslateKeyEgressInnerVsan:
  41891                     key_type_value = EGR_VLXLT_HASH_KEY_TYPE_IVID_VSAN;
  41892                     break;
  41893                 case bcmFcoeVsanTranslateKeyEgressOuterVsan:
  41894                     key_type_value = EGR_VLXLT_HASH_KEY_TYPE_OVID_VSAN;
  41895                     break;
  41896                 case bcmFcoeVsanTranslateKeyEgressDouble:
  41897                     key_type_value = EGR_VLXLT_HASH_KEY_TYPE_IVID_OVID;
  41898                     break;
  41899                 case bcmFcoeVsanTranslateKeyEgressInner:
  41900                     key_type_value = EGR_VLXLT_HASH_KEY_TYPE_IVID;
  41901                     break;
  41902                 case bcmFcoeVsanTranslateKeyEgressOuter:
  41903                     key_type_value = EGR_VLXLT_HASH_KEY_TYPE_OVID;
  41904                     break;
  41905                 default:
  41906                     return BCM_E_PARAM;
  41907             }
  41908 
  41909             if (type == bcmPortControlFcoeTranslateKeyFirstEgress) {
  41910                 if (SOC_IS_TRIDENT3X(unit) ||
  41911                     SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_VT_LOOKUP_1f)) {
  41912                     rv = _bcm_esw_egr_port_tab_set(unit, port,
  41913                                                    FCOE_VT_LOOKUP_1f,
  41914                                                    key_type_value);
  41915                 }
  41916             } else {
  41917                 if (SOC_IS_TRIDENT3X(unit) ||
  41918                     SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_VT_LOOKUP_2f)) {
  41919                     rv = _bcm_esw_egr_port_tab_set(unit, port,
  41920                                                    FCOE_VT_LOOKUP_2f,
  41921                                                    key_type_value);
  41922                 }
  41923             }
  41924         }
  41925         break;
  41926 
  41927 #endif  /* TRIDENT2 */
  41928     case bcmPortControlEEEMode:
  41929         if (soc_feature(unit, soc_feature_eee_bb_mode)) {
  41930             uint32 rval = 0;
  41931             uint32 fval = 0;
  41932             uint32 temp = 0;
  41933             if (soc_feature (unit, soc_feature_high_portcount_register)) {
  41934                 soc_reg_t eee_bb_reg;
  41935                 int phy_port;
  41936                 int mmu_port;
  41937                 int offset;
  41938 
  41939                 phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  41940                 mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port];
  41941                 if (mmu_port < 32) {
  41942                     eee_bb_reg = EEE_BB_ENABLE_0r;
  41943                     offset = mmu_port;
  41944                 } else if ((mmu_port >=32) && (mmu_port < 64)) {
  41945                     eee_bb_reg = EEE_BB_ENABLE_1r;
  41946                     offset = mmu_port - 32;
  41947                 } else { /* mmu_port >= 64 */
  41948                     eee_bb_reg = EEE_BB_ENABLE_2r;
  41949                     offset = mmu_port - 64;
  41950                 }
  41951                 temp = (1 << offset);
  41952                 BCM_IF_ERROR_RETURN(
  41953                     soc_reg32_get(unit, eee_bb_reg, REG_PORT_ANY, 0, &rval));
  41954                 fval = soc_reg_field_get(unit, eee_bb_reg, rval,
  41955                                          EEE_BB_ENABLEf);
  41956                 if (value == bcmPortEEEBurstAndBatchMode) {
  41957                     fval |= temp;
  41958                 } else if (value == bcmPortEEENativeMode) {
  41959                     fval &= ~temp;
  41960                 } else {
  41961                     return BCM_E_PARAM;
  41962                 }
  41963                 rv = soc_reg_field32_modify(unit, eee_bb_reg, REG_PORT_ANY,
  41964                                             EEE_BB_ENABLEf,
  41965                                             fval);
  41966             } else {
  41967             temp = (1 << port);
  41968             temp >>= 2;
  41969             READ_EEE_BB_ENABLEr(unit, &rval);
  41970                 fval = soc_reg_field_get(unit, EEE_BB_ENABLEr, rval,
  41971                                          EEE_BB_ENABLEf);
  41972             if (value == bcmPortEEEBurstAndBatchMode) {
  41973                 fval |= temp;
  41974             } else if (value == bcmPortEEENativeMode) {
  41975                 fval &= ~temp;
  41976             } else {
  41977                 return BCM_E_PARAM;
  41978             }
  41979             rv = soc_reg_field32_modify(unit, EEE_BB_ENABLEr, REG_PORT_ANY,
  41980                                         EEE_BB_ENABLEf,
  41981                                         fval);
  41982         }
  41983         }
  41984         break;
  41985 #ifdef BCM_GREYHOUND_SUPPORT
  41986     case bcmPortControlWredDropCountUpdateEnableQueueMask:
  41987         if (soc_feature(unit, soc_feature_wred_drop_counter_per_port)) {
  41988 #if defined(BCM_GREYHOUND2_SUPPORT)
  41989             if (SOC_IS_GREYHOUND2(unit)) {
  41990                 rv = bcmi_gh2_cosq_wred_port_control_set(unit, port, type,
  41991                                                          value);
  41992             } else
  41993 #endif /* BCM_GREYHOUND2_SUPPORT */
  41994             {
  41995             rv = soc_reg_field32_modify(unit, WRED_DROP_CTR_CONFIGr,
  41996                 port, QUEUE_MASKf, value);
  41997         }
  41998         }
  41999         break;
  42000     case bcmPortControlWredDropCountUpdateEnableColorMask:
  42001         if (soc_feature(unit, soc_feature_wred_drop_counter_per_port)) {
  42002             /* parameter checking */
  42003             if (value & ~((0x1 << bcmColorGreen) |
  42004                 (0x1 << bcmColorYellow) |
  42005                 (0x1 << bcmColorRed))) {
  42006                 return BCM_E_PARAM;
  42007             }
  42008 #if defined(BCM_GREYHOUND2_SUPPORT)
  42009             if (SOC_IS_GREYHOUND2(unit)) {
  42010                 rv = bcmi_gh2_cosq_wred_port_control_set(unit, port, type,
  42011                                                          value);
  42012             } else
  42013 #endif /* BCM_GREYHOUND2_SUPPORT */
  42014             {
  42015             cur_val = 0;
  42016             if (value & (0x1 << bcmColorGreen)) {
  42017                 cur_val |= 0x4;
  42018             }
  42019             if (value & (0x1 << bcmColorYellow)) {
  42020                 cur_val |= 0x2;
  42021             }
  42022             if (value & (0x1 << bcmColorRed)) {
  42023                 cur_val |= 0x1;
  42024             }
  42025             rv = soc_reg_field32_modify(unit, WRED_DROP_CTR_CONFIGr,
  42026                 port, COLOR_MASKf, cur_val);
  42027         }
  42028         }
  42029         break;
  42030 #endif /* BCM_GREYHOUND_SUPPORT */
  42031 #ifdef BCM_TRIDENT2_SUPPORT
  42032     case bcmPortControlProbeSerdesReset:
  42033         if (SOC_IS_TD2_TT2(unit)) {
  42034             PORT_LOCK(unit);
  42035             if (value) {
  42036                 PORT(unit, port).flags |= _PORT_INFO_PROBE_RESET_SERDES;
  42037             } else {
  42038                 PORT(unit, port).flags &= ~_PORT_INFO_PROBE_RESET_SERDES;
  42039             }
  42040             PORT_UNLOCK(unit);
  42041             rv = BCM_E_NONE;
  42042         }
  42043         break;
  42044 #endif /* BCM_TRIDENT2_SUPPORT */
  42045     case bcmPortControlMmuDrain:
  42046         rv = bcm_esw_port_drain_cells(unit, port, value);
  42047         break;
  42048     case bcmPortControlMmuTrafficEnable:
  42049         rv = bcm_esw_port_enqueue_set(unit, port, value);
  42050         break;
  42051     case bcmPortControlRxFastLOS:
  42052         rv = _bcm_esw_link_fast_set(unit, port, value);
  42053         break;
  42054     case bcmPortControlStatCollectionEnable:
  42055         if (!SOC_PORT_VALID(unit, port)) {
  42056             return BCM_E_PORT;
  42057         }
  42058         rv = soc_counter_port_collect_enable_set(unit, port, value);
  42059         break;
  42060     case bcmPortControlLLFCReceive:
  42061     case bcmPortControlLLFCTransmit:
  42062 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  42063     case bcmPortControlSAFCReceive:
  42064     case bcmPortControlSAFCTransmit:
  42065 #endif
  42066         rv = _bcm_esw_port_llfc_set(unit, port, type, value);
  42067         break;
  42068     case bcmPortControlTrunkLoadBalancingRandomizer:
  42069 #ifdef BCM_TOMAHAWK_SUPPORT
  42070         if (soc_feature(unit, soc_feature_randomized_load_balance)) {
  42071             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  42072                                        OFFSET_TRUNK_RANDOM_LBf, value);
  42073         }
  42074 #endif /* BCM_TOMAHAWK_SUPPORT */
  42075         break;
  42076     case bcmPortControlECMPLevel1LoadBalancingRandomizer:
  42077 #ifdef BCM_TOMAHAWK_SUPPORT
  42078         if (soc_feature(unit, soc_feature_ecmp_random)) {
  42079             if ((value < 0) || (value > 15)) {
  42080                 return BCM_E_PARAM;
  42081             }
  42082             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  42083                                        OFFSET_ECMP_RANDOM_LBf, value);
  42084         }
  42085 #endif /* BCM_TOMAHAWK_SUPPORT */
  42086         break;
  42087     case bcmPortControlECMPLevel2LoadBalancingRandomizer:
  42088 #ifdef BCM_TOMAHAWK_SUPPORT
  42089         if (soc_feature(unit, soc_feature_ecmp_random)) {
  42090             if ((value < 0) || (value > 15)) {
  42091                 return BCM_E_PARAM;
  42092             }
  42093             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  42094                                        OFFSET_ECMP_LEVEL2_RANDOM_LBf,
  42095                                        value);
  42096         }
  42097 #endif /* BCM_TOMAHAWK_SUPPORT */
  42098         break;
  42099     case bcmPortControlMcastGroupRemap:
  42100           if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, NETWORK_PORTf)) {
  42101               rv = soc_mem_field32_modify(unit, SOURCE_VPm, port,
  42102                       NETWORK_PORTf, value ? 1 : 0);
  42103           }
  42104           break;
  42105     case bcmPortControlOOBFCTxReportIngEnable:
  42106         if (soc_feature(unit, soc_feature_oob_fc)) {
  42107 #ifdef BCM_TOMAHAWK_SUPPORT
  42108             if (SOC_IS_TOMAHAWKX(unit)) { 
  42109                 rv = _bcm_th_oob_fc_tx_port_control_set(unit, port, value, 0);
  42110             }
  42111 #endif
  42112 #ifdef BCM_KATANA2_SUPPORT
  42113             if (SOC_IS_KATANA2(unit)) {
  42114                 rv = _bcm_kt2_oob_fc_tx_port_control_set(unit, port, value, 0);
  42115             }
  42116 #endif
  42117 #ifdef BCM_TRIDENT3_SUPPORT
  42118             if (SOC_IS_TRIDENT3X(unit)) {
  42119                 rv = _bcm_td3_oob_fc_tx_port_control_set(unit, port, value, 0);
  42120             }
  42121 #endif
  42122 #ifdef BCM_APACHE_SUPPORT
  42123             if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
  42124                 rv = _bcm_ap_oob_fc_tx_port_control_set(unit, port, value, 0);
  42125             }
  42126 #endif
  42127         }
  42128         break;
  42129     case bcmPortControlOOBFCTxReportEgrEnable:
  42130         if (soc_feature(unit, soc_feature_oob_fc)) {
  42131 #ifdef BCM_TOMAHAWK_SUPPORT
  42132             if (SOC_IS_TOMAHAWKX(unit)) {
  42133                 rv = _bcm_th_oob_fc_tx_port_control_set(unit, port, value, 1);
  42134             }
  42135 #endif
  42136 #ifdef BCM_APACHE_SUPPORT
  42137             if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
  42138                 rv = _bcm_ap_oob_fc_tx_port_control_set(unit, port, value, 1);
  42139             }
  42140 #endif
  42141 #ifdef BCM_KATANA2_SUPPORT
  42142             if (SOC_IS_KATANA2(unit)) {
  42143                 rv = _bcm_kt2_oob_fc_tx_port_control_set(unit, port, value, 1); 
  42144             }
  42145 #endif
  42146 #ifdef BCM_TRIDENT3_SUPPORT
  42147             if (SOC_IS_TRIDENT3X(unit)) {
  42148                 rv = _bcm_th_oob_fc_tx_port_control_set(unit, port, value, 1);
  42149             }
  42150 #endif
  42151         }
  42152         break;
  42153 
  42154 	case bcmPortControlSubportTagSize:
  42155 #ifdef BCM_HGPROXY_COE_SUPPORT
  42156           if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 
  42157                                   DESTINATION_SUBPORT_TAG_TYPEf)) {
  42158 
  42159               int local_port = 0;
  42160               if (BCM_GPORT_IS_SET(port)) {
  42161                   BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port));
  42162               } else {
  42163                   if(!SOC_PORT_VALID(unit, port)) {
  42164                       return BCM_E_PORT;
  42165                   } else {
  42166                       local_port = port;
  42167                   }
  42168               }
  42169 
  42170               /* Setting of tag_type to 8Byte is not supported currently,
  42171                  hence return error if 'value' is non-zero */
  42172               if(value) {
  42173                   return BCM_E_UNAVAIL;
  42174               }
  42175 
  42176               rv = soc_mem_field32_modify(unit, EGR_PORTm, local_port,
  42177                       DESTINATION_SUBPORT_TAG_TYPEf, value ? 1 : 0);
  42178           }
  42179           if (SOC_IS_TRIDENT3X(unit)) {
  42180               if (value) {
  42181                   return BCM_E_UNAVAIL;
  42182               }
  42183               else {
  42184                   return BCM_E_NONE;
  42185               }
  42186           }
  42187 #endif
  42188 		  break;
  42189 
  42190 	case bcmPortControlSystemPortOverride:
  42191 #ifdef BCM_HGPROXY_COE_SUPPORT
  42192         if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, VT_SYS_PORT_OVERRIDEf)) {
  42193             rv = bcmi_xgs5_subport_subtag_port_override_set(unit, port, value);
  42194         }
  42195 #endif
  42196         break;
  42197 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  42198     case bcmPortControlSampleIngressDest:
  42199         if(soc_feature(unit, soc_feature_sflow_ing_mem)) {
  42200             sflow_ing_data_source_entry_t sflow_entry;
  42201             uint32 field_values[2] = {0, 0};
  42202             if ((value < 0) || (value > 3)) {
  42203                 return BCM_E_PARAM;
  42204             }
  42205 
  42206             if ((value & BCM_PORT_CONTROL_SAMPLE_DEST_CPU) ==
  42207                  BCM_PORT_CONTROL_SAMPLE_DEST_CPU) {
  42208                 field_values[0] = 1;
  42209             }
  42210             if ((value & BCM_PORT_CONTROL_SAMPLE_DEST_MIRROR) ==
  42211                  BCM_PORT_CONTROL_SAMPLE_DEST_MIRROR) {
  42212                 field_values[1] = 1;
  42213             }
  42214 
  42215             BCM_IF_ERROR_RETURN
  42216                 (READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  42217                                              &sflow_entry));
  42218             soc_SFLOW_ING_DATA_SOURCEm_field_set(unit, &sflow_entry,
  42219                                                  CPUf, &field_values[0]);
  42220             soc_SFLOW_ING_DATA_SOURCEm_field_set(unit, &sflow_entry,
  42221                                                  MIRRORf, &field_values[1]);
  42222             BCM_IF_ERROR_RETURN
  42223                 (WRITE_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  42224                                               &sflow_entry));
  42225             rv = BCM_E_NONE;
  42226         }
  42227         break;
  42228     case bcmPortControlSampleFlexDest:
  42229         if(soc_feature(unit, soc_feature_sflow_flex)) {
  42230             sflow_ing_flex_data_source_entry_t sflow_entry;
  42231             uint32 field_values[2] = {0, 0};
  42232             if ((value < 0) || (value > 3)) {
  42233                 return BCM_E_PARAM;
  42234             }
  42235 
  42236             if ((value & BCM_PORT_CONTROL_SAMPLE_DEST_CPU) ==
  42237                  BCM_PORT_CONTROL_SAMPLE_DEST_CPU) {
  42238                 field_values[0] = 1;
  42239             }
  42240             if ((value & BCM_PORT_CONTROL_SAMPLE_DEST_MIRROR) ==
  42241                  BCM_PORT_CONTROL_SAMPLE_DEST_MIRROR) {
  42242                 field_values[1] = 1;
  42243             }
  42244 
  42245             BCM_IF_ERROR_RETURN
  42246                 (READ_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  42247                                                   &sflow_entry));
  42248             soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_set(unit, &sflow_entry,
  42249                                                       CPUf, &field_values[0]);
  42250             soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_set(unit, &sflow_entry,
  42251                                                       MIRRORf, &field_values[1]);
  42252             BCM_IF_ERROR_RETURN
  42253                 (WRITE_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  42254                                                    &sflow_entry));
  42255             rv = BCM_E_NONE;
  42256         }
  42257         break;
  42258     case bcmPortControlSampleFlexRate:
  42259         if(soc_feature(unit, soc_feature_sflow_flex)) {
  42260             uint32 values[2] = {0, 0};
  42261             sflow_ing_flex_data_source_entry_t sflow_entry;
  42262             soc_counter_non_dma_t *non_dma = NULL;
  42263             soc_control_t *soc;
  42264             uint32 count = 0, subset_ct = 0;
  42265 
  42266             if (value < 0) {
  42267                 return BCM_E_PARAM;
  42268             }
  42269             /* Set sampling threshold */
  42270             if (value > 0) {
  42271                 /* Enable sFlow */
  42272                 values[0] = 1;
  42273 
  42274                 /* Set sampling threshold */
  42275                 if (value == 1) {
  42276                     /* Needs special handling to avoid register overflow */
  42277                     values[1] = (1 << (SFLOW_RANGE_MAX(unit))) - 1;
  42278                 } else {
  42279                     /* Calculate threshold based on sampling rate */
  42280                     values[1] = (1 << (SFLOW_RANGE_MAX(unit))) / value;
  42281                 }
  42282             }
  42283 
  42284             /* Update Flex rate limiting data table. */
  42285             BCM_IF_ERROR_RETURN
  42286                 (READ_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  42287                                                   &sflow_entry));
  42288             soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_set(unit, &sflow_entry,
  42289                                                       ENABLEf, &values[0]);
  42290             soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_set(unit, &sflow_entry,
  42291                                                       THRESHOLDf, &values[1]);
  42292             BCM_IF_ERROR_RETURN
  42293                 (WRITE_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  42294                                                    &sflow_entry));
  42295 
  42296             /* Enable counter thread for Flex sFlow samplers */
  42297             if (values[0] == 1) {
  42298                 soc = SOC_CONTROL(unit);
  42299                 non_dma = &soc->counter_non_dma[
  42300                             SOC_COUNTER_NON_DMA_SFLOW_FLEX_PKT -
  42301                             SOC_COUNTER_NON_DMA_START];
  42302                 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
  42303                     /* Do PACKET_CTRf and BYTE_CTRf sequentially. Hence 2x loop */
  42304                     subset_ct = non_dma->extra_ctr_ct << 1;
  42305                     non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID;
  42306                     non_dma = non_dma->extra_ctrs;
  42307 
  42308                     do {
  42309                         non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID;
  42310                         /* BYTE_CTRf not currently supported */
  42311                         count += 2;
  42312                         non_dma += 2;
  42313                     } while ((count < subset_ct));
  42314                 }
  42315             }
  42316             rv = BCM_E_NONE;
  42317         }
  42318         break;
  42319 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */
  42320 #ifdef BCM_XGS3_SWITCH_SUPPORT
  42321     case bcmPortControlSampleIngressEnable:
  42322         if (SOC_IS_XGS3_SWITCH(unit)) {
  42323             uint32 regval       = 0;
  42324             uint32 field_enable = 0;
  42325 #ifdef BCM_TOMAHAWK_SUPPORT
  42326             sflow_ing_data_source_entry_t sflow_entry;
  42327             soc_counter_non_dma_t *non_dma = NULL;
  42328             soc_control_t *soc;
  42329             uint32 count = 0, subset_ct = 0;
  42330 #endif /* BCM_TOMAHAWK_SUPPORT */
  42331 
  42332             field_enable = value ? 1 : 0;
  42333 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  42334             /* Update Ingress rate limiting data table. */
  42335             if(soc_feature(unit, soc_feature_sflow_ing_mem)) {
  42336                 BCM_IF_ERROR_RETURN(
  42337                     READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  42338                                                 &sflow_entry));
  42339                 soc_SFLOW_ING_DATA_SOURCEm_field_set(unit, &sflow_entry, ENABLEf,
  42340                                                      &field_enable);
  42341 
  42342                 BCM_IF_ERROR_RETURN(
  42343                     WRITE_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  42344                                                  &sflow_entry));
  42345 
  42346                 /* Enable counter thread for Ingress sFlow samplers */
  42347                 if (field_enable) {
  42348                     soc = SOC_CONTROL(unit);
  42349                     non_dma = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_SFLOW_ING_PKT -
  42350                                                     SOC_COUNTER_NON_DMA_START];
  42351                     if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) {
  42352                         /* Do PACKET_CTRf and BYTE_CTRf sequentially. Hence 2x loop */
  42353                         subset_ct = non_dma->extra_ctr_ct << 1;
  42354                         non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID;
  42355                         non_dma = non_dma->extra_ctrs;
  42356 
  42357                         do {
  42358                             non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID;
  42359                             /* BYTE_CTRf not currently supported */
  42360                             count += 2;
  42361                             non_dma += 2;
  42362                         } while ((count < subset_ct));
  42363                     }
  42364                 }
  42365                 rv =  BCM_E_NONE;
  42366             } else
  42367 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */
  42368             {
  42369                 if (!SOC_REG_IS_VALID(unit, SFLOW_ING_THRESHOLDr)) {
  42370                     return BCM_E_UNAVAIL;
  42371                 }
  42372                 BCM_IF_ERROR_RETURN(READ_SFLOW_ING_THRESHOLDr(unit, port, &regval));
  42373                 soc_reg_field_set(unit, SFLOW_ING_THRESHOLDr, &regval,
  42374                                   ENABLEf, field_enable);
  42375 
  42376                 BCM_IF_ERROR_RETURN(WRITE_SFLOW_ING_THRESHOLDr(unit, port, regval));
  42377                 rv = BCM_E_NONE;
  42378             }
  42379         } else {
  42380             rv = BCM_E_UNAVAIL;
  42381         }
  42382         break;
  42383     case bcmPortControlSampleEgressEnable:
  42384         if (SOC_IS_XGS3_SWITCH(unit)) {
  42385             uint32 regval       = 0;
  42386             uint32 field_enable = 0;
  42387 
  42388             if (!SOC_REG_IS_VALID(unit, SFLOW_EGR_THRESHOLDr)) {
  42389                 return BCM_E_UNAVAIL;
  42390             }
  42391             BCM_IF_ERROR_RETURN(READ_SFLOW_EGR_THRESHOLDr(unit, port, &regval));
  42392 
  42393             field_enable = value ? 1 : 0;
  42394             soc_reg_field_set(unit, SFLOW_EGR_THRESHOLDr, &regval,
  42395                               ENABLEf, field_enable);
  42396 
  42397             BCM_IF_ERROR_RETURN(WRITE_SFLOW_EGR_THRESHOLDr(unit, port, regval));
  42398             rv = BCM_E_NONE;
  42399         } else {
  42400             rv = BCM_E_UNAVAIL;
  42401         }
  42402         break;
  42403     case bcmPortControlSampleIngressRate:
  42404         if (SOC_IS_XGS3_SWITCH(unit)) {
  42405             uint32 field_value = 0;
  42406             uint32 regval = 0;
  42407 #ifdef BCM_TOMAHAWK_SUPPORT
  42408             sflow_ing_data_source_entry_t sflow_entry;
  42409 #endif /* BCM_TOMAHAWK_SUPPORT */
  42410 
  42411 
  42412                 /*           rate         - (IN)Every 1/rate a packet will be sampled
  42413                  *            1 indicating sample all.
  42414                  *            0 indicating sample none.*/
  42415             if (value > 0) {
  42416                 /* Set sampling threshold */
  42417                 if (value == 1) {
  42418                     /* Needs special handling to avoid register overflow */
  42419                     field_value = (1 << (SFLOW_RANGE_MAX(unit))) - 1;
  42420                 } else if (value <= ((1 << (SFLOW_RANGE_MAX(unit))) - 1)) {
  42421                     /* Calculate threshold based on sampling rate */
  42422                     field_value = (1 << (SFLOW_RANGE_MAX(unit))) / value;
  42423                 } else {
  42424                     return BCM_E_PARAM;
  42425                 }
  42426 
  42427                 /*
  42428                  * For early sFlow implementations the 16-bit threshold value
  42429                  * is compared to bits [23:8] of the sFlow random number.
  42430                  */
  42431                 if (soc_feature(unit, soc_feature_sample_offset8)) {
  42432                     field_value >>= 8;
  42433                 }
  42434 
  42435                 /* Cut the value in case 16 bit threshold can not accomodate it. */
  42436                 if (soc_feature(unit, soc_feature_sample_thresh16)) {
  42437                     if (field_value >= (1 << 16)) {
  42438                         field_value = (1 << 16) - 1;
  42439                     }
  42440                 }
  42441             }
  42442 
  42443 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  42444             /* Update Ingress rate limiting data table. */
  42445             if(soc_feature(unit, soc_feature_sflow_ing_mem)) {
  42446                 BCM_IF_ERROR_RETURN(
  42447                     READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  42448                                                 &sflow_entry));
  42449                 soc_SFLOW_ING_DATA_SOURCEm_field_set(unit, &sflow_entry, THRESHOLDf,
  42450                                                      &field_value);
  42451 
  42452                 BCM_IF_ERROR_RETURN(
  42453                     WRITE_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  42454                                                  &sflow_entry));
  42455 
  42456                 rv =  BCM_E_NONE;
  42457             } else
  42458 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */
  42459             {
  42460                 if (!SOC_REG_IS_VALID(unit, SFLOW_ING_THRESHOLDr)) {
  42461                     return BCM_E_UNAVAIL;
  42462                 }
  42463                 BCM_IF_ERROR_RETURN(READ_SFLOW_ING_THRESHOLDr(unit, port, &regval));
  42464                 soc_reg_field_set(unit, SFLOW_ING_THRESHOLDr, &regval,
  42465                                   THRESHOLDf, field_value);
  42466 
  42467                 BCM_IF_ERROR_RETURN(WRITE_SFLOW_ING_THRESHOLDr(unit, port, regval));
  42468                 rv = BCM_E_NONE;
  42469             }
  42470         } else {
  42471             rv = BCM_E_UNAVAIL;
  42472         }
  42473         break;
  42474     case bcmPortControlSampleEgressRate:
  42475         if (SOC_IS_XGS3_SWITCH(unit)) {
  42476             uint32 field_value = 0, regval = 0;
  42477 
  42478                 /*           rate         - (IN)Every 1/rate a packet will be sampled
  42479                  *            1 indicating sample all.
  42480                  *            0 indicating sample none.*/
  42481             if (value > 0) {
  42482                 /* Set sampling threshold */
  42483                 if (value == 1) {
  42484                     /* Needs special handling to avoid register overflow */
  42485                     field_value = (1 << (SFLOW_RANGE_MAX(unit))) - 1;
  42486                 } else if (value <= ((1 << (SFLOW_RANGE_MAX(unit))) - 1)) {
  42487                     /* Calculate threshold based on sampling rate */
  42488                     field_value = (1 << (SFLOW_RANGE_MAX(unit))) / value;
  42489                 } else {
  42490                     return BCM_E_PARAM;
  42491                 }
  42492 
  42493                 /*
  42494                  * For early sFlow implementations the 16-bit threshold value
  42495                  * is compared to bits [23:8] of the sFlow random number.
  42496                  */
  42497                 if (soc_feature(unit, soc_feature_sample_offset8)) {
  42498                     field_value >>= 8;
  42499                 }
  42500 
  42501                 /* Cut the value in case 16 bit threshold can not accomodate it. */
  42502                 if (soc_feature(unit, soc_feature_sample_thresh16)) {
  42503                     if (field_value >= (1 << 16)) {
  42504                         field_value = (1 << 16) - 1;
  42505                     }
  42506                 }
  42507             }
  42508 
  42509             if (!SOC_REG_IS_VALID(unit, SFLOW_EGR_THRESHOLDr)) {
  42510                 return BCM_E_UNAVAIL;
  42511             }
  42512 
  42513             BCM_IF_ERROR_RETURN(READ_SFLOW_EGR_THRESHOLDr(unit, port, &regval));
  42514             soc_reg_field_set(unit, SFLOW_EGR_THRESHOLDr, &regval,
  42515                               THRESHOLDf, field_value);
  42516 
  42517             BCM_IF_ERROR_RETURN(WRITE_SFLOW_EGR_THRESHOLDr(unit, port, regval));
  42518             rv = BCM_E_NONE;
  42519         } else {
  42520             rv = BCM_E_UNAVAIL;
  42521         }
  42522         break;
  42523 #endif
  42524     case bcmPortControlExternalBufferEnable:
  42525 #if defined(BCM_KATANA2_SUPPORT)
  42526           if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_ddr3)) {
  42527               rv = _bcm_kt2_cosq_port_ext_buf_set(unit, port, value);
  42528           }
  42529 #endif 
  42530           break;
  42531 #ifdef BCM_HURRICANE3_SUPPORT
  42532     case bcmPortControlTrustMimlPri:
  42533         if (soc_feature(unit, soc_feature_miml)) {
  42534             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42535                                        USE_MIML_PCP_FOR_PRIf, value ? 1 : 0);
  42536             if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) {
  42537                 if (BCM_FAILURE(rv)) {
  42538                     return rv;
  42539                 }
  42540                 /*
  42541                  * Make sure TREAT_PKTPRI_AS_DOT1P bit is set for
  42542                  * MiML internal priority mapping.
  42543                  */
  42544                 rv = bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update
  42545                          (unit, (value) ? 1 : -1);
  42546             }
  42547         }
  42548         break;
  42549     case bcmPortControlTrustCustomHeaderPri:
  42550         if (soc_feature(unit, soc_feature_custom_header)) {
  42551             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42552                                        USE_CUSTOM_HEADER_FOR_PRIf,
  42553                                        value ? 1 : 0);
  42554         }
  42555         break;
  42556     case bcmPortControlCustomHeaderEncapEnable:
  42557         if (soc_feature(unit, soc_feature_custom_header)) {
  42558             uint64 val64;
  42559 
  42560             rv = READ_EGR_PORT_64r(unit, port, &val64);
  42561             if (BCM_SUCCESS(rv)) {
  42562                 soc_reg64_field32_set(unit, EGR_PORT_64r,
  42563                     &val64,
  42564                     CUSTOM_HEADER_ENABLEf, value ? 1 : 0);
  42565             }
  42566 
  42567             rv = WRITE_EGR_PORT_64r(unit, port, val64);
  42568         }
  42569         break;
  42570 #endif /* BCM_HURRICANE3_SUPPORT */
  42571 #if defined(BCM_SABER2_SUPPORT)
  42572     case bcmPortControlSatEnable:
  42573         PORT_LOCK(unit);
  42574         if (SOC_IS_SABER2(unit)) {
  42575             COUNTER_LOCK(unit);
  42576             SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit));
  42577             rv = _bcm_sb2_port_oamp_enable(unit, port, value);
  42578             COUNTER_UNLOCK(unit);
  42579             SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit));
  42580         } else {
  42581             rv = BCM_E_UNAVAIL;
  42582         }
  42583         PORT_UNLOCK(unit);
  42584         break;
  42585 #endif
  42586     case bcmPortControl1588P2PDelay:
  42587         {
  42588             int p_speed=0;
  42589             rv = bcm_esw_port_speed_get(unit, port, &p_speed);
  42590             if (BCM_FAILURE(rv)) {
  42591                 rv = BCM_E_FAIL;
  42592             }
  42593             PORT(unit, port).link_delay_offset = value;
  42594             rv = _bcm_esw_port_link_delay_update(unit, port, p_speed);
  42595         }
  42596         break;
  42597     case bcmPortControlPacketTimeStampInsertRx:
  42598 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  42599     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  42600         if (soc_feature(unit, soc_feature_timestamp)) {
  42601             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  42602             BCM_IF_ERROR_RETURN(
  42603                 _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42604                                       INSERT_RX_TIMESTAMPf, value ? 1 : 0));
  42605             rv = BCM_E_NONE;
  42606         }
  42607         break;
  42608 #endif
  42609     case bcmPortControlPacketTimeStampInsertTx:
  42610 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  42611     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  42612         if (soc_feature(unit, soc_feature_timestamp)) {
  42613             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  42614             SOC_IF_ERROR_RETURN(
  42615                 soc_reg_field32_modify(unit, EGR_TS_CONTROLr, port,
  42616                                        INSERT_TX_TIMESTAMPf, value ? 1 : 0));
  42617             rv = BCM_E_NONE;
  42618         }
  42619         break;
  42620 #endif
  42621     case bcmPortControlPacketTimeStampSrcPortInsertCancel:
  42622 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  42623     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  42624         if (soc_feature(unit, soc_feature_timestamp)) {
  42625             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  42626             BCM_IF_ERROR_RETURN(
  42627                 _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  42628                                       DISABLE_TIMESTAMPINGf, value ? 1 : 0));
  42629             rv = BCM_E_NONE;
  42630         }
  42631         break;
  42632 #endif
  42633     case bcmPortControlPacketTimeStampDestPortInsertCancel:
  42634 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  42635     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  42636         if (soc_feature(unit, soc_feature_timestamp)) {
  42637             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  42638             SOC_IF_ERROR_RETURN(
  42639                 soc_reg_field32_modify(unit, EGR_TS_CONTROLr, port,
  42640                                        DISABLE_TIMESTAMPINGf, value ? 1 : 0));
  42641             rv = BCM_E_NONE;
  42642         }
  42643         break;
  42644 #endif
  42645     case bcmPortControlPacketTimeStampRxId:
  42646 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  42647     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  42648         if (soc_feature(unit, soc_feature_timestamp)) {
  42649             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  42650             if ((value < 0) || (value >= 0x7FFFFF)) {
  42651                 return BCM_E_PARAM;
  42652             }
  42653             if (SOC_REG_IS_VALID(unit,EGR_TS_ING_PORT_MAPr)) {
  42654                 SOC_IF_ERROR_RETURN(
  42655                      soc_reg_field32_modify(unit, EGR_TS_ING_PORT_MAPr,
  42656                                        port, TS_RX_ORIGIN_IDf, value));
  42657             } else {
  42658             SOC_IF_ERROR_RETURN(
  42659                 soc_mem_field32_modify(unit, EGR_TS_ING_PORT_MAPm,
  42660                                        port, TS_RX_ORIGIN_IDf, value));
  42661             }
  42662             rv = BCM_E_NONE;
  42663         }
  42664 #endif
  42665         break;
  42666     case bcmPortControlPacketTimeStampTxId:
  42667 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  42668     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  42669         if (soc_feature(unit, soc_feature_timestamp)) {
  42670             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  42671             if ((value < 0) || (value >= 0x7FFFFF)) {
  42672                 return BCM_E_PARAM;
  42673             }
  42674             if (soc_reg_field_valid(unit, EGR_TS_CONTROL_2r, TS_TX_ORIGIN_IDf))
  42675             {
  42676                 rv = soc_reg_field32_modify(unit, EGR_TS_CONTROL_2r,
  42677                                             port, TS_TX_ORIGIN_IDf, value);
  42678             } else {
  42679                 rv = soc_reg_field32_modify(unit, EGR_TS_CONTROLr,
  42680                                             port, TS_TX_ORIGIN_IDf, value);
  42681             }
  42682         }
  42683 #endif
  42684         break;
  42685     case bcmPortControlPacketTimeStampByteMeterAdjust:
  42686 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  42687     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  42688         if (soc_feature(unit, soc_feature_timestamp) && !SOC_IS_TOMAHAWK3(unit))
  42689         {
  42690             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  42691             rv = soc_reg_field32_modify(unit, EGR_TS_CONTROLr, port,
  42692                                         TS_ADJUST_METERSf, (value) ? 1 : 0);
  42693         }
  42694 #endif
  42695         break;
  42696     case bcmPortControlE2EFCTransmitEnable:
  42697         if (soc_feature(unit, soc_feature_e2efc)) {
  42698             uint64 val;
  42699 #if defined(BCM_KATANA2_SUPPORT)
  42700             uint32 val32;
  42701 #endif
  42702             if (!IS_HG_PORT(unit, port)) {
  42703                 LOG_ERROR(
  42704                     BSL_LS_BCM_PORT,
  42705                     (BSL_META_U(unit,
  42706                                 "Error: unit %d port %d is not a Higig port. "
  42707                                 "E2EFC messages can only be transmitted to "
  42708                                 "or received from Higig ports.\n"),
  42709                      unit, port));
  42710                 return BCM_E_PARAM;
  42711             }
  42712 #if defined(BCM_KATANA2_SUPPORT)
  42713             if (SOC_IS_KATANA2(unit)) {
  42714                 val32 = value ? 1: 0;
  42715                 rv = WRITE_E2EFC_IBP_ENr(unit, val32);
  42716             } else
  42717 #endif
  42718             if (IS_XL_PORT(unit, port)) {
  42719                 BCM_IF_ERROR_RETURN(READ_XLMAC_E2E_CTRLr(unit, port, &val));
  42720                 soc_reg64_field32_set(unit, XLMAC_E2E_CTRLr,
  42721                                       &val, E2E_ENABLEf, value ? 1 : 0);
  42722                 rv = WRITE_XLMAC_E2E_CTRLr(unit, port, val);
  42723             } else if (IS_CL_PORT(unit, port)) {
  42724                 BCM_IF_ERROR_RETURN(READ_CLMAC_E2E_CTRLr(unit, port, &val));
  42725                 soc_reg64_field32_set(unit, CLMAC_E2E_CTRLr,
  42726                                       &val, E2E_ENABLEf, value ? 1 : 0);
  42727                 rv = WRITE_CLMAC_E2E_CTRLr(unit, port, val);
  42728             } else {
  42729                 return BCM_E_PARAM;
  42730             }
  42731         }
  42732         break;
  42733     case bcmPortControlE2EFCReceiveEnable:
  42734         if (soc_feature(unit, soc_feature_e2efc)) {
  42735             uint32 val;
  42736 
  42737             BCM_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &val));
  42738             soc_reg_field_set(unit, IE2E_CONTROLr,
  42739                               &val, IBP_ENABLEf, value ? 1 : 0);
  42740             rv = WRITE_IE2E_CONTROLr(unit, port, val);
  42741         }
  42742         break;
  42743     case bcmPortControlE2EFCCopyToCpuEnable:
  42744         if (soc_feature(unit, soc_feature_e2efc)) {
  42745             uint32 val;
  42746 
  42747             BCM_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &val));
  42748             soc_reg_field_set(unit, IE2E_CONTROLr,
  42749                               &val, IBP_TOCPUf, value ? 1 : 0);
  42750             rv = WRITE_IE2E_CONTROLr(unit, port, val);
  42751         }
  42752         break;
  42753     /* Higher 3 bytes of Destination MAC address */
  42754     case bcmPortControlE2EFCDestMacOui:
  42755         if (soc_feature(unit, soc_feature_e2efc)) {
  42756             uint32 val_lo, val_hi;
  42757             uint64 val_64, data_0;
  42758 #if defined(BCM_KATANA2_SUPPORT)
  42759             uint32 val;
  42760 #endif
  42761             soc_reg_t reg;
  42762 
  42763             if (!IS_HG_PORT(unit, port)) {
  42764                 LOG_ERROR(
  42765                     BSL_LS_BCM_PORT,
  42766                     (BSL_META_U(unit,
  42767                                 "Error: unit %d port %d is not a Higig port. "
  42768                                 "E2EFC messages can only be transmitted to "
  42769                                 "or received from Higig ports.\n"),
  42770                      unit, port));
  42771                 return BCM_E_PARAM;
  42772             }
  42773 #if defined(BCM_KATANA2_SUPPORT)
  42774             if (SOC_IS_KATANA2(unit)) {
  42775 #if defined(BCM_SABER2_SUPPORT)
  42776                 if (SOC_IS_SABER2(unit)) {
  42777                     /* Do nothing */
  42778                 } else
  42779 #endif /* BCM_SABER2_SUPPORT */
  42780                {
  42781                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D0r, port, 0, &val));
  42782                     val_hi = soc_reg_field_get(unit, XIBP_D0r, val, DATA_BYTES_0_3f);
  42783                     val_hi = (val_hi & 0xff) | ((value & 0xffffff) << 8);
  42784                     soc_reg_field_set(unit, XIBP_D0r, &val, DATA_BYTES_0_3f, val_hi);
  42785                     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D0r, port, 0, val));
  42786                     rv = BCM_E_NONE;
  42787                     break;
  42788                }
  42789            }
  42790 #endif /* BCM_KATANA2_SUPPORT */
  42791             if (IS_XL_PORT(unit, port)) {
  42792                 reg = XLMAC_E2EFC_DATA_HDR_0r;
  42793             } else if (IS_CL_PORT(unit, port)) {
  42794                 reg = CLMAC_E2EFC_DATA_HDR_0r;
  42795             } else {
  42796                 return BCM_E_PARAM;
  42797             }
  42798             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port,
  42799                                             0, &val_64));
  42800             data_0 = soc_reg64_field_get(unit, reg,
  42801                                          val_64, E2EFC_DATA_HDR_0f);
  42802             COMPILER_64_TO_32_LO(val_lo, data_0);
  42803             COMPILER_64_TO_32_HI(val_hi, data_0);
  42804             val_hi = (val_hi & 0xff) | ((value & 0xffffff) << 8);
  42805             COMPILER_64_SET(data_0, val_hi, val_lo);
  42806             soc_reg64_field_set(unit, reg, &val_64, E2EFC_DATA_HDR_0f,
  42807                                 data_0);
  42808             rv = soc_reg64_set(unit, reg, port, 0, val_64);
  42809         }
  42810         break;
  42811     /* Lower 3 bytes of Destination MAC address */
  42812     case bcmPortControlE2EFCDestMacNonOui:
  42813         if (soc_feature(unit, soc_feature_e2efc)) {
  42814             uint32 val_lo, val_hi;
  42815             uint64 val_64, data_0;
  42816             soc_reg_t reg;
  42817 #if defined(BCM_KATANA2_SUPPORT)
  42818             uint32 val;
  42819 #endif
  42820 
  42821             if (!IS_HG_PORT(unit, port)) {
  42822                 LOG_ERROR(
  42823                     BSL_LS_BCM_PORT,
  42824                     (BSL_META_U(unit,
  42825                                 "Error: unit %d port %d is not a Higig port. "
  42826                                 "E2EFC messages can only be transmitted to "
  42827                                 "or received from Higig ports.\n"),
  42828                      unit, port));
  42829                 return BCM_E_PARAM;
  42830             }
  42831 #if defined(BCM_KATANA2_SUPPORT)
  42832             if (SOC_IS_KATANA2(unit)) {
  42833 #if defined(BCM_SABER2_SUPPORT)
  42834                 if (SOC_IS_SABER2(unit)) {
  42835                     /* Do nothing */
  42836                 } else
  42837 #endif /* BCM_SABER2_SUPPORT */
  42838                {
  42839                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D1r, port, 0, &val));
  42840                     val_lo = soc_reg_field_get(unit, XIBP_D1r, val, DATA_BYTES_4_7f);
  42841                     val_lo = (val_lo & 0xffff) | ((value & 0xffff) << 16);
  42842                     soc_reg_field_set(unit, XIBP_D1r, &val, DATA_BYTES_4_7f, val_lo);
  42843                     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D1r, port, 0, val));
  42844 
  42845                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D0r, port, 0, &val));
  42846                     val_hi = soc_reg_field_get(unit, XIBP_D0r, val, DATA_BYTES_0_3f);
  42847                     val_hi = (val_hi & 0xffffff00) | ((value >> 16) & 0xff);
  42848                     soc_reg_field_set(unit, XIBP_D0r, &val, DATA_BYTES_0_3f, val_hi);
  42849                     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D0r, port, 0, val));
  42850                     rv = BCM_E_NONE;
  42851                     break;
  42852                }
  42853            }
  42854 #endif /* BCM_KATANA2_SUPPORT */
  42855             if (IS_XL_PORT(unit, port)) {
  42856                 reg = XLMAC_E2EFC_DATA_HDR_0r;
  42857             } else if (IS_CL_PORT(unit, port)) {
  42858                 reg = CLMAC_E2EFC_DATA_HDR_0r;
  42859             } else {
  42860                 return BCM_E_PARAM;
  42861             }
  42862             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port,
  42863                                             0, &val_64));
  42864             data_0 = soc_reg64_field_get(unit, reg,
  42865                                          val_64, E2EFC_DATA_HDR_0f);
  42866             COMPILER_64_TO_32_LO(val_lo, data_0);
  42867             COMPILER_64_TO_32_HI(val_hi, data_0);
  42868             val_hi = (val_hi & 0xffffff00) | ((value >> 16) & 0xff);
  42869             val_lo = (val_lo & 0xffff) | ((value & 0xffff) << 16);
  42870             COMPILER_64_SET(data_0, val_hi, val_lo);
  42871             soc_reg64_field_set(unit, reg, &val_64, E2EFC_DATA_HDR_0f,
  42872                                 data_0);
  42873             rv = soc_reg64_set(unit, reg, port, 0, val_64);
  42874         }
  42875         break;
  42876     /* Higher 3 bytes of Source MAC address */
  42877     case bcmPortControlE2EFCSrcMacOui:
  42878         if (soc_feature(unit, soc_feature_e2efc)) {
  42879             uint32 val_lo, val_hi;
  42880             uint64 val_64, data_1, data_0;
  42881             soc_reg_t reg_1, reg_0;
  42882 #if defined(BCM_KATANA2_SUPPORT)
  42883             uint32 val;
  42884 #endif
  42885             if (!IS_HG_PORT(unit, port)) {
  42886                 LOG_ERROR(
  42887                     BSL_LS_BCM_PORT,
  42888                     (BSL_META_U(unit,
  42889                                 "Error: unit %d port %d is not a Higig port. "
  42890                                 "E2EFC messages can only be transmitted to "
  42891                                 "or received from Higig ports.\n"),
  42892                      unit, port));
  42893                 return BCM_E_PARAM;
  42894             }
  42895 #if defined(BCM_KATANA2_SUPPORT)
  42896             if (SOC_IS_KATANA2(unit)) {
  42897 #if defined(BCM_SABER2_SUPPORT)
  42898                 if (SOC_IS_SABER2(unit)) {
  42899                     /* Do nothing */
  42900                 } else
  42901 #endif /* BCM_SABER2_SUPPORT */
  42902                {
  42903                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D1r, port, 0, &val));
  42904                     val_lo = soc_reg_field_get(unit, XIBP_D1r, val, DATA_BYTES_4_7f);
  42905                     val_lo = (val_lo & 0xffff0000) | ((value >> 8) & 0xffff);
  42906                     soc_reg_field_set(unit, XIBP_D1r, &val, DATA_BYTES_4_7f, val_lo);
  42907                     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D1r, port, 0, val));
  42908 
  42909                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D2r, port, 0, &val));
  42910                     val_hi = soc_reg_field_get(unit, XIBP_D2r, val, DATA_BYTES_8_11f);
  42911                     val_hi = (val_hi & 0xffffff) | ((value & 0xff) << 24);
  42912                     soc_reg_field_set(unit, XIBP_D2r, &val, DATA_BYTES_8_11f, val_hi);
  42913                     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D2r, port, 0, val));
  42914                     rv = BCM_E_NONE;
  42915                     break;
  42916                }
  42917            }
  42918 #endif /* BCM_KATANA2_SUPPORT */
  42919             if (IS_XL_PORT(unit, port)) {
  42920                 reg_1 = XLMAC_E2EFC_DATA_HDR_1r;
  42921                 reg_0 = XLMAC_E2EFC_DATA_HDR_0r;
  42922             } else if (IS_CL_PORT(unit, port)) {
  42923                 reg_1 = CLMAC_E2EFC_DATA_HDR_1r;
  42924                 reg_0 = CLMAC_E2EFC_DATA_HDR_0r;
  42925             } else {
  42926                 return BCM_E_PARAM;
  42927             }
  42928 
  42929             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg_1, port,
  42930                                             0, &val_64));
  42931             data_1 = soc_reg64_field_get(unit, reg_1,
  42932                                          val_64, E2EFC_DATA_HDR_1f);
  42933             COMPILER_64_TO_32_LO(val_lo, data_1);
  42934             COMPILER_64_TO_32_HI(val_hi, data_1);
  42935             val_hi = (val_hi & 0xffffff) | ((value & 0xff) << 24);
  42936             COMPILER_64_SET(data_1, val_hi, val_lo);
  42937             soc_reg64_field_set(unit, reg_1, &val_64, E2EFC_DATA_HDR_1f,
  42938                                 data_1);
  42939             BCM_IF_ERROR_RETURN(soc_reg64_set(unit, reg_1,  port, 0, val_64));
  42940             /* SA MAC setting across 2 registers */
  42941             COMPILER_64_ZERO(val_64);
  42942             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg_0, port,
  42943                                             0, &val_64));
  42944             data_0 = soc_reg64_field_get(unit, reg_0,
  42945                                          val_64, E2EFC_DATA_HDR_0f);
  42946             COMPILER_64_TO_32_LO(val_lo, data_0);
  42947             COMPILER_64_TO_32_HI(val_hi, data_0);
  42948             val_lo = (val_lo & 0xffff0000) | ((value >> 8) & 0xffff);
  42949             COMPILER_64_SET(data_0, val_hi, val_lo);
  42950             soc_reg64_field_set(unit, reg_0, &val_64, E2EFC_DATA_HDR_0f,
  42951                                 data_0);
  42952             rv = soc_reg64_set(unit, reg_0, port, 0, val_64);
  42953         }
  42954         break;
  42955     /* Lower 3 bytes of Source MAC address */
  42956     case bcmPortControlE2EFCSrcMacNonOui:
  42957         if (soc_feature(unit, soc_feature_e2efc)) {
  42958             uint32 val_lo, val_hi;
  42959             uint64 val_64, data_1;
  42960             soc_reg_t reg;
  42961 #if defined(BCM_KATANA2_SUPPORT)
  42962             uint32 val;
  42963 #endif
  42964             if (!IS_HG_PORT(unit, port)) {
  42965                 LOG_ERROR(
  42966                     BSL_LS_BCM_PORT,
  42967                     (BSL_META_U(unit,
  42968                                 "Error: unit %d port %d is not a Higig port. "
  42969                                 "E2EFC messages can only be transmitted to "
  42970                                 "or received from Higig ports.\n"),
  42971                      unit, port));
  42972                 return BCM_E_PARAM;
  42973             }
  42974 #if defined(BCM_KATANA2_SUPPORT)
  42975             if (SOC_IS_KATANA2(unit)) {
  42976 #if defined(BCM_SABER2_SUPPORT)
  42977                 if (SOC_IS_SABER2(unit)) {
  42978                     /* Do nothing */
  42979                 } else
  42980 #endif /* BCM_SABER2_SUPPORT */
  42981                {
  42982                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D2r, port, 0, &val));
  42983                     val_hi = soc_reg_field_get(unit, XIBP_D2r, val, DATA_BYTES_8_11f);
  42984                     val_hi = (val_hi & 0xff000000) | (value & 0xffffff);
  42985                     soc_reg_field_set(unit, XIBP_D2r, &val, DATA_BYTES_8_11f, val_hi);
  42986                     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D2r, port, 0, val));
  42987                     rv = BCM_E_NONE;
  42988                     break;
  42989                }
  42990             }
  42991 #endif /* BCM_KATANA2_SUPPORT */
  42992             if (IS_XL_PORT(unit, port)) {
  42993                 reg = XLMAC_E2EFC_DATA_HDR_1r;
  42994             } else if (IS_CL_PORT(unit, port)) {
  42995                 reg = CLMAC_E2EFC_DATA_HDR_1r;
  42996             } else {
  42997                 return BCM_E_PARAM;
  42998             }
  42999             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port,
  43000                                             0, &val_64));
  43001             data_1 = soc_reg64_field_get(unit, reg,
  43002                                          val_64, E2EFC_DATA_HDR_1f);
  43003             COMPILER_64_TO_32_LO(val_lo, data_1);
  43004             COMPILER_64_TO_32_HI(val_hi, data_1);
  43005             val_hi = (val_hi & 0xff000000) | (value & 0xffffff);
  43006             COMPILER_64_SET(data_1, val_hi, val_lo);
  43007             soc_reg64_field_set(unit, reg, &val_64, E2EFC_DATA_HDR_1f,
  43008                                 data_1);
  43009 
  43010             rv = soc_reg64_set(unit, reg, port, 0, val_64);
  43011         }
  43012         break;
  43013     case bcmPortControlE2EFCEtherType:
  43014         if (soc_feature(unit, soc_feature_e2efc)) {
  43015             uint32 val_lo, val_hi;
  43016             uint64 val_64, data_1;
  43017             soc_reg_t reg;
  43018 #if defined(BCM_KATANA2_SUPPORT)
  43019             uint32 val;
  43020 #endif
  43021             if (!IS_HG_PORT(unit, port)) {
  43022                 LOG_ERROR(
  43023                     BSL_LS_BCM_PORT,
  43024                     (BSL_META_U(unit,
  43025                                 "Error: unit %d port %d is not a Higig port. "
  43026                                 "E2EFC messages can only be transmitted to "
  43027                                 "or received from Higig ports.\n"),
  43028                      unit, port));
  43029                 return BCM_E_PARAM;
  43030             }
  43031 #if defined(BCM_KATANA2_SUPPORT)
  43032             if (SOC_IS_KATANA2(unit)) {
  43033 #if defined(BCM_SABER2_SUPPORT)
  43034                 if (SOC_IS_SABER2(unit)) {
  43035                     /* Do nothing */
  43036                 } else
  43037 #endif /* BCM_SABER2_SUPPORT */
  43038                {
  43039                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D3r, port, 0, &val));
  43040                     val_lo = soc_reg_field_get(unit, XIBP_D3r, val, D_BYTES_12_15f);
  43041                     val_lo = (val_lo & 0xffff) | ((value & 0xffff) << 16);
  43042                     soc_reg_field_set(unit, XIBP_D3r, &val, D_BYTES_12_15f, val_lo);
  43043                     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D3r, port, 0, val));
  43044                     rv = BCM_E_NONE;
  43045                     break;
  43046                }
  43047             }
  43048 #endif /* BCM_KATANA2_SUPPORT */
  43049             if (IS_XL_PORT(unit, port)) {
  43050                 reg = XLMAC_E2EFC_DATA_HDR_1r;
  43051             } else if (IS_CL_PORT(unit, port)) {
  43052                 reg = CLMAC_E2EFC_DATA_HDR_1r;
  43053             } else {
  43054                 return BCM_E_PARAM;
  43055             }
  43056 
  43057             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port,
  43058                                             0, &val_64));
  43059             data_1 = soc_reg64_field_get(unit, reg,
  43060                                          val_64, E2EFC_DATA_HDR_1f);
  43061             COMPILER_64_TO_32_LO(val_lo, data_1);
  43062             COMPILER_64_TO_32_HI(val_hi, data_1);
  43063             val_lo = (val_lo & 0xffff) | ((value & 0xffff) << 16);
  43064             COMPILER_64_SET(data_1, val_hi, val_lo);
  43065             soc_reg64_field_set(unit, reg, &val_64, E2EFC_DATA_HDR_1f,
  43066                                 data_1);
  43067             rv = soc_reg64_set(unit, reg, port, 0, val_64);
  43068         }
  43069         break;
  43070     case bcmPortControlE2EFCOpcode:
  43071         if (soc_feature(unit, soc_feature_e2efc)) {
  43072             uint32 val_lo, val_hi;
  43073             uint64 val_64, data_1;
  43074             soc_reg_t reg;
  43075 #if defined(BCM_KATANA2_SUPPORT)
  43076             uint32 val;
  43077 #endif
  43078 
  43079             if (!IS_HG_PORT(unit, port)) {
  43080                 LOG_ERROR(
  43081                     BSL_LS_BCM_PORT,
  43082                     (BSL_META_U(unit,
  43083                                 "Error: unit %d port %d is not a Higig port. "
  43084                                 "E2EFC messages can only be transmitted to "
  43085                                 "or received from Higig ports.\n"),
  43086                      unit, port));
  43087                 return BCM_E_PARAM;
  43088             }
  43089 #if defined(BCM_KATANA2_SUPPORT)
  43090             if (SOC_IS_KATANA2(unit)) {
  43091 #if defined(BCM_SABER2_SUPPORT)
  43092                 if (SOC_IS_SABER2(unit)) {
  43093                     /* Do nothing */
  43094                 } else
  43095 #endif /* BCM_SABER2_SUPPORT */
  43096                {
  43097                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D3r, port, 0, &val));
  43098                     val_lo = soc_reg_field_get(unit, XIBP_D3r, val, D_BYTES_12_15f);
  43099                     val_lo = (val_lo & 0xffff0000) | (value & 0xffff);
  43100                     soc_reg_field_set(unit, XIBP_D3r, &val, D_BYTES_12_15f, val_lo);
  43101                     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D3r, port, 0, val));
  43102                     rv = BCM_E_NONE;
  43103                     break;
  43104                }
  43105             }
  43106 #endif /* BCM_KATANA2_SUPPORT */
  43107             if (IS_XL_PORT(unit, port)) {
  43108                 reg = XLMAC_E2EFC_DATA_HDR_1r;
  43109             } else if (IS_CL_PORT(unit, port)) {
  43110                 reg = CLMAC_E2EFC_DATA_HDR_1r;
  43111             } else {
  43112                 return BCM_E_PARAM;
  43113             }
  43114             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port,
  43115                                             0, &val_64));
  43116             data_1 = soc_reg64_field_get(unit, reg,
  43117                                          val_64, E2EFC_DATA_HDR_1f);
  43118             COMPILER_64_TO_32_LO(val_lo, data_1);
  43119             COMPILER_64_TO_32_HI(val_hi, data_1);
  43120             val_lo = (val_lo & 0xffff0000) | (value & 0xffff);
  43121             COMPILER_64_SET(data_1, val_hi, val_lo);
  43122             soc_reg64_field_set(unit, reg, &val_64, E2EFC_DATA_HDR_1f,
  43123                                 data_1);
  43124             rv = soc_reg64_set(unit, reg, port, 0, val_64);
  43125         }
  43126         break;
  43127     case bcmPortControlResetSerdes:
  43128         
  43129 
  43130 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TOMAHAWKPLUS_SUPPORT)
  43131         if (SOC_IS_TOMAHAWK(unit) || SOC_IS_TOMAHAWKPLUS(unit)) {
  43132             rv = soc_th_reset_serdes(unit, port, value);
  43133 
  43134         } else 
  43135 #endif            
  43136 
  43137 #if defined(BCM_HURRICANE3_SUPPORT)
  43138         if (SOC_IS_HURRICANE3(unit)) {
  43139             rv = soc_hurricane3_tsc_core_reset(unit, port, value);
  43140         } else
  43141 #endif
  43142         {            
  43143             rv = BCM_E_UNAVAIL;
  43144         }
  43145         break;
  43146     case bcmPortControlIntEnable:
  43147 #if defined(BCM_TOMAHAWK3_SUPPORT) 
  43148         if (soc_feature(unit, soc_feature_inband_network_telemetry)) {
  43149             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, INT_ENABLEf, value);   
  43150         }
  43151 #endif
  43152         break;
  43153     case bcmPortControlIntTurnaround:
  43154 #if defined(BCM_TOMAHAWK3_SUPPORT)
  43155         if (soc_feature(unit, soc_feature_inband_network_telemetry)) {
  43156             SOC_IF_ERROR_RETURN
  43157                 (READ_INT_TURNAROUND_EN_BMAPm(unit, MEM_BLOCK_ANY, 0,
  43158                                      &int_turnaround_en_bmap_entry));
  43159             soc_mem_pbmp_field_get(unit, INT_TURNAROUND_EN_BMAPm,
  43160                            &int_turnaround_en_bmap_entry, PORT_BITMAPf, &pbmp);
  43161             if (value)
  43162                 SOC_PBMP_PORT_ADD(pbmp, port);
  43163             else
  43164                 SOC_PBMP_PORT_REMOVE(pbmp, port);
  43165                 
  43166             soc_mem_pbmp_field_set(unit, INT_TURNAROUND_EN_BMAPm,
  43167                            &int_turnaround_en_bmap_entry, PORT_BITMAPf, &pbmp);
  43168             SOC_IF_ERROR_RETURN
  43169                 (WRITE_INT_TURNAROUND_EN_BMAPm(unit, MEM_BLOCK_ANY, 0,
  43170                                       &int_turnaround_en_bmap_entry));
  43171         }
  43172 #endif
  43173         break;
  43174     case bcmPortControlObmClassifierPriority:
  43175     case bcmPortControlObmClassifierEnableDscp:
  43176     case bcmPortControlObmClassifierEnableMpls:
  43177     case bcmPortControlObmClassifierEnableEtag:
  43178     case bcmPortControlObmClassifierEtagEthertype:
  43179     case bcmPortControlObmClassifierVntagEthertype:
  43180 
  43181 #if defined(BCM_MONTEREY_SUPPORT)
  43182         if (SOC_IS_MONTEREY(unit)) {
  43183             rv = bcm_mn_obm_classifier_port_control_set(unit, port, type, value);
  43184         } else
  43185 #endif
  43186 #if defined(BCM_APACHE_SUPPORT)
  43187         if (SOC_IS_APACHE(unit)) {
  43188             rv = bcm_apache_obm_classifier_port_control_set(unit, port, type, value);
  43189         } else
  43190 #endif
  43191         {
  43192             rv = BCM_E_UNAVAIL;
  43193         }
  43194         break;
  43195     case bcmPortControlObmClassifierInternal:
  43196 #if defined(BCM_MONTEREY_SUPPORT)
  43197         if (SOC_IS_MONTEREY(unit)) {
  43198             rv = bcm_mn_obm_classifier_port_control_set(unit, port, type, value);
  43199         } else
  43200 #endif
  43201         {
  43202             rv = BCM_E_UNAVAIL;
  43203         }
  43204         break;
  43205 
  43206    case bcmPortControlWirelessCosMapSelect:
  43207 #if defined(BCM_HELIX5_SUPPORT)
  43208         if (SOC_IS_HELIX5(unit)) {
  43209             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
  43210                                        WIRED_WIRELESSf, (value) ? 1 : 0);
  43211         } else
  43212 #endif
  43213         {
  43214            rv = BCM_E_UNAVAIL;
  43215         }
  43216     break;
  43217 
  43218    case bcmPortControlHiGigCosSelect:
  43219 #if defined(BCM_HELIX5_SUPPORT)
  43220         if (SOC_IS_HELIX5(unit)) {
  43221             rv = bcm_hx5_hgcos_select_port_control_set(unit, port, type, value);
  43222         } else
  43223 #endif
  43224         {
  43225            rv = BCM_E_UNAVAIL;
  43226         }
  43227     break;
  43228     case bcmPortControlInternalLoopback:
  43229 #ifdef BCM_TRIDENT3_SUPPORT
  43230         if (SOC_IS_TRIDENT3X(unit)) {
  43231             rv = bcmi_td3_port_internal_loopback_set(unit,port,value);
  43232             
  43233         } else
  43234 #endif
  43235         {
  43236             rv = BCM_E_UNAVAIL;
  43237         }
  43238         break;
  43239 #ifdef BCM_MONTEREY_SUPPORT
  43240     case bcmPortControlObmInterruptTypeDropPreempt :
  43241     case bcmPortControlObmInterruptTypeOverflowPreempt : 
  43242     case bcmPortControlObmInterruptTypeDropExpress :  
  43243     case  bcmPortControlObmInterruptTypeOverflowExpress : 
  43244         if (SOC_IS_MONTEREY(unit)) {
  43245             rv = bcm_mn_obm_interrupt_port_control_set(unit, port, type, value);
  43246             
  43247         } else 
  43248 #endif
  43249         {
  43250             rv = BCM_E_UNAVAIL;
  43251         }
  43252         break;
  43253     default:
  43254         break;
  43255     }
  43256     return rv;
  43257 }
  43258 
  43259 
  43260 /*
  43261  * Function:
  43262  *      bcm_esw_port_control_get
  43263  * Description:
  43264  *      Get the status of specified port feature.
  43265  * Parameters:
  43266  *      unit - Device number
  43267  *      port - Port number
  43268  *      type - Enum  value of the feature
  43269  *      value - (OUT) Current value of the port feature
  43270  * Return Value:
  43271  *      BCM_E_NONE
  43272  *      BCM_E_UNAVAIL - Functionality not available
  43273  */
  43274 int
  43275 bcm_esw_port_control_get(int unit, bcm_port_t port,
  43276                          bcm_port_control_t type, int *value)
  43277 {
  43278     int rv = BCM_E_UNAVAIL;
  43279     int valid = 0;
  43280 #if defined(BCM_SHADOW_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  43281     uint32 val = 0;
  43282 #endif /* BCM_SHADOW_SUPPORT || BCM_GREYHOUND_SUPPORT */
  43283 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  43284     int chk_gx_port = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  43285                        SOC_IS_VALKYRIE2(unit) || SOC_IS_SCORPION(unit));
  43286 #endif
  43287 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_REGEX)
  43288     int udp;
  43289     int tcp;
  43290     int enable;
  43291 #endif
  43292     source_vp_entry_t svp_entry;
  43293 #if defined(BCM_TOMAHAWK3_SUPPORT)
  43294 int_turnaround_en_bmap_entry_t int_turnaround_en_bmap_entry;
  43295 bcm_pbmp_t  pbmp;
  43296 #endif
  43297     if (value == NULL) {
  43298         return BCM_E_PARAM;
  43299     }
  43300 
  43301     /* Make sure port module is initialized. */
  43302     PORT_INIT(unit);
  43303 
  43304     if(bcm_common_oamp_port_enable_get(unit, port) &&
  43305             (type != bcmPortControlSatEnable)) {
  43306         LOG_ERROR(BSL_LS_BCM_PORT,
  43307                   (BSL_META("Error: Not permitted on OAMP port %d.n"),
  43308                    port));
  43309         return BCM_E_PARAM;
  43310     }
  43311 
  43312     /* Call Port Control module */
  43313     if (SOC_USE_PORTCTRL(unit)) {
  43314         /*
  43315          * Check that port control feature is valid in Port Control.
  43316          * If valid, call Port Control routine to handle feature; otherwise
  43317          * continue with rest of logic.
  43318          */
  43319         BCM_IF_ERROR_RETURN
  43320             (bcmi_esw_portctrl_control_validate(unit, type, &valid));
  43321         if (valid) {
  43322             return bcmi_esw_portctrl_control_get(unit, port, type, value);
  43323         }
  43324     }
  43325 
  43326 #if defined(BCM_SHADOW_SUPPORT)
  43327     if (SOC_IS_SHADOW(unit)) {
  43328         /*  If unsupported port control type, return unavail */
  43329         if (!_bcm_port_type_shadow_support (unit, port, type)) {
  43330             return BCM_E_UNAVAIL;
  43331         }
  43332     }
  43333 #endif /* BCM_SHADOW_SUPPORT */
  43334 
  43335     if (type == bcmPortControlEsmEligibility) {
  43336 #ifdef BCM_TRIUMPH3_SUPPORT
  43337         /* For bcmPortControlEsmEligibility, a non-local port
  43338          * is accepted. For other port controls, a non-local
  43339          * port is not accepted. Hence, bcmPortControlEsmEligibility
  43340          * is implemented here, before the _bcm_esw_port_gport_validate
  43341          * procedure below.
  43342          */
  43343         return bcm_tr3_port_esm_eligible_get(unit, port, value);
  43344 #endif /* BCM_TRIUMPH3_SUPPORT */
  43345     }
  43346 
  43347 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
  43348     if (
  43349 #ifdef BCM_HGPROXY_COE_SUPPORT
  43350         (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  43351          _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port) &&
  43352          ((type == bcmPortControlVlanVpGroupIngress) ||
  43353           (type == bcmPortControlVlanVpGroupEgress))) ||
  43354 #endif
  43355         BCM_GPORT_IS_TRUNK(port) ||
  43356         BCM_GPORT_IS_VLAN_PORT(port) ||
  43357         BCM_GPORT_IS_NIV_PORT(port) ||
  43358         BCM_GPORT_IS_VXLAN_PORT(port) ||
  43359         BCM_GPORT_IS_MIM_PORT(port) ||
  43360         BCM_GPORT_IS_MPLS_PORT(port) ||
  43361         BCM_GPORT_IS_L2GRE_PORT(port) ||
  43362         BCM_GPORT_IS_FLOW_PORT(port) ||
  43363         BCM_GPORT_IS_EXTENDER_PORT(port)) {
  43364         return bcm_td_vp_control_get(unit, port, type, value);
  43365     } else
  43366 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  43367 #if defined(BCM_KATANA2_SUPPORT)
  43368     if (((BCM_GPORT_IS_MIM_PORT(port)) ||
  43369          (BCM_GPORT_IS_MPLS_PORT(port))) && SOC_IS_KATANA2(unit)) {
  43370         rv = BCM_E_NONE;
  43371     } else
  43372 #endif /* BCM_KATANA2_SUPPORT */
  43373     if ((BCM_GPORT_IS_LOCAL_CPU_IEEE(port)) || 
  43374         (BCM_GPORT_IS_LOCAL_CPU_HIGIG(port))) {
  43375         rv = BCM_E_NONE;
  43376     } else
  43377 #ifdef BCM_HGPROXY_COE_SUPPORT
  43378     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  43379         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  43380         rv = BCM_E_NONE;
  43381     } else
  43382 #endif
  43383     {
  43384         rv = bcm_esw_port_control_validate(unit, port, type, &port);
  43385     }
  43386     BCM_IF_ERROR_RETURN(rv);
  43387     rv = BCM_E_UNAVAIL;
  43388 
  43389     /*
  43390      * At this point, 'port' can be:
  43391      *    GPORT WLAN
  43392      *    GPORT PROXY
  43393      *    BCM valid local port
  43394      *
  43395      * Some switch cases only handles 'port' in BCM port format
  43396      * (non-gport).  Corresponding checks must be added in those
  43397      * cases to ensure that 'port' is not a gport.
  43398      */
  43399     switch (type) {
  43400     case bcmPortControlBridge:
  43401         if (SOC_IS_XGS3_SWITCH(unit)) {
  43402             rv = _bcm_esw_port_tab_get(unit, port, PORT_BRIDGEf, value);
  43403         }
  43404         break;
  43405     case bcmPortControlTrunkHashSet:
  43406 #if defined(BCM_TRIUMPH3_SUPPORT)
  43407         if (SOC_IS_TRIUMPH3(unit)) {
  43408             return BCM_E_UNAVAIL;
  43409         } else
  43410 #endif /* BCM_TRIUMPH3_SUPPORT */
  43411         {
  43412 #if defined(BCM_BRADLEY_SUPPORT)
  43413             if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) {
  43414                 rv = _bcm_esw_port_tab_get(unit, port,
  43415                                            RTAG7_HASH_CFG_SEL_TRUNKf, value);
  43416             }
  43417 #endif /* BCM_BRADLEY_SUPPORT */
  43418         }
  43419         break;
  43420     case bcmPortControlFabricTrunkHashSet:
  43421 #if defined(BCM_TRIUMPH3_SUPPORT)
  43422         if (SOC_IS_TRIUMPH3(unit)) {
  43423             return BCM_E_UNAVAIL;
  43424         } else
  43425 #endif /* BCM_TRIUMPH3_SUPPORT */
  43426         {
  43427 #if defined(BCM_BRADLEY_SUPPORT)
  43428             if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) {
  43429                 rv = _bcm_esw_port_tab_get(unit, port,
  43430                                            RTAG7_HASH_CFG_SEL_HIGIG_TRUNKf,
  43431                                            value);
  43432             }
  43433 #endif /* BCM_BRADLEY_SUPPORT */
  43434         }
  43435         break;
  43436     case bcmPortControlECMPHashSet:
  43437 #if defined(BCM_TRIUMPH3_SUPPORT)
  43438         if (SOC_IS_TRIUMPH3(unit)) {
  43439             return BCM_E_UNAVAIL;
  43440         } else
  43441 #endif /* BCM_TRIUMPH3_SUPPORT */
  43442         {
  43443 #if defined(BCM_BRADLEY_SUPPORT)
  43444             if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) {
  43445                 rv = _bcm_esw_port_tab_get(unit, port,
  43446                                            RTAG7_HASH_CFG_SEL_ECMPf, value);
  43447             }
  43448 #endif /* BCM_BRADLEY_SUPPORT */
  43449         }
  43450         break;
  43451     case bcmPortControlLoadBalanceHashSet:
  43452 #if defined(BCM_TRIUMPH3_SUPPORT)
  43453         if (SOC_IS_TRIUMPH3(unit)) {
  43454             return BCM_E_UNAVAIL;
  43455         } else
  43456 #endif /* BCM_TRIUMPH3_SUPPORT */
  43457         {
  43458 #if defined(BCM_BRADLEY_SUPPORT)
  43459             if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) {
  43460                 rv = _bcm_esw_port_tab_get(unit, port,
  43461                                            RTAG7_HASH_CFG_SEL_LBIDf, value);
  43462             }
  43463 #endif /* BCM_BRADLEY_SUPPORT */
  43464         }
  43465         break;
  43466     case bcmPortControlLoadBalancingNumber:
  43467 #if defined(BCM_BRADLEY_SUPPORT)
  43468         if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) {
  43469             rv = _bcm_esw_port_tab_get(unit, port,
  43470                                        RTAG7_PORT_LBNf, value);
  43471         }
  43472 #endif /* BCM_BRADLEY_SUPPORT */
  43473         break;
  43474     case bcmPortControlErrorSymbolDetect:
  43475 #if defined(BCM_GREYHOUND_SUPPORT)
  43476         if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  43477             SOC_IS_GREYHOUND2(unit)) {
  43478             rv = BCM_E_UNAVAIL;
  43479         } else
  43480 #endif /* BCM_GREYHOUND_SUPPORT */
  43481         {
  43482 #ifdef BCM_XGS3_SWITCH_SUPPORT
  43483             if (SOC_IS_XGS3_SWITCH(unit)) {
  43484                  rv = _bcm_esw_port_err_sym_detect_get(unit, port, value);
  43485             }
  43486 #endif
  43487         }
  43488         break;
  43489     case bcmPortControlErrorSymbolCount:
  43490 #if defined(BCM_GREYHOUND_SUPPORT)
  43491         if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  43492             SOC_IS_GREYHOUND2(unit)) {
  43493             rv = BCM_E_UNAVAIL;
  43494         } else
  43495 #endif /* BCM_GREYHOUND_SUPPORT */
  43496         {
  43497 #ifdef BCM_XGS3_SWITCH_SUPPORT
  43498             if (SOC_IS_XGS3_SWITCH(unit)) {
  43499                 rv = _bcm_esw_port_err_sym_count_get(unit, port, value);
  43500             }
  43501 #endif
  43502         }
  43503         break;
  43504     case bcmPortControlIP4:
  43505         if (SOC_IS_XGS3_SWITCH(unit)) {
  43506 #if defined(BCM_TRX_SUPPORT)
  43507             if (BCM_GPORT_LOCAL_CPU_HIGIG == port) {
  43508                 rv = _bcm_esw_iport_tab_get(unit, CMIC_PORT(unit), V4L3_ENABLEf, value);
  43509             } else 
  43510 #endif
  43511             {
  43512                 rv = _bcm_esw_port_tab_get(unit, port, V4L3_ENABLEf, value);
  43513             }
  43514         }
  43515         break;
  43516     case bcmPortControlIP6:
  43517         if (SOC_IS_XGS3_SWITCH(unit)) {
  43518             rv = _bcm_esw_port_tab_get(unit, port, V6L3_ENABLEf, value);
  43519         }
  43520         break;
  43521     case bcmPortControlIP4Mcast:
  43522         if (SOC_IS_XGS3_SWITCH(unit)) {
  43523             rv = _bcm_esw_port_tab_get(unit, port, V4IPMC_ENABLEf, value);
  43524         }
  43525         break;
  43526     case bcmPortControlIP6Mcast:
  43527         if (SOC_IS_XGS3_SWITCH(unit)) {
  43528             rv = _bcm_esw_port_tab_get(unit, port, V6IPMC_ENABLEf, value);
  43529         }
  43530         break;
  43531     case bcmPortControlIPMC4Ucast:
  43532         if (soc_feature(unit, soc_feature_ipmc_unicast)) {
  43533             rv = _bcm_esw_port_tab_get(unit, port,
  43534                     IPMCV4_UNICAST_MACDA_ENABLEf, value);
  43535         }
  43536         break;
  43537     case bcmPortControlIPMC6Ucast:
  43538         if (soc_feature(unit, soc_feature_ipmc_unicast)) {
  43539             rv = _bcm_esw_port_tab_get(unit, port,
  43540                     IPMCV6_UNICAST_MACDA_ENABLEf, value);
  43541         }
  43542         break;
  43543     case bcmPortControlIP4McastL2:
  43544 #if defined(BCM_TRX_SUPPORT)
  43545         if (SOC_IS_XGS3_SWITCH(unit)) {
  43546             if (SOC_IS_TD2_TT2(unit) &&
  43547                     soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm,
  43548                                                          IPMCV4_L2_ENABLEf)) {
  43549                 rv = _bcm_trx_source_trunk_map_get(unit, port,
  43550                                      IPMCV4_L2_ENABLEf, (uint32 *)value);
  43551             } else {
  43552                 rv = _bcm_esw_port_tab_get(unit, port, V4IPMC_L2_ENABLEf, value);
  43553             }
  43554         }
  43555 #endif /* BCM_TRX_SUPPORT */
  43556         break;
  43557     case bcmPortControlIP6McastL2:
  43558 #ifdef BCM_TRX_SUPPORT
  43559         if (SOC_IS_XGS3_SWITCH(unit)) {
  43560             if (SOC_IS_TD2_TT2(unit) && 
  43561                     soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm,
  43562                                                          IPMCV6_L2_ENABLEf)) {
  43563                 rv = _bcm_trx_source_trunk_map_get(unit, port,
  43564                                     IPMCV6_L2_ENABLEf, (uint32 *)value);
  43565             } else {
  43566                 rv = _bcm_esw_port_tab_get(unit, port, V6IPMC_L2_ENABLEf, value);
  43567             }
  43568         }
  43569 #endif
  43570         break;
  43571 
  43572     case bcmPortControlMpls:
  43573 #if defined(BCM_TRIUMPH_SUPPORT)
  43574         if (SOC_IS_XGS3_SWITCH(unit)) {
  43575             rv = _bcm_esw_port_tab_get(unit, port, MPLS_ENABLEf, value);
  43576         }
  43577 #endif
  43578         break;
  43579 
  43580     case bcmPortControlMacInMac:
  43581 #if defined(BCM_TRIUMPH2_SUPPORT)
  43582         if (SOC_IS_XGS3_SWITCH(unit) && soc_feature(unit, soc_feature_mim)) {
  43583             rv = _bcm_esw_port_tab_get(unit, port, MIM_TERM_ENABLEf, value);
  43584         }
  43585 #endif
  43586         break;
  43587 
  43588     case bcmPortControlMimUcastTermEnable:
  43589 #if defined(BCM_TRIUMPH2_SUPPORT)
  43590         if (SOC_IS_XGS3_SWITCH(unit) && soc_feature(unit, soc_feature_mim)) {
  43591             rv = _bcm_esw_port_tab_get(unit, port, MIM_TERM_ENABLEf, value);
  43592         }
  43593 #endif
  43594         break;
  43595 
  43596     case bcmPortControlMimMcastTermEnable:
  43597 #if defined(BCM_TRIUMPH2_SUPPORT)
  43598         if (SOC_IS_XGS3_SWITCH(unit) && soc_feature(unit, soc_feature_mim)) {
  43599             rv = _bcm_esw_port_tab_get(unit, port, MIM_MC_TERM_ENABLEf, value);
  43600         }
  43601 #endif
  43602         break;
  43603 
  43604     case bcmPortControlSrcBmacMissToCpu:
  43605 #ifdef BCM_TRIUMPH2_SUPPORT
  43606      if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  43607          SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit) ||
  43608          SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA(unit)) {
  43609          /* 0x2: ToCPU 0x1: Drop(default) */
  43610          rv = _bcm_esw_port_tab_get(unit, port, CML_BMAC_NEWf, value);
  43611          *value = (*value == 0x2) ? TRUE : FALSE;
  43612      }
  43613 #endif /* BCM_TRIUMPH2_SUPPORT */
  43614          break;
  43615 
  43616     case bcmPortControlQosRemarkResolution:
  43617 #ifdef BCM_TRIDENT3_SUPPORT
  43618         if (SOC_IS_TRIDENT3X(unit)) {
  43619             rv = _bcm_esw_egr_port_tab_get(unit, port, QOS_CTRL_IDf, value);
  43620             /* TD3 only supports 2 of the 4 valid hardware configurations for now.
  43621              * 1: Serial resolution.
  43622              * 3: Layered resolution.
  43623              * Other value: Invalid.
  43624              */
  43625             if (rv == BCM_E_NONE) {
  43626                 if (*value == 1) {
  43627                     *value = BCM_PORT_QOS_SERIAL_RESOLUTION;
  43628                 } else if (*value == 3) {
  43629                     *value = BCM_PORT_QOS_LAYERED_RESOLUTION;
  43630                 } else {
  43631                     return BCM_E_PARAM;
  43632                 }
  43633             }
  43634         }
  43635 #endif /* BCM_TRIDENT3_SUPPORT */
  43636          break;
  43637 
  43638     case bcmPortControlFabricQueue:
  43639 #if defined(BCM_TRIUMPH2_SUPPORT)
  43640         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  43641         if (IS_ST_PORT(unit, port)) {
  43642             if  (SOC_REG_FIELD_VALID(unit, EGR_PORT_64r, EH_EXT_HDR_ENABLEf)) {
  43643                 uint64 egr_val64;
  43644                 rv = READ_EGR_PORT_64r(unit, port, &egr_val64);
  43645                 if (BCM_SUCCESS(rv)) {
  43646                     *value = soc_reg64_field32_get(unit, EGR_PORT_64r, 
  43647                                               egr_val64, EH_EXT_HDR_ENABLEf);
  43648                 }
  43649             }
  43650             else if(SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EH_EXT_HDR_ENABLEf)){
  43651                 egr_port_entry_t entry;
  43652                 rv = soc_mem_read(unit, EGR_PORTm, MEM_BLOCK_ANY, port,
  43653                             &entry);
  43654                  if (BCM_SUCCESS(rv)) {
  43655                     *value = soc_mem_field32_get(unit, EGR_PORTm, &entry,
  43656                                             EH_EXT_HDR_ENABLEf);
  43657                 }
  43658             }
  43659         } else {
  43660 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  43661             /* Allow CPU port on TD2+ to add extended header */
  43662             if (SOC_IS_TRIDENT2PLUS(unit) && IS_CPU_PORT(unit, port)) {
  43663                 egr_port_entry_t entry;
  43664                 rv = soc_mem_read(unit, EGR_PORTm, MEM_BLOCK_ANY, port,
  43665                             &entry);
  43666                  if (BCM_SUCCESS(rv)) {
  43667                     *value = soc_mem_field32_get(unit, EGR_PORTm, &entry,
  43668                                             EH_EXT_HDR_ENABLEf);
  43669                 }
  43670             }
  43671 #endif
  43672 #if defined(BCM_TOMAHAWK_SUPPORT)
  43673             if (SOC_IS_TOMAHAWKX(unit) && IS_CPU_PORT(unit, port)) {
  43674                 egr_port_entry_t entry;
  43675                 rv = soc_mem_read(unit, EGR_PORTm, MEM_BLOCK_ANY, port, &entry);
  43676                 if (BCM_SUCCESS(rv)) {
  43677                     *value = soc_mem_field32_get(unit, EGR_PORTm, &entry,
  43678                                             EH_EXT_HDR_ENABLEf);
  43679                 }
  43680             }
  43681 #endif
  43682         }
  43683 #if defined(BCM_TRIDENT3_SUPPORT)
  43684         if (SOC_IS_TRIDENT3X(unit) &&
  43685             soc_feature(unit, soc_feature_egr_lport_tab_profile)) {
  43686            uint32 lport_idx;
  43687            egr_port_entry_t entry;
  43688            egr_lport_profile_entry_t lport_entry;
  43689 
  43690            BCM_IF_ERROR_RETURN(READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, &entry));
  43691            lport_idx = soc_mem_field32_get(unit, EGR_PORTm, &entry,
  43692                                            EGR_LPORT_PROFILE_IDXf);
  43693            rv = (READ_EGR_LPORT_PROFILEm(unit, MEM_BLOCK_ANY,
  43694                                          lport_idx, &lport_entry));
  43695            if (BCM_SUCCESS(rv)) {
  43696                *value = soc_mem_field32_get(unit, EGR_LPORT_PROFILEm, &lport_entry,
  43697                                             EH_EXT_HDR_ENABLEf);
  43698            }
  43699         }
  43700 #endif
  43701 #endif
  43702         break;
  43703     case bcmPortControlPassControlFrames:
  43704         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  43705 #ifdef BCM_XGS_SWITCH_SUPPORT
  43706         if (IS_XE_PORT(unit, port) || IS_CE_PORT(unit, port) ||
  43707             (IS_GE_PORT(unit, port)
  43708              && soc_feature(unit, soc_feature_unified_port)) ||
  43709             (SOC_IS_KATANAX(unit) && IS_MXQ_PORT(unit, port))) {
  43710             if(soc_feature(unit, soc_feature_pgw_mac_control_frame)) {
  43711                 uint32 rval32 = 0;
  43712                 rv = READ_PGW_MAC_RSV_MASKr(unit, port, &rval32);
  43713                 if (BCM_SUCCESS(rv)) {
  43714                     /* PGW_MAC_RSV_MASK: Bit 11 Control Frame recieved
  43715                      * the bit value needs to be reversed
  43716                      */
  43717                     *value = ((rval32 & 0x800) >> 11) ? 0 : 1 ;
  43718                 }
  43719             } else {
  43720                 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  43721                                      SOC_MAC_PASS_CONTROL_FRAME, value);
  43722             }
  43723         }
  43724 #endif
  43725         break;
  43726 #ifdef BCM_XGS3_SWITCH_SUPPORT
  43727     case bcmPortControlFilterLookup:
  43728 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  43729         rv = _bcm_esw_port_tab_get(unit, port, VFP_ENABLEf, value);
  43730 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  43731         break;
  43732     case bcmPortControlFilterIngress:
  43733 #if defined(BCM_TRX_SUPPORT)
  43734         if (BCM_GPORT_LOCAL_CPU_HIGIG == port) {
  43735             rv = _bcm_esw_iport_tab_get(unit, CMIC_PORT(unit), FILTER_ENABLEf, value);
  43736         } else
  43737 #endif
  43738         if (BCM_GPORT_LOCAL_CPU_IEEE == port) {
  43739             rv = _bcm_esw_port_tab_get(unit, CMIC_PORT(unit), FILTER_ENABLEf, value);
  43740         } else {
  43741             rv = _bcm_esw_port_tab_get(unit, port, FILTER_ENABLEf, value);
  43742         }
  43743         break;
  43744     case bcmPortControlFilterEgress:
  43745 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  43746         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  43747         if (SOC_REG_FIELD_VALID(unit, EGR_PORTr, EFP_FILTER_ENABLEf)) {
  43748             uint32 egr_val;
  43749 
  43750             rv = READ_EGR_PORTr(unit, port, &egr_val);
  43751             if (BCM_SUCCESS(rv)) {
  43752                 *value = soc_reg_field_get(unit, EGR_PORTr, egr_val,
  43753                                            EFP_FILTER_ENABLEf);
  43754             }
  43755         } else if (SOC_REG_FIELD_VALID(unit, EGR_PORT_64r,
  43756                                        EFP_FILTER_ENABLEf)) {
  43757             uint64 egr_val64;
  43758 
  43759             rv = READ_EGR_PORT_64r(unit, port, &egr_val64);
  43760             if (BCM_SUCCESS(rv)) {
  43761                 *value = soc_reg64_field32_get(unit, EGR_PORT_64r,
  43762                                                egr_val64,
  43763                                                EFP_FILTER_ENABLEf);
  43764             }
  43765         } else {
  43766             rv = _bcm_esw_egr_port_tab_get(unit, port, EFP_FILTER_ENABLEf, value);
  43767 
  43768         }
  43769 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  43770         break;
  43771     case bcmPortControlFrameSpacingStretch:
  43772         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  43773         rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  43774                              SOC_MAC_CONTROL_FRAME_SPACING_STRETCH, value);
  43775         break;
  43776     case bcmPortControlPreservePacketPriority:
  43777 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  43778         if (SOC_IS_TRIUMPH3(unit)) {
  43779             /* Triumph3 has unity mapping to ING_OUTER_DOT1P_MAPPING_TABLE */
  43780             rv = _bcm_esw_port_tab_get(unit, port,
  43781                                        DOT1P_REMAP_POINTERf, value);
  43782             if (BCM_SUCCESS(rv)) {
  43783                /* True if pointed to default dot1p profile */
  43784                *value = (*value) ? 0 : 1;
  43785             }
  43786         } else {
  43787             rv = _bcm_esw_port_tab_get(unit, port, USE_INCOMING_DOT1Pf, value);
  43788         }
  43789 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  43790         break;
  43791     case bcmPortControlLearnClassEnable:
  43792 #if defined(BCM_TRX_SUPPORT)
  43793         if (soc_feature(unit, soc_feature_class_based_learning)) {
  43794             rv = _bcm_esw_port_tab_get(unit, port, CLASS_BASED_SM_ENABLEf,
  43795                                        value);
  43796         }
  43797 #endif /* BCM_TRX_SUPPORT */
  43798         break;
  43799     case bcmPortControlTrustIncomingVlan:
  43800 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_TRX_SUPPORT)
  43801          rv = _bcm_esw_port_tab_get(unit, port, TRUST_INCOMING_VIDf, value);
  43802 #endif /* BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */
  43803         break;
  43804     case bcmPortControlDoNotCheckVlan:
  43805 #if defined(BCM_TRX_SUPPORT)
  43806         if (!SOC_IS_SHADOW(unit)) {
  43807 #if defined(BCM_TRIDENT3_SUPPORT)
  43808             if (SOC_IS_TRIDENT3X(unit)) {
  43809                 rv = _bcm_esw_port_tab_get(unit, port,
  43810                                            DISABLE_VLAN_CHECKSf, value);
  43811             } else
  43812 #endif
  43813             if (soc_mem_field_valid(unit, PORT_TABm, DISABLE_VLAN_CHECKSf)) {
  43814                 if (CMIC_PORT(unit) == port) {
  43815                     rv = _bcm_esw_iport_tab_get(unit, port,
  43816                                                 DISABLE_VLAN_CHECKSf, value);
  43817                 } else {
  43818                     rv = _bcm_esw_port_tab_get(unit, port,
  43819                                                DISABLE_VLAN_CHECKSf, value);
  43820                 }
  43821             } else if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm,
  43822                         DISABLE_VLAN_CHECKSf)) {
  43823 #if defined(BCM_KATANA2_SUPPORT)
  43824                 if (SOC_IS_KATANA2(unit)) {
  43825                     rv = _bcm_kt2_source_trunk_map_get(unit, port,
  43826                             DISABLE_VLAN_CHECKSf, (uint32 *)value);
  43827                 } else
  43828 #endif
  43829                 {
  43830                     rv = _bcm_trx_source_trunk_map_get(unit, port,
  43831                             DISABLE_VLAN_CHECKSf, (uint32 *)value);
  43832                 }
  43833             }
  43834         }
  43835 #endif /* BCM_TRX_SUPPORT */
  43836           break;
  43837     case bcmPortControlDoNotCheckVlanFromCpu:
  43838 #if defined(BCM_TRX_SUPPORT)
  43839         if (!SOC_IS_SHADOW(unit)) {
  43840             if (CMIC_PORT(unit) == port) {
  43841                 if (soc_mem_field_valid(unit, PORT_TABm, DISABLE_VLAN_CHECKSf) ||
  43842                     SOC_IS_TRIDENT3X(unit)) {
  43843                     rv = _bcm_esw_port_tab_get(unit, port,
  43844                                            DISABLE_VLAN_CHECKSf, value);
  43845                 } else if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm,
  43846                         DISABLE_VLAN_CHECKSf)) {
  43847                     rv = _bcm_trx_source_trunk_map_get(unit, port,
  43848                         DISABLE_VLAN_CHECKSf, (uint32 *)value);
  43849                 }
  43850             } else {
  43851                 rv = BCM_E_PORT;
  43852             }
  43853         }
  43854 #endif /* BCM_TRX_SUPPORT */
  43855          break;
  43856     case bcmPortControlIEEE8021ASEnableIngress:
  43857 #if defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_ENDURO_SUPPORT)
  43858         if (soc_feature(unit, soc_feature_rx_timestamp)) {
  43859             rv = _bcm_esw_port_tab_get(unit, port,
  43860                                        IEEE_802_1AS_ENABLEf, value);
  43861         }
  43862 #endif /* BCM_HAWKEYE_SUPPORT */
  43863         break;
  43864     case bcmPortControlIEEE8021ASEnableEgress:
  43865 #if defined(BCM_HAWKEYE_SUPPORT)
  43866         if (SOC_IS_HAWKEYE(unit)) {
  43867             uint32 egr_val;
  43868 
  43869             rv = READ_EGR_PORTr(unit, port, &egr_val);
  43870             if (BCM_SUCCESS(rv)) {
  43871                 *value = soc_reg_field_get(unit, EGR_PORTr, egr_val,
  43872                                            IEEE_802_1AS_ENABLEf);
  43873             }
  43874         }
  43875 #endif /* BCM_HAWKEYE_SUPPORT */
  43876         break;
  43877     case bcmPortControlEgressVlanPriUsesPktPri:
  43878 #if defined(BCM_TRX_SUPPORT)
  43879 #if defined (BCM_HGPROXY_COE_SUPPORT)
  43880         if (!(soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  43881             BCM_GPORT_IS_SUBPORT_PORT(port)))
  43882 #endif
  43883         {
  43884             BCM_IF_ERROR_RETURN(
  43885                 _bcm_esw_port_gport_validate(unit, port, &port));
  43886         }
  43887         if (SOC_IS_TRX(unit) && !SOC_IS_SHADOW(unit)) {
  43888             uint32 val;
  43889 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  43890             if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
  43891                 if (soc_feature(unit, soc_feature_egr_all_profile)) {
  43892                     rv = bcm_esw_port_egr_lport_field_get(unit,
  43893                         port, EGR_VLAN_CONTROL_1m, REMARK_OUTER_DOT1Pf,
  43894                         (uint32 *)value);
  43895                     *value = *value ? 0 : 1;
  43896                 } else {
  43897 #if defined (BCM_HGPROXY_COE_SUPPORT)
  43898                     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  43899                         BCM_GPORT_IS_SUBPORT_PORT(port)) {
  43900                         rv = bcm_esw_port_egr_lport_field_get(
  43901                                 unit, port, EGR_VLAN_CONTROL_1m,
  43902                                 REMARK_OUTER_DOT1Pf, (uint32 *)value);
  43903                         *value = *value ? 0 : 1;
  43904                     } else
  43905 #endif
  43906                     {
  43907                         egr_vlan_control_1_entry_t entry;
  43908                         rv = READ_EGR_VLAN_CONTROL_1m(
  43909                                 unit, MEM_BLOCK_ANY, port, &entry);
  43910                         if (BCM_SUCCESS(rv)) {
  43911                             *value = soc_EGR_VLAN_CONTROL_1m_field32_get(
  43912                                         unit, &entry,
  43913                                         REMARK_OUTER_DOT1Pf) ? 0 : 1;
  43914                         }
  43915                     }
  43916                 }
  43917             } else
  43918 #endif
  43919             {
  43920                 rv = READ_EGR_VLAN_CONTROL_1r(unit, port, &val);
  43921                 if (BCM_SUCCESS(rv)) {
  43922                     *value = (soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r, val,
  43923                                                 REMARK_OUTER_DOT1Pf)) ? 0 : 1;
  43924                 }
  43925             }
  43926         }
  43927 #endif /* BCM_TRX_SUPPORT */
  43928         break;
  43929     case bcmPortControlEgressModifyDscp:
  43930 #if defined(BCM_TRX_SUPPORT)
  43931         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  43932         if (SOC_IS_TRX(unit) && !SOC_IS_SHADOW(unit)) {
  43933             uint32 val;
  43934 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  43935             if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
  43936                 if (soc_feature(unit, soc_feature_egr_all_profile)) {
  43937                     rv = bcm_esw_port_egr_lport_field_get(unit,
  43938                         port, EGR_VLAN_CONTROL_1m, REMARK_OUTER_DSCPf,
  43939                         (uint32 *)value);
  43940                     *value = *value ? 1 : 0;
  43941                 } else {
  43942                 egr_vlan_control_1_entry_t entry;
  43943                 rv = READ_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, &entry);
  43944                 if (BCM_SUCCESS(rv)) {
  43945                     *value = soc_EGR_VLAN_CONTROL_1m_field32_get(unit, &entry,
  43946                                             REMARK_OUTER_DSCPf) ? 1 : 0;
  43947                 }
  43948                 }
  43949             } else
  43950 #endif
  43951             {
  43952                 rv = READ_EGR_VLAN_CONTROL_1r(unit, port, &val);
  43953                 if (BCM_SUCCESS(rv)) {
  43954                     *value = (soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r, val,
  43955                                                 REMARK_OUTER_DSCPf)) ? 1 : 0;
  43956                 }
  43957             }
  43958         }
  43959 #endif /* BCM_TRX_SUPPORT */
  43960         break;
  43961     case bcmPortControlIpfixRate:
  43962 #ifdef BCM_TRIUMPH2_SUPPORT
  43963         if (soc_feature(unit, soc_feature_ipfix_rate)) {
  43964             rv = _bcm_esw_port_tab_get(unit, port, IPFIX_FLOW_METER_IDf,
  43965                                        value);
  43966         }
  43967 #endif /* BCM_TRIUMPH2_SUPPORT */
  43968         break;
  43969     case bcmPortControlCustomerQueuing:
  43970         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  43971 #ifdef BCM_ENDURO_SUPPORT
  43972         if (SOC_IS_ENDURO(unit) && !IS_HG_PORT(unit, port)) {
  43973             return BCM_E_UNAVAIL;
  43974         }
  43975 #endif
  43976 #ifdef BCM_KATANA_SUPPORT
  43977         if (SOC_IS_KATANAX(unit)) {
  43978             uint32 rval, ing_cos_mode, rqe_cos_mode;
  43979             BCM_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, &rval));
  43980             ing_cos_mode = soc_reg_field_get(unit, ING_COS_MODEr, rval, COS_MODEf);
  43981             if (SOC_IS_KATANA(unit)) {
  43982                 SOC_IF_ERROR_RETURN(READ_RQE_PORT_CONFIGr(unit, port, &rval));
  43983                 rqe_cos_mode = soc_reg_field_get(unit, RQE_PORT_CONFIGr, rval, COS_MODEf);
  43984             } else {
  43985                 SOC_IF_ERROR_RETURN(READ_RQE_PP_PORT_CONFIGr(unit, port, &rval));
  43986                 rqe_cos_mode = soc_reg_field_get(unit, RQE_PP_PORT_CONFIGr, rval, COS_MODEf);
  43987             }
  43988             if ((ing_cos_mode != rqe_cos_mode) && (ing_cos_mode != 1)) {
  43989                 *value = 4;
  43990             } else {
  43991                 *value = ing_cos_mode;
  43992             }
  43993             rv = BCM_E_NONE;
  43994             break;
  43995         }
  43996 #endif /* BCM_KATANA_SUPPORT */
  43997 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
  43998         if ((SOC_IS_TRIDENT3X(unit)) || (SOC_IS_TOMAHAWKX(unit))) {
  43999             uint64 rval1;
  44000             if (SOC_REG_IS_VALID(unit, ING_COS_MODEr)) {
  44001                 rv = soc_reg_get(unit, ING_COS_MODEr, port, 0, &rval1);
  44002                 BCM_IF_ERROR_RETURN(rv);
  44003                 *value = soc_reg64_field32_get(unit, ING_COS_MODEr, rval1,
  44004                                                COS_MODEf);
  44005             }
  44006             break;
  44007         }
  44008 #endif /* BCM_TRIDENT3_SUPPORT || BCM_TOMAHAWK_SUPPORT */
  44009 #ifdef BCM_TRIDENT2_SUPPORT
  44010         if (SOC_IS_TD2_TT2(unit)) {
  44011             uint64 rval;
  44012             rv = READ_ING_COS_MODE_64r(unit, port, &rval);
  44013             BCM_IF_ERROR_RETURN(rv);
  44014 
  44015             if (SOC_REG_FIELD_VALID(unit, ING_COS_MODE_64r, QUEUE_MODEf)) {
  44016                 *value = soc_reg64_field32_get(unit, ING_COS_MODE_64r, rval,
  44017                                                QUEUE_MODEf);
  44018                 break;
  44019             }
  44020         }
  44021 #endif /* BCM_TRIDENT2_SUPPORT */
  44022 #ifdef BCM_TRIUMPH2_SUPPORT
  44023         if (soc_feature(unit, soc_feature_vlan_queue_map)) {
  44024             uint32 rval;
  44025             soc_field_t field;
  44026             if (SOC_REG_IS_VALID(unit, ING_COS_MODEr)) {
  44027                 rv = READ_ING_COS_MODEr(unit, port, &rval);
  44028                 if (SOC_REG_FIELD_VALID(unit, ING_COS_MODEr, SELECTf)) {
  44029                     field = SELECTf;
  44030                 } else if (SOC_REG_FIELD_VALID(unit, ING_COS_MODEr,
  44031                                                QUEUE_MODEf)) {
  44032                     field = QUEUE_MODEf;
  44033                 } else {
  44034                     rv = BCM_E_UNAVAIL;
  44035                     break;
  44036                 }
  44037                 if (SOC_IS_TRIUMPH3(unit)) {
  44038                     *value = soc_reg_field_get(unit, ING_COS_MODEr, rval, field);
  44039                 } else {
  44040                 if (soc_reg_field_get(unit, ING_COS_MODEr, rval, field)
  44041                     == 3) {
  44042                     *value = 1;
  44043                 } else {
  44044                     *value = 0;
  44045                 }
  44046             }
  44047         }
  44048         }
  44049 #endif /* BCM_TRIUMPH2_SUPPORT */
  44050         break;
  44051 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  44052 
  44053 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_APOLLO_SUPPORT)
  44054     case bcmPortControlOAMEnable:
  44055         rv = _bcm_esw_port_tab_get(unit, port, OAM_ENABLEf, value);
  44056         break;
  44057 #endif /* defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_APOLLO_SUPPORT) */
  44058 
  44059 #if defined (BCM_OLP_SUPPORT)
  44060     case bcmPortControlOlpEnable:
  44061         if (soc_feature(unit, soc_feature_olp)) {
  44062             bcm_module_t module_id = 0;
  44063             bcm_module_t my_modid;
  44064             bcm_port_t port_id;
  44065             bcm_trunk_t trunk_id = BCM_TRUNK_INVALID;
  44066             int         local_id;
  44067 
  44068             BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
  44069 
  44070             if (BCM_GPORT_IS_SET(port)) {
  44071                 SOC_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, &module_id, 
  44072                             &port_id, &trunk_id, &local_id));
  44073 
  44074 #if defined(BCM_KATANA2_SUPPORT) 
  44075                 if (SOC_IS_KATANA2(unit) && 
  44076                         (BCM_GPORT_IS_SUBPORT_PORT(port)) &&
  44077                         ((_BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) ||
  44078                          (_BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port)))) {
  44079 
  44080                     LOG_ERROR(BSL_LS_BCM_L2,
  44081                             (BSL_META_U(unit,
  44082                                         "OLP is not allowed on SUBPORT. \
  44083                                         \n")));
  44084                     return BCM_E_PARAM;
  44085                 }
  44086 #endif
  44087             } else {
  44088                 port_id = port;
  44089             }
  44090             if ((module_id == 0) || (module_id == my_modid)) {
  44091 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  44092                 if(SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) {
  44093                     iarb_ing_port_table_entry_t entry;
  44094 
  44095                     SOC_IF_ERROR_RETURN(soc_mem_read(unit, IARB_ING_PORT_TABLEm,
  44096                                         MEM_BLOCK_ANY, port_id, &entry));
  44097                     *value = soc_IARB_ING_PORT_TABLEm_field32_get(unit,
  44098                                                             &entry, OLP_ENABLEf);
  44099 
  44100                 } else 
  44101 #endif
  44102                 {
  44103                     iarb_ing_physical_port_entry_t entry;
  44104                     SOC_IF_ERROR_RETURN(soc_mem_read(unit, IARB_ING_PHYSICAL_PORTm, 
  44105                                          MEM_BLOCK_ANY, port_id, &entry));
  44106                     *value = soc_IARB_ING_PHYSICAL_PORTm_field32_get(unit, 
  44107                                                         &entry, OLP_ENABLEf);
  44108                 }
  44109             }
  44110             rv = BCM_E_NONE;
  44111         }
  44112         break;
  44113 #endif /* BCM_OLP_SUPPORT*/
  44114 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_APACHE_SUPPORT)
  44115 
  44116     case bcmPortControlPortMacOui:
  44117     case bcmPortControlPortMacNonOui:
  44118 
  44119         /*
  44120          * In case of KT2, SB2 and TD2+ NONTCAM STATION related to OAM, OLP, XGS can be programmed
  44121          * by either of bcm_l2_station_xxx API or  bcm_switch_olp_l2_addr_xxx
  44122          *
  44123          * Use either of two set of APIs
  44124          */
  44125 
  44126         if (_BCM_SWITCH_OLP_APIV(unit) == _BCM_SWITCH_OLP_L2_STATION_API) {
  44127             LOG_VERBOSE(BSL_LS_BCM_L2,
  44128                         (BSL_META_U(unit,
  44129                                     "use bcm_l2_station_xxx API\n")));
  44130             return BCM_E_UNAVAIL;
  44131         }
  44132         _BCM_SWITCH_OLP_APIV_SET(unit, _BCM_SWITCH_OLP_TRUE_API);
  44133 
  44134 #if defined(BCM_KATANA2_SUPPORT)
  44135         if (SOC_IS_KATANA2(unit) &&
  44136                  (soc_feature(unit, soc_feature_oam)  ||
  44137                   soc_feature(unit, soc_feature_sat))) {
  44138 
  44139             uint32 val_lo, val_hi;
  44140             uint64 mac_field;
  44141 
  44142             PORT_LOCK(unit);
  44143 
  44144             rv = _bcm_kt2_port_mac_get(unit, port, &mac_field);
  44145             if (BCM_FAILURE(rv)) {
  44146                 PORT_UNLOCK(unit);
  44147                 return (rv);
  44148             }
  44149             COMPILER_64_TO_32_LO(val_lo, mac_field);
  44150             COMPILER_64_TO_32_HI(val_hi, mac_field);
  44151 
  44152             switch (type) {
  44153                 case bcmPortControlPortMacOui:
  44154                     *value = 0xffffff & ((val_hi << 8) | ((val_lo >> 24) & 0xff));
  44155                     break;
  44156 
  44157                 case bcmPortControlPortMacNonOui:
  44158                     *value = (val_lo & 0xffffff);
  44159                     break;
  44160                 default:
  44161                      break;
  44162             }
  44163             PORT_UNLOCK(unit);
  44164 
  44165             rv = BCM_E_NONE;
  44166         }
  44167 #endif /* BCM_KATANA2_SUPPORT */
  44168 
  44169 #if defined(BCM_MONTEREY_SUPPORT)
  44170         if (SOC_IS_MONTEREY(unit)) {
  44171             uint32 mac;
  44172 
  44173             PORT_LOCK(unit);
  44174             rv = _bcm_monterey_port_mac_get(unit,
  44175                                           port,
  44176                                           type == bcmPortControlPortMacOui,
  44177                                           &mac);
  44178             PORT_UNLOCK(unit);
  44179 
  44180             *value = mac;
  44181         }
  44182 #endif 
  44183 #if defined(BCM_APACHE_SUPPORT)
  44184         if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
  44185             uint32 mac;
  44186 
  44187             PORT_LOCK(unit);
  44188             rv = _bcm_apache_port_mac_get(unit,
  44189                                           port,
  44190                                           type == bcmPortControlPortMacOui,
  44191                                           &mac);
  44192             PORT_UNLOCK(unit);
  44193 
  44194             *value = mac;
  44195         }
  44196 #endif /* BCM_APACHE_SUPPORT */
  44197         break;
  44198 #endif /* BCM_KATANA2_SUPPORT || BCM_APACHE_SUPPORT*/
  44199 
  44200 #ifdef BCM_TRX_SUPPORT
  44201      case bcmPortControlOamLoopback:
  44202         if (SOC_IS_TRX(unit) && !SOC_IS_HURRICANE(unit)
  44203             && !SOC_IS_SHADOW(unit))
  44204         {
  44205             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  44206             if (soc_reg_field_valid(unit,ING_MISC_PORT_CONFIGr,
  44207                                     OAM_DO_NOT_MODIFYf)) {
  44208                 uint32 reg_value;
  44209 
  44210                 rv = READ_ING_MISC_PORT_CONFIGr(unit, port, &reg_value);
  44211 
  44212                 if (SOC_SUCCESS(rv)) {
  44213                     *value = soc_reg_field_get(unit, ING_MISC_PORT_CONFIGr,
  44214                                                reg_value, OAM_DO_NOT_MODIFYf);
  44215                 }
  44216             } else {
  44217                 return BCM_E_UNAVAIL;
  44218             }
  44219         }
  44220 
  44221         break;
  44222 #endif /* BCM_TRX_SUPPORT */
  44223 
  44224     case bcmPortControlLanes:
  44225         if (soc_feature(unit, soc_feature_flexport_no_legacy)) {
  44226             return BCM_E_UNAVAIL;
  44227         }
  44228         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  44229 #if defined(BCM_TRIUMPH2_SUPPORT)
  44230         if (soc_feature(unit, soc_feature_flex_port)) {
  44231 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT
  44232             if (soc_feature(unit, soc_feature_xgs5_flexport_legacy_mode)) {
  44233                 rv = bcmi_xgs5_port_lanes_get(unit, port, value);
  44234             } else
  44235 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT */
  44236 #if defined(BCM_ENDURO_SUPPORT)
  44237             if (SOC_IS_ENDURO(unit)) {
  44238                 rv = _bcm_en_port_lanes_get(unit, port, value);
  44239             } else
  44240 #endif
  44241 #if defined(BCM_HURRICANE1_SUPPORT)
  44242             if (SOC_IS_HURRICANE(unit)) {
  44243                 rv = _bcm_hu_port_lanes_get(unit, port, value);
  44244             } else
  44245 #endif
  44246 #if defined(BCM_HURRICANE2_SUPPORT)
  44247             if (SOC_IS_HURRICANE2(unit)) {
  44248                 rv = soc_hurricane2_port_lanes_get(unit, port, value);
  44249             } else
  44250 #endif
  44251 #if defined(BCM_MONTEREY_SUPPORT)
  44252             if (SOC_IS_MONTEREY(unit)) {
  44253                 rv = bcmi_monterey_port_lanes_get(unit, port, value);
  44254             } else
  44255 #endif
  44256 #if defined(BCM_APACHE_SUPPORT)
  44257             if (SOC_IS_APACHE(unit)) {
  44258                 rv = bcmi_apache_port_lanes_get(unit, port, value);
  44259             } else
  44260 #endif
  44261 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  44262             if (SOC_IS_TD2P_TT2P(unit)) {
  44263                 rv = bcmi_td2p_port_lanes_get(unit, port, value);
  44264             } else
  44265 #endif
  44266 #if defined(BCM_TRIDENT2_SUPPORT)
  44267             if (SOC_IS_TD2_TT2(unit)) {
  44268                 rv = soc_trident2_port_lanes_get(unit, port, value);
  44269             } else
  44270 #endif /* BCM_TRIDENT2_SUPPORT */
  44271 #ifdef BCM_TRIDENT_SUPPORT
  44272             if (SOC_IS_TD_TT(unit)) {
  44273                 if (!SOC_PORT_VALID(unit, port)) {
  44274                     return BCM_E_PORT;
  44275                 }
  44276                 /* coverity[overrun-local : FALSE] */
  44277                 *value = SOC_INFO(unit).port_num_lanes[port];
  44278                 rv = BCM_E_NONE;
  44279             } else
  44280 #endif /* BCM_TRIDENT_SUPPORT */
  44281 #ifdef BCM_SHADOW_SUPPORT
  44282             if (SOC_IS_SHADOW(unit)) {
  44283                 if (!SOC_PORT_VALID(unit, port)) {
  44284                     return BCM_E_PORT;
  44285                 }
  44286                 /* coverity[overrun-local : FALSE] */
  44287                 *value = SOC_INFO(unit).port_num_lanes[port];
  44288                 rv = BCM_E_NONE;
  44289             } else
  44290 #endif /* BCM_SHADOW_SUPPORT */
  44291 #ifdef BCM_TRIUMPH3_SUPPORT
  44292             if (SOC_IS_TRIUMPH3(unit)) {
  44293                 rv = _bcm_tr3_port_lanes_get(unit, port, value);
  44294             } else
  44295 #endif /* BCM_TRIUMPH3_SUPPORT */
  44296 #ifdef BCM_METROLITE_SUPPORT
  44297             if (SOC_IS_METROLITE(unit)) {
  44298                 rv = _bcm_ml_port_lanes_get(unit, port, value);
  44299             } else
  44300 #endif /* BCM_METROLITE_SUPPORT */
  44301 #ifdef BCM_SABER2_SUPPORT
  44302             if (SOC_IS_SABER2(unit)) {
  44303                 rv = _bcm_sb2_port_lanes_get(unit, port, value);
  44304             } else
  44305 #endif /* BCM_SABER2_SUPPORT */
  44306 #ifdef BCM_KATANA2_SUPPORT
  44307             if (SOC_IS_KATANA2(unit)) {
  44308                 rv = _bcm_kt2_port_lanes_get(unit, port, value);
  44309             } else
  44310 #endif /* BCM_KATANA2_SUPPORT */
  44311             {
  44312                 rv = _bcm_tr2_port_lanes_get(unit, port, value);
  44313             }
  44314         }
  44315 #endif
  44316         break;
  44317     case bcmPortControlPFCEthertype:
  44318 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  44319         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  44320             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  44321             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  44322                 /* IS_GX_PORT == IS_XL_PORT */
  44323                 return BCM_E_PORT;
  44324             }
  44325             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  44326                                  SOC_MAC_CONTROL_PFC_TYPE, value);
  44327         }
  44328 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  44329           break;
  44330     case bcmPortControlPFCOpcode:
  44331 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  44332         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  44333             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  44334             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  44335                 /* IS_GX_PORT == IS_XL_PORT */
  44336                 return BCM_E_PORT;
  44337             }
  44338             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  44339                                  SOC_MAC_CONTROL_PFC_OPCODE, value);
  44340         }
  44341 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  44342           break;
  44343     case bcmPortControlPFCReceive:
  44344 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  44345         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  44346             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  44347             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  44348                 /* IS_GX_PORT == IS_XL_PORT */
  44349                 return BCM_E_PORT;
  44350             }
  44351             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  44352                                  SOC_MAC_CONTROL_PFC_RX_ENABLE, value);
  44353         }
  44354 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  44355           break;
  44356     case bcmPortControlPFCTransmit:
  44357 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  44358         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  44359             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  44360             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  44361                 /* IS_GX_PORT == IS_XL_PORT */
  44362                 return BCM_E_PORT;
  44363             }
  44364             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  44365                                  SOC_MAC_CONTROL_PFC_TX_ENABLE, value);
  44366         }
  44367 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  44368           break;
  44369     case bcmPortControlPFCClasses:
  44370 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  44371         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  44372             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  44373             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  44374                 /* IS_GX_PORT == IS_XL_PORT */
  44375                 return BCM_E_PORT;
  44376             }
  44377             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  44378                                  SOC_MAC_CONTROL_PFC_CLASSES, value);
  44379         }
  44380 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  44381         break;
  44382     case bcmPortControlPFCPassFrames:
  44383 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  44384         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  44385             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  44386             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  44387                 /* IS_GX_PORT == IS_XL_PORT */
  44388                 return BCM_E_PORT;
  44389             }
  44390 
  44391             if(soc_feature(unit, soc_feature_pgw_mac_pfc_frame)) {
  44392                 uint32 rval32 = 0;
  44393                 soc_reg_t reg = INVALIDr;
  44394                 if(SOC_REG_IS_VALID(unit, PGW_MAC_RSV_MASKr)) {
  44395                     reg = PGW_MAC_RSV_MASKr;
  44396                 } else if(IS_CL_PORT(unit, port) &&
  44397                           SOC_REG_IS_VALID(unit, CLPORT_MAC_RSV_MASKr)) {
  44398                     reg = CLPORT_MAC_RSV_MASKr;
  44399                 } else if(IS_XL_PORT(unit, port) &&
  44400                           SOC_REG_IS_VALID(unit, XLPORT_MAC_RSV_MASKr)) {
  44401                     reg = XLPORT_MAC_RSV_MASKr;
  44402                 } else {
  44403                     reg = INVALIDr;
  44404                 }
  44405 
  44406                 if (reg != INVALIDr) {
  44407                     rv = soc_reg32_get(unit, reg, port, 0, &rval32);
  44408                 if (BCM_SUCCESS(rv)) {
  44409                         /* xxx_MAC_RSV_MASK: Bit 18 PFC frame detected
  44410                      * the bit value needs to be reversed
  44411                      */
  44412                     *value = ((rval32 & 0x40000) >> 18) ? 0 : 1 ;
  44413                 }
  44414             } else {
  44415                     rv = BCM_E_UNAVAIL;
  44416                 }
  44417             } else {
  44418                 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  44419                                      SOC_MAC_CONTROL_PFC_RX_PASS, value);
  44420             }
  44421         }
  44422 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  44423         break;
  44424 
  44425     case bcmPortControlPFCDestMacOui:
  44426 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  44427         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  44428             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  44429             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  44430                 /* IS_GX_PORT == IS_XL_PORT */
  44431                 return BCM_E_PORT;
  44432             }
  44433             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  44434                                  SOC_MAC_CONTROL_PFC_MAC_DA_OUI, value);
  44435         }
  44436 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  44437         break;
  44438 
  44439     case bcmPortControlPFCDestMacNonOui:
  44440 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT)
  44441         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  44442             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  44443             if (chk_gx_port && !IS_GX_PORT(unit, port)) {
  44444                 /* IS_GX_PORT == IS_XL_PORT */
  44445                 return BCM_E_PORT;
  44446             }
  44447             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  44448                                  SOC_MAC_CONTROL_PFC_MAC_DA_NONOUI, value);
  44449         }
  44450 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */
  44451         break;
  44452 
  44453     case bcmPortControlPFCRefreshTime:
  44454 #if defined(BCM_TRIDENT_SUPPORT)|defined(BCM_GREYHOUND_SUPPORT)
  44455         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  44456             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  44457             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  44458                                  SOC_MAC_CONTROL_PFC_REFRESH_TIME, value);
  44459         }
  44460 #endif /* BCM_TRIDENT_SUPPORT */
  44461         break;
  44462 
  44463     case bcmPortControlPFCXOffTime:
  44464 #if defined(BCM_TRIDENT_SUPPORT)||defined(BCM_GREYHOUND_SUPPORT)
  44465         if (soc_feature(unit, soc_feature_priority_flow_control)) {
  44466             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  44467             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  44468                                  SOC_MAC_CONTROL_PFC_XOFF_TIME, value);
  44469         }
  44470 #endif /* BCM_TRIDENT_SUPPORT */
  44471         break;
  44472 
  44473     case bcmPortControlVrf:
  44474         rv = _bcm_esw_port_vrf_get(unit, port, value);
  44475           break;
  44476 
  44477     case bcmPortControlL3Ingress:
  44478 #if defined(BCM_TRIUMPH_SUPPORT)
  44479         {
  44480             if (!soc_feature(unit, soc_feature_l3_ingress_interface)) {
  44481                 return BCM_E_UNAVAIL;
  44482             }
  44483 
  44484             *value = 0;
  44485             if (soc_mem_field_valid(unit, PORT_TABm, PORT_OPERATIONf) ||
  44486                 SOC_IS_TRIDENT3X(unit)) {
  44487                 rv = _bcm_esw_port_tab_get(unit, port, PORT_OPERATIONf, value);
  44488                 BCM_IF_ERROR_RETURN(rv);
  44489                 if ((*value == 0x2) &&
  44490                     (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm,
  44491                                          L3_IIFf)) ) {
  44492 #if defined(BCM_KATANA2_SUPPORT)
  44493                     if (SOC_IS_KATANA2(unit)) {
  44494                         rv = _bcm_kt2_source_trunk_map_get(unit, port, L3_IIFf,
  44495                                                        (uint32 *)value);
  44496                     } else
  44497 #endif
  44498                     {
  44499                         rv = _bcm_trx_source_trunk_map_get(unit, port, L3_IIFf,
  44500                                                        (uint32 *)value);
  44501                     }
  44502                 }
  44503             }
  44504         }
  44505 #endif  /* BCM_TRIUMPH_SUPPORT */
  44506         break;
  44507 
  44508     case bcmPortControlL2Learn:
  44509 #if defined(BCM_TRX_SUPPORT)
  44510         if (SOC_IS_TRX(unit)) {
  44511             bcm_port_cfg_t port_cfg;
  44512 
  44513             rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &port_cfg);
  44514             if (BCM_SUCCESS(rv)) {
  44515                 rv = _bcm_trx_port_cml_hw2flags(unit, port_cfg.pc_cml,
  44516                                                 (uint32 *)value);
  44517             }
  44518         }
  44519 #endif /* BCM_TRX_SUPPORT */
  44520         break;
  44521 
  44522     case bcmPortControlL2Move:
  44523 #if defined(BCM_TRX_SUPPORT)
  44524         if (SOC_IS_TRX(unit)) {
  44525             bcm_port_cfg_t port_cfg;
  44526 
  44527             rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &port_cfg);
  44528             if (BCM_SUCCESS(rv)) {
  44529                 rv = _bcm_trx_port_cml_hw2flags(unit, port_cfg.pc_cml_move,
  44530                                                 (uint32 *)value);
  44531             }
  44532         }
  44533 #endif /* BCM_TRX_SUPPORT */
  44534           break;
  44535 
  44536     case bcmPortControlForwardStaticL2MovePkt:
  44537 #if defined(BCM_TRX_SUPPORT)
  44538          rv = _bcm_esw_port_tab_get(unit, port, DISABLE_STATIC_MOVE_DROPf,
  44539                                     value);
  44540 #endif /* BCM_TRX_SUPPORT */
  44541          break;
  44542 
  44543     case bcmPortControlPrbsRxStatus:
  44544         PORT_LOCK(unit);
  44545         rv = soc_phyctrl_control_get(unit, port,
  44546                                      SOC_PHY_CONTROL_PRBS_RX_STATUS,
  44547                                      (uint32 *)value);
  44548         PORT_UNLOCK(unit);
  44549         break;
  44550     case bcmPortControlLinkFaultLocalEnable:
  44551         rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  44552                              SOC_MAC_CONTROL_FAULT_LOCAL_ENABLE, value);
  44553         break;
  44554     case bcmPortControlLinkFaultRemoteEnable:
  44555         rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  44556                              SOC_MAC_CONTROL_FAULT_REMOTE_ENABLE, value);
  44557         break;
  44558     case bcmPortControlLinkFaultLocal:
  44559         rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  44560                              SOC_MAC_CONTROL_FAULT_LOCAL_STATUS, value);
  44561         break;
  44562     case bcmPortControlLinkFaultRemote:
  44563         rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  44564                              SOC_MAC_CONTROL_FAULT_REMOTE_STATUS, value);
  44565         break;
  44566     case bcmPortControlTimestampTransmit:
  44567 #if defined(BCM_TIMESYNC_SUPPORT)
  44568         if (soc_feature(unit, soc_feature_timesync_support)) {
  44569             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  44570                                  SOC_MAC_CONTROL_TIMESTAMP_TRANSMIT, value);
  44571         } else
  44572 #endif  /* BCM_TIMESYNC_SUPPORT */
  44573         {
  44574             return BCM_E_UNAVAIL;
  44575         }
  44576         break;
  44577     case bcmPortControlTimestampEnable:
  44578 #if defined(BCM_HAWKEYE_SUPPORT)
  44579         if (SOC_IS_HAWKEYE(unit)) {
  44580             uint32 rval;
  44581             if (!SOC_PORT_VALID(unit, port)) {
  44582                 return BCM_E_PORT;
  44583             }
  44584             SOC_IF_ERROR_RETURN(READ_EAV_ENABLE_BMAPr(unit, &rval));
  44585             if ( port < 32 ) {
  44586                 *value = (rval & (1 << port)) ? TRUE:FALSE;
  44587             } else {
  44588                 *value = FALSE;
  44589             }
  44590             rv = BCM_E_NONE;
  44591         } else
  44592 #endif /* BCM_HAWKEYE_SUPPORT */
  44593         if (soc_feature (unit, soc_feature_xlmac_timestamp_disable)) {
  44594             if (IS_XL_PORT(unit, port)) {
  44595                 int tmp;
  44596                 uint32 rval;
  44597                 SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit,
  44598                                                              port, &rval));
  44599                 tmp = soc_reg_field_get(unit, XLPORT_MAC_CONTROLr,
  44600                                         rval, XLMAC_TS_DISABLEf);
  44601                 if (tmp) {
  44602                     *value = FALSE;
  44603                 } else {
  44604                     *value = TRUE;
  44605                 }
  44606                 rv = BCM_E_NONE;
  44607             }
  44608         }
  44609         break;
  44610     case bcmPortControlSerdesDriverEqualizationTuneStatusFarEnd:
  44611         PORT_LOCK(unit);
  44612         rv = soc_phyctrl_control_get(unit, port,
  44613              SOC_PHY_CONTROL_SERDES_DRIVER_EQUALIZATION_TUNE_STATUS_FAR_END,
  44614                                      (uint32 *)value);
  44615         PORT_UNLOCK(unit);
  44616         break;
  44617     case bcmPortControlLinkdownTransmit:
  44618         PORT_LOCK(unit);
  44619         rv = soc_phyctrl_control_get(unit, port,
  44620                                      SOC_PHY_CONTROL_LINKDOWN_TRANSMIT,
  44621                                      (uint32 *)value);
  44622         PORT_UNLOCK(unit);
  44623         /* Most of PHYs have nothing to configure and simply return UNAVAIL*/
  44624         if ((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL)) {
  44625             rv = _bcm_esw_link_down_tx_get(unit, port, value);
  44626         }
  44627         break;
  44628     case bcmPortControlSerdesTuneMarginMode:
  44629         PORT_LOCK(unit);
  44630         rv = soc_phyctrl_control_get(unit, port,
  44631                                      SOC_PHY_CONTROL_SERDES_TUNE_MARGIN_MODE,
  44632                                      (uint32 *)value);
  44633         PORT_UNLOCK(unit);
  44634         break;
  44635     case bcmPortControlSerdesTuneMarginValue:
  44636         PORT_LOCK(unit);
  44637         rv = soc_phyctrl_control_get(unit, port,
  44638                                      SOC_PHY_CONTROL_SERDES_TUNE_MARGIN_VALUE,
  44639                                      (uint32 *)value);
  44640         PORT_UNLOCK(unit);
  44641         break;
  44642     case bcmPortControlSerdesTuneMarginMax:
  44643         PORT_LOCK(unit);
  44644         rv = soc_phyctrl_control_get(unit, port,
  44645                                      SOC_PHY_CONTROL_SERDES_TUNE_MARGIN_MAX,
  44646                                      (uint32 *)value);
  44647         PORT_UNLOCK(unit);
  44648         break;
  44649     case bcmPortControlStatOversize:
  44650         rv = _bcm_esw_stat_ovr_threshold_get(unit, port, value);
  44651         break;
  44652 
  44653     case bcmPortControlStatOversizeIsError:
  44654         rv = _bcm_esw_stat_ovr_error_control_get(unit, port, value);
  44655         break;
  44656 
  44657     case bcmPortControlEEEEnable:
  44658         if (!SOC_PORT_VALID(unit, port)) {
  44659             return BCM_E_PORT;
  44660         }
  44661 
  44662         PORT_LOCK(unit);
  44663 
  44664 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \
  44665         || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \
  44666         || defined(BCM_HURRICANE2_SUPPORT)
  44667 
  44668         if (soc_feature(unit, soc_feature_eee)) {
  44669             *value = eee_cfg[unit][port];
  44670             rv = BCM_E_NONE;
  44671         } else
  44672 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPORT ||
  44673           BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */
  44674 
  44675         {
  44676             uint32 eeenative, eeeauto;
  44677             int rv1 = BCM_E_UNAVAIL, rv2 = BCM_E_UNAVAIL;
  44678 
  44679             rv = BCM_E_NONE;
  44680 
  44681             if ((rv1 = soc_phyctrl_control_get(unit, port,
  44682                             BCM_PORT_PHY_CONTROL_EEE, &eeenative)) !=
  44683                 SOC_E_UNAVAIL) {
  44684                 *value = eeenative;
  44685             }
  44686 
  44687             if ((rv2 = soc_phyctrl_control_get(unit, port,
  44688                             BCM_PORT_PHY_CONTROL_EEE_AUTO, &eeeauto)) !=
  44689                 SOC_E_UNAVAIL) {
  44690                 *value = eeeauto;
  44691             }
  44692 
  44693             /* If neither Native EEE nor AutoGrEEEn mode is supported */
  44694             if ((rv1 == SOC_E_UNAVAIL) && (rv2 == SOC_E_UNAVAIL)) {
  44695                 rv = BCM_E_UNAVAIL;
  44696             }
  44697 
  44698             /* If both Native EEE and AutoGrEEEn mode are supported */
  44699             if ((rv1 != SOC_E_UNAVAIL) && (rv2 != SOC_E_UNAVAIL)) {
  44700                 *value = eeenative ? (eeeauto ? 0 : 1) : (eeeauto ? 1 : 0);
  44701             }
  44702         }
  44703 
  44704         PORT_UNLOCK (unit);
  44705 
  44706         break;
  44707 
  44708  /**********************      EEE Mode Overview    ************************
  44709  *                      |DET|                              |  WT |
  44710  *   Signalling   |idles|   |------------------------------|     | idles   |
  44711  *   from Tx MAC  | or  |   |   Low Power Idle (LPI)       |idles|  or     |
  44712  *   to local PHY |data |   |------------------------------|     | data    |
  44713  *                          *                              *
  44714  *                          *                              *
  44715  *                          *  -------LPI state------------*
  44716  *   Local PHY    |         |  |      |  |       |  |      |   |           |
  44717  *   signaling    |   Active|Ts|  Tq  |Tr|  Tq   |Tr|  Tq  |Tw |Active     |
  44718  *   on MDI       |         |  |      |  |       |  |      |   |           |
  44719  *                          *------------------------------*
  44720  *                          *                              *
  44721  *                          *                               *
  44722  *   Signaling    |   idles |-------------------------------|id| PHY is    |
  44723  *   from LP PHY  |     or  |  Low Power Idle (LPI)         |le| ready     |
  44724  *   to Rx MAC    |   data  |-------------------------------|s | for data  |
  44725  *
  44726  *   where DET = Delay Entry Timer    WT = MAC Wake Timer
  44727  */
  44728     case bcmPortControlEEETransmitIdleTime:
  44729         /* DET = Time (in microsecs) for which condition to move to LPI state
  44730          * is satisfied, at the end of which MAC TX transitions to LPI state */
  44731         if (!SOC_PORT_VALID(unit, port)) {
  44732             return BCM_E_PORT;
  44733         }
  44734 
  44735         PORT_LOCK(unit);
  44736 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \
  44737         || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \
  44738         || defined(BCM_HURRICANE2_SUPPORT)
  44739         if (soc_feature (unit, soc_feature_eee)) {
  44740             rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  44741                     SOC_MAC_CONTROL_EEE_TX_IDLE_TIME, value);
  44742         } else
  44743 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT ||
  44744           BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */
  44745         {
  44746             rv = BCM_E_UNAVAIL;
  44747         }
  44748         PORT_UNLOCK(unit);
  44749         break;
  44750 
  44751     case bcmPortControlEEETransmitEventCount:
  44752         /* Number of time MAC TX enters LPI state for
  44753          * a given measurement interval*/
  44754         if (!SOC_PORT_VALID(unit, port)) {
  44755             return BCM_E_PORT;
  44756         }
  44757 
  44758         PORT_LOCK(unit);
  44759 
  44760 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \
  44761         || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \
  44762         || defined(BCM_HURRICANE2_SUPPORT)
  44763         if (soc_feature(unit, soc_feature_eee)) {
  44764             int mac_val;
  44765             uint32 phy_val;
  44766             uint64 rval64, rval64_2nd;
  44767             soc_reg_t reg, reg_2nd = INVALIDr;
  44768 
  44769             COMPILER_64_ZERO(rval64);
  44770             COMPILER_64_ZERO(rval64_2nd);
  44771 
  44772             if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  44773                      SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) != SOC_E_UNAVAIL) &&
  44774                 (soc_phyctrl_control_get(unit, port,
  44775                      BCM_PORT_PHY_CONTROL_EEE, &phy_val) != SOC_E_UNAVAIL)) {
  44776                 /* If MAC/Switch is EEE aware (Native EEE mode is supported)
  44777                  * and PHY also supports Native mode
  44778                  */
  44779 
  44780                 /* On Katana TX/RX register are swapped */
  44781                 reg = (SOC_IS_KATANAX(unit)) ? RX_EEE_LPI_EVENT_COUNTERr :
  44782                       ((SOC_IS_HURRICANE2(unit) && IS_GE_PORT(unit, port)) ?
  44783                       GTX_EEE_LPI_EVENT_COUNTERr :
  44784                       TX_EEE_LPI_EVENT_COUNTERr);
  44785                 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) {
  44786                     if (IS_XL_PORT(unit, port)){
  44787                         reg = TX_EEE_LPI_EVENT_COUNTERr;
  44788                     } else {
  44789                         reg = GTX_EEE_LPI_EVENT_COUNTERr;
  44790                     }
  44791                 } else if (SOC_IS_GREYHOUND2(unit)) {
  44792                     if (IS_CL_PORT(unit, port)){
  44793                         reg = CLMIB_TX_EEE_LPI_EVENT_COUNTERr;
  44794                     } else if (IS_XL_PORT(unit, port)) {
  44795                         reg = XLMIB_TX_EEE_LPI_EVENT_COUNTERr;
  44796                         reg_2nd = XLPMIB_TX_EEE_LPI_EVENT_COUNTERr;
  44797                     } else {
  44798                         reg = GTX_EEE_LPI_EVENT_COUNTERr;
  44799                     }
  44800                 }
  44801 
  44802                 rv = soc_reg_get(unit, reg, port, 0, &rval64);
  44803 
  44804                 if (BCM_SUCCESS(rv)) {
  44805                     *value = COMPILER_64_LO(rval64);
  44806                 }
  44807 
  44808                 if (SOC_REG_IS_VALID(unit, reg_2nd)) {
  44809                     rv = soc_reg_get(unit, reg_2nd, port, 0, &rval64_2nd);
  44810     
  44811                     if (BCM_SUCCESS(rv)) {
  44812                         *value += COMPILER_64_LO(rval64_2nd);
  44813                     }
  44814                 }
  44815             } else {
  44816                 /* Get counter value from PHY. If PHY does not support
  44817                  * EEE counters, rv will be assigned SOC_E_UNAVAIL.
  44818                  */
  44819                 rv = soc_phyctrl_control_get(unit, port,
  44820                         BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_EVENTS, &phy_val);
  44821                 if (SOC_SUCCESS(rv)) {
  44822                     *value = phy_val;
  44823                 }
  44824             }
  44825         } else
  44826 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT ||
  44827           BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */
  44828 
  44829         {
  44830             /* On legacy devices that don't support native EEE,
  44831              * get counter value from PHY. If PHY does not support
  44832              * EEE counters, rv will be assigned SOC_E_UNAVAIL.
  44833              */
  44834             uint32 phy_val;
  44835             rv = soc_phyctrl_control_get(unit, port,
  44836                     BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_EVENTS, &phy_val);
  44837             if (SOC_SUCCESS(rv)) {
  44838                 *value = phy_val;
  44839             }
  44840         }
  44841 
  44842         PORT_UNLOCK (unit);
  44843 
  44844         break;
  44845 
  44846     case bcmPortControlEEETransmitDuration:
  44847         /* Time in (microsecs) for which MAC TX enters LPI state
  44848          * during a measurement interval*/
  44849         if (!SOC_PORT_VALID(unit, port)) {
  44850             return BCM_E_PORT;
  44851         }
  44852 
  44853         PORT_LOCK(unit);
  44854 
  44855 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \
  44856         || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \
  44857         || defined(BCM_HURRICANE2_SUPPORT)
  44858         if (soc_feature(unit, soc_feature_eee)) {
  44859             int mac_val;
  44860             uint32 phy_val;
  44861             uint64 rval64, rval64_2nd;
  44862             soc_reg_t reg, reg_2nd = INVALIDr;
  44863 
  44864             COMPILER_64_ZERO(rval64);
  44865             COMPILER_64_ZERO(rval64_2nd);
  44866 
  44867             if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  44868                      SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) != SOC_E_UNAVAIL) &&
  44869                 (soc_phyctrl_control_get(unit, port,
  44870                      BCM_PORT_PHY_CONTROL_EEE, &phy_val) != SOC_E_UNAVAIL)) {
  44871                 /* If MAC/Switch is EEE aware (Native EEE mode is supported)
  44872                  * and PHY also supports Native mode
  44873                  */
  44874                 /* On Katana TX/RX register are swapped */
  44875                 reg = (SOC_IS_KATANAX(unit)) ? RX_EEE_LPI_DURATION_COUNTERr :
  44876                       ((SOC_IS_HURRICANE2(unit) && IS_GE_PORT(unit, port)) ?
  44877                       GTX_EEE_LPI_DURATION_COUNTERr :
  44878                       TX_EEE_LPI_DURATION_COUNTERr);
  44879                 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) {
  44880                     if (IS_XL_PORT(unit, port)) {
  44881                         reg = TX_EEE_LPI_DURATION_COUNTERr;
  44882                     } else {
  44883                         reg = GTX_EEE_LPI_DURATION_COUNTERr;
  44884                     }
  44885                 } else if (SOC_IS_GREYHOUND2(unit)) {
  44886                     if (IS_CL_PORT(unit, port)){
  44887                         reg = CLMIB_TX_EEE_LPI_DURATION_COUNTERr;
  44888                     } else if (IS_XL_PORT(unit, port)) {
  44889                         reg = XLMIB_TX_EEE_LPI_DURATION_COUNTERr;
  44890                         reg_2nd = XLPMIB_TX_EEE_LPI_DURATION_COUNTERr;
  44891                     } else {
  44892                         reg = GTX_EEE_LPI_DURATION_COUNTERr;
  44893                     }
  44894                 }
  44895 
  44896                 rv = soc_reg_get(unit, reg, port, 0, &rval64);
  44897 
  44898                 if (BCM_SUCCESS(rv)) {
  44899                     *value = COMPILER_64_LO(rval64);
  44900                 }
  44901 
  44902                 if (SOC_REG_IS_VALID(unit, reg_2nd)) {
  44903                     rv = soc_reg_get(unit, reg_2nd, port, 0, &rval64_2nd);
  44904                     if (BCM_SUCCESS(rv)) {
  44905                         /* add the 2nd register */
  44906                         *value += COMPILER_64_LO(rval64_2nd);
  44907                     }
  44908                 }
  44909             } else {
  44910                 /* Get counter value from PHY. If PHY does not support
  44911                  * EEE counters, rv will be assigned SOC_E_UNAVAIL.
  44912                  */
  44913                 rv = soc_phyctrl_control_get(unit, port,
  44914                         BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_DURATION, &phy_val);
  44915                 if (SOC_SUCCESS(rv)) {
  44916                     *value = phy_val;
  44917                 }
  44918             }
  44919         } else
  44920 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT ||
  44921           BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */
  44922         {
  44923             /* On legacy devices that don't support native EEE,
  44924              * get counter value from PHY. If PHY does not support
  44925              * EEE counters, rv will be assigned SOC_E_UNAVAIL.
  44926              */
  44927             uint32 phy_val;
  44928             rv = soc_phyctrl_control_get(unit, port,
  44929                     BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_DURATION, &phy_val);
  44930             if (SOC_SUCCESS(rv)) {
  44931                 *value = phy_val;
  44932             }
  44933         }
  44934 
  44935         PORT_UNLOCK (unit);
  44936         break;
  44937 
  44938     case bcmPortControlEEEReceiveEventCount:
  44939         /* Number of time MAC RX enters LPI state for
  44940          * a given measurement interval */
  44941         if (!SOC_PORT_VALID(unit, port)) {
  44942             return BCM_E_PORT;
  44943         }
  44944 
  44945         PORT_LOCK(unit);
  44946 
  44947 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \
  44948         || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \
  44949         || defined(BCM_HURRICANE2_SUPPORT)
  44950         if (soc_feature(unit, soc_feature_eee)) {
  44951             int mac_val;
  44952             uint32 phy_val;
  44953             uint64 rval64, rval64_2nd;
  44954             soc_reg_t reg, reg_2nd = INVALIDr;
  44955 
  44956             COMPILER_64_ZERO(rval64);
  44957             COMPILER_64_ZERO(rval64_2nd);
  44958 
  44959             if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  44960                      SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) != SOC_E_UNAVAIL) &&
  44961                 (soc_phyctrl_control_get(unit, port,
  44962                      BCM_PORT_PHY_CONTROL_EEE, &phy_val) != SOC_E_UNAVAIL)) {
  44963                 /* If MAC/Switch is EEE aware (Native EEE mode is supported)
  44964                  * and PHY also supports Native mode
  44965                  */
  44966                 /* On Katana TX/RX register are swapped */
  44967                 reg = (SOC_IS_KATANAX(unit)) ? TX_EEE_LPI_EVENT_COUNTERr :
  44968                       ((SOC_IS_HURRICANE2(unit) && IS_GE_PORT(unit, port)) ?
  44969                       GRX_EEE_LPI_EVENT_COUNTERr :
  44970                       RX_EEE_LPI_EVENT_COUNTERr);
  44971                 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) {
  44972                     if (IS_XL_PORT(unit, port)) {
  44973                         reg = RX_EEE_LPI_EVENT_COUNTERr;
  44974                     } else {
  44975                         reg = GRX_EEE_LPI_EVENT_COUNTERr;
  44976                     }
  44977                 } else if (SOC_IS_GREYHOUND2(unit)) {
  44978                     if (IS_CL_PORT(unit, port)){
  44979                         reg = CLMIB_RX_EEE_LPI_EVENT_COUNTERr;
  44980                     } else if (IS_XL_PORT(unit, port)) {
  44981                         reg = XLMIB_RX_EEE_LPI_EVENT_COUNTERr;
  44982                         reg_2nd = XLPMIB_RX_EEE_LPI_EVENT_COUNTERr;
  44983                     } else {
  44984                         reg = GRX_EEE_LPI_EVENT_COUNTERr;
  44985                     }
  44986                 }
  44987 
  44988                 rv = soc_reg_get(unit, reg, port, 0, &rval64);
  44989 
  44990                 if (BCM_SUCCESS(rv)) {
  44991                     *value = COMPILER_64_LO(rval64);
  44992                 }
  44993 
  44994                 if (SOC_REG_IS_VALID(unit, reg_2nd)) {
  44995                     rv = soc_reg_get(unit, reg_2nd, port, 0, &rval64_2nd);
  44996                     if (BCM_SUCCESS(rv)) {
  44997                         /* add the 2nd register */
  44998                         *value += COMPILER_64_LO(rval64_2nd);
  44999                     }
  45000                 }
  45001             } else {
  45002                 /* Get counter value from PHY. If PHY does not support
  45003                  * EEE counters, rv will be assigned SOC_E_UNAVAIL.
  45004                  */
  45005                 rv = soc_phyctrl_control_get(unit, port,
  45006                         BCM_PORT_PHY_CONTROL_EEE_RECEIVE_EVENTS, &phy_val);
  45007                 if (SOC_SUCCESS(rv)) {
  45008                     *value = phy_val;
  45009                 }
  45010             }
  45011         } else
  45012 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT ||
  45013           BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */
  45014         {
  45015             /* On legacy devices that don't support native EEE,
  45016              * get counter value from PHY. If PHY does not support
  45017              * EEE counters, rv will be assigned SOC_E_UNAVAIL.
  45018              */
  45019             uint32 phy_val;
  45020             rv = soc_phyctrl_control_get(unit, port,
  45021                     BCM_PORT_PHY_CONTROL_EEE_RECEIVE_EVENTS, &phy_val);
  45022             if (SOC_SUCCESS(rv)) {
  45023                 *value = phy_val;
  45024             }
  45025         }
  45026 
  45027         PORT_UNLOCK (unit);
  45028         break;
  45029 
  45030     case bcmPortControlEEEReceiveDuration:
  45031         /* Time in (microsecs) for which MAC RX enters LPI state
  45032          * during a measurement interval*/
  45033         if (!SOC_PORT_VALID(unit, port)) {
  45034             return BCM_E_PORT;
  45035         }
  45036         if (!IS_E_PORT(unit, port)) {
  45037             return BCM_E_UNAVAIL;
  45038         }
  45039 
  45040         PORT_LOCK(unit);
  45041 
  45042 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \
  45043         || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT)
  45044         if (soc_feature(unit, soc_feature_eee)) {
  45045             int mac_val;
  45046             uint32 phy_val;
  45047             uint64 rval64, rval64_2nd;
  45048             soc_reg_t reg, reg_2nd = INVALIDr;
  45049 
  45050             COMPILER_64_ZERO(rval64);
  45051             COMPILER_64_ZERO(rval64_2nd);
  45052 
  45053             if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  45054                      SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) != SOC_E_UNAVAIL) &&
  45055                 (soc_phyctrl_control_get(unit, port,
  45056                      BCM_PORT_PHY_CONTROL_EEE, &phy_val) != SOC_E_UNAVAIL)) {
  45057                 /* If MAC/Switch is EEE aware (Native EEE mode is supported)
  45058                  * and PHY also supports Native mode
  45059                  */
  45060                 /* On Katana TX/RX register are swapped */
  45061                 reg = (SOC_IS_KATANAX(unit)) ? TX_EEE_LPI_DURATION_COUNTERr :
  45062                       ((SOC_IS_HURRICANE2(unit) && IS_GE_PORT(unit, port)) ?
  45063                       GRX_EEE_LPI_DURATION_COUNTERr :
  45064                       RX_EEE_LPI_DURATION_COUNTERr);
  45065                 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) {
  45066                     if (IS_XL_PORT(unit, port)) {
  45067                         reg = RX_EEE_LPI_DURATION_COUNTERr;
  45068                     } else {
  45069                         reg = GRX_EEE_LPI_DURATION_COUNTERr;
  45070                     }
  45071                 } else if (SOC_IS_GREYHOUND2(unit)) {
  45072                     if (IS_CL_PORT(unit, port)){
  45073                         reg = CLMIB_RX_EEE_LPI_DURATION_COUNTERr;
  45074                     } else if (IS_XL_PORT(unit, port)) {
  45075                         reg = XLMIB_RX_EEE_LPI_DURATION_COUNTERr;
  45076                         reg_2nd = XLPMIB_RX_EEE_LPI_DURATION_COUNTERr;
  45077                     } else {
  45078                         reg = GRX_EEE_LPI_DURATION_COUNTERr;
  45079                     }
  45080                 }
  45081 
  45082                 rv = soc_reg_get(unit, reg, port, 0, &rval64);
  45083 
  45084                 if (BCM_SUCCESS(rv)) {
  45085                     *value = COMPILER_64_LO(rval64);
  45086                 }
  45087 
  45088                 if (SOC_REG_IS_VALID(unit, reg_2nd)) {
  45089                     rv = soc_reg_get(unit, reg_2nd, port, 0, &rval64_2nd);
  45090                     if (BCM_SUCCESS(rv)) {
  45091                         /* add the 2nd register */
  45092                         *value += COMPILER_64_LO(rval64_2nd);
  45093                     }
  45094                 }
  45095             } else {
  45096                 /* Get counter value from PHY. If PHY does not support
  45097                  * EEE counters, rv will be assigned SOC_E_UNAVAIL.
  45098                  */
  45099                 rv = soc_phyctrl_control_get(unit, port,
  45100                         BCM_PORT_PHY_CONTROL_EEE_RECEIVE_DURATION, &phy_val);
  45101                 if (SOC_SUCCESS(rv)) {
  45102                     *value = phy_val;
  45103                 }
  45104             }
  45105         } else
  45106 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT ||
  45107           BCM_TRIDENT_SUPPORT */
  45108         {
  45109             /* On legacy devices that don't support native EEE,
  45110              * get counter value from PHY. If PHY does not support
  45111              * EEE counters, rv will be assigned SOC_E_UNAVAIL.
  45112              */
  45113             uint32 phy_val;
  45114             rv = soc_phyctrl_control_get(unit, port,
  45115                     BCM_PORT_PHY_CONTROL_EEE_RECEIVE_DURATION, &phy_val);
  45116             if (SOC_SUCCESS(rv)) {
  45117                 *value = phy_val;
  45118             }
  45119         }
  45120 
  45121         PORT_UNLOCK (unit);
  45122         break;
  45123 
  45124     case bcmPortControlEEETransmitRefreshTime:
  45125         if (!SOC_PORT_VALID(unit, port)) {
  45126             return BCM_E_PORT;
  45127         }
  45128         if (!IS_E_PORT(unit, port)) {
  45129             return BCM_E_UNAVAIL;
  45130         }
  45131         PORT_LOCK(unit);
  45132         rv = soc_phyctrl_control_get(unit, port,
  45133                 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_REFRESH_TIME,
  45134                                      (uint32 *)value);
  45135         PORT_UNLOCK (unit);
  45136         break;
  45137 
  45138     case bcmPortControlEEETransmitSleepTime:
  45139         if (!SOC_PORT_VALID(unit, port)) {
  45140             return BCM_E_PORT;
  45141         }
  45142         if (!IS_E_PORT(unit, port)) {
  45143             return BCM_E_UNAVAIL;
  45144         }
  45145         PORT_LOCK(unit);
  45146         rv = soc_phyctrl_control_get(unit, port,
  45147                 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_SLEEP_TIME, (uint32 *)value);
  45148         PORT_UNLOCK (unit);
  45149         break;
  45150 
  45151     case bcmPortControlEEETransmitQuietTime:
  45152         if (!SOC_PORT_VALID(unit, port)) {
  45153             return BCM_E_PORT;
  45154         }
  45155         if (!IS_E_PORT(unit, port)) {
  45156             return BCM_E_UNAVAIL;
  45157         }
  45158         PORT_LOCK(unit);
  45159         rv = soc_phyctrl_control_get(unit, port,
  45160                 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_QUIET_TIME, (uint32 *)value);
  45161         PORT_UNLOCK (unit);
  45162         break;
  45163 
  45164     case bcmPortControlEEETransmitWakeTime:
  45165         /* Time(in microsecs) to wait before transmitter can leave LPI State*/
  45166         if (!SOC_PORT_VALID(unit, port)) {
  45167             return BCM_E_PORT;
  45168         }
  45169         if (!IS_E_PORT(unit, port)) {
  45170             return BCM_E_UNAVAIL;
  45171         }
  45172 
  45173         PORT_LOCK(unit);
  45174 
  45175 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \
  45176         || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT)
  45177         if (soc_feature(unit, soc_feature_eee)) {
  45178             int mac_val;
  45179             uint32 phy_val;
  45180 
  45181             if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  45182                      SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) != SOC_E_UNAVAIL) &&
  45183                 (soc_phyctrl_control_get(unit, port,
  45184                      BCM_PORT_PHY_CONTROL_EEE, &phy_val) != SOC_E_UNAVAIL)) {
  45185                 /* If MAC/Switch is EEE aware (Native EEE mode is supported)
  45186                  * and PHY also supports Native mode
  45187                  */
  45188                 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port,
  45189                         SOC_MAC_CONTROL_EEE_TX_WAKE_TIME, value);
  45190 
  45191             } else {
  45192                 /* Get timer value from PHY. If PHY does not support
  45193                  * EEE timers, rv will be assigned SOC_E_UNAVAIL.
  45194                  */
  45195                 rv = soc_phyctrl_control_get(unit, port,
  45196                         BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_WAKE_TIME, &phy_val);
  45197                 if (SOC_SUCCESS(rv)) {
  45198                     *value = phy_val;
  45199                 }
  45200             }
  45201         } else
  45202 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT ||
  45203           BCM_TRIDENT_SUPPORT */
  45204         {
  45205             /* On legacy devices that don't support native EEE,
  45206              * get timer value from PHY. If PHY does not support
  45207              * EEE timers, rv will be assigned SOC_E_UNAVAIL.
  45208              */
  45209             uint32 phy_val;
  45210             rv = soc_phyctrl_control_get(unit, port,
  45211                     BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_WAKE_TIME, &phy_val);
  45212             if (SOC_SUCCESS(rv)) {
  45213                 *value = phy_val;
  45214             }
  45215         }
  45216 
  45217         PORT_UNLOCK (unit);
  45218         break;
  45219 
  45220     case bcmPortControlEEEReceiveSleepTime:
  45221         if (!SOC_PORT_VALID(unit, port)) {
  45222             return BCM_E_PORT;
  45223         }
  45224         if (!IS_E_PORT(unit, port)) {
  45225             return BCM_E_UNAVAIL;
  45226         }
  45227         PORT_LOCK(unit);
  45228         rv = soc_phyctrl_control_get(unit, port,
  45229                 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_SLEEP_TIME, (uint32 *)value);
  45230         PORT_UNLOCK (unit);
  45231         break;
  45232 
  45233     case bcmPortControlEEEReceiveQuietTime:
  45234         if (!SOC_PORT_VALID(unit, port)) {
  45235             return BCM_E_PORT;
  45236         }
  45237         if (!IS_E_PORT(unit, port)) {
  45238             return BCM_E_UNAVAIL;
  45239         }
  45240         PORT_LOCK(unit);
  45241         rv = soc_phyctrl_control_get(unit, port,
  45242                 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_QUIET_TIME, (uint32 *)value);
  45243         PORT_UNLOCK (unit);
  45244         break;
  45245 
  45246     case bcmPortControlEEEReceiveWakeTime:
  45247         if (!SOC_PORT_VALID(unit, port)) {
  45248             return BCM_E_PORT;
  45249         }
  45250         if (!IS_E_PORT(unit, port)) {
  45251             return BCM_E_UNAVAIL;
  45252         }
  45253         PORT_LOCK(unit);
  45254         rv = soc_phyctrl_control_get(unit, port,
  45255                 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_WAKE_TIME, (uint32 *)value);
  45256         PORT_UNLOCK (unit);
  45257         break;
  45258 
  45259     case bcmPortControlEEEEventCountSymmetric:
  45260         if (!SOC_PORT_VALID(unit, port)) {
  45261             return BCM_E_PORT;
  45262         }
  45263         if (!IS_E_PORT(unit, port)) {
  45264             return BCM_E_UNAVAIL;
  45265         }
  45266 #if defined(BCM_HURRICANE2_SUPPORT)
  45267         if (SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) ||
  45268             SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  45269             uint32 reg_value;
  45270             soc_reg_t   reg;
  45271             if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) {
  45272                 reg = IS_XL_PORT(unit, port) ? XLPORT_EEE_COUNTER_MODEr : 
  45273                                                CLPORT_EEE_COUNTER_MODEr;
  45274 
  45275                 if (SOC_REG_FIELD_VALID(unit, reg, MODE_BITf)) {
  45276                     rv = soc_reg32_get(unit, reg, port, 0, &reg_value);
  45277                     if (SOC_SUCCESS(rv)) {
  45278                         *value = soc_reg_field_get(unit, reg, 
  45279                                                    reg_value, MODE_BITf);
  45280                     }
  45281                 } else {
  45282                     return BCM_E_INTERNAL;
  45283                 }
  45284             } else {
  45285                 return BCM_E_PORT;
  45286             }
  45287         } else
  45288 #endif
  45289         {
  45290 #if defined(BCM_TRIUMPH3_SUPPORT)
  45291             if (SOC_REG_FIELD_VALID(unit, PORT_EEE_COUNTER_MODEr, MODE_BITf)) {
  45292                   uint32 reg_value;
  45293 
  45294                   rv = READ_PORT_EEE_COUNTER_MODEr(unit, port, &reg_value);
  45295 
  45296                   if (SOC_SUCCESS(rv)) {
  45297                       *value = soc_reg_field_get(unit, PORT_EEE_COUNTER_MODEr,
  45298                           reg_value, MODE_BITf);
  45299                   }
  45300             }
  45301 #endif
  45302        }
  45303         break;
  45304 
  45305     case bcmPortControlEEELinkActiveDuration:
  45306         if (!SOC_PORT_VALID(unit, port)) {
  45307             return BCM_E_PORT;
  45308         }
  45309         if (!IS_E_PORT(unit, port)) {
  45310             return BCM_E_UNAVAIL;
  45311         }
  45312 #if defined(BCM_HURRICANE2_SUPPORT)
  45313         if (SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) ||
  45314             SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  45315             soc_reg_t   reg;
  45316 
  45317             if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) {
  45318 
  45319                 reg = IS_XL_PORT(unit, port) ? 
  45320                                 XLMAC_EEE_1_SEC_LINK_STATUS_TIMERr : 
  45321                                 CLMAC_EEE_1_SEC_LINK_STATUS_TIMERr;
  45322                 if (SOC_REG_FIELD_VALID(unit, reg, ONE_SECOND_TIMERf)) {
  45323                     uint64 reg_value;
  45324 
  45325                     rv = soc_reg_get(unit, reg, port, 0, &reg_value);
  45326                     if (SOC_SUCCESS(rv)) {
  45327                         *value = soc_reg64_field32_get(unit,
  45328                                                        reg, reg_value,
  45329                             ONE_SECOND_TIMERf);
  45330                     }
  45331                 }
  45332             } else {
  45333                 return BCM_E_PORT;
  45334             }
  45335         } else
  45336 #endif
  45337         {
  45338 #if defined(BCM_TRIUMPH3_SUPPORT)
  45339             {
  45340                 soc_reg_t reg;
  45341 
  45342                 reg = IS_C_PORT(unit, port) ?
  45343                     CMAC_EEE_1_SEC_LINK_STATUS_TIMERr :
  45344                     XMAC_EEE_1_SEC_LINK_STATUS_TIMERr;
  45345                 if (SOC_REG_FIELD_VALID(unit, reg, ONE_SECOND_TIMERf)) {
  45346                     uint64 reg_value;
  45347 
  45348                     rv = soc_reg_get(unit, reg, port, 0, &reg_value);
  45349                     if (SOC_SUCCESS(rv)) {
  45350                         *value = soc_reg64_field32_get(unit, reg, reg_value,
  45351                                                      ONE_SECOND_TIMERf);
  45352                     }
  45353                 }
  45354             }
  45355 #endif
  45356         }
  45357         break;
  45358 
  45359     case bcmPortControlRemoteCpuTcMapping:
  45360         if (soc_feature(unit, soc_feature_rcpu_tc_mapping)) {
  45361             rv = _bcm_esw_port_tab_get(unit, port, REMOTE_CPU_ENf, value);
  45362         } else {
  45363             rv = BCM_E_UNAVAIL;
  45364         }
  45365         break;
  45366 
  45367     case bcmPortControlTrill:
  45368 #if defined(BCM_TRIDENT_SUPPORT)
  45369         if (soc_feature(unit, soc_feature_trill)) {
  45370             rv = _bcm_esw_port_tab_get(unit, port, TRILL_ENABLEf, value);
  45371         }
  45372 #endif /* BCM_TRIDENT_SUPPORT */
  45373         break;
  45374 
  45375     case bcmPortControlTrillAllow:
  45376 #if defined(BCM_TRIDENT_SUPPORT)
  45377         if (soc_feature(unit, soc_feature_trill)) {
  45378             rv = _bcm_esw_port_tab_get(unit, port,
  45379                                        ALLOW_TRILL_FRAMESf, value);
  45380         }
  45381 #endif /* BCM_TRIDENT_SUPPORT */
  45382         break;
  45383 
  45384     case bcmPortControlNonTrillAllow:
  45385 #if defined(BCM_TRIDENT_SUPPORT)
  45386         if (soc_feature(unit, soc_feature_trill)) {
  45387             rv = _bcm_esw_port_tab_get(unit, port,
  45388                                        ALLOW_NON_TRILL_FRAMESf, value);
  45389         }
  45390 #endif /* BCM_TRIDENT_SUPPORT */
  45391         break;
  45392 
  45393     case bcmPortControlTrillCoreISISToCPU:
  45394 #if defined(BCM_TRIDENT_SUPPORT)
  45395         if (soc_feature(unit, soc_feature_trill)) {
  45396             rv = _bcm_esw_port_tab_get(unit, port,
  45397                                        COPY_CORE_IS_IS_TO_CPUf, value);
  45398         }
  45399 #endif /* BCM_TRIDENT_SUPPORT */
  45400         break;
  45401 
  45402     case bcmPortControlTrillHashSelect:
  45403 #if defined(BCM_TRIDENT_SUPPORT)
  45404         if (soc_feature(unit, soc_feature_trill)) {
  45405             rv = _bcm_esw_port_tab_get(unit, port,
  45406                                        RTAG7_HASH_CFG_SEL_TRILL_ECMPf, value);
  45407         }
  45408 #endif /* BCM_TRIDENT_SUPPORT */
  45409         break;
  45410 
  45411     case bcmPortControlNivAccessVirtualInterfaceId:
  45412     case bcmPortControlExtendedPortVid:
  45413 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  45414          if (soc_feature(unit, soc_feature_niv) ||
  45415                  soc_feature(unit, soc_feature_port_extension)) {
  45416             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  45417                 SOC_IS_GREYHOUND2(unit)) {
  45418                 uint64 val64;
  45419                 rv = READ_EGR_PORT_64r(unit, port, &val64);
  45420                 if (BCM_SUCCESS(rv)) {
  45421                     *value = soc_reg64_field32_get(unit, EGR_PORT_64r,
  45422                                             val64, NIV_VIF_IDf);
  45423                 }
  45424             } else {
  45425                 rv = _bcm_esw_port_tab_get(unit, port, NIV_VIF_IDf, value);
  45426             }
  45427          }
  45428 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  45429          break;
  45430 
  45431     case bcmPortControlNivNonVntagDrop:
  45432     case bcmPortControlNonEtagDrop:
  45433 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  45434          if (soc_feature(unit, soc_feature_niv) ||
  45435                  soc_feature(unit, soc_feature_port_extension)) {
  45436              rv = _bcm_esw_port_tab_get(unit, port,
  45437                      DISCARD_IF_VNTAG_NOT_PRESENTf, value);
  45438          }
  45439 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  45440          break;
  45441 
  45442     case bcmPortControlNivVntagDrop:
  45443     case bcmPortControlEtagDrop:
  45444 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  45445         if (soc_feature(unit, soc_feature_niv) ||
  45446             soc_feature(unit, soc_feature_port_extension)) {
  45447             rv = _bcm_esw_port_tab_get(unit, port,
  45448                                        DISCARD_IF_VNTAG_PRESENTf, value);
  45449         }
  45450 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  45451         break;
  45452 
  45453     case bcmPortControlSubportPktTagDrop:
  45454 #if defined(BCM_KATANA2_SUPPORT)
  45455          if (soc_feature(unit, soc_feature_lltag)) {
  45456              rv = _bcm_esw_port_tab_get(unit, port,
  45457                      DISCARD_IF_LLTAG_PRESENTf, value);
  45458          }
  45459 #endif /* BCM_KATANA2_SUPPORT */
  45460          break;
  45461 
  45462     case bcmPortControlNoSubportPktTagDrop:
  45463 #if defined(BCM_KATANA2_SUPPORT)
  45464          if (soc_feature(unit, soc_feature_lltag)) {
  45465              rv = _bcm_esw_port_tab_get(unit, port,
  45466                      DISCARD_IF_LLTAG_NOT_PRESENTf, value);
  45467          }
  45468 #endif /* BCM_KATANA2_SUPPORT */
  45469          break;
  45470 
  45471     case bcmPortControlNivNonVntagAdd:
  45472 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  45473         if (soc_feature(unit, soc_feature_niv)) {
  45474             int vntag_action;
  45475             rv = _bcm_esw_port_tab_get(unit, port,
  45476                                        VNTAG_ACTIONS_IF_NOT_PRESENTf,
  45477                                        &vntag_action);
  45478             if (BCM_SUCCESS(rv)) {
  45479                 *value = (vntag_action == VNTAG_ADD) ? TRUE : FALSE;
  45480             }
  45481         }
  45482 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  45483         break;
  45484 
  45485     case bcmPortControlNonEtagAdd:
  45486 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  45487         if (soc_feature(unit, soc_feature_port_extension)) {
  45488             int etag_action;
  45489             rv = _bcm_esw_port_tab_get(unit, port,
  45490                                        VNTAG_ACTIONS_IF_NOT_PRESENTf,
  45491                                        &etag_action);
  45492             if (BCM_SUCCESS(rv)) {
  45493                 *value = (etag_action == 2) ? TRUE : FALSE;
  45494             }
  45495         }
  45496 #endif /* BCM_TRIUMPH3_SUPPORT||BCM_GREYHOUND_SUPPORT */
  45497         break;
  45498 
  45499     case bcmPortControlNivVntagIngressReplace:
  45500     case bcmPortControlEtagIngressReplace:
  45501 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  45502         if (soc_feature(unit, soc_feature_niv) ||
  45503             soc_feature(unit, soc_feature_port_extension)) {
  45504             int vntag_action;
  45505             rv = _bcm_esw_port_tab_get(unit, port,
  45506                                        VNTAG_ACTIONS_IF_PRESENTf,
  45507                                        &vntag_action);
  45508             if (BCM_SUCCESS(rv)) {
  45509                 *value = (vntag_action == VNTAG_REPLACE) ? TRUE : FALSE;
  45510             }
  45511         }
  45512 #endif /* BCM_TRIDENT_SUPPORT ||BCM_GREYHOUND_SUPPORT */
  45513         break;
  45514 
  45515     case bcmPortControlNivVntagEgressReplace:
  45516     case bcmPortControlEtagEgressReplace:
  45517 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  45518          if (soc_feature(unit, soc_feature_niv) ||
  45519                  soc_feature(unit, soc_feature_port_extension)) {
  45520             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  45521                 SOC_IS_GREYHOUND2(unit)) {
  45522                 uint64 val64;
  45523                 int vntag_action;
  45524 
  45525                 if (type == bcmPortControlEtagEgressReplace) {
  45526                     return BCM_E_UNAVAIL;
  45527                 }
  45528 
  45529                 rv = READ_EGR_PORT_64r(unit, port, &val64);
  45530                 if (BCM_SUCCESS(rv)) {
  45531                     vntag_action = soc_reg64_field32_get(unit, EGR_PORT_64r,
  45532                                             val64, VNTAG_ACTIONS_IF_PRESENTf);
  45533                     *value = (vntag_action == VNTAG_REPLACE) ? TRUE : FALSE;
  45534                 }
  45535             } else {
  45536                 int vntag_action;
  45537                 rv = _bcm_esw_egr_port_tab_get(unit, port,
  45538                                                VNTAG_ACTIONS_IF_PRESENTf,
  45539                                                &vntag_action);
  45540                 if (BCM_SUCCESS(rv)) {
  45541                     *value = (vntag_action == VNTAG_REPLACE) ? TRUE : FALSE;
  45542                 }
  45543             }
  45544          }
  45545 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  45546          break;
  45547 
  45548     case bcmPortControlNivVntagIngressDelete:
  45549     case bcmPortControlEtagIngressDelete:
  45550 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  45551         if (soc_feature(unit, soc_feature_niv) ||
  45552             soc_feature(unit, soc_feature_port_extension)) {
  45553             int vntag_action;
  45554             rv = _bcm_esw_port_tab_get(unit, port,
  45555                                        VNTAG_ACTIONS_IF_PRESENTf,
  45556                                        &vntag_action);
  45557             if (BCM_SUCCESS(rv)) {
  45558                 *value = (vntag_action == VNTAG_DELETE) ? TRUE : FALSE;
  45559             }
  45560         }
  45561 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  45562         break;
  45563 
  45564     case bcmPortControlNivVntagEgressDelete:
  45565     case bcmPortControlEtagEgressDelete:
  45566 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  45567         if (soc_feature(unit, soc_feature_niv) ||
  45568             soc_feature(unit, soc_feature_port_extension)) {
  45569             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  45570                 SOC_IS_GREYHOUND2(unit)) {
  45571                 uint64 val64;
  45572                 int vntag_action;
  45573                 rv = READ_EGR_PORT_64r(unit, port, &val64);
  45574                 if (BCM_SUCCESS(rv)) {
  45575                     vntag_action = soc_reg64_field32_get(unit, EGR_PORT_64r,
  45576                                             val64, VNTAG_ACTIONS_IF_PRESENTf);
  45577                     *value = (vntag_action == VNTAG_DELETE) ? TRUE : FALSE;
  45578                 }
  45579             } else {
  45580                 int vntag_action;
  45581                 rv = _bcm_esw_egr_port_tab_get(unit, port,
  45582                                                VNTAG_ACTIONS_IF_PRESENTf,
  45583                                                &vntag_action);
  45584                 if (BCM_SUCCESS(rv)) {
  45585                     *value = (vntag_action == VNTAG_DELETE) ? TRUE : FALSE;
  45586                 }
  45587             }
  45588         }
  45589 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  45590         break;
  45591 
  45592     case bcmPortControlNivRpfCheck:
  45593     case bcmPortControlExtenderRpfCheck:
  45594 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  45595         if (soc_feature(unit, soc_feature_niv) ||
  45596             soc_feature(unit, soc_feature_port_extension)) {
  45597             rv = _bcm_esw_port_tab_get(unit, port,
  45598                                        NIV_RPF_CHECK_ENABLEf, value);
  45599         }
  45600 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  45601         break;
  45602 
  45603     case bcmPortControlNivSourceKnockout:
  45604     case bcmPortControlExtenderSourceKnockout:
  45605 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  45606         if (soc_feature(unit, soc_feature_niv) ||
  45607             soc_feature(unit, soc_feature_port_extension)) {
  45608             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  45609                 SOC_IS_GREYHOUND2(unit)) {
  45610                 uint64 val64;
  45611                 rv = READ_EGR_PORT_64r(unit, port, &val64);
  45612                 if (BCM_SUCCESS(rv)) {
  45613                     *value = soc_reg64_field32_get(unit, EGR_PORT_64r,
  45614                                             val64, NIV_PRUNE_ENABLEf);
  45615                 }
  45616             } else {
  45617                 rv = _bcm_esw_egr_port_tab_get(unit, port,
  45618                                                NIV_PRUNE_ENABLEf, value);
  45619             }
  45620         }
  45621 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  45622          break;
  45623 
  45624     case bcmPortControlNivForwardPort:
  45625     case bcmPortControlExtenderForwardPort:
  45626 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  45627         if (soc_feature(unit, soc_feature_niv) ||
  45628             soc_feature(unit, soc_feature_port_extension)) {
  45629             int is_niv_uplink;
  45630             int tx_dest_port;
  45631             _bcm_gport_dest_t dest;
  45632 
  45633             BCM_IF_ERROR_RETURN
  45634                 (_bcm_esw_port_tab_get(unit, port,
  45635                                        NIV_UPLINK_PORTf, &is_niv_uplink));
  45636             if (is_niv_uplink) {
  45637                 *value = -1;
  45638             } else {
  45639                 if (soc_feature(unit, soc_feature_generic_dest)) {
  45640                     uint32 dt, dval;
  45641                     BCM_IF_ERROR_RETURN
  45642                         (_bcm_esw_port_tab_get(unit, port, DESTINATIONf,
  45643                                                &tx_dest_port));
  45644                     _soc_mem_dest_value_resolve(unit, tx_dest_port, &dt, &dval);
  45645                     if (dt == SOC_MEM_FIF_DEST_LAG) {
  45646                         dest.tgid = dval;
  45647                         dest.gport_type = _SHR_GPORT_TYPE_TRUNK;
  45648                     } else {
  45649                         dest.port = dval & SOC_MEM_FIF_DGPP_PORT_MASK;
  45650                         dest.modid = (dval & SOC_MEM_FIF_DGPP_MOD_ID_MASK) >>
  45651                                         SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS;
  45652                         dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
  45653                     }
  45654                 } else {
  45655                 BCM_IF_ERROR_RETURN
  45656                     (_bcm_esw_port_tab_get(unit, port,
  45657                                            TX_DEST_PORTf, &tx_dest_port));
  45658                 if ((tx_dest_port >> SOC_TRUNK_BIT_POS(unit)) & 0x1) {
  45659                     dest.tgid = tx_dest_port - (1 << SOC_TRUNK_BIT_POS(unit));
  45660                     dest.gport_type = _SHR_GPORT_TYPE_TRUNK;
  45661                 } else {
  45662 #if defined(BCM_METROLITE_SUPPORT)
  45663                   /* Metrolite DGLP still uses 7 bits for port like saber 2 */
  45664                   if (SOC_IS_METROLITE(unit)) {
  45665                       dest.port = tx_dest_port & 0x7f;
  45666                       dest.modid =( tx_dest_port & 0xff10) >> 7;
  45667                   } else
  45668 #endif
  45669                   {
  45670                       dest.port = tx_dest_port & SOC_PORT_ADDR_MAX(unit);
  45671                       dest.modid = (tx_dest_port - dest.port) /
  45672                                    (SOC_PORT_ADDR_MAX(unit) + 1);
  45673                   }
  45674                     dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
  45675                     }
  45676                 }
  45677                 BCM_IF_ERROR_RETURN
  45678                     (_bcm_esw_gport_construct(unit, &dest, value));
  45679             }
  45680             rv = BCM_E_NONE;
  45681         }
  45682 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  45683         break;
  45684 
  45685     case bcmPortControlNivType:
  45686         if (soc_feature(unit, soc_feature_niv)) {
  45687             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  45688                 SOC_IS_GREYHOUND2(unit)) {
  45689 #if defined(BCM_GREYHOUND_SUPPORT)
  45690                 rv = bcm_gh_port_niv_type_get(unit, port, value);
  45691 #endif /* BCM_GREYHOUND_SUPPORT */
  45692             } else {
  45693 #if defined(BCM_TRIDENT_SUPPORT)
  45694                 rv = bcm_td_port_niv_type_get(unit, port, value);
  45695 #endif /* BCM_TRIDENT_SUPPORT */
  45696             }
  45697         }
  45698         break;
  45699 
  45700     case bcmPortControlExtenderType:
  45701         if (soc_feature(unit, soc_feature_port_extension)) {
  45702             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  45703                 SOC_IS_GREYHOUND2(unit)) {
  45704 #if defined(BCM_GREYHOUND_SUPPORT)
  45705                 rv = bcm_gh_port_extender_type_get(unit, port, value);
  45706 #endif /* BCM_GREYHOUND_SUPPORT */
  45707             } else {
  45708 #if defined(BCM_TRIUMPH3_SUPPORT)
  45709                 rv = bcm_tr3_port_extender_type_get(unit, port, value);
  45710 #endif /* BCM_TRIUMPH3_SUPPORT */
  45711             }
  45712         }
  45713         break;
  45714 
  45715     case bcmPortControlNivNameSpace:
  45716     case bcmPortControlExtenderNameSpace:
  45717 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  45718         if (soc_feature(unit, soc_feature_niv) ||
  45719             soc_feature(unit, soc_feature_port_extension)) {
  45720             rv = _bcm_esw_port_tab_get(unit, port, NIV_NAMESPACEf, value);
  45721         }
  45722 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  45723         break;
  45724 
  45725     case bcmPortControlEtagPcpDeSelect:
  45726 #if defined(INCLUDE_L3)
  45727         if (soc_feature(unit, soc_feature_port_extension)) {
  45728             if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) ||
  45729                 SOC_IS_GREYHOUND2(unit)) {
  45730 #if defined(BCM_GREYHOUND_SUPPORT)
  45731                 rv = bcm_gh_port_etag_pcp_de_source_get(unit, port, value);
  45732 #endif /* BCM_GREYHOUND_SUPPORT */
  45733             } else {
  45734 #if defined(BCM_TRIUMPH3_SUPPORT)
  45735                 rv = bcm_tr3_port_etag_pcp_de_source_get(unit, port, value);
  45736 #endif /* BCM_TRIUMPH3_SUPPORT */
  45737             }
  45738         }
  45739 #endif /* INCLUDE_L3 */
  45740         break;
  45741 
  45742     case bcmPortControlEtagPcp:
  45743 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  45744         if (soc_feature(unit, soc_feature_port_extension)) {
  45745             rv = _bcm_esw_port_tab_get(unit, port, ETAG_PCPf, value);
  45746         }
  45747 #endif /* BCM_TRIUMPH3_SUPPORT||BCM_GREYHOUND_SUPPORT */
  45748         break;
  45749 
  45750     case bcmPortControlEtagDe:
  45751 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  45752         if (soc_feature(unit, soc_feature_port_extension)) {
  45753             rv = _bcm_esw_port_tab_get(unit, port, ETAG_DEf, value);
  45754         }
  45755 #endif /* BCM_TRIUMPH3_SUPPORT||BCM_GREYHOUND_SUPPORT */
  45756         break;
  45757 
  45758     case bcmPortControlUseEtagPri:
  45759 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  45760         if (soc_feature(unit, soc_feature_port_extension)) {
  45761             rv = _bcm_esw_port_tab_get(unit, port, PHB_FROM_ETAGf, value);
  45762         }
  45763 #endif /* BCM_TRIUMPH3_SUPPORT||BCM_GREYHOUND_SUPPORT */
  45764         break;
  45765 
  45766     case bcmPortControlUseSubportPktTagPri:
  45767 #if defined(BCM_KATANA2_SUPPORT)
  45768          if (soc_feature(unit, soc_feature_lltag)) {
  45769              rv = _bcm_esw_port_tab_get(unit, port, PHB_FROM_LLTAGf, value);
  45770          }
  45771 #endif /* BCM_KATANA2_SUPPORT */
  45772          break;
  45773 
  45774     case bcmPortControlProhibitedDot1p:
  45775 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT)
  45776         rv = _bcm_esw_port_tab_get(unit, port, PROHIBITED_DOT1Pf, value);
  45777 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */
  45778         break;
  45779 
  45780     case bcmPortControlFabricSourceKnockout:
  45781         rv = _bcm_esw_port_tab_get(unit, port, REMOVE_HG_HDR_SRC_PORTf,
  45782                                    value);
  45783         break;
  45784 
  45785     case bcmPortControlPrbsPolynomial:
  45786         rv = soc_phyctrl_control_get(unit, port,
  45787                                      SOC_PHY_CONTROL_PRBS_POLYNOMIAL,
  45788                                      (uint32 *)value);
  45789         break;
  45790     case bcmPortControlPrbsTxEnable:
  45791         rv = soc_phyctrl_control_get(unit, port,
  45792                                      SOC_PHY_CONTROL_PRBS_TX_ENABLE,
  45793                                      (uint32 *)value);
  45794         break;
  45795 
  45796     case bcmPortControlPrbsRxEnable:
  45797         rv = soc_phyctrl_control_get(unit, port,
  45798                                      SOC_PHY_CONTROL_PRBS_RX_ENABLE,
  45799                                      (uint32 *)value);
  45800         break;
  45801 
  45802     case bcmPortControlPrbsTxInvertData:
  45803         rv = soc_phyctrl_control_get(unit, port,
  45804                                      SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA,
  45805                                      (uint32 *)value);
  45806         break;
  45807 
  45808     case bcmPortControlRxEnable:
  45809         rv = _bcm_esw_mac_rx_control(unit, port, 1, value);
  45810         break;
  45811     case bcmPortControlTxEnable:
  45812         if (SOC_REG_IS_VALID(unit, COSMASKr) ||
  45813 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
  45814             /* Trident2plus/Trident2 uses soc_td2_port_traffic_egr_enable_set */
  45815             SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_TRIDENT2(unit) ||
  45816 #endif
  45817 #ifdef BCM_APACHE_SUPPORT
  45818             SOC_IS_APACHE(unit) ||
  45819 #endif
  45820 #ifdef BCM_TRIDENT3_SUPPORT
  45821             SOC_IS_TRIDENT3X(unit) ||
  45822 #endif
  45823 #ifdef BCM_TOMAHAWK_SUPPORT
  45824             SOC_IS_TOMAHAWKX(unit) ||
  45825 #endif
  45826 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT)
  45827             (SOC_IS_HELIX4(unit) || SOC_IS_TRIUMPH3(unit)) ||
  45828 #endif
  45829             (SOC_REG_IS_VALID(unit, EGRMETERINGCONFIGr) &&
  45830              SOC_REG_IS_VALID(unit, EGRMETERINGBUCKETr))) {
  45831             *value = 1;
  45832             if (PORT(unit, port).flags & _PORT_INFO_STOP_TX) {
  45833                 *value = 0;
  45834             }
  45835             rv = SOC_E_NONE;
  45836         }
  45837         break;
  45838 
  45839     case bcmPortControlL2GreEnable:
  45840 #if defined(BCM_TRIUMPH3_SUPPORT)
  45841         if (soc_feature(unit, soc_feature_l2gre)
  45842 #if defined(BCM_TRIDENT3_SUPPORT)
  45843             || soc_feature(unit, soc_feature_flex_flow)
  45844 #endif
  45845             ) {
  45846             rv = _bcm_esw_port_tab_get(unit, port,
  45847                                        L2GRE_TERMINATION_ALLOWEDf, value);
  45848         }
  45849 #endif /* BCM_TRIUMPH3_SUPPORT */
  45850        break;
  45851 
  45852     case bcmPortControlL2GreTunnelbasedVpnId:
  45853 #if defined(BCM_TRIUMPH3_SUPPORT)
  45854         if (soc_feature(unit, soc_feature_l2gre) 
  45855 #if defined(BCM_TRIDENT3_SUPPORT)
  45856             || soc_feature(unit, soc_feature_flex_flow)
  45857 #endif
  45858             ) {
  45859             rv = _bcm_esw_port_tab_get(unit, port,
  45860                                        L2GRE_VPNID_LOOKUP_KEY_TYPEf, value);
  45861         }
  45862 #endif /* BCM_TRIUMPH3_SUPPORT */
  45863         break;
  45864 
  45865     case bcmPortControlL2GreDefaultTunnelEnable:
  45866 #if defined(BCM_TRIUMPH3_SUPPORT)
  45867         if (soc_feature(unit, soc_feature_l2gre)
  45868 #if defined(BCM_TRIDENT3_SUPPORT)
  45869             || soc_feature(unit, soc_feature_flex_flow)
  45870 #endif
  45871             ) {
  45872             rv = _bcm_esw_port_tab_get(unit, port,
  45873                                        L2GRE_DEFAULT_SVP_ENABLEf, value);
  45874         }
  45875 #endif /* BCM_TRIUMPH3_SUPPORT */
  45876 
  45877        break;
  45878 
  45879     case bcmPortControlVxlanEnable:
  45880 #if defined(BCM_TRIDENT2_SUPPORT)
  45881         if ((soc_feature(unit, soc_feature_vxlan)) ||
  45882             (soc_feature(unit, soc_feature_flex_flow))) {
  45883             rv = _bcm_esw_port_tab_get(unit, port,
  45884                                        VXLAN_TERMINATION_ALLOWEDf, value);
  45885         }
  45886 #endif /* BCM_TRIDENT2_SUPPORT */
  45887        break;
  45888 
  45889     case bcmPortControlVxlanTunnelbasedVnId:
  45890 #if defined(BCM_TRIDENT2_SUPPORT)
  45891         if ((soc_feature(unit, soc_feature_vxlan)) ||
  45892             (soc_feature(unit, soc_feature_flex_flow))) {
  45893             rv = _bcm_esw_port_tab_get(unit, port,
  45894                                        VXLAN_VN_ID_LOOKUP_KEY_TYPEf, value);
  45895         }
  45896 #endif /* BCM_TRIDENT2_SUPPORT */
  45897        break;
  45898     case bcmPortControlVxlanVpnAssignmentCriteria:
  45899 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  45900         if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) {
  45901             rv = _bcm_esw_port_tab_get(unit, port,
  45902                                        VXLAN_VN_ID_LOOKUP_KEY_TYPEf, value);
  45903         }
  45904 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  45905         break;
  45906     case bcmPortControlVxlanTerminationMatchCriteria:
  45907 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  45908         if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) {
  45909             rv = _bcm_esw_port_tab_get(unit, port,
  45910                                        VXLAN_TERMINATION_LOOKUP_TYPEf, value);
  45911         }
  45912 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  45913         break;
  45914     case bcmPortControlVxlanGportAssignmentCriteria:
  45915 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  45916         if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) {
  45917             rv = _bcm_esw_port_tab_get(unit, port, 
  45918                                        VXLAN_SVP_ASSIGNMENT_KEY_TYPEf, value);
  45919         }
  45920 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  45921         break;
  45922     case bcmPortControlVxlanDefaultTunnelEnable:
  45923 #if defined(BCM_TRIDENT2_SUPPORT)
  45924         if ((soc_feature(unit, soc_feature_vxlan)) ||
  45925             (soc_feature(unit, soc_feature_flex_flow))) {
  45926             rv = _bcm_esw_port_tab_get(unit, port,
  45927                                        VXLAN_DEFAULT_SVP_ENABLEf, value);
  45928         }
  45929 #endif /* BCM_TRIDENT2_SUPPORT */
  45930         break;
  45931 
  45932 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_REGEX)
  45933     case bcmPortControlRegex:
  45934         rv = _bcm_esw_port_regex_control_get(unit, port, &udp, &tcp, &enable);
  45935         if (enable != 0) {
  45936             *value = 1;
  45937         } else {
  45938             *value = 0;
  45939         }
  45940         break;
  45941     case bcmPortControlRegexTcp:
  45942         rv = _bcm_esw_port_regex_control_get(unit, port, &udp, &tcp, &enable);
  45943         if (tcp != 0) {
  45944             *value = 1;
  45945         } else {
  45946             *value = 0;
  45947         }
  45948         break;
  45949     case bcmPortControlRegexUdp:
  45950         rv = _bcm_esw_port_regex_control_get(unit, port, &udp, &tcp, &enable);
  45951         if (udp != 0) {
  45952             *value = 1;
  45953         } else {
  45954             *value = 0;
  45955         }
  45956         break;
  45957 #endif
  45958 
  45959     case bcmPortControlMplsEntropyHashSet:
  45960 #if defined(BCM_KATANA2_SUPPORT)
  45961         if (SOC_IS_KATANA2(unit)) {
  45962             return BCM_E_UNAVAIL;
  45963         } else
  45964 #endif /* BCM_KATANA2_SUPPORT */
  45965         {
  45966 #if defined(BCM_KATANA_SUPPORT)
  45967             if (soc_feature(unit, soc_feature_mpls)) {
  45968                 rv = _bcm_esw_port_tab_get(unit, port,
  45969                                            RTAG7_HASH_CFG_SEL_ENTROPY_LABELf,
  45970                                            value);
  45971             }
  45972 #endif /* BCM_KATANA_SUPPORT */
  45973         }
  45974         break;
  45975 
  45976 #ifdef BCM_SHADOW_SUPPORT
  45977     case bcmPortControlManagementPacketIp6Reserved:
  45978         if (!SOC_IS_SHADOW(unit)) {
  45979             return BCM_E_UNAVAIL;
  45980         }
  45981         PORT_LOCK(unit);
  45982         rv = READ_MGMT_FRAME_ENABLEr(unit, port, &val);
  45983         if (BCM_SUCCESS(rv)) {
  45984             *value = soc_reg_field_get(unit, MGMT_FRAME_ENABLEr,
  45985                                        val, IPV6_RESVf);
  45986         }
  45987         PORT_UNLOCK(unit);
  45988         break;
  45989     case bcmPortControlManagementPacketIp4Reserved:
  45990         if (!SOC_IS_SHADOW(unit)) {
  45991             return BCM_E_UNAVAIL;
  45992         }
  45993         PORT_LOCK(unit);
  45994         rv = READ_MGMT_FRAME_ENABLEr(unit, port, &val);
  45995         if (BCM_SUCCESS(rv)) {
  45996             *value = soc_reg_field_get(unit, MGMT_FRAME_ENABLEr,
  45997                                        val, IPV4_RESVf);
  45998         }
  45999         PORT_UNLOCK(unit);
  46000         break;
  46001     case bcmPortControlManagementPacketLinkConstrained:
  46002         if (!SOC_IS_SHADOW(unit)) {
  46003             return BCM_E_UNAVAIL;
  46004         }
  46005         PORT_LOCK(unit);
  46006         rv = READ_MGMT_FRAME_ENABLEr(unit, port, &val);
  46007         if (BCM_SUCCESS(rv)) {
  46008             *value = soc_reg_field_get(unit, MGMT_FRAME_ENABLEr,
  46009                                        val, LINK_CONSTf);
  46010         }
  46011         PORT_UNLOCK(unit);
  46012         break;
  46013     case bcmPortControlManagementPacketGarp:
  46014         if (!SOC_IS_SHADOW(unit)) {
  46015             return BCM_E_UNAVAIL;
  46016         }
  46017         PORT_LOCK(unit);
  46018         rv = READ_MGMT_FRAME_ENABLEr(unit, port, &val);
  46019         if (BCM_SUCCESS(rv)) {
  46020             *value = soc_reg_field_get(unit, MGMT_FRAME_ENABLEr,
  46021                                        val, DOT1D_GARPf);
  46022         }
  46023         PORT_UNLOCK(unit);
  46024         break;
  46025     case bcmPortControlManagementPacketCos:
  46026         if (!SOC_IS_SHADOW(unit)) {
  46027             return BCM_E_UNAVAIL;
  46028         }
  46029         PORT_LOCK(unit);
  46030         rv = READ_COSDP_REMAP_CONTROLr(unit, port, &val);
  46031         if (BCM_SUCCESS(rv)) {
  46032             *value = soc_reg_field_get(unit, COSDP_REMAP_CONTROLr,
  46033                                        val, MGMT_FRAME_COSf);
  46034         }
  46035         PORT_UNLOCK(unit);
  46036         break;
  46037     case bcmPortControlManagementPacketColor:
  46038         rv = BCM_E_UNAVAIL;
  46039         break;
  46040     case bcmPortControlTaggedL3PacketPktPri:
  46041         if (!SOC_IS_SHADOW(unit)) {
  46042             return BCM_E_UNAVAIL;
  46043         }
  46044         PORT_LOCK(unit);
  46045         rv = READ_COSDP_REMAP_CONTROLr(unit, port, &val);
  46046         if (BCM_SUCCESS(rv)) {
  46047             *value = soc_reg_field_get(unit, COSDP_REMAP_CONTROLr,
  46048                                        val, SELECT5f);
  46049             switch (*value) {
  46050             case 0:
  46051                 *value = BCM_PORT_COS_REMAP_DSCP;
  46052             break;
  46053             case 1:
  46054                 *value = BCM_PORT_COS_REMAP_EXP;
  46055             break;
  46056             case 2:
  46057                 *value = BCM_PORT_COS_REMAP_VLAN_PRI;
  46058             break;
  46059             default:
  46060                 *value = BCM_PORT_COS_REMAP_VLAN_PRI;
  46061             }
  46062         }
  46063         PORT_UNLOCK(unit);
  46064         break;
  46065     case bcmPortControlTaggedMPLSPacketPktPri:
  46066         if (!SOC_IS_SHADOW(unit)) {
  46067             return BCM_E_UNAVAIL;
  46068         }
  46069         PORT_LOCK(unit);
  46070         rv = READ_COSDP_REMAP_CONTROLr(unit, port, &val);
  46071         if (BCM_SUCCESS(rv)) {
  46072             *value = soc_reg_field_get(unit, COSDP_REMAP_CONTROLr,
  46073                                        val, SELECT3f);
  46074             switch (*value) {
  46075             case 0:
  46076                 *value = BCM_PORT_COS_REMAP_DSCP;
  46077             break;
  46078             case 1:
  46079                 *value = BCM_PORT_COS_REMAP_EXP;
  46080             break;
  46081             case 2:
  46082                 *value = BCM_PORT_COS_REMAP_VLAN_PRI;
  46083             break;
  46084             default:
  46085                 *value = BCM_PORT_COS_REMAP_VLAN_PRI;
  46086             }
  46087         }
  46088         PORT_UNLOCK(unit);
  46089         break;
  46090     case bcmPortControlTaggedMPLSL3PacketPktPri:
  46091         if (!SOC_IS_SHADOW(unit)) {
  46092             return BCM_E_UNAVAIL;
  46093         }
  46094         PORT_LOCK(unit);
  46095         rv = READ_COSDP_REMAP_CONTROLr(unit, port, &val);
  46096         if (BCM_SUCCESS(rv)) {
  46097             *value = soc_reg_field_get(unit, COSDP_REMAP_CONTROLr,
  46098                                        val, SELECT7f);
  46099             switch (*value) {
  46100             case 0:
  46101                 *value = BCM_PORT_COS_REMAP_DSCP;
  46102             break;
  46103             case 1:
  46104                 *value = BCM_PORT_COS_REMAP_EXP;
  46105             break;
  46106             case 2:
  46107                 *value = BCM_PORT_COS_REMAP_VLAN_PRI;
  46108             break;
  46109             default:
  46110                 *value = BCM_PORT_COS_REMAP_VLAN_PRI;
  46111             }
  46112         }
  46113         PORT_UNLOCK(unit);
  46114         break;
  46115 #endif
  46116 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  46117     case bcmPortControlFieldEgressClassSelect:
  46118 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  46119         if (soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) {
  46120             rv = _bcm_td2p_port_control_egress_class_select_get(unit, port,
  46121                                                                 (uint32 *)value);
  46122         } else
  46123 #endif
  46124         {
  46125         rv = _bcm_trx_port_control_egress_class_select_get(unit, port,
  46126                                                            (uint32 *)value);
  46127         }
  46128         break;
  46129 #endif
  46130 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  46131     case bcmPortControlFieldHiGigClassSelect:
  46132 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  46133         if (soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) {
  46134             rv = _bcm_td2p_port_control_higig_class_select_get(unit, port,
  46135                                                                (uint32 *)value);
  46136         } else
  46137 #endif
  46138         {
  46139         rv = _bcm_trx_port_control_higig_class_select_get(unit, port,
  46140                                                            (uint32 *)value);
  46141         }
  46142         break;
  46143 #endif
  46144     case bcmPortControlSubportTagEnable:
  46145 #if defined (BCM_HGPROXY_COE_SUPPORT)
  46146         if(soc_feature(unit, soc_feature_hgproxy_subtag_coe)) {
  46147             rv = bcmi_xgs5_port_control_subtag_status_get(unit, port, value);
  46148         }
  46149 #endif 
  46150 #if defined (BCM_KATANA2_SUPPORT)
  46151         if (soc_feature(unit, soc_feature_subtag_coe)) {
  46152             if (SOC_IS_KATANA2(unit)) {
  46153                 rv = bcm_kt2_port_control_subtag_status_get(unit, port, value);
  46154             }
  46155         }
  46156 #endif
  46157         break;
  46158 
  46159 
  46160     case bcmPortControlLinkPhyEnable:
  46161 #if defined (BCM_KATANA2_SUPPORT)
  46162         if (soc_feature(unit, soc_feature_linkphy_coe)) {
  46163             if (SOC_IS_KATANA2(unit)) {
  46164                 rv = bcm_kt2_port_control_linkphy_status_get(unit, port, value);
  46165             }
  46166         }
  46167 #endif
  46168         break;
  46169 
  46170 #if defined(BCM_TRIDENT2_SUPPORT)
  46171 
  46172     case bcmPortControlFcoeRouteEnable:
  46173         if (soc_feature(unit, soc_feature_fcoe)) {
  46174 #ifdef BCM_TRIDENT3_SUPPORT
  46175             if (SOC_IS_TRIDENT3X(unit)) {
  46176                 rv = _bcm_esw_port_tab_get(unit, port,
  46177                                        FCOE_ROUTE_ENABLEf, value);
  46178             } else 
  46179 #endif
  46180             {
  46181             if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_ROUTE_ENABLEf)) {
  46182                 rv = _bcm_esw_port_tab_get(unit, port,
  46183                                            FCOE_ROUTE_ENABLEf, value);
  46184             }
  46185         }
  46186         }
  46187         break;
  46188 
  46189     case bcmPortControlFcoeVftEnable:
  46190         if (soc_feature(unit, soc_feature_fcoe)) {
  46191             if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VFT_ENABLEf)) {
  46192                 rv = _bcm_esw_port_tab_get(unit, port,
  46193                                            FCOE_VFT_ENABLEf, value);
  46194             }
  46195         }
  46196         break;
  46197 
  46198     case bcmPortControlFcoeZoneCheckEnable:
  46199         if (soc_feature(unit, soc_feature_fcoe)) {
  46200             if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm,
  46201                                     FCOE_ZONE_CHECK_ENABLEf)) {
  46202                 rv = _bcm_esw_port_tab_get(unit, port,
  46203                                            FCOE_ZONE_CHECK_ENABLEf, value);
  46204             }
  46205         }
  46206         break;
  46207 
  46208     case bcmPortControlFcoeSourceBindCheckEnable:
  46209         if (soc_feature(unit, soc_feature_fcoe)) {
  46210             if (SOC_MEM_FIELD_VALID(unit, PORT_TABm,
  46211                                     FCOE_SRC_BIND_CHECK_ENABLEf)) {
  46212                 rv = _bcm_esw_port_tab_get(unit, port,
  46213                                            FCOE_SRC_BIND_CHECK_ENABLEf,
  46214                                            value);
  46215             }
  46216         }
  46217         break;
  46218 
  46219     case bcmPortControlFcoeFpmaPrefixCheckEnable:
  46220         if (soc_feature(unit, soc_feature_fcoe)) {
  46221             if (SOC_MEM_FIELD_VALID(unit, PORT_TABm,
  46222                                     FCOE_SRC_FPMA_PREFIX_CHECK_ENABLEf)) {
  46223                 rv = _bcm_esw_port_tab_get(unit, port,
  46224                                            FCOE_SRC_FPMA_PREFIX_CHECK_ENABLEf,
  46225                                            value);
  46226             }
  46227         }
  46228         break;
  46229 
  46230     case bcmPortControlFcoeDoNotLearn:
  46231         if (soc_feature(unit, soc_feature_fcoe)) {
  46232             if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_DO_NOT_LEARNf))) {
  46233                 rv = _bcm_esw_port_tab_get(unit, port,
  46234                                            FCOE_DO_NOT_LEARNf, value);
  46235             }
  46236         }
  46237         break;
  46238 
  46239     case bcmPortControlFcoeNetworkPort:
  46240         if (soc_feature(unit, soc_feature_fcoe)) {
  46241             if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_NETWORK_PORTf))) {
  46242                 rv = _bcm_esw_port_tab_get(unit, port,
  46243                                            FCOE_NETWORK_PORTf, value);
  46244             }
  46245         }
  46246         break;
  46247 
  46248     case bcmPortControlFcoeFabricSel:
  46249         if (soc_feature(unit, soc_feature_fcoe)) {
  46250             if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_SELf)) {
  46251                 rv = _bcm_esw_port_tab_get(unit, port,
  46252                                            FCOE_FABRIC_SELf, value);
  46253             }
  46254         }
  46255         break;
  46256 
  46257     case bcmPortControlFcoeFabricId:
  46258         if (soc_feature(unit, soc_feature_fcoe)) {
  46259 #ifdef BCM_TRIDENT3_SUPPORT
  46260             if (SOC_IS_TRIDENT3X(unit)) {
  46261                     rv = _bcm_esw_port_tab_get(unit, port,
  46262                                            FCOE_FABRIC_IDf, value);
  46263             } else
  46264 #endif
  46265             {
  46266             if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_IDf)) {
  46267                 rv = _bcm_esw_port_tab_get(unit, port,
  46268                                            FCOE_FABRIC_IDf, value);
  46269             }
  46270         }
  46271         }
  46272         break;
  46273 
  46274     case bcmPortControlFcoeFabricPri:
  46275         if (soc_feature(unit, soc_feature_fcoe)) {
  46276 #ifdef BCM_TRIDENT3_SUPPORT
  46277             if (SOC_IS_TRIDENT3X(unit)) {
  46278                 rv = _bcm_esw_port_tab_get(unit, port,
  46279                                            FCOE_FABRIC_PRIf, value);
  46280             } else
  46281 #endif
  46282             if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_PRIf)) {
  46283                 rv = _bcm_esw_port_tab_get(unit, port,
  46284                                            FCOE_FABRIC_PRIf, value);
  46285             }
  46286         }
  46287         break;
  46288 
  46289     case bcmPortControlFcoeFcCrcAction:
  46290         if (soc_feature(unit, soc_feature_fcoe)) {
  46291             if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm,
  46292                                     FCOE_FC_CRC_ACTIONf)) {
  46293                 egr_ing_port_entry_t egr_ing_port_entry;
  46294 
  46295                 rv = READ_EGR_ING_PORTm(unit, MEM_BLOCK_ANY, port,
  46296                                         &egr_ing_port_entry);
  46297                 if (BCM_SUCCESS(rv)) {
  46298                     *value = soc_mem_field32_get(unit, EGR_ING_PORTm,
  46299                                                  &egr_ing_port_entry,
  46300                                                  FCOE_FC_CRC_ACTIONf);
  46301                 }
  46302             }
  46303         }
  46304         break;
  46305 
  46306     case bcmPortControlFcoeFcCrcRecompute:
  46307         if (soc_feature(unit, soc_feature_fcoe)) {
  46308             if (SOC_MEM_IS_VALID(unit, EGR_PORTm) &&
  46309                 SOC_MEM_FIELD_VALID(unit, EGR_PORTm,
  46310                                     FCOE_FC_CRC_RECOMPUTEf)) {
  46311                 egr_port_entry_t egr_port_entry;
  46312 
  46313                 rv = READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port,
  46314                                     &egr_port_entry);
  46315                 if (BCM_SUCCESS(rv)) {
  46316                     *value = soc_mem_field32_get(unit, EGR_PORTm,
  46317                                                  &egr_port_entry,
  46318                                                  FCOE_FC_CRC_RECOMPUTEf);
  46319                 }
  46320             }
  46321         }
  46322         break;
  46323 
  46324     case bcmPortControlFcoeFcEofIgnore:
  46325         if (soc_feature(unit, soc_feature_fcoe)) {
  46326             if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm,
  46327                                     FCOE_FC_EOF_IGNOREf)) {
  46328                 egr_ing_port_entry_t egr_ing_port_entry;
  46329 
  46330                 rv = READ_EGR_ING_PORTm(unit, MEM_BLOCK_ANY, port,
  46331                                         &egr_ing_port_entry);
  46332                 if (BCM_SUCCESS(rv)) {
  46333                     *value = soc_mem_field32_get(unit, EGR_ING_PORTm,
  46334                                                  &egr_ing_port_entry,
  46335                                                  FCOE_FC_EOF_IGNOREf);
  46336                 }
  46337             }
  46338         }
  46339         break;
  46340 
  46341     case bcmPortControlFcoeTranslateKeyFirst:
  46342     case bcmPortControlFcoeTranslateKeySecond:
  46343         if (soc_feature(unit, soc_feature_fcoe)) {
  46344             int reg_val;
  46345             int key_type;
  46346             int use_port = 0;
  46347             int vt_port_type;
  46348 
  46349             if (type == bcmPortControlFcoeTranslateKeyFirst) {
  46350                 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VT_KEY_TYPE_1f)) {
  46351                     rv = _bcm_esw_port_tab_get(unit, port,
  46352                                                FCOE_VT_KEY_TYPE_1f, &reg_val);
  46353                 }
  46354 
  46355                 if (BCM_SUCCESS(rv)) {
  46356                     rv = _bcm_esw_port_config_get(unit, port,
  46357                                                   _bcmPortVTKeyPortFirst,
  46358                                                  &vt_port_type);
  46359                     if (BCM_SUCCESS(rv)) {
  46360                         if (vt_port_type != 0) {
  46361                             use_port = 1;
  46362                         }
  46363                     }
  46364                 }
  46365             } else {
  46366                 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VT_KEY_TYPE_2f)) {
  46367                     rv = _bcm_esw_port_tab_get(unit, port,
  46368                                                FCOE_VT_KEY_TYPE_2f, &reg_val);
  46369                 }
  46370                 if (BCM_SUCCESS(rv)) {
  46371                     rv = _bcm_esw_port_config_get(unit, port,
  46372                                                   _bcmPortVTKeyPortSecond,
  46373                                                  &vt_port_type);
  46374                     if (BCM_SUCCESS(rv)) {
  46375                         if (vt_port_type != 0) {
  46376                             use_port = 1;
  46377                         }
  46378                     }
  46379                 }
  46380             }
  46381 
  46382             if (BCM_SUCCESS(rv)) {
  46383                 /* convert register value to common key type */
  46384                 rv = _bcm_esw_vlan_xlate_key_type_get(unit, reg_val, &key_type);
  46385                 if (!BCM_SUCCESS(rv)) {
  46386                     break;
  46387                 }
  46388 
  46389                 /* convert common key type value to
  46390                    bcm_fcoe_vsan_translate_key_t */
  46391                 switch (key_type) {
  46392                     case VLXLT_HASH_KEY_TYPE_IVID_OVID:
  46393                         if (use_port) {
  46394                             *value = bcmFcoeVsanTranslateKeyPortDouble;
  46395                         } else {
  46396                             *value = bcmFcoeVsanTranslateKeyDouble;
  46397                         }
  46398                         break;
  46399                     case VLXLT_HASH_KEY_TYPE_OTAG:
  46400                         if (use_port) {
  46401                             *value = bcmFcoeVsanTranslateKeyPortOuterTag;
  46402                         } else {
  46403                             *value = bcmFcoeVsanTranslateKeyOuterTag;
  46404                         }
  46405                         break;
  46406                     case VLXLT_HASH_KEY_TYPE_ITAG:
  46407                         if (use_port) {
  46408                             *value = bcmFcoeVsanTranslateKeyPortInnerTag;
  46409                         } else {
  46410                             *value = bcmFcoeVsanTranslateKeyInnerTag;
  46411                         }
  46412                         break;
  46413                     case VLXLT_HASH_KEY_TYPE_OVID:
  46414                         if (use_port) {
  46415                             *value = bcmFcoeVsanTranslateKeyPortOuter;
  46416                         } else {
  46417                             *value = bcmFcoeVsanTranslateKeyOuter;
  46418                         }
  46419                         break;
  46420                     case VLXLT_HASH_KEY_TYPE_IVID:
  46421                         if (use_port) {
  46422                             *value = bcmFcoeVsanTranslateKeyPortInner;
  46423                         } else {
  46424                             *value = bcmFcoeVsanTranslateKeyInner;
  46425                         }
  46426                         break;
  46427                     case VLXLT_HASH_KEY_TYPE_PRI_CFI:
  46428                         if (use_port) {
  46429                             *value = bcmFcoeVsanTranslateKeyPortOuterPri;
  46430                         } else {
  46431                             *value = bcmFcoeVsanTranslateKeyOuterPri;
  46432                         }
  46433                         break;
  46434                     case VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN:
  46435                         if (use_port) {
  46436                             *value = bcmFcoeVsanTranslateKeyPortDoubleVsan;
  46437                         } else {
  46438                             *value = bcmFcoeVsanTranslateKeyDoubleVsan;
  46439                         }
  46440                         break;
  46441                     case VLXLT_HASH_KEY_TYPE_IVID_VSAN:
  46442                         if (use_port) {
  46443                             *value = bcmFcoeVsanTranslateKeyPortInnerVsan;
  46444                         } else {
  46445                             *value = bcmFcoeVsanTranslateKeyInnerVsan;
  46446                         }
  46447                         break;
  46448                     case VLXLT_HASH_KEY_TYPE_OVID_VSAN:
  46449                         if (use_port) {
  46450                             *value = bcmFcoeVsanTranslateKeyPortOuterVsan;
  46451                         } else {
  46452                             *value = bcmFcoeVsanTranslateKeyOuterVsan;
  46453                         }
  46454                         break;
  46455                     default:
  46456                         *value = bcmFcoeVsanTranslateKeyInvalid;
  46457                         break;
  46458                 }
  46459             }
  46460         } else {
  46461             rv = BCM_E_UNAVAIL;
  46462         }
  46463         break;
  46464 
  46465     case bcmPortControlFcoeTranslateKeyFirstEgress:
  46466     case bcmPortControlFcoeTranslateKeySecondEgress:
  46467         if (soc_feature(unit, soc_feature_fcoe)) {
  46468             int key_type = -1;
  46469 
  46470             if (type == bcmPortControlFcoeTranslateKeyFirstEgress) {
  46471                 if (SOC_IS_TRIDENT3X(unit) ||
  46472                     SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_VT_LOOKUP_1f)) {
  46473                     rv = _bcm_esw_egr_port_tab_get(unit, port,
  46474                                                    FCOE_VT_LOOKUP_1f,
  46475                                                    &key_type);
  46476                 }
  46477             } else {
  46478                 if (SOC_IS_TRIDENT3X(unit) ||
  46479                     SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_VT_LOOKUP_2f)) {
  46480                     rv = _bcm_esw_egr_port_tab_get(unit, port,
  46481                                                    FCOE_VT_LOOKUP_2f,
  46482                                                    &key_type);
  46483                 }
  46484             }
  46485 
  46486             if (BCM_SUCCESS(rv)) {
  46487                 /* convert common key type value to
  46488                    bcm_fcoe_vsan_translate_key_egress_t */
  46489                 switch (key_type) {
  46490                     case EGR_VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN:
  46491                         *value = bcmFcoeVsanTranslateKeyEgressDoubleVsan;
  46492                         break;
  46493                     case EGR_VLXLT_HASH_KEY_TYPE_VSAN:
  46494                         *value = bcmFcoeVsanTranslateKeyEgressVsan;
  46495                         break;
  46496                     case EGR_VLXLT_HASH_KEY_TYPE_IVID_VSAN:
  46497                         *value = bcmFcoeVsanTranslateKeyEgressInnerVsan;
  46498                         break;
  46499                     case EGR_VLXLT_HASH_KEY_TYPE_OVID_VSAN:
  46500                         *value = bcmFcoeVsanTranslateKeyEgressOuterVsan;
  46501                         break;
  46502                     case EGR_VLXLT_HASH_KEY_TYPE_IVID_OVID:
  46503                         *value = bcmFcoeVsanTranslateKeyEgressDouble;
  46504                         break;
  46505                     case EGR_VLXLT_HASH_KEY_TYPE_IVID:
  46506                         *value = bcmFcoeVsanTranslateKeyEgressInner;
  46507                         break;
  46508                     case EGR_VLXLT_HASH_KEY_TYPE_OVID:
  46509                         *value = bcmFcoeVsanTranslateKeyEgressOuter;
  46510                         break;
  46511                     default:
  46512                         *value = bcmFcoeVsanTranslateKeyEgressInvalid;
  46513                         break;
  46514                 }
  46515             }
  46516         } else {
  46517             rv = BCM_E_UNAVAIL;
  46518         }
  46519         break;
  46520 
  46521 #endif  /* BCM_TRIDENT2_SUPPORT */
  46522     case bcmPortControlEEEMode:
  46523         if (soc_feature(unit, soc_feature_eee_bb_mode)) {
  46524             uint32 fval = 0;
  46525             uint32 rval = 0;
  46526             uint32 temp = 0;
  46527             if (soc_feature (unit, soc_feature_high_portcount_register)) {
  46528                 soc_reg_t eee_bb_reg;
  46529                 int phy_port;
  46530                 int mmu_port;
  46531                 int offset;
  46532 
  46533                 phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  46534                 mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port];
  46535                 if (mmu_port < 32) {
  46536                     eee_bb_reg = EEE_BB_ENABLE_0r;
  46537                     offset = mmu_port;
  46538                 } else if ((mmu_port >=32) && (mmu_port < 64)) {
  46539                     eee_bb_reg = EEE_BB_ENABLE_1r;
  46540                     offset = mmu_port - 32;
  46541                 } else { /* mmu_port >= 64 */
  46542                     eee_bb_reg = EEE_BB_ENABLE_2r;
  46543                     offset = mmu_port - 64;
  46544                 }
  46545                 temp = (1 << offset);
  46546                 BCM_IF_ERROR_RETURN(
  46547                     soc_reg32_get(unit, eee_bb_reg, REG_PORT_ANY, 0, &rval));
  46548                 fval = soc_reg_field_get(unit, eee_bb_reg, rval,
  46549                                          EEE_BB_ENABLEf);
  46550                 *value = (fval & temp) ? \
  46551                          bcmPortEEEBurstAndBatchMode:bcmPortEEENativeMode;
  46552             } else {
  46553             temp = (1 << port);
  46554             temp >>= 2;
  46555             rv = READ_EEE_BB_ENABLEr(unit, &rval);
  46556             if (BCM_SUCCESS(rv)) {
  46557                 fval = soc_reg_field_get(unit, EEE_BB_ENABLEr, rval,
  46558                                            EEE_BB_ENABLEf);
  46559                 *value = (fval & temp) ? \
  46560                  bcmPortEEEBurstAndBatchMode:bcmPortEEENativeMode;
  46561             }
  46562         }
  46563         }
  46564         break;
  46565 #ifdef BCM_GREYHOUND_SUPPORT
  46566         case bcmPortControlWredDropCountUpdateEnableQueueMask:
  46567             if (soc_feature(unit, soc_feature_wred_drop_counter_per_port)) {
  46568 #if defined(BCM_GREYHOUND2_SUPPORT)
  46569                 if (SOC_IS_GREYHOUND2(unit)) {
  46570                     rv = bcmi_gh2_cosq_wred_port_control_get(unit, port, type,
  46571                                                              value);
  46572                 } else
  46573 #endif /* BCM_GREYHOUND2_SUPPORT */
  46574                 {
  46575                 rv = READ_WRED_DROP_CTR_CONFIGr(unit, port, &val);
  46576                 *value = soc_reg_field_get(unit, WRED_DROP_CTR_CONFIGr,
  46577                                         val, QUEUE_MASKf);
  46578             }
  46579             }
  46580             break;
  46581         case bcmPortControlWredDropCountUpdateEnableColorMask:
  46582             if (soc_feature(unit, soc_feature_wred_drop_counter_per_port)) {
  46583 #if defined(BCM_GREYHOUND2_SUPPORT)
  46584                 if (SOC_IS_GREYHOUND2(unit)) {
  46585                     rv = bcmi_gh2_cosq_wred_port_control_get(unit, port, type,
  46586                                                              value);
  46587                 } else
  46588 #endif /* BCM_GREYHOUND2_SUPPORT */
  46589                 {
  46590                 uint32 fld_val;
  46591                 rv = READ_WRED_DROP_CTR_CONFIGr(unit, port, &val);
  46592                 if (BCM_SUCCESS(rv)) {
  46593                     fld_val = soc_reg_field_get(unit, WRED_DROP_CTR_CONFIGr,
  46594                                         val, COLOR_MASKf);
  46595                     *value = 0;
  46596                     if (fld_val & 0x4) {
  46597                         *value |= (0x1 << bcmColorGreen);
  46598                     }
  46599                     if (fld_val & 0x2) {
  46600                         *value |= (0x1 << bcmColorYellow);
  46601                     }
  46602                     if (fld_val & 0x1) {
  46603                         *value |= (0x1 << bcmColorRed);
  46604                     }
  46605                 }
  46606             }
  46607             }
  46608             break;
  46609 #endif /* BCM_GREYHOUND_SUPPORT */
  46610 #ifdef BCM_TRIDENT2_SUPPORT
  46611     case bcmPortControlProbeSerdesReset:
  46612         if (SOC_IS_TD2_TT2(unit)) {
  46613             *value =
  46614                 PORT(unit, port).flags & _PORT_INFO_PROBE_RESET_SERDES ?
  46615                 1 : 0;
  46616             rv = BCM_E_NONE;
  46617         }
  46618         break;
  46619 #endif /* BCM_TRIDENT2_SUPPORT */
  46620         case bcmPortControlMmuTrafficEnable:
  46621             rv = bcm_esw_port_enqueue_get(unit, port, value);
  46622             break;
  46623     case bcmPortControlRxFastLOS:
  46624         rv = _bcm_esw_link_fast_get(unit, port, value);
  46625         break;
  46626     case bcmPortControlLLFCReceive:
  46627     case bcmPortControlLLFCTransmit:
  46628 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  46629     case bcmPortControlSAFCReceive:
  46630     case bcmPortControlSAFCTransmit:
  46631 #endif
  46632         rv = _bcm_esw_port_llfc_get(unit, port, type, value);
  46633         break;
  46634     case bcmPortControlTrunkLoadBalancingRandomizer:
  46635 #ifdef BCM_TOMAHAWK_SUPPORT
  46636         if (soc_feature(unit, soc_feature_randomized_load_balance)) {
  46637             rv = _bcm_esw_port_tab_get(unit, port,
  46638                                        OFFSET_TRUNK_RANDOM_LBf, value);
  46639         }
  46640 #endif /* BCM_TOMAHAWK_SUPPORT */
  46641         break;
  46642     case bcmPortControlECMPLevel1LoadBalancingRandomizer:
  46643 #ifdef BCM_TOMAHAWK_SUPPORT
  46644         if (soc_feature(unit, soc_feature_ecmp_random)) {
  46645             rv = _bcm_esw_port_tab_get(unit, port,
  46646                                        OFFSET_ECMP_RANDOM_LBf , value);
  46647         }
  46648 #endif /* BCM_TOMAHAWK_SUPPORT */
  46649         break;
  46650     case bcmPortControlECMPLevel2LoadBalancingRandomizer:
  46651 #ifdef BCM_TOMAHAWK_SUPPORT
  46652         if (soc_feature(unit, soc_feature_ecmp_random)) {
  46653             rv = _bcm_esw_port_tab_get(unit, port,
  46654                                        OFFSET_ECMP_LEVEL2_RANDOM_LBf,
  46655                                        value);
  46656         }
  46657 #endif /* BCM_TOMAHAWK_SUPPORT */
  46658         break;
  46659     case bcmPortControlMcastGroupRemap:
  46660        if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, NETWORK_PORTf)) {
  46661            SOC_IF_ERROR_RETURN
  46662                (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, port, &svp_entry));
  46663            *value = soc_SOURCE_VPm_field32_get(unit, &svp_entry,
  46664                                                NETWORK_PORTf);
  46665            rv = BCM_E_NONE;
  46666        }
  46667        break;
  46668     case bcmPortControlOOBFCTxReportIngEnable:
  46669         if (soc_feature(unit, soc_feature_oob_fc)) {
  46670 #ifdef BCM_TOMAHAWK_SUPPORT
  46671             if (SOC_IS_TOMAHAWKX(unit)) {
  46672                 rv = _bcm_th_oob_fc_tx_port_control_get(unit, port, value, 0);
  46673             }
  46674 #endif
  46675 #ifdef BCM_KATANA2_SUPPORT
  46676             if (SOC_IS_KATANA2(unit)) {
  46677                 rv = _bcm_kt2_oob_fc_tx_port_control_get(unit, port, value, 0);
  46678             }
  46679 #endif
  46680 #ifdef BCM_TRIDENT3_SUPPORT
  46681             if (SOC_IS_TRIDENT3X(unit)) {
  46682                 rv = _bcm_td3_oob_fc_tx_port_control_get(unit, port, value, 0);
  46683             } 
  46684 #endif
  46685 #ifdef BCM_APACHE_SUPPORT
  46686             if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
  46687                 rv = _bcm_ap_oob_fc_tx_port_control_get(unit, port, value, 0);
  46688             }
  46689 #endif
  46690         }
  46691         break;
  46692     case bcmPortControlOOBFCTxReportEgrEnable:
  46693         if (soc_feature(unit, soc_feature_oob_fc)) {
  46694 #ifdef BCM_TOMAHAWK_SUPPORT
  46695             if (SOC_IS_TOMAHAWKX(unit)) {
  46696                 rv = _bcm_th_oob_fc_tx_port_control_get(unit, port, value, 1);
  46697             } 
  46698 #endif
  46699 #ifdef BCM_APACHE_SUPPORT
  46700             if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) {
  46701                 rv = _bcm_ap_oob_fc_tx_port_control_get(unit, port, value, 1);
  46702             } 
  46703 #endif
  46704 #ifdef BCM_KATANA2_SUPPORT
  46705             if (SOC_IS_KATANA2(unit)) {
  46706                 rv = _bcm_kt2_oob_fc_tx_port_control_get(unit, port, value, 1);
  46707             }
  46708 #endif
  46709 #ifdef BCM_TRIDENT3_SUPPORT
  46710             if (SOC_IS_TRIDENT3X(unit)) {
  46711                 rv = _bcm_td3_oob_fc_tx_port_control_get(unit, port, value, 1);
  46712             }
  46713 #endif
  46714         }
  46715         break;
  46716 
  46717 	case bcmPortControlSubportTagSize:
  46718 #ifdef BCM_HGPROXY_COE_SUPPORT
  46719           if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 
  46720                                   DESTINATION_SUBPORT_TAG_TYPEf)) {
  46721 
  46722               int local_port = 0;
  46723 			  egr_port_entry_t  egr_port_entry;
  46724               if (BCM_GPORT_IS_SET(port)) {
  46725                   BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port));
  46726               } else {
  46727                   if(!SOC_PORT_VALID(unit, port)) {
  46728                       return BCM_E_PORT;
  46729                   } else {
  46730                       local_port = port;
  46731                   }
  46732               }
  46733 
  46734               SOC_IF_ERROR_RETURN
  46735                   (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, local_port, &egr_port_entry));
  46736               *value = soc_EGR_PORTm_field32_get(unit, &egr_port_entry,
  46737                                                   DESTINATION_SUBPORT_TAG_TYPEf);
  46738               rv = BCM_E_NONE;
  46739           }
  46740           if (SOC_IS_TRIDENT3X(unit)) {
  46741               *value = 0;
  46742               rv = BCM_E_NONE;
  46743           }
  46744 #endif
  46745 		  break;
  46746 
  46747 	case bcmPortControlSystemPortOverride:
  46748 #ifdef BCM_HGPROXY_COE_SUPPORT
  46749           if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 
  46750                                   VT_SYS_PORT_OVERRIDEf)) {
  46751 
  46752               rv = bcmi_xgs5_subport_subtag_port_override_get(unit, port,
  46753                                                               value);
  46754           }
  46755 #endif
  46756           break;
  46757 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  46758     case bcmPortControlSampleIngressDest:
  46759         if(soc_feature(unit, soc_feature_sflow_ing_mem)) {
  46760             sflow_ing_data_source_entry_t sflow_entry;
  46761             uint32 field_values[2] = {0, 0};
  46762             BCM_IF_ERROR_RETURN
  46763                 (READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  46764                                              &sflow_entry));
  46765             soc_SFLOW_ING_DATA_SOURCEm_field_get(unit, &sflow_entry,
  46766                                                  CPUf, &field_values[0]);
  46767             soc_SFLOW_ING_DATA_SOURCEm_field_get(unit, &sflow_entry,
  46768                                                  MIRRORf, &field_values[1]);
  46769             *value = field_values[0] | (field_values[1] << 1);
  46770             rv = BCM_E_NONE;
  46771         }
  46772         break;
  46773     case bcmPortControlSampleFlexDest:
  46774         if(soc_feature(unit, soc_feature_sflow_flex)) {
  46775             sflow_ing_flex_data_source_entry_t sflow_entry;
  46776             uint32 field_values[2] = {0, 0};
  46777             BCM_IF_ERROR_RETURN
  46778                 (READ_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  46779                                                   &sflow_entry));
  46780             soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_get(unit, &sflow_entry,
  46781                                                       CPUf, &field_values[0]);
  46782             soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_get(unit, &sflow_entry,
  46783                                                       MIRRORf, &field_values[1]);
  46784             *value = field_values[0] | (field_values[1] << 1);
  46785             rv = BCM_E_NONE;
  46786         }
  46787         break;
  46788     case bcmPortControlSampleFlexRate:
  46789         if(soc_feature(unit, soc_feature_sflow_flex)) {
  46790             sflow_ing_flex_data_source_entry_t sflow_entry;
  46791             uint32 field_enable, field_thresh;
  46792 
  46793             /* Read ENABLE and THRESHOLD fields from flex rate data table */
  46794             BCM_IF_ERROR_RETURN
  46795                 (READ_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  46796                                                   &sflow_entry));
  46797             soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_get(unit, &sflow_entry,
  46798                                                       ENABLEf, &field_enable);
  46799             soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_get(unit, &sflow_entry,
  46800                                                       THRESHOLDf,
  46801                                                       &field_thresh);
  46802 
  46803             if (field_enable) {
  46804                 if (field_thresh) {
  46805                     *value = (1 << (SFLOW_RANGE_MAX(unit))) / field_thresh;
  46806                 } else {
  46807                     *value = 1 << (SFLOW_RANGE_MAX(unit));
  46808                 }
  46809             } else {
  46810                 *value = 0;
  46811                 if (field_thresh) {
  46812                     return BCM_E_INTERNAL;
  46813                 }
  46814             }
  46815             rv = BCM_E_NONE;
  46816         }
  46817         break;
  46818 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */
  46819 #ifdef BCM_XGS3_SWITCH_SUPPORT
  46820     case bcmPortControlSampleIngressEnable:
  46821         if (SOC_IS_XGS3_SWITCH(unit)) {
  46822             uint32 regval       = 0;
  46823             uint32 field_enable = 0;
  46824 #ifdef BCM_TOMAHAWK_SUPPORT
  46825             sflow_ing_data_source_entry_t sflow_entry;
  46826 #endif /* BCM_TOMAHAWK_SUPPORT */
  46827 
  46828 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  46829             if (soc_feature(unit, soc_feature_sflow_ing_mem)) {
  46830                 BCM_IF_ERROR_RETURN(
  46831                     READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  46832                                                 &sflow_entry));
  46833 
  46834                 soc_SFLOW_ING_DATA_SOURCEm_field_get(unit, &sflow_entry, ENABLEf,
  46835                                              &field_enable);
  46836             } else
  46837 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */
  46838             {
  46839                 if (!SOC_REG_IS_VALID(unit, SFLOW_ING_THRESHOLDr)) {
  46840                     return BCM_E_UNAVAIL;
  46841                 }
  46842                 BCM_IF_ERROR_RETURN(READ_SFLOW_ING_THRESHOLDr(unit, port, &regval));
  46843                 field_enable = soc_reg_field_get(unit, SFLOW_ING_THRESHOLDr, regval,
  46844                                                          ENABLEf);
  46845             }
  46846 
  46847             *value = field_enable ? 1 : 0;
  46848             rv = BCM_E_NONE;
  46849         } else {
  46850             rv = BCM_E_UNAVAIL;
  46851         }
  46852         break;
  46853     case bcmPortControlSampleEgressEnable:
  46854         if (SOC_IS_XGS3_SWITCH(unit)) {
  46855             uint32 regval       = 0;
  46856             uint32 field_enable = 0;
  46857 
  46858             if (!SOC_REG_IS_VALID(unit, SFLOW_EGR_THRESHOLDr)) {
  46859                 return BCM_E_UNAVAIL;
  46860             }
  46861             BCM_IF_ERROR_RETURN(READ_SFLOW_EGR_THRESHOLDr(unit, port, &regval));
  46862             field_enable = soc_reg_field_get(unit, SFLOW_EGR_THRESHOLDr, regval,
  46863                                                     ENABLEf);
  46864 
  46865             *value = field_enable ? 1 : 0;
  46866             rv = BCM_E_NONE;
  46867         } else {
  46868             rv = BCM_E_UNAVAIL;
  46869         }
  46870         break;
  46871     case bcmPortControlSampleIngressRate:
  46872         if (SOC_IS_XGS3_SWITCH(unit)) {
  46873             uint32 regval       = 0;
  46874             uint32 field_value;
  46875 #ifdef BCM_TOMAHAWK_SUPPORT
  46876             sflow_ing_data_source_entry_t sflow_entry;
  46877 #endif /* BCM_TOMAHAWK_SUPPORT */
  46878 
  46879 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
  46880             if (soc_feature(unit, soc_feature_sflow_ing_mem)) {
  46881                 BCM_IF_ERROR_RETURN(
  46882                     READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port,
  46883                                                 &sflow_entry));
  46884 
  46885                 soc_SFLOW_ING_DATA_SOURCEm_field_get(unit, &sflow_entry, THRESHOLDf,
  46886                                              &field_value);
  46887             } else
  46888 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */
  46889             {
  46890                 if (!SOC_REG_IS_VALID(unit, SFLOW_ING_THRESHOLDr)) {
  46891                     return BCM_E_UNAVAIL;
  46892                 }
  46893                 BCM_IF_ERROR_RETURN(READ_SFLOW_ING_THRESHOLDr(unit, port, &regval));
  46894 
  46895                 field_value = soc_reg_field_get(unit, SFLOW_ING_THRESHOLDr,
  46896                                                      regval, THRESHOLDf);
  46897             }
  46898 
  46899             /*
  46900              * For early sFlow implementations the 16-bit threshold value
  46901              * is compared to bits [23:8] of the sFlow random number.
  46902              */
  46903             if (soc_feature(unit, soc_feature_sample_offset8)) {
  46904                 field_value <<= 8;
  46905             }
  46906 
  46907             if (field_value) {
  46908                 *value = (1 << (SFLOW_RANGE_MAX(unit))) / field_value;
  46909             } else {
  46910                 *value = 0;
  46911             }
  46912             rv = BCM_E_NONE;
  46913         } else {
  46914             rv = BCM_E_UNAVAIL;
  46915         }
  46916         break;
  46917     case bcmPortControlSampleEgressRate:
  46918         if (SOC_IS_XGS3_SWITCH(unit)) {
  46919             uint32 regval;
  46920             uint32 field_value;
  46921 
  46922             if (!SOC_REG_IS_VALID(unit, SFLOW_EGR_THRESHOLDr)) {
  46923                 return BCM_E_UNAVAIL;
  46924             }
  46925             BCM_IF_ERROR_RETURN(READ_SFLOW_EGR_THRESHOLDr(unit, port, &regval));
  46926 
  46927             field_value = soc_reg_field_get(unit, SFLOW_EGR_THRESHOLDr,
  46928                                                     regval, THRESHOLDf);
  46929 
  46930             /*
  46931              * For early sFlow implementations the 16-bit threshold value
  46932              * is compared to bits [23:8] of the sFlow random number.
  46933              */
  46934             if (soc_feature(unit, soc_feature_sample_offset8)) {
  46935                 field_value <<= 8;
  46936             }
  46937 
  46938             if (field_value) {
  46939                 *value = (1 << (SFLOW_RANGE_MAX(unit))) / field_value;
  46940             } else {
  46941                 *value = 0;
  46942             }
  46943             rv = BCM_E_NONE;
  46944         } else {
  46945             rv = BCM_E_UNAVAIL;
  46946         }
  46947         break;
  46948 #endif
  46949     case bcmPortControlExternalBufferEnable:
  46950 #if defined(BCM_KATANA2_SUPPORT)
  46951           if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_ddr3)) {
  46952               rv = _bcm_kt2_cosq_port_ext_buf_get(unit, port, value);
  46953           }
  46954 #endif
  46955         break;
  46956 #ifdef BCM_HURRICANE3_SUPPORT
  46957     case bcmPortControlTrustMimlPri:
  46958         if (soc_feature(unit, soc_feature_miml)) {
  46959             rv = _bcm_esw_port_tab_get(unit, port,
  46960                                        USE_MIML_PCP_FOR_PRIf, value);
  46961         }
  46962         break;
  46963     case bcmPortControlTrustCustomHeaderPri:
  46964         if (soc_feature(unit, soc_feature_custom_header)) {
  46965             rv = _bcm_esw_port_tab_get(unit, port,
  46966                                        USE_CUSTOM_HEADER_FOR_PRIf, value);
  46967         }
  46968         break;
  46969     case bcmPortControlCustomHeaderEncapEnable:
  46970         if (soc_feature(unit, soc_feature_custom_header)) {
  46971             uint64 val64;
  46972 
  46973             rv = READ_EGR_PORT_64r(unit, port, &val64);
  46974             if (BCM_SUCCESS(rv)) {
  46975                 *value = soc_reg64_field32_get(unit, EGR_PORT_64r,
  46976                                         val64, CUSTOM_HEADER_ENABLEf);
  46977             }
  46978         }
  46979         break;
  46980 #endif /* BCM_HURRICANE3_SUPPORT */
  46981     case bcmPortControl1588P2PDelay:
  46982         {
  46983             uint32 link_delay;
  46984             int mac_rx_latency = 0;
  46985             int speed;
  46986             rv = bcm_esw_port_speed_get(unit, port, &speed);
  46987             soc_property_port_get(unit, port,
  46988                                               spn_LINK_DELAY(speed), mac_rx_latency);
  46989 
  46990             if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAYr, port)) {
  46991                 soc_reg32_get(unit, EGR_1588_LINK_DELAYr,
  46992                                         port, LINK_DELAYf, &link_delay);
  46993                 *value = link_delay - mac_rx_latency;
  46994                 rv =  BCM_E_NONE;
  46995             } else if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAY_64r, port)) {
  46996                 soc_reg_above_64_field32_read(unit, EGR_1588_LINK_DELAY_64r,
  46997                                             port, 0, LINK_DELAYf, &link_delay);
  46998                 *value = link_delay - mac_rx_latency;
  46999                 rv =  BCM_E_NONE;
  47000             } else {
  47001                 rv = BCM_E_UNAVAIL;
  47002                 /* No LINK_DELAY register, so no-op */
  47003             }
  47004         }
  47005         break;
  47006     case bcmPortControlPacketTimeStampInsertRx:
  47007 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  47008     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  47009         if (soc_feature(unit, soc_feature_timestamp)) {
  47010             int ing_insert;
  47011             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  47012 
  47013             BCM_IF_ERROR_RETURN(
  47014                 _bcm_esw_port_tab_get(unit, port, INSERT_RX_TIMESTAMPf,
  47015                                       &ing_insert));
  47016             *value = ing_insert;
  47017             rv = BCM_E_NONE;
  47018         }
  47019 #endif
  47020         break;
  47021     case bcmPortControlPacketTimeStampInsertTx:
  47022 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  47023     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  47024         if (soc_feature(unit, soc_feature_timestamp)) {
  47025             uint32 regval;
  47026             uint32 egr_insert;
  47027             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  47028 
  47029             BCM_IF_ERROR_RETURN(READ_EGR_TS_CONTROLr(unit, port, &regval));
  47030             egr_insert = soc_reg_field_get(unit, EGR_TS_CONTROLr, regval,
  47031                                            INSERT_TX_TIMESTAMPf);
  47032             *value = (int)egr_insert;
  47033             rv = BCM_E_NONE;
  47034         }
  47035 #endif
  47036         break;
  47037     case bcmPortControlPacketTimeStampSrcPortInsertCancel:
  47038 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  47039     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  47040         if (soc_feature(unit, soc_feature_timestamp)) {
  47041             int ing_disable;
  47042             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  47043 
  47044             BCM_IF_ERROR_RETURN(
  47045                 _bcm_esw_port_tab_get(unit, port, DISABLE_TIMESTAMPINGf,
  47046                                       &ing_disable));
  47047             *value = ing_disable;
  47048             rv = BCM_E_NONE;
  47049         }
  47050 #endif
  47051         break;
  47052     case bcmPortControlPacketTimeStampDestPortInsertCancel:
  47053 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  47054     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  47055         if (soc_feature(unit, soc_feature_timestamp)) {
  47056             uint32 regval;
  47057             uint32 egr_disable;
  47058             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  47059 
  47060             BCM_IF_ERROR_RETURN(READ_EGR_TS_CONTROLr(unit, port, &regval));
  47061             egr_disable = soc_reg_field_get(unit, EGR_TS_CONTROLr, regval,
  47062                                             DISABLE_TIMESTAMPINGf);
  47063             *value = (int)egr_disable;
  47064             rv = BCM_E_NONE;
  47065         }
  47066 #endif
  47067         break;
  47068     case bcmPortControlPacketTimeStampRxId:
  47069 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  47070     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  47071         if (soc_feature(unit, soc_feature_timestamp)) {
  47072             uint32 regval;
  47073             egr_ts_ing_port_map_entry_t egr_ts_entry;
  47074             uint32 id;
  47075             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  47076             if (SOC_REG_IS_VALID(unit, EGR_TS_ING_PORT_MAPr)) {
  47077                 BCM_IF_ERROR_RETURN(READ_EGR_TS_ING_PORT_MAPr(unit, port, &regval));
  47078                 id = soc_reg_field_get(unit, EGR_TS_ING_PORT_MAPr, regval,
  47079                                            TS_RX_ORIGIN_IDf);
  47080                 *value = (int)id;
  47081             } else {
  47082 
  47083             BCM_IF_ERROR_RETURN(
  47084                 READ_EGR_TS_ING_PORT_MAPm(unit, MEM_BLOCK_ANY, port, &egr_ts_entry));
  47085             soc_EGR_TS_ING_PORT_MAPm_field_get(unit, &egr_ts_entry, TS_RX_ORIGIN_IDf,
  47086                                                &regval);
  47087                 *value = (int)regval;
  47088 
  47089             }
  47090             rv = BCM_E_NONE;
  47091         }
  47092 #endif
  47093         break;
  47094     case bcmPortControlPacketTimeStampTxId:
  47095 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  47096     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  47097         if (soc_feature(unit, soc_feature_timestamp)) {
  47098             uint32 regval;
  47099             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  47100 
  47101             if (soc_reg_field_valid(unit, EGR_TS_CONTROL_2r, TS_TX_ORIGIN_IDf))
  47102             {
  47103                 BCM_IF_ERROR_RETURN(
  47104                             READ_EGR_TS_CONTROL_2r(unit, port, &regval));
  47105                 *value = soc_reg_field_get(
  47106                             unit, EGR_TS_CONTROL_2r, regval, TS_TX_ORIGIN_IDf);
  47107             } else {
  47108                 BCM_IF_ERROR_RETURN(READ_EGR_TS_CONTROLr(unit, port, &regval));
  47109                 *value = soc_reg_field_get(
  47110                             unit, EGR_TS_CONTROLr, regval, TS_TX_ORIGIN_IDf);
  47111             }
  47112             rv = BCM_E_NONE;
  47113         }
  47114 #endif
  47115         break;
  47116     case bcmPortControlPacketTimeStampByteMeterAdjust:
  47117 #if defined(BCM_TOMAHAWK2_SUPPORT) || \
  47118     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT)
  47119         if (soc_feature(unit, soc_feature_timestamp) && !SOC_IS_TOMAHAWK3(unit))
  47120         {
  47121             uint32 regval;
  47122             BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  47123 
  47124             BCM_IF_ERROR_RETURN(READ_EGR_TS_CONTROLr(unit, port, &regval));
  47125             *value = soc_reg_field_get(unit, EGR_TS_CONTROLr, regval,
  47126                                        TS_ADJUST_METERSf);
  47127             rv = BCM_E_NONE;
  47128         }
  47129 #endif
  47130         break;
  47131     case bcmPortControlE2EFCTransmitEnable:
  47132         if (soc_feature(unit, soc_feature_e2efc)) {
  47133             uint32 fval;
  47134             uint64 val;
  47135 
  47136             if (!IS_HG_PORT(unit, port)) {
  47137                 LOG_ERROR(
  47138                     BSL_LS_BCM_PORT,
  47139                     (BSL_META_U(unit,
  47140                                 "Error: unit %d port %d is not a Higig port. "
  47141                                 "E2EFC messages can only be transmitted to "
  47142                                 "or received from Higig ports.\n"),
  47143                      unit, port));
  47144                 return BCM_E_PARAM;
  47145             }
  47146 #if defined(BCM_KATANA2_SUPPORT)
  47147             if (SOC_IS_KATANA2(unit)) {
  47148                 BCM_IF_ERROR_RETURN(READ_E2EFC_IBP_ENr(unit, &fval));
  47149                 *value = fval;
  47150             } else
  47151 #endif
  47152             if (IS_XL_PORT(unit, port)) {
  47153                 BCM_IF_ERROR_RETURN(READ_XLMAC_E2E_CTRLr(unit, port, &val));
  47154                 fval = soc_reg64_field32_get(unit, XLMAC_E2E_CTRLr,
  47155                                              val, E2E_ENABLEf);
  47156                 *value = fval;
  47157             } else if (IS_CL_PORT(unit, port)) {
  47158                 BCM_IF_ERROR_RETURN(READ_CLMAC_E2E_CTRLr(unit, port, &val));
  47159                 fval = soc_reg64_field32_get(unit, CLMAC_E2E_CTRLr,
  47160                                              val, E2E_ENABLEf);
  47161                 *value = fval;
  47162             } else {
  47163                 return BCM_E_PARAM;
  47164             }
  47165 
  47166             rv = BCM_E_NONE;
  47167         }
  47168         break;
  47169     case bcmPortControlE2EFCReceiveEnable:
  47170         if (soc_feature(unit, soc_feature_e2efc)) {
  47171             uint32 val, fval;
  47172 
  47173             BCM_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &val));
  47174             fval = soc_reg_field_get(unit, IE2E_CONTROLr,
  47175                                      val, IBP_ENABLEf);
  47176             *value = fval;
  47177             rv = BCM_E_NONE;
  47178         }
  47179         break;
  47180     case bcmPortControlE2EFCCopyToCpuEnable:
  47181         if (soc_feature(unit, soc_feature_e2efc)) {
  47182             uint32 val, fval;
  47183 
  47184             BCM_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &val));
  47185             fval = soc_reg_field_get(unit, IE2E_CONTROLr,
  47186                                      val, IBP_TOCPUf);
  47187             *value = fval;
  47188             rv = BCM_E_NONE;
  47189         }
  47190         break;
  47191     /* Higher 3 bytes of Destination MAC address */
  47192     case bcmPortControlE2EFCDestMacOui:
  47193         if (soc_feature(unit, soc_feature_e2efc)) {
  47194             uint32 val_hi;
  47195             uint64 val_64, data_0;
  47196             soc_reg_t reg;
  47197 #if defined(BCM_KATANA2_SUPPORT)
  47198             uint32 val;
  47199 #endif
  47200             if (!IS_HG_PORT(unit, port)) {
  47201                 LOG_ERROR(
  47202                     BSL_LS_BCM_PORT,
  47203                     (BSL_META_U(unit,
  47204                                 "Error: unit %d port %d is not a Higig port. "
  47205                                 "E2EFC messages can only be transmitted to "
  47206                                 "or received from Higig ports.\n"),
  47207                      unit, port));
  47208                 return BCM_E_PARAM;
  47209             }
  47210 #if defined(BCM_KATANA2_SUPPORT)
  47211             if (SOC_IS_KATANA2(unit)) {
  47212 #if defined(BCM_SABER2_SUPPORT)
  47213                 if (SOC_IS_SABER2(unit)) {
  47214                     /* Do nothing */
  47215                 } else
  47216 #endif /* BCM_SABER2_SUPPORT */
  47217               {
  47218                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D0r, port, 0, &val));
  47219                     val_hi = soc_reg_field_get(unit, XIBP_D0r, val, DATA_BYTES_0_3f);
  47220                     *value = (val_hi >> 8) & 0xffffff;
  47221                     rv = BCM_E_NONE;
  47222                     break;
  47223                }
  47224            }
  47225 #endif /* BCM_KATANA2_SUPPORT */
  47226             if (IS_XL_PORT(unit, port)) {
  47227                 reg = XLMAC_E2EFC_DATA_HDR_0r;
  47228             } else if (IS_CL_PORT(unit, port)) {
  47229                 reg = CLMAC_E2EFC_DATA_HDR_0r;
  47230             } else {
  47231                 return BCM_E_PARAM;
  47232             }
  47233 
  47234             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg,
  47235                                             port, 0, &val_64));
  47236             data_0 = soc_reg64_field_get(unit, reg,
  47237                                          val_64, E2EFC_DATA_HDR_0f);
  47238             COMPILER_64_TO_32_HI(val_hi, data_0);
  47239             *value = (val_hi >> 8) & 0xffffff;
  47240             rv = BCM_E_NONE;
  47241         }
  47242         break;
  47243     /* Lower 3 bytes of Destination MAC address */
  47244     case bcmPortControlE2EFCDestMacNonOui:
  47245         if (soc_feature(unit, soc_feature_e2efc)) {
  47246             uint32 val_lo, val_hi;
  47247             uint64 val_64, data_0;
  47248             soc_reg_t reg;
  47249 #if defined(BCM_KATANA2_SUPPORT)
  47250             uint32 val;
  47251 #endif
  47252             if (!IS_HG_PORT(unit, port)) {
  47253                 LOG_ERROR(
  47254                     BSL_LS_BCM_PORT,
  47255                     (BSL_META_U(unit,
  47256                                 "Error: unit %d port %d is not a Higig port. "
  47257                                 "E2EFC messages can only be transmitted to "
  47258                                 "or received from Higig ports.\n"),
  47259                      unit, port));
  47260                 return BCM_E_PARAM;
  47261             }
  47262 #if defined(BCM_KATANA2_SUPPORT)
  47263             if (SOC_IS_KATANA2(unit)) {
  47264 #if defined(BCM_SABER2_SUPPORT)
  47265                 if (SOC_IS_SABER2(unit)) {
  47266                     /* Do nothing */
  47267                 } else
  47268 #endif /* BCM_SABER2_SUPPORT */
  47269               {
  47270                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D0r, port, 0, &val));
  47271                     val_hi = soc_reg_field_get(unit, XIBP_D0r, val, DATA_BYTES_0_3f);
  47272                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D1r, port, 0, &val));
  47273                     val_lo = soc_reg_field_get(unit, XIBP_D1r, val, DATA_BYTES_4_7f);
  47274                     *value = ((val_hi & 0xff) << 16) | ((val_lo >> 16) & 0xffff);
  47275                     rv = BCM_E_NONE;
  47276                     break;
  47277                }
  47278            }
  47279 #endif /* BCM_KATANA2_SUPPORT */
  47280             if (IS_XL_PORT(unit, port)) {
  47281                 reg = XLMAC_E2EFC_DATA_HDR_0r;
  47282             } else if (IS_CL_PORT(unit, port)) {
  47283                 reg = CLMAC_E2EFC_DATA_HDR_0r;
  47284             } else {
  47285                 return BCM_E_PARAM;
  47286             }
  47287 
  47288             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg,
  47289                                             port, 0, &val_64));
  47290             data_0 = soc_reg64_field_get(unit, reg,
  47291                                          val_64, E2EFC_DATA_HDR_0f);
  47292             COMPILER_64_TO_32_LO(val_lo, data_0);
  47293             COMPILER_64_TO_32_HI(val_hi, data_0);
  47294             *value = ((val_hi & 0xff) << 16) | ((val_lo >> 16) & 0xffff);
  47295             rv = BCM_E_NONE;
  47296         }
  47297         break;
  47298     /* Higher 3 bytes of Source MAC address */
  47299     case bcmPortControlE2EFCSrcMacOui:
  47300         if (soc_feature(unit, soc_feature_e2efc)) {
  47301             uint32 val_0_lo, val_1_hi;
  47302             uint64 val_64, data_1, data_0;
  47303             soc_reg_t reg_0, reg_1;
  47304 #if defined(BCM_KATANA2_SUPPORT)
  47305             uint32 val;
  47306 #endif
  47307             if (!IS_HG_PORT(unit, port)) {
  47308                 LOG_ERROR(
  47309                     BSL_LS_BCM_PORT,
  47310                     (BSL_META_U(unit,
  47311                                 "Error: unit %d port %d is not a Higig port. "
  47312                                 "E2EFC messages can only be transmitted to "
  47313                                 "or received from Higig ports.\n"),
  47314                      unit, port));
  47315                 return BCM_E_PARAM;
  47316             }
  47317 #if defined(BCM_KATANA2_SUPPORT)
  47318             if (SOC_IS_KATANA2(unit)) {
  47319 #if defined(BCM_SABER2_SUPPORT)
  47320                 if (SOC_IS_SABER2(unit)) {
  47321                     /* Do nothing */
  47322                 } else
  47323 #endif /* BCM_SABER2_SUPPORT */
  47324               {
  47325                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D1r, port, 0, &val));
  47326                     val_0_lo = soc_reg_field_get(unit, XIBP_D1r, val, DATA_BYTES_4_7f);
  47327                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D2r, port, 0, &val));
  47328                     val_1_hi = soc_reg_field_get(unit, XIBP_D2r, val, DATA_BYTES_8_11f);
  47329                     *value = ((val_1_hi >> 24) & 0xff) | ((val_0_lo & 0xffff) << 8);
  47330                     rv = BCM_E_NONE;
  47331                    break;
  47332                }
  47333            }
  47334 #endif /* BCM_KATANA2_SUPPORT */
  47335             if (IS_XL_PORT(unit, port)) {
  47336                 reg_0 = XLMAC_E2EFC_DATA_HDR_0r;
  47337                 reg_1 = XLMAC_E2EFC_DATA_HDR_1r;
  47338             } else if (IS_CL_PORT(unit, port)) {
  47339                 reg_0 = CLMAC_E2EFC_DATA_HDR_0r;
  47340                 reg_1 = CLMAC_E2EFC_DATA_HDR_1r;
  47341             } else {
  47342                 return BCM_E_PARAM;
  47343             }
  47344 
  47345             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg_1,
  47346                                             port, 0, &val_64));
  47347             data_1 = soc_reg64_field_get(unit, reg_1,
  47348                                          val_64, E2EFC_DATA_HDR_1f);
  47349             COMPILER_64_TO_32_HI(val_1_hi, data_1);
  47350             /* SA MAC setting across 2 registers */
  47351             COMPILER_64_ZERO(val_64);
  47352             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg_0,
  47353                                             port, 0, &val_64));
  47354             data_0 = soc_reg64_field_get(unit, reg_0,
  47355                                          val_64, E2EFC_DATA_HDR_0f);
  47356             COMPILER_64_TO_32_LO(val_0_lo, data_0);
  47357             *value = ((val_1_hi >> 24) & 0xff) | ((val_0_lo & 0xffff) << 8);
  47358             rv = BCM_E_NONE;
  47359         }
  47360         break;
  47361     /* Lower 3 bytes of Source MAC address */
  47362     case bcmPortControlE2EFCSrcMacNonOui:
  47363         if (soc_feature(unit, soc_feature_e2efc)) {
  47364             uint32 val_hi;
  47365             uint64 val_64, data_1;
  47366             soc_reg_t   reg;
  47367 #if defined(BCM_KATANA2_SUPPORT)
  47368             uint32 val;
  47369 #endif
  47370             if (!IS_HG_PORT(unit, port)) {
  47371                 LOG_ERROR(
  47372                     BSL_LS_BCM_PORT,
  47373                     (BSL_META_U(unit,
  47374                                 "Error: unit %d port %d is not a Higig port. "
  47375                                 "E2EFC messages can only be transmitted to "
  47376                                 "or received from Higig ports.\n"),
  47377                      unit, port));
  47378                 return BCM_E_PARAM;
  47379             }
  47380 #if defined(BCM_KATANA2_SUPPORT)
  47381             if (SOC_IS_KATANA2(unit)) {
  47382 #if defined(BCM_SABER2_SUPPORT)
  47383                if (SOC_IS_SABER2(unit)) {
  47384                     /* Do nothing */
  47385                 } else
  47386 #endif /* BCM_SABER2_SUPPORT */
  47387                {
  47388                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D2r, port, 0, &val));
  47389                     val_hi = soc_reg_field_get(unit, XIBP_D2r, val, DATA_BYTES_8_11f);
  47390                     *value = val_hi & 0xffffff;
  47391                     rv = BCM_E_NONE;
  47392                     break;
  47393                }
  47394             }
  47395 #endif /* BCM_KATANA2_SUPPORT */
  47396 
  47397             if (IS_XL_PORT(unit, port)) {
  47398                 reg = XLMAC_E2EFC_DATA_HDR_1r;
  47399             } else if (IS_CL_PORT(unit, port)) {
  47400                 reg = CLMAC_E2EFC_DATA_HDR_1r;
  47401             } else {
  47402                 return BCM_E_PARAM;
  47403             }
  47404 
  47405             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg,
  47406                                             port, 0, &val_64));
  47407             data_1 = soc_reg64_field_get(unit, reg,
  47408                                          val_64, E2EFC_DATA_HDR_1f);
  47409             COMPILER_64_TO_32_HI(val_hi, data_1);
  47410             *value = val_hi & 0xffffff;
  47411             rv = BCM_E_NONE;
  47412         }
  47413         break;
  47414     case bcmPortControlE2EFCEtherType:
  47415         if (soc_feature(unit, soc_feature_e2efc)) {
  47416             uint32 val_lo;
  47417             uint64 val_64, data_1;
  47418             soc_reg_t reg;
  47419 #if defined(BCM_KATANA2_SUPPORT)
  47420             uint32 val;
  47421 #endif
  47422             if (!IS_HG_PORT(unit, port)) {
  47423                 LOG_ERROR(
  47424                     BSL_LS_BCM_PORT,
  47425                     (BSL_META_U(unit,
  47426                                 "Error: unit %d port %d is not a Higig port. "
  47427                                 "E2EFC messages can only be transmitted to "
  47428                                 "or received from Higig ports.\n"),
  47429                      unit, port));
  47430                 return BCM_E_PARAM;
  47431             }
  47432 #if defined(BCM_KATANA2_SUPPORT)
  47433             if (SOC_IS_KATANA2(unit)) {
  47434 #if defined(BCM_SABER2_SUPPORT)
  47435                if (SOC_IS_SABER2(unit)) {
  47436                     /* Do nothing */
  47437                 } else
  47438 #endif /* BCM_SABER2_SUPPORT */
  47439                {
  47440                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D3r, port, 0, &val));
  47441                     val_lo = soc_reg_field_get(unit, XIBP_D3r, val, D_BYTES_12_15f);
  47442                     *value = (val_lo >> 16) & 0xffff;
  47443                     rv = BCM_E_NONE;
  47444                     break;
  47445                }
  47446             }
  47447 #endif /* BCM_KATANA2_SUPPORT */
  47448             if (IS_XL_PORT(unit, port)) {
  47449                 reg = XLMAC_E2EFC_DATA_HDR_1r;
  47450             } else if (IS_CL_PORT(unit, port)) {
  47451                 reg = CLMAC_E2EFC_DATA_HDR_1r;
  47452             } else {
  47453                 return BCM_E_PARAM;
  47454             }
  47455 
  47456             BCM_IF_ERROR_RETURN(
  47457                 soc_reg_get(unit, reg, port, 0, &val_64));
  47458                 data_1 = soc_reg64_field_get(unit, reg,
  47459                                              val_64, E2EFC_DATA_HDR_1f);
  47460             COMPILER_64_TO_32_LO(val_lo, data_1);
  47461             *value = (val_lo >> 16) & 0xffff;
  47462             rv = BCM_E_NONE;
  47463         }
  47464         break;
  47465     case bcmPortControlE2EFCOpcode:
  47466         if (soc_feature(unit, soc_feature_e2efc)) {
  47467             uint32 val_lo;
  47468             uint64 val_64, data_1;
  47469             soc_reg_t reg;
  47470 #if defined(BCM_KATANA2_SUPPORT)
  47471             uint32 val;
  47472 #endif
  47473             if (!IS_HG_PORT(unit, port)) {
  47474                 LOG_ERROR(
  47475                     BSL_LS_BCM_PORT,
  47476                     (BSL_META_U(unit,
  47477                                 "Error: unit %d port %d is not a Higig port. "
  47478                                 "E2EFC messages can only be transmitted to "
  47479                                 "or received from Higig ports.\n"),
  47480                      unit, port));
  47481                 return BCM_E_PARAM;
  47482             }
  47483 #if defined(BCM_KATANA2_SUPPORT)
  47484             if (SOC_IS_KATANA2(unit)) {
  47485 #if defined(BCM_SABER2_SUPPORT)
  47486                if (SOC_IS_SABER2(unit)) {
  47487                     /* Do nothing */
  47488                 } else
  47489 #endif /* BCM_SABER2_SUPPORT */
  47490                {
  47491                     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D3r, port, 0, &val));
  47492                     val_lo = soc_reg_field_get(unit, XIBP_D3r, val, D_BYTES_12_15f);
  47493                     *value = val_lo & 0xffff;
  47494                     rv = BCM_E_NONE;
  47495                     break;
  47496                }
  47497             }
  47498 #endif /* BCM_KATANA2_SUPPORT */
  47499             if (IS_XL_PORT(unit, port)) {
  47500                 reg = XLMAC_E2EFC_DATA_HDR_1r;
  47501             } else if (IS_CL_PORT(unit, port)) {
  47502                 reg = CLMAC_E2EFC_DATA_HDR_1r;
  47503             } else {
  47504                 return BCM_E_PARAM;
  47505             }
  47506 
  47507             BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg,
  47508                                             port, 0, &val_64));
  47509             data_1 = soc_reg64_field_get(unit, reg,
  47510                                          val_64, E2EFC_DATA_HDR_1f);
  47511             COMPILER_64_TO_32_LO(val_lo, data_1);
  47512             *value = val_lo & 0xffff;
  47513             rv = BCM_E_NONE;
  47514         }
  47515         break;
  47516     case bcmPortControlIntEnable:
  47517 #if defined(BCM_TOMAHAWK3_SUPPORT)
  47518         if (soc_feature(unit, soc_feature_inband_network_telemetry)) {
  47519             rv = _bcm_esw_port_tab_get(unit, port, INT_ENABLEf, value);
  47520         }
  47521 #endif
  47522         break;
  47523     case bcmPortControlIntTurnaround:
  47524 #if defined(BCM_TOMAHAWK3_SUPPORT)
  47525         if (soc_feature(unit, soc_feature_inband_network_telemetry)) {
  47526             SOC_IF_ERROR_RETURN
  47527                 (READ_INT_TURNAROUND_EN_BMAPm(unit, MEM_BLOCK_ANY, 0,
  47528                                      &int_turnaround_en_bmap_entry));
  47529             soc_mem_pbmp_field_get(unit, INT_TURNAROUND_EN_BMAPm, 
  47530                            &int_turnaround_en_bmap_entry, PORT_BITMAPf, &pbmp);
  47531             *value = 0;
  47532             if (SOC_PBMP_MEMBER(pbmp, port))
  47533                 *value = 1;
  47534         }
  47535 #endif
  47536         break;
  47537     case bcmPortControlObmClassifierPriority:
  47538     case bcmPortControlObmClassifierEnableDscp:
  47539     case bcmPortControlObmClassifierEnableMpls:
  47540     case bcmPortControlObmClassifierEnableEtag:
  47541     case bcmPortControlObmClassifierEtagEthertype:
  47542     case bcmPortControlObmClassifierVntagEthertype:
  47543 
  47544 #if defined(BCM_MONTEREY_SUPPORT)
  47545         if (SOC_IS_MONTEREY(unit)) {
  47546             rv = bcm_mn_obm_classifier_port_control_get(unit, port, type, value);
  47547         } else
  47548 #endif
  47549 #if defined(BCM_APACHE_SUPPORT)
  47550         if (SOC_IS_APACHE(unit)) {
  47551             rv = bcm_apache_obm_classifier_port_control_get(unit, port, type, value);
  47552         } else
  47553 #endif
  47554         {
  47555             rv = BCM_E_UNAVAIL;
  47556         }
  47557         break;
  47558     case bcmPortControlObmClassifierInternal:
  47559 #if defined(BCM_MONTEREY_SUPPORT)
  47560         if (SOC_IS_MONTEREY(unit)) {
  47561             rv = bcm_mn_obm_classifier_port_control_get(unit, port, type, value);
  47562         } else
  47563 #endif
  47564         {
  47565             rv = BCM_E_UNAVAIL;
  47566         }
  47567         break;
  47568 
  47569    case bcmPortControlWirelessCosMapSelect:
  47570 #if defined(BCM_HELIX5_SUPPORT)
  47571         if (SOC_IS_HELIX5(unit)) {
  47572             rv = _bcm_esw_port_tab_get(unit, port, WIRED_WIRELESSf, value);
  47573         } else
  47574 #endif
  47575         {
  47576            rv = BCM_E_UNAVAIL;
  47577         }
  47578     break;
  47579 
  47580    case bcmPortControlHiGigCosSelect:
  47581 #if defined(BCM_HELIX5_SUPPORT)
  47582         if (SOC_IS_HELIX5(unit)) {
  47583             rv = bcm_hx5_hgcos_select_port_control_get(unit, port, type, value);
  47584         } else
  47585 #endif
  47586         {
  47587            rv = BCM_E_UNAVAIL;
  47588         }
  47589     break;
  47590 #ifdef BCM_MONTEREY_SUPPORT
  47591     case bcmPortControlObmInterruptTypeDropPreempt :
  47592     case bcmPortControlObmInterruptTypeOverflowPreempt : 
  47593     case bcmPortControlObmInterruptTypeDropExpress :  
  47594     case  bcmPortControlObmInterruptTypeOverflowExpress : 
  47595         if (SOC_IS_MONTEREY(unit)) {
  47596             rv = bcm_mn_obm_interrupt_port_control_get(unit, port, type, value);
  47597             
  47598         }else 
  47599 #endif
  47600         {
  47601             rv = BCM_E_UNAVAIL;
  47602         }
  47603         break;
  47604      default:
  47605         break;
  47606     }
  47607 
  47608     if (BCM_SUCCESS(rv)) {
  47609         LOG_INFO(BSL_LS_BCM_PORT,
  47610                  (BSL_META_U(unit,
  47611                              "bcm_port_control_get: u=%d p=%d v=%d\n"),
  47612                   unit, port, *value));
  47613     } else {
  47614         /* On error, the value is not guaranteed valid */
  47615         LOG_INFO(BSL_LS_BCM_PORT,
  47616                  (BSL_META_U(unit,
  47617                              "bcm_port_control_get failure: u=%d p=%d: %s\n"),
  47618                   unit, port, bcm_errmsg(rv)));
  47619     }
  47620 
  47621     return rv;
  47622 }
  47623 
  47624 /*
  47625  * Function:
  47626  *      bcm_esw_port_mac_failover_notify
  47627  * Description:
  47628  *      disable RX routine on MAC
  47629  *      note: omitting XLMAC since it should not be disabled during failover
  47630  * Parameters:
  47631  *      unit - Device number
  47632  *      port - Port number
  47633  * Return Value:
  47634  *      BCM_E_NONE
  47635  *      BCM_E_UNAVAIL - Functionality not available
  47636  */
  47637 int
  47638 _bcm_esw_port_mac_failover_notify(int unit, bcm_port_t port)
  47639 {
  47640     int rv = BCM_E_NONE;
  47641 
  47642     if (!SOC_USE_PORTCTRL(unit)) {
  47643         /* disable RX for MAC and XMAC controller.
  47644            for TD2, lag failover has been implemented within XLMAC;
  47645            thus, XLMAC rx should not be disabled during failover */
  47646         PORT_LOCK(unit);
  47647         rv = (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port,
  47648                           SOC_MAC_CONTROL_FAILOVER_RX_SET, FALSE));
  47649         PORT_UNLOCK(unit);
  47650     }
  47651     return rv;
  47652 }
  47653 
  47654 
  47655 /*
  47656  * Function:
  47657  *      _bcm_esw_port_policer_get
  47658  * Purpose:
  47659  *       Internal function to Retrieve the Policer ID accociated
  47660  *       with specified physical port.
  47661  * Parameters:
  47662  *     Unit                  - (IN) unit number
  47663  *     port                  - (IN) Port Number
  47664  *     policer_id            - (OUT) policer Id
  47665  * Returns:
  47666  *     BCM_E_XXX
  47667  */
  47668 int _bcm_esw_port_policer_get(
  47669     int unit,
  47670     bcm_port_t port,
  47671     bcm_policer_t *policer_id)
  47672 {
  47673     int rv = BCM_E_NONE;
  47674 
  47675 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  47676     defined(BCM_GREYHOUND2_SUPPORT)
  47677     int index = 0;
  47678     int offset_mode = 0;
  47679 
  47680     BCM_IF_ERROR_RETURN
  47681             (_bcm_esw_port_config_get(unit, port,
  47682                                       _bcmPortSvcMeterIndex, &index));
  47683     BCM_IF_ERROR_RETURN
  47684             (_bcm_esw_port_config_get(unit, port,
  47685                                     _bcmPortSvcMeterOffsetMode, &offset_mode));
  47686     _bcm_esw_get_policer_id_from_index_offset(unit, index,
  47687                                                     offset_mode, policer_id);
  47688 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT ||
  47689           BCM_GREYHOUND2_SUPPORT */
  47690     return rv;
  47691 }
  47692 
  47693 /*
  47694  * Function:
  47695  *      bcm_esw_port_policer_get
  47696  * Purpose:
  47697  *       Retrieve the Policer ID accociated for the specified physical port.
  47698  * Parameters:
  47699  *     Unit                  - (IN) unit number
  47700  *     port                  - (IN) Port Number
  47701  *     policer_id            - (OUT) policer Id
  47702  * Returns:
  47703  *     BCM_E_XXX
  47704  */
  47705 int bcm_esw_port_policer_get(
  47706     int unit,
  47707     bcm_port_t port,
  47708     bcm_policer_t *policer_id)
  47709 {
  47710 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  47711     defined(BCM_GREYHOUND2_SUPPORT)
  47712     int rv = BCM_E_NONE;
  47713 
  47714     /* Make sure port module is initialized. */
  47715     PORT_INIT(unit);
  47716     if (!soc_feature(unit, soc_feature_global_meter)) {
  47717         return BCM_E_UNAVAIL;
  47718     }
  47719     BCM_IF_ERROR_RETURN(_check_global_meter_init(unit));
  47720     rv = _bcm_esw_port_gport_validate(unit, port, &port);
  47721     BCM_IF_ERROR_RETURN(rv);
  47722     rv = _bcm_esw_port_policer_get(unit, port, policer_id);
  47723     return rv;
  47724 #else /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT ||
  47725          BCM_GREYHOUND2_SUPPORT */
  47726     return BCM_E_UNAVAIL;
  47727 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT ||
  47728           BCM_GREYHOUND2_SUPPORT */
  47729 }
  47730 
  47731 #if defined(BCM_GLOBAL_METER_V2_SUPPORT)
  47732 /*
  47733  * Function:
  47734  *     bcmi_esw_port_policer_set
  47735  * Purpose:
  47736  *     Set the Policer ID accociated for the specified physical port.
  47737  * Parameters:
  47738  *     Unit                  - (IN) unit number
  47739  *     port                  - (IN) Port Number
  47740  *     policer_id            - (IN) policer Id
  47741  * Returns:
  47742  *     BCM_E_XXX
  47743  */
  47744 STATIC int
  47745 bcmi_esw_port_policer_set(
  47746     int unit,
  47747     bcm_port_t port,
  47748     bcm_policer_t policer_id)
  47749 {
  47750     int rv = BCM_E_UNAVAIL;
  47751 #if defined(BCM_GREYHOUND2_SUPPORT)
  47752     int index = 0;
  47753     int offset_mode = 0;
  47754     bcm_policer_t current_policer_id = 0;
  47755 
  47756     if (SOC_IS_GREYHOUND2(unit)) {
  47757         /* Make sure port module is initialized. */
  47758         PORT_INIT(unit);
  47759         if (!soc_feature(unit, soc_feature_global_meter)) {
  47760             return BCM_E_UNAVAIL;
  47761         }
  47762         BCM_IF_ERROR_RETURN(_check_global_meter_init(unit));
  47763         rv = _bcm_esw_port_gport_validate(unit, port, &port);
  47764         BCM_IF_ERROR_RETURN(rv);
  47765         /* validate policer id */
  47766         rv = _bcm_esw_policer_validate(unit, &policer_id);
  47767         if (BCM_FAILURE(rv)) {
  47768             LOG_VERBOSE(BSL_LS_BCM_PORT,
  47769                         (BSL_META_U(unit,
  47770                                     "Invalid policer id passed: %x \n"),
  47771                          policer_id));
  47772             return (rv);
  47773         }
  47774         /* get the policer id that is currently configured */
  47775         rv = _bcm_esw_port_policer_get(unit, port, &current_policer_id);
  47776         if (BCM_FAILURE(rv)) {
  47777             LOG_VERBOSE(BSL_LS_BCM_PORT,
  47778                         (BSL_META_U(unit,
  47779                                     "Unabel to get the current policer configured \n")));
  47780             return (rv);
  47781         }
  47782 
  47783         /* Set policer id */
  47784         BCM_IF_ERROR_RETURN(
  47785             _bcm_esw_get_policer_table_index(unit, policer_id, &index));
  47786         BCM_IF_ERROR_RETURN(
  47787             _bcm_esw_policer_offset_mode_get(unit, policer_id, &offset_mode));
  47788 
  47789         BCM_IF_ERROR_RETURN(
  47790             _bcm_esw_port_config_set(
  47791                 unit, port, _bcmPortSvcMeterIndex, index));
  47792         BCM_IF_ERROR_RETURN(
  47793             _bcm_esw_port_config_set(
  47794                 unit, port, _bcmPortSvcMeterOffsetMode, offset_mode));
  47795 
  47796         /* increment new set policer ref_cnt */
  47797         rv = _bcm_esw_policer_increment_ref_count(unit, policer_id);
  47798         BCM_IF_ERROR_RETURN(rv);
  47799 
  47800         /* decrement current hw policer ref_cnt */
  47801         rv = _bcm_esw_policer_validate(unit, &current_policer_id);
  47802 
  47803         /* Don't need to handle fail case since existed index could be 0 */
  47804         if (BCM_SUCCESS(rv)) {
  47805             rv = _bcm_esw_policer_decrement_ref_count(unit, current_policer_id);
  47806             BCM_IF_ERROR_RETURN(rv);
  47807         }
  47808 
  47809         rv = BCM_E_NONE;
  47810     }
  47811 #endif /* BCM_GREYHOUND2_SUPPORT */
  47812     return rv;
  47813 }
  47814 
  47815 #endif /* BCM_GLOBAL_METER_V2_SUPPORT */
  47816 
  47817 /*
  47818  * Function:
  47819  *      bcm_esw_port_policer_set
  47820  * Purpose:
  47821  *      Set the Policer ID accociated for the specified physical port.
  47822  * Parameters:
  47823  *     Unit                  - (IN) unit number
  47824  *     port                  - (IN) Port Number
  47825  *     policer_id            - (IN) policer Id
  47826  * Returns:
  47827  *     BCM_E_XXX
  47828  */
  47829 int bcm_esw_port_policer_set(
  47830     int unit,
  47831     bcm_port_t port,
  47832     bcm_policer_t policer)
  47833 {
  47834 #if (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) ||    \
  47835      defined(BCM_APACHE_SUPPORT))
  47836     int rv = BCM_E_NONE;
  47837     int index=0;
  47838     int offset_mode=0;
  47839     bcm_policer_t current_policer = 0;
  47840 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT ||
  47841          BCM_APACHE_SUPPORT */
  47842 
  47843 #if defined(BCM_GLOBAL_METER_V2_SUPPORT)
  47844     if (soc_feature(unit, soc_feature_global_meter_v2)) {
  47845         return bcmi_esw_port_policer_set(unit, port, policer);
  47846     }
  47847 #endif /* BCM_GLOBAL_METER_V2_SUPPORT */
  47848 
  47849 #if (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) ||    \
  47850      defined(BCM_APACHE_SUPPORT))
  47851 
  47852     /* Make sure port module is initialized. */
  47853     PORT_INIT(unit);
  47854     if (!soc_feature(unit, soc_feature_global_meter)) {
  47855         return BCM_E_UNAVAIL;
  47856     }
  47857     BCM_IF_ERROR_RETURN(_check_global_meter_init(unit));
  47858     rv = _bcm_esw_port_gport_validate(unit, port, &port);
  47859     BCM_IF_ERROR_RETURN(rv);
  47860     /* validate policer id */
  47861     rv = _bcm_esw_policer_validate(unit, &policer);
  47862     if (BCM_FAILURE(rv)) {
  47863         LOG_VERBOSE(BSL_LS_BCM_PORT,
  47864                     (BSL_META_U(unit,
  47865                                 "Invalid policer id passed: %x \n"),
  47866                      policer));
  47867         return (rv);
  47868     }
  47869     /* get the policer id that is currently configured */
  47870     rv = _bcm_esw_port_policer_get(unit, port, &current_policer);
  47871     if (BCM_FAILURE(rv)) {
  47872         LOG_VERBOSE(BSL_LS_BCM_PORT,
  47873                     (BSL_META_U(unit,
  47874                                 "Unabel to get the current policer configured \n")));
  47875         return (rv);
  47876     }
  47877     rv = BCM_E_UNAVAIL;
  47878     /* Set policer id */
  47879     _bcm_esw_get_policer_table_index(unit, policer, &index);
  47880     offset_mode = (((policer) & BCM_POLICER_GLOBAL_METER_MODE_MASK) >>
  47881                                     BCM_POLICER_GLOBAL_METER_MODE_SHIFT);
  47882     if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)) {
  47883         if ((offset_mode == 0) && (policer != 0)) {
  47884             /* 
  47885              * Not a Global meter policer, 
  47886              * policer zero is used to detach already configured policer
  47887              */
  47888             return (BCM_E_PARAM);
  47889         }
  47890     }
  47891     if (offset_mode >= 1) {
  47892         offset_mode = offset_mode - 1;
  47893     }
  47894     if (index >= soc_mem_index_count(unit,SVM_METER_TABLEm))  {
  47895         LOG_VERBOSE(BSL_LS_BCM_PORT,
  47896                     (BSL_META_U(unit,
  47897                                 "Invalid table index\n")));
  47898         return BCM_E_PARAM;
  47899     }
  47900     if (offset_mode >= (soc_mem_index_count(unit,SVM_OFFSET_TABLEm) >>
  47901                                BCM_POLICER_SVC_METER_OFFSET_TABLE_KEY_SIZE))  {
  47902         LOG_VERBOSE(BSL_LS_BCM_PORT,
  47903                     (BSL_META_U(unit,
  47904                                 "Invalid offset mode\n")));
  47905         return BCM_E_PARAM;
  47906     }
  47907     BCM_IF_ERROR_RETURN(
  47908             _bcm_esw_port_config_set(unit, port,
  47909                                       _bcmPortSvcMeterIndex, index));
  47910     BCM_IF_ERROR_RETURN(
  47911              _bcm_esw_port_config_set(unit, port,
  47912                                      _bcmPortSvcMeterOffsetMode, offset_mode));
  47913     /* decrement current policer if any */
  47914     if ((current_policer & BCM_POLICER_GLOBAL_METER_INDEX_MASK) > 0) {
  47915         rv = _bcm_esw_policer_decrement_ref_count(unit, current_policer);
  47916         BCM_IF_ERROR_RETURN(rv);
  47917     }
  47918     /* increment policer reference count */
  47919     if ((policer & BCM_POLICER_GLOBAL_METER_INDEX_MASK) > 0 ) {
  47920         rv = _bcm_esw_policer_increment_ref_count(unit, policer);
  47921         BCM_IF_ERROR_RETURN(rv);
  47922     }
  47923     return rv;
  47924 #else /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT ||
  47925          BCM_APACHE_SUPPORT */
  47926     return BCM_E_UNAVAIL;
  47927 #endif
  47928 }
  47929 
  47930 /*
  47931  * Function:
  47932  *      bcm_port_vlan_inner_tag_set
  47933  * Purpose:
  47934  *      Set the inner tag to be added to the packet.
  47935  * Parameters:
  47936  *      unit       - (IN) BCM unit.
  47937  *      port       - (IN) Port number.
  47938  *      inner_tag  - (IN) Inner tag.
  47939  *                    Priority[15:13] CFI[12] VLAN ID [11:0]
  47940  * Returns:
  47941  *      BCM_E_XXX
  47942  */
  47943 int
  47944 bcm_esw_port_vlan_inner_tag_set(int unit, bcm_port_t port, uint16 inner_tag)
  47945 {
  47946     int rv;
  47947 
  47948     /* Make sure port module is initialized. */
  47949     PORT_INIT(unit);
  47950 
  47951     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  47952 
  47953     rv = BCM_E_UNAVAIL;
  47954 
  47955 #ifdef BCM_TRX_SUPPORT
  47956     if (SOC_IS_TRX(unit)) {
  47957         bcm_vlan_action_set_t action;
  47958 
  47959         if (!soc_feature(unit, soc_feature_vlan_action)) {
  47960             return BCM_E_UNAVAIL;
  47961         }
  47962 
  47963         PORT_LOCK(unit);
  47964         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  47965             (_bcm_trx_vlan_port_default_action_get(unit, port, &action));
  47966         action.new_inner_vlan = BCM_VLAN_CTRL_ID(inner_tag);
  47967 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT)
  47968         if (SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) {
  47969             rv =_bcm_trx_vlan_port_default_action_profile_set(unit, port, &action);
  47970         } else
  47971 #endif
  47972         {
  47973             rv = _bcm_trx_vlan_port_default_action_set(unit, port, &action);
  47974         }
  47975         PORT_UNLOCK(unit);
  47976         return rv;
  47977     }
  47978 #endif
  47979 
  47980 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT)
  47981     if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) {
  47982         PORT_LOCK(unit);
  47983 
  47984         rv = soc_reg_field32_modify(unit, EGR_SRC_PORTr, port,
  47985                                     INNER_TAGf, inner_tag);
  47986         PORT_UNLOCK(unit);
  47987     }
  47988 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT */
  47989 
  47990     return rv;
  47991 }
  47992 
  47993 /*
  47994  * Function:
  47995  *      bcm_port_vlan_inner_tag_get
  47996  * Purpose:
  47997  *      Get the inner tag to be added to the packet.
  47998  * Parameters:
  47999  *      unit       - (IN) BCM unit.
  48000  *      port       - (IN) Port number.
  48001  *      inner_tag  - (OUT) Inner tag.
  48002  *                    Priority[15:13] CFI[12] VLAN ID [11:0]
  48003  * Returns:
  48004  *      BCM_E_XXX
  48005  */
  48006 int
  48007 bcm_esw_port_vlan_inner_tag_get(int unit, bcm_port_t port, uint16 *inner_tag)
  48008 {
  48009     int rv;
  48010 
  48011     /* Make sure port module is initialized. */
  48012     PORT_INIT(unit);
  48013 
  48014     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  48015 
  48016     rv = BCM_E_UNAVAIL;
  48017 
  48018 #ifdef BCM_TRX_SUPPORT
  48019     if (SOC_IS_TRX(unit)) {
  48020         bcm_vlan_action_set_t action;
  48021 
  48022         if (!soc_feature(unit, soc_feature_vlan_action)) {
  48023             return BCM_E_UNAVAIL;
  48024         }
  48025 
  48026         PORT_LOCK(unit);
  48027         _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK
  48028             (_bcm_trx_vlan_port_default_action_get(unit, port, &action));
  48029         *inner_tag = action.new_inner_vlan;
  48030         PORT_UNLOCK(unit);
  48031         return BCM_E_NONE;
  48032     }
  48033 #endif
  48034 
  48035 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT)
  48036         if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) {
  48037         uint32 value;
  48038 
  48039         rv = READ_EGR_SRC_PORTr(unit, port, &value);
  48040         *inner_tag = soc_reg_field_get(unit, EGR_SRC_PORTr, value,
  48041                                        INNER_TAGf);
  48042     }
  48043 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT */
  48044     return rv;
  48045 }
  48046 
  48047 #if defined(INCLUDE_L3) && defined(BCM_TRIDENT_SUPPORT)
  48048 STATIC int
  48049 _bcm_esw_port_vp_type_id_get(int unit, bcm_port_t port,
  48050                              _bcm_vp_type_e *vp_type, int *vp)
  48051 {
  48052     *vp = -1;
  48053     *vp_type = _bcmVpTypeAny;
  48054 
  48055     if (BCM_GPORT_IS_MIM_PORT(port) && soc_feature(unit, soc_feature_mim)) {
  48056         *vp_type = _bcmVpTypeMim;
  48057         *vp = BCM_GPORT_MIM_PORT_ID_GET(port);
  48058     } else if (BCM_GPORT_IS_TRILL_PORT(port) && soc_feature(unit, soc_feature_trill)) {
  48059         *vp_type = _bcmVpTypeTrill;
  48060         *vp = BCM_GPORT_TRILL_PORT_ID_GET(port);
  48061     } else if (BCM_GPORT_IS_VXLAN_PORT(port) && soc_feature(unit, soc_feature_vxlan)) {
  48062         *vp_type = _bcmVpTypeVxlan;
  48063         *vp = BCM_GPORT_VXLAN_PORT_ID_GET(port);
  48064     } else if (BCM_GPORT_IS_MPLS_PORT(port) && soc_feature(unit, soc_feature_mpls)) {
  48065         *vp_type = _bcmVpTypeMpls;
  48066         *vp = BCM_GPORT_MPLS_PORT_ID_GET(port);
  48067     } else if (BCM_GPORT_IS_EXTENDER_PORT(port) && soc_feature(unit, soc_feature_port_extension)) {
  48068         *vp_type = _bcmVpTypeExtender;
  48069         *vp = BCM_GPORT_EXTENDER_PORT_ID_GET(port);
  48070     } else if (BCM_GPORT_IS_WLAN_PORT(port) && soc_feature(unit, soc_feature_wlan)) {
  48071         *vp_type = _bcmVpTypeWlan;
  48072         *vp = BCM_GPORT_WLAN_PORT_ID_GET(port);
  48073     } else if (BCM_GPORT_IS_NIV_PORT(port) && soc_feature(unit, soc_feature_niv)) {
  48074         *vp_type = _bcmVpTypeNiv;
  48075         *vp = BCM_GPORT_NIV_PORT_ID_GET(port);
  48076     } else if (BCM_GPORT_IS_VLAN_PORT(port) && soc_feature(unit, soc_feature_vlan_vp)) {
  48077         *vp_type = _bcmVpTypeVlan;
  48078         *vp = BCM_GPORT_VLAN_PORT_ID_GET(port);
  48079     } else if (BCM_GPORT_IS_L2GRE_PORT(port) && soc_feature(unit, soc_feature_l2gre)) {
  48080         *vp_type = _bcmVpTypeL2Gre;
  48081         *vp = BCM_GPORT_L2GRE_PORT_ID_GET(port);
  48082     } else if (BCM_GPORT_IS_FLOW_PORT(port) && soc_feature(unit, soc_feature_flex_flow)) {
  48083         *vp_type = _bcmVpTypeFlow;
  48084         *vp = BCM_GPORT_FLOW_PORT_ID_GET(port);
  48085     } else if (BCM_GPORT_IS_TRUNK(port) && soc_feature(unit, soc_feature_vp_lag)) {
  48086         *vp_type = _bcmVpTypeVpLag;
  48087         BCM_IF_ERROR_RETURN(
  48088             _bcm_esw_trunk_tid_to_vp_lag_vp(unit, BCM_GPORT_TRUNK_GET(port),
  48089                                             vp));
  48090     }
  48091     return BCM_E_NONE;
  48092 }
  48093 #endif
  48094 
  48095 /*
  48096  * Function    :
  48097  *     bcm_port_class_set
  48098  * Description :
  48099  *     Set the ports class ID. Ports with the
  48100  *     same class ID can be treated as a group in
  48101  *     field processing and VLAN translation.
  48102  * Parameters  :
  48103  *     (IN) unit      - BCM device number
  48104  *     (IN) port      - Device or logical port number
  48105  *     (IN) pclass    - Classification type
  48106  *     (IN) pclass_id - New class ID of the port.
  48107  * Returns     :
  48108  *     BCM_E_NONE     - Success
  48109  *     BCM_E_XXX      - Failed
  48110  */
  48111 int
  48112 bcm_esw_port_class_set(int unit, bcm_port_t port,
  48113                        bcm_port_class_t pclass, uint32 pclass_id)
  48114 {
  48115     int        rv = BCM_E_UNAVAIL;
  48116     bcm_port_t port_out = port;
  48117 #if defined(BCM_TOMAHAWK_SUPPORT)
  48118     soc_mem_t port_mem = PORT_TABm;
  48119 #endif
  48120 
  48121     /* Make sure port module is initialized. */
  48122     PORT_INIT(unit);
  48123 
  48124 #if defined(INCLUDE_L3)
  48125 #if defined(BCM_TRIDENT_SUPPORT)
  48126     if (BCM_GPORT_IS_SET(port)) {
  48127         int vp;
  48128         _bcm_vp_type_e vp_type;
  48129         BCM_IF_ERROR_RETURN(_bcm_esw_port_vp_type_id_get(unit, port,
  48130                                                          &vp_type, &vp));
  48131         switch (pclass) {
  48132         case bcmPortClassFieldIngress:
  48133             if (vp_type == _bcmVpTypeMim || vp_type == _bcmVpTypeTrill ||
  48134                 vp_type == _bcmVpTypeVxlan || vp_type == _bcmVpTypeMpls ||
  48135                 vp_type == _bcmVpTypeExtender || vp_type == _bcmVpTypeWlan ||
  48136                 vp_type == _bcmVpTypeNiv || vp_type == _bcmVpTypeVlan ||
  48137                 vp_type == _bcmVpTypeL2Gre || vp_type == _bcmVpTypeVpLag ||
  48138                 vp_type == _bcmVpTypeFlow){
  48139                
  48140                 if (!_bcm_vp_used_get(unit, vp, vp_type)) {
  48141                     return BCM_E_PORT;
  48142                 }
  48143                 rv = soc_mem_field32_modify(unit, SOURCE_VPm, vp, CLASS_IDf, pclass_id);
  48144                 return rv;    
  48145             }
  48146             break;
  48147         case bcmPortClassVlanTranslateEgress:
  48148 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  48149             /* class_id of DVP used in egress VLAN translation */
  48150         /* class_id of DVP used in egress VLAN translation */
  48151             if ((vp_type == _bcmVpTypeVxlan) || (vp_type == _bcmVpTypeMim) || 
  48152                  (vp_type == _bcmVpTypeMpls) || (vp_type == _bcmVpTypeL2Gre) ||
  48153                  (vp_type == _bcmVpTypeFlow) ) {
  48154                 int network_port;
  48155                 source_vp_entry_t svp;
  48156                 _bcm_vp_info_t vp_info;
  48157 
  48158                 if (!_bcm_vp_used_get(unit, vp, vp_type)) {
  48159                     return BCM_E_PORT;
  48160                 }
  48161                 BCM_IF_ERROR_RETURN (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp));
  48162                 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  48163                 if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) {
  48164                     network_port = TRUE;
  48165                 } else {
  48166                     network_port = FALSE;
  48167                 }
  48168 
  48169                 if (SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm, 
  48170                                                         VT_DVP_GROUP_IDf)
  48171 #if defined(BCM_TRIDENT3_SUPPORT)
  48172                   || (SOC_IS_TRIDENT3X(unit) && SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm,
  48173                                                         COMMON__VT_DVP_GROUP_IDf))
  48174 #endif
  48175                     ) {
  48176                     if ((network_port) && (vp_type == _bcmVpTypeVxlan)) {
  48177                         rv = soc_mem_field32_modify(unit, EGR_DVP_ATTRIBUTEm, vp,
  48178                                                     VXLAN__VT_DVP_GROUP_IDf, pclass_id);
  48179                     } else if ((network_port) && (vp_type == _bcmVpTypeL2Gre)) {
  48180                         rv = soc_mem_field32_modify(unit, EGR_DVP_ATTRIBUTEm, vp,
  48181                                                     L2GRE__VT_DVP_GROUP_IDf, pclass_id);
  48182                     } else {
  48183                         rv = soc_mem_field32_modify(unit, EGR_DVP_ATTRIBUTEm, vp,
  48184                                                     COMMON__VT_DVP_GROUP_IDf, pclass_id);
  48185                     }
  48186                 } else {
  48187                     return BCM_E_UNAVAIL;
  48188                 }
  48189                 return rv;
  48190             }
  48191 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  48192             break;
  48193 #if defined(BCM_TOMAHAWK_SUPPORT)
  48194         case bcmPortClassFieldIngressSourceGport:
  48195             if  (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) {
  48196                 return BCM_E_UNAVAIL;
  48197             }
  48198             if (pclass_id > 33) {
  48199                 return BCM_E_PARAM;
  48200             }
  48201             if (vp_type == _bcmVpTypeVxlan || vp_type == _bcmVpTypeVlan ||
  48202                 vp_type == _bcmVpTypeExtender || vp_type == _bcmVpTypeVpLag ||
  48203                 vp_type == _bcmVpTypeNiv || vp_type == _bcmVpTypeMpls ||
  48204                 vp_type == _bcmVpTypeL2Gre || vp_type == _bcmVpTypeMim ||
  48205                 vp_type == _bcmVpTypeFlow) {
  48206                 if (!_bcm_vp_used_get(unit, vp, vp_type)) {
  48207                     return BCM_E_PORT;
  48208                 }
  48209                 rv = soc_mem_field32_modify(unit, SOURCE_VPm, vp,
  48210                                             IPBM_INDEXf, pclass_id);
  48211                 return rv;
  48212             }
  48213             break;
  48214 #endif /* BCM_TOMAHAWK_SUPPORT */
  48215 
  48216         default:
  48217             break;
  48218         }
  48219     }
  48220 #endif /* BCM_TRIDENT_SUPPORT*/
  48221 #endif /* INCLUDE_L3 */
  48222 
  48223 #ifdef BCM_XGS3_SWITCH_SUPPORT
  48224     if (SOC_IS_XGS3_SWITCH(unit)) {
  48225 #if defined(BCM_TOMAHAWK_SUPPORT)
  48226         bcm_module_t mod;
  48227         bcm_trunk_t tid_out;
  48228         int id_out;
  48229         int index;
  48230 #endif /* BCM_TOMAHAWK_SUPPORT */
  48231         switch (pclass) {
  48232             case bcmPortClassFieldIngressSystemPort:
  48233 #if defined(BCM_TOMAHAWK_SUPPORT)
  48234                 if  (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) {
  48235                     return BCM_E_UNAVAIL;
  48236                 }
  48237                 if (pclass_id > 33) {
  48238 #if defined(BCM_TRIDENT3_SUPPORT)
  48239                     if (!SOC_IS_TRIDENT3X(unit) ||
  48240                       soc_feature(unit, soc_feature_ifp_no_inports_support))
  48241 #endif
  48242                     return BCM_E_PARAM;
  48243                 }
  48244                 if (BCM_GPORT_IS_SET(port)) {
  48245                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  48246                                         &mod, &port_out, &tid_out, &id_out));
  48247                     if (-1 != tid_out || -1 != id_out) {
  48248                         return BCM_E_PORT;
  48249                     }
  48250                 } else {
  48251                     if (!SOC_PORT_VALID(unit, port)) {
  48252                         return BCM_E_PORT;
  48253                     }
  48254                     port_out = port;
  48255                     BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mod));
  48256                 }
  48257                 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit,
  48258                                     mod, port_out, &index));
  48259 #if defined(BCM_TRIDENT3_SUPPORT)
  48260                 if (SOC_IS_TRIDENT3X(unit) &&
  48261                       !soc_feature(unit, soc_feature_ifp_no_inports_support)) {
  48262                     rv = bcm_td3_port_ipbm_opaque_set(unit, index, pclass_id);
  48263                     return rv;
  48264                 }
  48265 #endif
  48266                 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, index,
  48267                                                 IPBM_INDEXf, pclass_id);
  48268                 return rv;
  48269 #endif /* BCM_TOMAHAWK_SUPPORT */
  48270                 break;
  48271             default:
  48272                 break;
  48273         }
  48274     }
  48275 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  48276     /*
  48277      * Skip port validation if soc_feature_shg_support_remote_port
  48278      * is true and ptype is bcmPortClassFieldIngress.
  48279      */
  48280     if (!(soc_feature(unit, soc_feature_shg_support_remote_port) &&
  48281         (pclass == bcmPortClassFieldIngress))) {
  48282         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port_out));
  48283     }
  48284 
  48285 
  48286 #ifdef BCM_XGS3_SWITCH_SUPPORT
  48287     if (SOC_IS_XGS3_SWITCH(unit)) {
  48288 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  48289         int        port_class_id;
  48290         soc_reg_t egr_port_reg;
  48291         egr_port_reg = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  48292                         SOC_IS_VALKYRIE2(unit) || SOC_IS_GREYHOUND(unit) ||
  48293                         SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ?
  48294                         EGR_PORT_64r : EGR_PORTr;
  48295 #endif /* BCM_FIREBOLT_SUPPORT || BCM_TRX_SUPPORT */
  48296 
  48297         switch (pclass) {
  48298             case bcmPortClassFieldIngressGroupSel:
  48299 #if defined(BCM_TOMAHAWK_SUPPORT)
  48300                 if (SOC_IS_TRIDENT3X(unit)) {
  48301                     port_mem = LPORT_TABm;
  48302                 }
  48303                 if (soc_mem_field_valid(unit, port_mem, IFP_KEY_SEL_CLASS_IDf)) {
  48304                     rv = soc_mem_field_pbmp_fit(unit, port_mem,
  48305                                                 IFP_KEY_SEL_CLASS_IDf, &pclass_id);
  48306                     if (rv == BCM_E_NONE) {
  48307                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48308                                                    IFP_KEY_SEL_CLASS_IDf, pclass_id);
  48309                     }
  48310                 }
  48311 #endif
  48312                 break;
  48313         case bcmPortClassFieldLookup:
  48314 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  48315             if (soc_mem_field_valid(unit, PORT_TABm, VFP_PORT_GROUP_IDf) ||
  48316                 SOC_IS_TRIDENT3X(unit)) {
  48317                 /* Intentional use of var pclass_id, to be filled here */
  48318                 if (soc_mem_field_valid(unit, PORT_TABm, VFP_PORT_GROUP_IDf)) {
  48319                 /* coverity [callee_ptr_arith] */
  48320                     rv = soc_mem_field_pbmp_fit(unit, PORT_TABm,
  48321                                 VFP_PORT_GROUP_IDf, &pclass_id);
  48322                 } else if (SOC_IS_TRIDENT3X(unit)) {
  48323                     rv = soc_mem_field_pbmp_fit(unit, LPORT_TABm,
  48324                                 VFP_PORT_GROUP_IDf, &pclass_id);
  48325                 }
  48326                 if (rv == BCM_E_NONE) {
  48327                     port_class_id = (int) pclass_id;
  48328                     rv = _bcm_esw_port_tab_set(unit, port,
  48329                                                _BCM_CPU_TABS_BOTH,
  48330                                                VFP_PORT_GROUP_IDf,
  48331                                                port_class_id);
  48332                 }
  48333             }
  48334 #endif /* BCM_FIREBOLT_SUPPORT || BCM_TRX_SUPPORT */
  48335 #if defined(BCM_TRX_SUPPORT)
  48336             if ((SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
  48337                                      VFP_PORT_GROUP_IDf)) &&
  48338                 (BCM_SUCCESS(rv))) {
  48339 #if defined(BCM_KATANA2_SUPPORT)
  48340                 if (SOC_IS_KATANA2(unit)) {
  48341                     rv = _bcm_kt2_source_trunk_map_set(unit, port_out,
  48342                                                    VFP_PORT_GROUP_IDf,
  48343                                                    pclass_id);
  48344                 } else
  48345 #endif
  48346                 {
  48347                     rv = _bcm_trx_source_trunk_map_set(unit, port,
  48348                                                    VFP_PORT_GROUP_IDf,
  48349                                                    pclass_id);
  48350                 }
  48351             }
  48352 #endif /* BCM_TRX_SUPPORT */
  48353             break;
  48354         case bcmPortClassVlanTranslateIngress:
  48355 #if defined(BCM_TRIDENT2_SUPPORT)
  48356             if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, PORT_GROUPf)) {
  48357                 rv = _bcm_trx_source_trunk_map_set(unit, port,
  48358                                                    PORT_GROUPf, pclass_id);
  48359             }
  48360 #endif /* BCM_TRIDENT2_SUPPORT */
  48361             break;
  48362         case bcmPortClassFieldIngress:
  48363 #if defined(BCM_TRX_SUPPORT)
  48364             if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, CLASS_IDf)) {
  48365 #if defined(BCM_KATANA2_SUPPORT)
  48366                 if (SOC_IS_KATANA2(unit)) {
  48367                     rv = _bcm_kt2_source_trunk_map_set(unit, port_out,
  48368                                                     CLASS_IDf, pclass_id);
  48369                 } else
  48370 #endif
  48371                 {
  48372                     rv = _bcm_trx_source_trunk_map_set(unit, port,
  48373                                                    CLASS_IDf, pclass_id);
  48374                 }
  48375             }
  48376 #endif /* BCM_TRX_SUPPORT */
  48377             break;
  48378         case bcmPortClassFieldEgress:
  48379 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  48380             if (soc_reg_field_valid(unit, egr_port_reg, EGR_PORT_GROUP_IDf)) {
  48381                 rv = soc_reg_field32_modify(unit, egr_port_reg, port_out,
  48382                                             EGR_PORT_GROUP_IDf, pclass_id);
  48383             }
  48384 #ifdef BCM_TRIDENT_SUPPORT
  48385             else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EGR_PORT_GROUP_IDf) ||
  48386                      SOC_IS_TRIDENT3X(unit)) {
  48387                 rv = _bcm_esw_egr_port_tab_set(unit, port,
  48388                                                EGR_PORT_GROUP_IDf, pclass_id);
  48389             }
  48390 #endif /* BCM_TRIDENT_SUPPORT */
  48391 #endif /* BCM_FIREBOLT_SUPPORT || BCM_TRX_SUPPORT */
  48392             break;
  48393         case bcmPortClassVlanTranslateEgress:
  48394 #if defined(BCM_TRX_SUPPORT)
  48395             if (soc_reg_field_valid(unit, egr_port_reg, VT_PORT_GROUP_IDf)) {
  48396                 soc_control_t   *sc = SOC_CONTROL(unit);
  48397 
  48398                 if (sc->soc_flags & SOC_F_PORT_CLASS_BLOCKED) {
  48399                     return BCM_E_CONFIG;
  48400                 }
  48401                 rv = soc_reg_field32_modify(unit, egr_port_reg, port_out,
  48402                                             VT_PORT_GROUP_IDf, pclass_id);
  48403                 if (BCM_SUCCESS(rv)) {
  48404                     /* Once port class is changed system will not allow */
  48405                     /* To use bcm_vlan_translate_egress */
  48406                     sc->soc_flags |= SOC_F_XLATE_EGR_BLOCKED;
  48407                 }
  48408             }
  48409 #ifdef BCM_TRIDENT_SUPPORT
  48410             else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, VT_PORT_GROUP_IDf) ||
  48411                      SOC_IS_TRIDENT3X(unit)) {
  48412                 rv = _bcm_esw_egr_port_tab_set(unit, port,
  48413                                                VT_PORT_GROUP_IDf, pclass_id);
  48414             }
  48415 #endif /* BCM_TRIDENT_SUPPORT */
  48416 #endif /* BCM_TRX_SUPPORT */
  48417             break;
  48418 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  48419          case bcmPortClassEgress:
  48420             if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, CLASS_IDf) ||
  48421                 SOC_IS_TRIDENT3X(unit)) {
  48422                 rv = _bcm_esw_egr_port_tab_set(unit, port,
  48423                                                CLASS_IDf, pclass_id);
  48424             }
  48425             break;
  48426 #endif
  48427 #if defined(BCM_TOMAHAWK_SUPPORT)
  48428          case bcmPortClassFieldIngressDevicePort:
  48429             if  (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) {
  48430                 return BCM_E_UNAVAIL;
  48431             }
  48432             if (pclass_id > 33) {
  48433                 return BCM_E_PARAM;
  48434             }
  48435 
  48436             if (BCM_GPORT_IS_SET(port)) {
  48437                 bcm_module_t mod;
  48438                 bcm_trunk_t tid_out;
  48439                 int id_out;
  48440                 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  48441                                     &mod, &port_out, &tid_out, &id_out));
  48442                 if (-1 != tid_out || -1 != id_out) {
  48443                     return BCM_E_PORT;
  48444                 }
  48445             } else {
  48446                 if (!SOC_PORT_VALID(unit, port)) {
  48447                     return BCM_E_PORT;
  48448                 }
  48449             }
  48450             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48451                                        PORT_IPBM_INDEXf, pclass_id);
  48452             break;
  48453 #endif /* BCM_TOMAHAWK_SUPPORT */
  48454         default:
  48455             rv = BCM_E_PARAM;
  48456         }
  48457     }
  48458 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  48459 
  48460     return rv;
  48461 }
  48462 
  48463 /*
  48464  * Function    :
  48465  *     bcm_port_class_get
  48466  * Description :
  48467  *     Get the ports class ID. Ports with the
  48468  *     same class ID can be treated as a group in
  48469  *     field processing and VLAN translation.
  48470  * Parameters  :
  48471  *     (IN) unit       - BCM device number
  48472  *     (IN) port       - Device or logical port number
  48473  *     (IN) pclass     - Classification type
  48474  *     (OUT) pclass_id - New class ID of the port.
  48475  * Returns     :
  48476  *     BCM_E_NONE      - Success
  48477  *     BCM_E_XXX       - Failed
  48478  */
  48479 int
  48480 bcm_esw_port_class_get(int unit, bcm_port_t port,
  48481                        bcm_port_class_t pclass, uint32 *pclass_id)
  48482 {
  48483     int        rv = BCM_E_UNAVAIL;
  48484     bcm_port_t port_out = port;
  48485 
  48486     /* Make sure port module is initialized. */
  48487     PORT_INIT(unit);
  48488 
  48489 #if defined(INCLUDE_L3)
  48490 #if defined(BCM_TRIDENT_SUPPORT)
  48491     if (BCM_GPORT_IS_SET(port)) {
  48492         int vp;
  48493         _bcm_vp_type_e vp_type;
  48494         source_vp_entry_t entry; 
  48495         BCM_IF_ERROR_RETURN(_bcm_esw_port_vp_type_id_get(unit, port,
  48496                                                          &vp_type, &vp));
  48497         switch (pclass) {
  48498         case bcmPortClassFieldIngress:
  48499             if (vp_type == _bcmVpTypeMim || vp_type == _bcmVpTypeTrill ||
  48500                 vp_type == _bcmVpTypeVxlan || vp_type == _bcmVpTypeMpls ||
  48501                 vp_type == _bcmVpTypeExtender || vp_type == _bcmVpTypeWlan ||
  48502                 vp_type == _bcmVpTypeNiv || vp_type == _bcmVpTypeVlan ||
  48503                 vp_type == _bcmVpTypeL2Gre || vp_type == _bcmVpTypeVpLag ||
  48504                 vp_type == _bcmVpTypeFlow){
  48505                
  48506                 if (!_bcm_vp_used_get(unit, vp, vp_type)) {
  48507                     return BCM_E_PORT;
  48508                 }
  48509                 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &entry);
  48510                 if (BCM_SUCCESS(rv)) {
  48511                     *pclass_id = soc_mem_field32_get(unit, SOURCE_VPm, 
  48512                                                                         &entry, CLASS_IDf);
  48513                 }
  48514                 return rv;    
  48515             }
  48516             break;
  48517         case bcmPortClassVlanTranslateEgress:
  48518 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  48519             /* class_id of DVP used in egress VLAN translation */
  48520             if ((vp_type == _bcmVpTypeVxlan) || (vp_type == _bcmVpTypeMim) || 
  48521                 (vp_type == _bcmVpTypeMpls) || (vp_type == _bcmVpTypeL2Gre)) {
  48522                 int network_port;
  48523                 egr_dvp_attribute_entry_t dvp_entry;
  48524                 _bcm_vp_info_t vp_info;
  48525 
  48526                 if (!_bcm_vp_used_get(unit, vp, vp_type)) {
  48527                     return BCM_E_PORT;
  48528                 }
  48529 
  48530                 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  48531                 if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) {
  48532                     network_port = TRUE;
  48533                 } else {
  48534                     network_port = FALSE;
  48535                 }
  48536 
  48537                 if (SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm, 
  48538                                         VT_DVP_GROUP_IDf)
  48539 #if defined(BCM_TRIDENT3_SUPPORT)
  48540                   || (SOC_IS_TRIDENT3X(unit) && SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm,
  48541                                                         COMMON__VT_DVP_GROUP_IDf))
  48542 #endif
  48543                    ) {
  48544                     rv = READ_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ANY, 
  48545                                                                    vp, &dvp_entry);
  48546                     if (BCM_SUCCESS(rv)) {
  48547                         if ((network_port) && (vp_type == _bcmVpTypeVxlan)) {
  48548                             *pclass_id = soc_mem_field32_get
  48549                                         (unit, EGR_DVP_ATTRIBUTEm, &dvp_entry, 
  48550                                          VXLAN__VT_DVP_GROUP_IDf);
  48551                        } else if ((network_port) && (vp_type == _bcmVpTypeL2Gre)) {
  48552                             *pclass_id = soc_mem_field32_get
  48553                                         (unit, EGR_DVP_ATTRIBUTEm, &dvp_entry, 
  48554                                          L2GRE__VT_DVP_GROUP_IDf); 
  48555                        } else {
  48556                             *pclass_id = soc_mem_field32_get
  48557                                         (unit, EGR_DVP_ATTRIBUTEm, &dvp_entry, 
  48558                                          COMMON__VT_DVP_GROUP_IDf);
  48559                        }
  48560                     }
  48561                 } else {
  48562                     return BCM_E_UNAVAIL;
  48563                 }
  48564                 return rv;
  48565             }
  48566 
  48567 #endif  /* BCM_TRIDENT2PLUS_SUPPORT */
  48568             break;
  48569 #if defined(BCM_TOMAHAWK_SUPPORT)
  48570         case bcmPortClassFieldIngressSourceGport:
  48571             if  (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) {
  48572                 return BCM_E_UNAVAIL;
  48573             }
  48574             if (vp_type == _bcmVpTypeVxlan || vp_type == _bcmVpTypeVlan ||
  48575                 vp_type == _bcmVpTypeExtender || vp_type == _bcmVpTypeVpLag ||
  48576                 vp_type == _bcmVpTypeNiv || vp_type == _bcmVpTypeMpls ||
  48577                 vp_type == _bcmVpTypeL2Gre || vp_type == _bcmVpTypeMim ||
  48578                 vp_type == _bcmVpTypeFlow) {
  48579                 if (!_bcm_vp_used_get(unit, vp, vp_type)) {
  48580                     return BCM_E_PORT;
  48581                 }
  48582                 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &entry);
  48583                 if (BCM_SUCCESS(rv)) {
  48584                     *pclass_id = soc_mem_field32_get(unit, SOURCE_VPm,
  48585                                                      &entry, IPBM_INDEXf);
  48586                 }
  48587                 return rv;
  48588             }
  48589             break;
  48590 #endif /* BCM_TOMAHAWK_SUPPORT */
  48591         default:
  48592             break;
  48593         }
  48594     }
  48595 #endif /* BCM_TRIDENT_SUPPORT */
  48596 #endif /* INCLUDE_L3 */
  48597 #ifdef BCM_XGS3_SWITCH_SUPPORT
  48598     if (SOC_IS_XGS3_SWITCH(unit)) {
  48599 #if defined(BCM_TOMAHAWK_SUPPORT)
  48600         source_trunk_map_table_entry_t entry;
  48601         bcm_module_t mod;
  48602         bcm_trunk_t tid_out;
  48603         int id_out;
  48604         int index;
  48605 #endif /* BCM_TOMAHAWK_SUPPORT */
  48606 
  48607         switch (pclass) {
  48608             case bcmPortClassFieldIngressSystemPort:
  48609 #if defined(BCM_TOMAHAWK_SUPPORT)
  48610                 if  (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) {
  48611                     return BCM_E_UNAVAIL;
  48612                 }
  48613                 if (BCM_GPORT_IS_SET(port)) {
  48614                     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  48615                                         &mod, &port_out, &tid_out, &id_out));
  48616                     if (-1 != tid_out || -1 != id_out) {
  48617                         return BCM_E_PORT;
  48618                     }
  48619                 } else {
  48620                     if (!SOC_PORT_VALID(unit, port)) {
  48621                         return BCM_E_PORT;
  48622                     }
  48623                     port_out = port;
  48624                     BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mod));
  48625                 }
  48626                 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit,
  48627                                     mod, port_out, &index));
  48628 #if defined(BCM_TRIDENT3_SUPPORT)
  48629                 if (SOC_IS_TRIDENT3X(unit) &&
  48630                       !soc_feature(unit, soc_feature_ifp_no_inports_support)){
  48631                     rv = bcm_td3_port_ipbm_opaque_get(unit, index, pclass_id);
  48632                     return rv;
  48633                 }
  48634 #endif
  48635                 SOC_IF_ERROR_RETURN(soc_mem_read(unit, SOURCE_TRUNK_MAP_TABLEm,
  48636                                                  MEM_BLOCK_ANY, index, &entry));
  48637                 *pclass_id = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit,
  48638                                &entry, IPBM_INDEXf);
  48639                 return BCM_E_NONE;
  48640 #endif /* BCM_TOMAHAWK_SUPPORT */
  48641                 break;
  48642             default:
  48643                 break;
  48644         }
  48645     }
  48646 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  48647     /*
  48648      * Skip port validation if soc_feature_shg_support_remote_port
  48649      * is true and ptype is bcmPortClassFieldIngress.
  48650      */
  48651     if (!(soc_feature(unit, soc_feature_shg_support_remote_port) &&
  48652         (pclass == bcmPortClassFieldIngress))) {
  48653         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port_out));
  48654     }
  48655 
  48656     if (NULL == pclass_id) {
  48657         return BCM_E_PARAM;
  48658     }
  48659 
  48660 #ifdef BCM_XGS3_SWITCH_SUPPORT
  48661     if (SOC_IS_XGS3_SWITCH(unit)) {
  48662 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  48663         uint32 reg_val;
  48664         uint64 reg_val64;
  48665         int    port_class_id;
  48666 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  48667         switch (pclass) {
  48668             case bcmPortClassFieldIngressGroupSel:
  48669 #if defined(BCM_TOMAHAWK_SUPPORT)
  48670                 rv = _bcm_esw_port_tab_get(unit, port, IFP_KEY_SEL_CLASS_IDf,
  48671                                            (int32*) pclass_id);
  48672 #endif
  48673                 break;
  48674 
  48675         case bcmPortClassFieldLookup:
  48676 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  48677             if (soc_mem_field_valid(unit, PORT_TABm, VFP_PORT_GROUP_IDf) ||
  48678                 SOC_IS_TRIDENT3X(unit)) {
  48679                 rv = _bcm_esw_port_tab_get(unit, port, VFP_PORT_GROUP_IDf,
  48680                                            &port_class_id);
  48681                 *pclass_id = (uint32) port_class_id;
  48682             }
  48683 #endif /* BCM_FIREBOLT_SUPPORT || BCM_TRX_SUPPORT */
  48684             break;
  48685         case bcmPortClassVlanTranslateIngress:
  48686 #if defined(BCM_TRIDENT2_SUPPORT)
  48687             if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, PORT_GROUPf)) {
  48688                 rv = _bcm_trx_source_trunk_map_get(unit, port,
  48689                                                    PORT_GROUPf, pclass_id);
  48690             }
  48691 #endif /* BCM_TRIDENT2_SUPPORT */
  48692             break;
  48693         case bcmPortClassFieldIngress:
  48694 #if defined(BCM_TRX_SUPPORT)
  48695             if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, CLASS_IDf)) {
  48696 #if defined(BCM_KATANA2_SUPPORT)
  48697                 if (SOC_IS_KATANA2(unit)) {
  48698                     rv = _bcm_kt2_source_trunk_map_get(unit, port_out,
  48699                                                    CLASS_IDf, pclass_id);
  48700                 } else
  48701 #endif
  48702                 {
  48703                     rv = _bcm_trx_source_trunk_map_get(unit, port,
  48704                                                    CLASS_IDf, pclass_id);
  48705                 }
  48706             }
  48707 #endif /* BCM_TRX_SUPPORT */
  48708             break;
  48709         case bcmPortClassFieldEgress:
  48710 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  48711             if (soc_reg_field_valid(unit, EGR_PORT_64r, EGR_PORT_GROUP_IDf)) {
  48712                 rv = READ_EGR_PORT_64r(unit, port_out, &reg_val64);
  48713                 if (BCM_SUCCESS(rv)) {
  48714                     *pclass_id = soc_reg64_field32_get(unit, EGR_PORT_64r,
  48715                                                    reg_val64, EGR_PORT_GROUP_IDf);
  48716                 }
  48717             } else if (soc_reg_field_valid(unit, EGR_PORTr, EGR_PORT_GROUP_IDf)) {
  48718                 rv = READ_EGR_PORTr(unit, port_out, &reg_val);
  48719                 if (BCM_SUCCESS(rv)) {
  48720                     *pclass_id = soc_reg_field_get(unit, EGR_PORTr,
  48721                                                    reg_val, EGR_PORT_GROUP_IDf);
  48722                 }
  48723             }
  48724 #ifdef BCM_TRIDENT_SUPPORT
  48725             else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EGR_PORT_GROUP_IDf) ||
  48726                      SOC_IS_TRIDENT3X(unit)) {
  48727                 rv = _bcm_esw_egr_port_tab_get(unit, port, EGR_PORT_GROUP_IDf,
  48728                                                (int *)pclass_id);
  48729 
  48730             }
  48731 #endif /* BCM_TRIDENT_SUPPORT */
  48732 #endif /* BCM_FIREBOLT_SUPPORT || BCM_TRX_SUPPORT */
  48733             break;
  48734         case bcmPortClassVlanTranslateEgress:
  48735 #if defined(BCM_TRX_SUPPORT)
  48736             if (soc_reg_field_valid(unit, EGR_PORT_64r, VT_PORT_GROUP_IDf)) {
  48737                 if (SOC_REG_IS_VALID(unit, EGR_PORT_64r)) {
  48738                     rv = READ_EGR_PORT_64r(unit, port_out, &reg_val64);
  48739                     if (BCM_SUCCESS(rv)) {
  48740                         *pclass_id = soc_reg64_field32_get(unit, EGR_PORT_64r,
  48741                                                        reg_val64, VT_PORT_GROUP_IDf);
  48742                     }
  48743                 }
  48744             } else if (soc_reg_field_valid(unit, EGR_PORTr, VT_PORT_GROUP_IDf)) {
  48745                     rv = READ_EGR_PORTr(unit, port_out, &reg_val);
  48746                     if (BCM_SUCCESS(rv)) {
  48747                         *pclass_id = soc_reg_field_get(unit, EGR_PORTr,
  48748                                                        reg_val, VT_PORT_GROUP_IDf);
  48749                     }
  48750             }
  48751 #ifdef BCM_TRIDENT_SUPPORT
  48752             else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, VT_PORT_GROUP_IDf) ||
  48753                      SOC_IS_TRIDENT3X(unit)) {
  48754                 rv = _bcm_esw_egr_port_tab_get(unit, port, VT_PORT_GROUP_IDf,
  48755                                                (int *)pclass_id);
  48756             }
  48757 #endif /* BCM_TRIDENT_SUPPORT */
  48758 #endif /* BCM_TRX_SUPPORT */
  48759             break;
  48760 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  48761          case bcmPortClassEgress:
  48762             if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, CLASS_IDf) ||
  48763                 SOC_IS_TRIDENT3X(unit)) {
  48764                 rv = _bcm_esw_egr_port_tab_get(unit, port, CLASS_IDf,
  48765                                                (int *)pclass_id);
  48766             }
  48767             break;
  48768 #endif
  48769 #if defined(BCM_TOMAHAWK_SUPPORT)
  48770          case bcmPortClassFieldIngressDevicePort:
  48771             if  (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) {
  48772                 return BCM_E_UNAVAIL;
  48773             }
  48774             rv = _bcm_esw_port_tab_get(unit, port, PORT_IPBM_INDEXf,
  48775                                        &port_class_id);
  48776             if (BCM_SUCCESS(rv)) {
  48777                 *pclass_id = (uint32) port_class_id;
  48778             }
  48779             break;
  48780 #endif /* BCM_TOMAHAWK_SUPPORT */
  48781 
  48782         default:
  48783             rv = BCM_E_PARAM;
  48784         }
  48785     }
  48786 #endif /* BCM_XGS3_SWITCH_SUPPORT */
  48787 
  48788     return rv;
  48789 }
  48790 
  48791 
  48792 /*
  48793  * Function    : _bcm_esw_port_config_set
  48794  * Description : Internal function to set port configuration.
  48795  * Parameters  : (IN)unit  - BCM device number.
  48796  *               (IN)port  - Port number (see Notes for valid port formats).
  48797  *               (IN)type  - Port property.
  48798  *               (IN)value - New property value.
  48799  * Returns     : BCM_E_XXX
  48800  * Notes:
  48801  *      Current valid port types are:
  48802  *          GPORT PROXY
  48803  *          GPORT SUBPORT
  48804  *          GPORT (various types) that resolves to local physical port
  48805  *          BCM port (non-gport), local physical port
  48806  */
  48807 int
  48808 _bcm_esw_port_config_set(int unit, bcm_port_t port,
  48809                          _bcm_port_config_t type, int value)
  48810 {
  48811     int rv = BCM_E_UNAVAIL;    /* Operation return status. */
  48812     
  48813 #ifdef BCM_HGPROXY_COE_SUPPORT
  48814     if (BCM_GPORT_IS_SET(port) &&
  48815         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port) &&
  48816         soc_feature(unit, soc_feature_hgproxy_subtag_coe)) {
  48817         /* Don't resolve port */
  48818     } else
  48819 #endif
  48820     if (BCM_GPORT_IS_PROXY(port)) {
  48821         /* Don't resolve port */
  48822     } else {
  48823         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  48824     }
  48825 
  48826 
  48827     PORT_LOCK(unit);
  48828 
  48829     switch (type) {
  48830     case _bcmPortL3UrpfMode:
  48831 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  48832         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48833                                    URPF_MODEf, value);
  48834 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  48835         break;
  48836     case _bcmPortL3UrpfDefaultRoute:
  48837 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  48838         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48839                                    URPF_DEFAULTROUTECHECKf,
  48840                                    (value) ? 0 : 1);
  48841 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  48842         break;
  48843     case _bcmPortVlanTranslate:
  48844         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48845                                    VT_ENABLEf, value);
  48846 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
  48847     defined(BCM_KATANA2_SUPPORT)
  48848         if ((SOC_IS_TRIUMPH3(unit) ||
  48849              SOC_IS_TD2_TT2(unit) ||
  48850              SOC_IS_KATANA2(unit)) && (rv == SOC_E_NONE)) {
  48851             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48852                                        VT_PORT_TYPE_SELECTf, value);
  48853             if (rv == SOC_E_NONE) {
  48854                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48855                                            VT_PORT_TYPE_SELECT_2f, value);
  48856             }
  48857         } else
  48858 #endif
  48859         {
  48860 #if defined(BCM_TRX_SUPPORT)
  48861         if (SOC_IS_TRX(unit) && (rv == SOC_E_NONE)) {
  48862             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48863                                        VT_KEY_TYPE_USE_GLPf, value);
  48864             if (rv == SOC_E_NONE) {
  48865                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48866                                            VT_KEY_TYPE_2_USE_GLPf, value);
  48867             }
  48868         }
  48869 #endif
  48870         }
  48871         break;
  48872     case _bcmPortVlanPrecedence:
  48873         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48874                                    VLAN_PRECEDENCEf, value);
  48875         break;
  48876     case _bcmPortVTMissDrop:
  48877         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48878                                    VT_MISS_DROPf, value);
  48879         break;
  48880     case _bcmPortLookupMACEnable:
  48881         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48882                                    MAC_BASED_VID_ENABLEf, value);
  48883         break;
  48884     case _bcmPortLookupIPEnable:
  48885         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48886                                    SUBNET_BASED_VID_ENABLEf,
  48887                                    value);
  48888         break;
  48889     case _bcmPortUseInnerPri:
  48890 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \
  48891     defined(BCM_TRX_SUPPORT)
  48892         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48893                                    USE_INNER_PRIf, value);
  48894 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  48895         break;
  48896     case _bcmPortUseOuterPri:
  48897 #if defined(BCM_TRX_SUPPORT)
  48898         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48899                                    TRUST_OUTER_DOT1Pf, value);
  48900 #endif /* BCM_TRX_SUPPORT */
  48901         break;
  48902     case _bcmPortVerifyOuterTpid:
  48903 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \
  48904     defined(BCM_TRX_SUPPORT)
  48905         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48906                                    OUTER_TPID_VERIFYf, value);
  48907 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  48908         break;
  48909     case _bcmPortVTKeyTypeFirst:
  48910 #if defined(BCM_TRX_SUPPORT)
  48911         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48912                                    VT_KEY_TYPEf, value);
  48913 #endif /* BCM_TRX_SUPPORT */
  48914         break;
  48915     case _bcmPortVTKeyPortFirst:
  48916 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
  48917     defined(BCM_KATANA2_SUPPORT)
  48918        if (SOC_IS_TRIUMPH3(unit) ||
  48919            SOC_IS_TD2_TT2(unit) ||
  48920            SOC_IS_KATANA2(unit)) {
  48921             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48922                                        VT_PORT_TYPE_SELECTf, value);
  48923         } else
  48924 #endif
  48925         {
  48926 #if defined(BCM_TRX_SUPPORT)
  48927         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48928                                    VT_KEY_TYPE_USE_GLPf, value);
  48929 #endif /* BCM_TRX_SUPPORT */
  48930         }
  48931         break;
  48932     case _bcmPortVTKeyTypeSecond:
  48933 #if defined(BCM_TRX_SUPPORT)
  48934         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48935                                    VT_KEY_TYPE_2f, value);
  48936 #endif /* BCM_TRX_SUPPORT */
  48937         break;
  48938     case _bcmPortVTKeyPortSecond:
  48939 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
  48940     defined(BCM_KATANA2_SUPPORT)
  48941         if (SOC_IS_TRIUMPH3(unit) ||
  48942             SOC_IS_TD2_TT2(unit) ||
  48943             SOC_IS_KATANA2(unit)) {
  48944             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48945                                    VT_PORT_TYPE_SELECT_2f, value);
  48946         } else
  48947 #endif
  48948         {
  48949 #if defined(BCM_TRX_SUPPORT)
  48950         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48951                                    VT_KEY_TYPE_2_USE_GLPf, value);
  48952 #endif /* BCM_TRX_SUPPORT */
  48953         }
  48954         break;
  48955     case _bcmPortIpmcV4Enable:
  48956         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48957                                    V4IPMC_ENABLEf, value);
  48958         break;
  48959     case _bcmPortIpmcV6Enable:
  48960         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48961                                    V6IPMC_ENABLEf, value);
  48962         break;
  48963     case _bcmPortIpmcVlanKey:
  48964         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48965                                    IPMC_DO_VLANf, value);
  48966         break;
  48967     case _bcmPortCfiAsCng:
  48968         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48969                                    CFI_AS_CNGf, value);
  48970         break;
  48971     case _bcmPortNni:
  48972         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48973                                    NNI_PORTf, value);
  48974         break;
  48975     case _bcmPortHigigTrunkId:
  48976 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRX_SUPPORT)
  48977         if (value < 0) {
  48978             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48979                                        HIGIG_TRUNKf, 0);
  48980             if (BCM_SUCCESS(rv)) {
  48981                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48982                                            HIGIG_TRUNK_IDf, 0);
  48983             }
  48984         } else {
  48985             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48986                                        HIGIG_TRUNK_IDf, value);
  48987             if (BCM_SUCCESS(rv)) {
  48988                 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48989                                            HIGIG_TRUNKf, 1);
  48990             }
  48991         }
  48992 #endif /* BCM_BRADLEY_SUPPORT || BCM_TRX_SUPPORT */
  48993         break;
  48994     case _bcmPortModuleLoopback:
  48995         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  48996                                    ALLOW_SRC_MODf, value);
  48997         break;
  48998     case _bcmPortOuterTpidEnables:
  48999 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \
  49000     defined(BCM_TRX_SUPPORT)
  49001         if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 
  49002                                 OUTER_TPID_ENABLEf)) {
  49003 #ifdef BCM_TRX_SUPPORT
  49004             rv = _bcm_trx_source_trunk_map_set(unit, port, OUTER_TPID_ENABLEf,
  49005                                                (uint32)value);
  49006 #endif
  49007         } else {
  49008         rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  49009                                    OUTER_TPID_ENABLEf, value);
  49010         }
  49011 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  49012         break;
  49013 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  49014     defined(BCM_GREYHOUND2_SUPPORT)
  49015     case _bcmPortSvcMeterIndex:
  49016         if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||    \
  49017             SOC_IS_APACHE(unit) || SOC_IS_GREYHOUND2(unit)) {
  49018             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  49019                                    SVC_METER_INDEXf, value);
  49020         }
  49021         break;
  49022     case _bcmPortSvcMeterOffsetMode:
  49023         if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) ||    \
  49024             SOC_IS_APACHE(unit) || SOC_IS_GREYHOUND2(unit)) {
  49025             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  49026                                    SVC_METER_OFFSET_MODEf, value);
  49027         }
  49028         break;
  49029 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT ||
  49030           BCM_GREYHOUND2_SUPPORT */
  49031 #if defined(BCM_KATANA2_SUPPORT)
  49032     case _bcmPortOamUseXlatedInnerVlan:
  49033         if (SOC_IS_KATANA2(unit)) {
  49034             rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH,
  49035                                    OAM_CVLAN_MEP_AFTER_VXLTf, value);
  49036             rv = _bcm_esw_egr_port_tab_set(unit, port,
  49037                                    OAM_CVLAN_MEP_AFTER_VXLTf, value);
  49038         }
  49039         break;
  49040 #endif /* BCM_KATANA2_SUPPORT */
  49041     default:
  49042         rv = BCM_E_INTERNAL;
  49043     }
  49044 
  49045     PORT_UNLOCK(unit);
  49046     return (rv);
  49047 }
  49048 
  49049 /*
  49050  * Function    : _bcm_esw_port_config_get
  49051  * Description : Internal function to get port configuration.
  49052  * Parameters  : (IN)unit  - BCM device number.
  49053  *               (IN)port  - Port number.
  49054  *               (IN)type  - Port property.
  49055  *               (OUT)value -Port property value.
  49056  * Returns     : BCM_E_XXX
  49057  * Notes:
  49058  *      Current valid port types are:
  49059  *          GPORT PROXY
  49060  *          GPORT SUBPORT
  49061  *          GPORT (various types) that resolves to local physical port
  49062  *          BCM port (non-gport), local physical port
  49063  */
  49064 int
  49065 _bcm_esw_port_config_get(int unit, bcm_port_t port,
  49066                      _bcm_port_config_t type, int *value)
  49067 {
  49068     int rv = BCM_E_UNAVAIL;    /* Operation return status. */
  49069 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  49070     int tmp_value; /* Temporary value.     */
  49071 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  49072 
  49073 #ifdef BCM_HGPROXY_COE_SUPPORT
  49074     if (BCM_GPORT_IS_SET(port) &&
  49075         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port) &&
  49076         soc_feature(unit, soc_feature_hgproxy_subtag_coe)) {
  49077         /* Don't resolve port */
  49078     } else
  49079 #endif
  49080     if (BCM_GPORT_IS_PROXY(port)) {
  49081         /* Don't resolve port */
  49082     } else {
  49083         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  49084     }
  49085 
  49086     PORT_LOCK(unit);
  49087 
  49088     switch (type) {
  49089     case _bcmPortL3UrpfMode:
  49090 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  49091         rv = _bcm_esw_port_tab_get(unit, port, URPF_MODEf, value);
  49092 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  49093         break;
  49094     case _bcmPortL3UrpfDefaultRoute:
  49095 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)
  49096         rv = _bcm_esw_port_tab_get(unit, port, URPF_DEFAULTROUTECHECKf,
  49097                                    &tmp_value);
  49098         *value = (tmp_value) ? FALSE : TRUE;
  49099 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  49100         break;
  49101     case _bcmPortVlanTranslate:
  49102         rv = _bcm_esw_port_tab_get(unit, port, VT_ENABLEf, value);
  49103         break;
  49104     case _bcmPortVlanPrecedence:
  49105         rv = _bcm_esw_port_tab_get(unit, port, VLAN_PRECEDENCEf, value);
  49106         break;
  49107     case _bcmPortVTMissDrop:
  49108         rv = _bcm_esw_port_tab_get(unit, port, VT_MISS_DROPf, value);
  49109         break;
  49110     case _bcmPortLookupMACEnable:
  49111         rv = _bcm_esw_port_tab_get(unit, port, MAC_BASED_VID_ENABLEf, value);
  49112         break;
  49113     case _bcmPortLookupIPEnable:
  49114         rv = _bcm_esw_port_tab_get(unit, port, SUBNET_BASED_VID_ENABLEf,
  49115                                    value);
  49116         break;
  49117     case _bcmPortUseInnerPri:
  49118 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \
  49119     defined(BCM_TRX_SUPPORT)
  49120         rv = _bcm_esw_port_tab_get(unit, port, USE_INNER_PRIf, value);
  49121 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  49122         break;
  49123     case _bcmPortUseOuterPri:
  49124 #if defined(BCM_TRX_SUPPORT)
  49125         rv = _bcm_esw_port_tab_get(unit, port, TRUST_OUTER_DOT1Pf, value);
  49126 #endif /* BCM_TRX_SUPPORT */
  49127         break;
  49128     case _bcmPortVerifyOuterTpid:
  49129 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \
  49130     defined(BCM_TRX_SUPPORT)
  49131         rv = _bcm_esw_port_tab_get(unit, port, OUTER_TPID_VERIFYf, value);
  49132 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  49133         break;
  49134     case _bcmPortVTKeyTypeFirst:
  49135 #if defined(BCM_TRX_SUPPORT)
  49136         rv = _bcm_esw_port_tab_get(unit, port, VT_KEY_TYPEf, value);
  49137 #endif /* BCM_TRX_SUPPORT */
  49138         break;
  49139     case _bcmPortVTKeyPortFirst:
  49140 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
  49141     defined(BCM_KATANA2_SUPPORT)
  49142        if (SOC_IS_TRIUMPH3(unit) ||
  49143            SOC_IS_TD2_TT2(unit) ||
  49144            SOC_IS_KATANA2(unit)) {
  49145             rv = _bcm_esw_port_tab_get(unit, port,
  49146                                        VT_PORT_TYPE_SELECTf, value);
  49147         } else
  49148 #endif
  49149         {
  49150 #if defined(BCM_TRX_SUPPORT)
  49151         rv = _bcm_esw_port_tab_get(unit, port, VT_KEY_TYPE_USE_GLPf, value);
  49152 #endif /* BCM_TRX_SUPPORT */
  49153         }
  49154         break;
  49155     case _bcmPortVTKeyTypeSecond:
  49156 #if defined(BCM_TRX_SUPPORT)
  49157         rv = _bcm_esw_port_tab_get(unit, port, VT_KEY_TYPE_2f, value);
  49158 #endif /* BCM_TRX_SUPPORT */
  49159         break;
  49160     case _bcmPortVTKeyPortSecond:
  49161 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
  49162     defined(BCM_KATANA2_SUPPORT)
  49163         if (SOC_IS_TRIUMPH3(unit) ||
  49164             SOC_IS_TD2_TT2(unit) ||
  49165             SOC_IS_KATANA2(unit)) {
  49166             rv = _bcm_esw_port_tab_get(unit, port,
  49167                          VT_PORT_TYPE_SELECT_2f, value);
  49168         } else
  49169 #endif
  49170         {
  49171 #if defined(BCM_TRX_SUPPORT)
  49172         rv = _bcm_esw_port_tab_get(unit, port, VT_KEY_TYPE_2_USE_GLPf, value);
  49173 #endif /* BCM_TRX_SUPPORT */
  49174         }
  49175         break;
  49176     case _bcmPortIpmcV4Enable:
  49177         rv = _bcm_esw_port_tab_get(unit, port, V4IPMC_ENABLEf, value);
  49178         break;
  49179     case _bcmPortIpmcV6Enable:
  49180         rv = _bcm_esw_port_tab_get(unit, port, V6IPMC_ENABLEf, value);
  49181         break;
  49182     case _bcmPortIpmcVlanKey:
  49183         rv = _bcm_esw_port_tab_get(unit, port, IPMC_DO_VLANf, value);
  49184         break;
  49185     case _bcmPortCfiAsCng:
  49186         rv = _bcm_esw_port_tab_get(unit, port, CFI_AS_CNGf, value);
  49187         break;
  49188     case _bcmPortNni:
  49189         rv = _bcm_esw_port_tab_get(unit, port, NNI_PORTf, value);
  49190         break;
  49191     case _bcmPortHigigTrunkId:
  49192 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRX_SUPPORT)
  49193         rv = _bcm_esw_port_tab_get(unit, port, HIGIG_TRUNKf, value);
  49194         if (BCM_SUCCESS(rv)) {
  49195             if (*value == 0) {
  49196                 *value = -1;
  49197             } else {
  49198                 rv = _bcm_esw_port_tab_get(unit, port,
  49199                                            HIGIG_TRUNK_IDf, value);
  49200             }
  49201         }
  49202 #endif /* BCM_BRADLEY_SUPPORT || BCM_TRX_SUPPORT */
  49203         break;
  49204     case _bcmPortModuleLoopback:
  49205         rv = _bcm_esw_port_tab_get(unit, port, ALLOW_SRC_MODf, value);
  49206         break;
  49207     case _bcmPortOuterTpidEnables:
  49208 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \
  49209     defined(BCM_TRX_SUPPORT)
  49210         if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 
  49211                                 OUTER_TPID_ENABLEf)) {
  49212 #ifdef BCM_TRX_SUPPORT
  49213             rv = _bcm_trx_source_trunk_map_get(unit, port, OUTER_TPID_ENABLEf,
  49214                                                (uint32 *)value);
  49215 #endif
  49216         } else {
  49217         rv = _bcm_esw_port_tab_get(unit, port, OUTER_TPID_ENABLEf, value);
  49218         }
  49219 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */
  49220         break;
  49221 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  49222     defined(BCM_GREYHOUND2_SUPPORT)
  49223     case _bcmPortSvcMeterIndex:
  49224         if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)       \
  49225             || SOC_IS_APACHE(unit) || SOC_IS_GREYHOUND2(unit)) {
  49226             rv = _bcm_esw_port_tab_get(unit, port, SVC_METER_INDEXf, value);
  49227         }
  49228         break;
  49229     case _bcmPortSvcMeterOffsetMode:
  49230         if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)       \
  49231             || SOC_IS_APACHE(unit) || SOC_IS_GREYHOUND2(unit)) {
  49232             rv = _bcm_esw_port_tab_get(unit, port, SVC_METER_OFFSET_MODEf, value);
  49233         }
  49234         break;
  49235 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT ||
  49236           BCM_GREYHOUND2_SUPPORT */
  49237 #if defined(BCM_KATANA2_SUPPORT)
  49238     case _bcmPortOamUseXlatedInnerVlan:
  49239         if (SOC_IS_KATANA2(unit)) {
  49240             rv = _bcm_esw_port_tab_get(unit, port, OAM_CVLAN_MEP_AFTER_VXLTf,
  49241                                        value);
  49242         }
  49243         break;
  49244 #endif /* BCM_KATANA2_SUPPORT */
  49245     default:
  49246         rv = BCM_E_INTERNAL;
  49247     }
  49248     PORT_UNLOCK(unit);
  49249     return (rv);
  49250 }
  49251 
  49252 /*
  49253  * Function:
  49254  *     bcm_port_force_vlan_set
  49255  * Description:
  49256  *     To set the force vlan attribute of a port
  49257  * Parameters:
  49258  *     unit        device number
  49259  *     port        port number
  49260  *     vlan        vlan identifier
  49261  *                 (0 - 4095) - use this VLAN id if egress packet is tagged
  49262  *     pkt_prio    egress packet priority (-1, 0..7)
  49263  *                 any negative priority value disable the priority
  49264  *                 override if the egress packet is tagged
  49265  *     flags       bit fields
  49266  *                 BCM_PORT_FORCE_VLAN_ENABLE - enable force vlan on this
  49267  *                                              port
  49268  *                 BCM_PORT_FORCE_VLAN_UNTAG - egress untagged when force
  49269  *                                             vlan is enabled on this port
  49270  *
  49271  * Return:
  49272  *     BCM_E_NONE
  49273  *     BCM_E_UNIT
  49274  *     BCM_E_PORT
  49275  *     BCM_E_PARAM
  49276  *     BCM_E_UNAVAIL
  49277  *     BCM_E_XXX
  49278  */
  49279 int
  49280 bcm_esw_port_force_vlan_set(int unit, bcm_port_t port, bcm_vlan_t vlan,
  49281                             int pkt_prio, uint32 flags)
  49282 {
  49283     int rv = BCM_E_UNAVAIL;
  49284 
  49285     /* Make sure port module is initialized. */
  49286     PORT_INIT(unit);
  49287 
  49288 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
  49289     if (BCM_GPORT_IS_VLAN_PORT(port) ||
  49290         BCM_GPORT_IS_NIV_PORT(port) ||
  49291         BCM_GPORT_IS_EXTENDER_PORT(port)) {
  49292         return bcm_td_vp_force_vlan_set(unit, port, vlan, flags);
  49293     }
  49294 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  49295 
  49296     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  49297 #if defined(BCM_TRX_SUPPORT)
  49298     if (SOC_REG_FIELD_VALID(unit, EGR_PVLAN_EPORT_CONTROLr, PVLAN_UNTAGf)) {
  49299         rv = _bcm_trx_port_force_vlan_set(unit, port, vlan, pkt_prio, flags);
  49300     }
  49301 #endif /* defined(BCM_TRX_SUPPORT) */
  49302 
  49303     return rv;
  49304 }
  49305 
  49306 /*
  49307  * Function:
  49308  *     bcm_port_force_vlan_get
  49309  * Description:
  49310  *     To get the force vlan attribute of a port
  49311  * Parameters:
  49312  *     unit        device number
  49313  N_UNTAGf*     port        port number
  49314  *     vlan        pointer to vlan identifier
  49315  *                 (0 - 4095) - use this VLAN id if egress packet is tagged
  49316  *                 valid only when BCM_PORT_FORCE_VLAN_ENABLE is set and
  49317  *                 BCM_PORT_FORCE_VLAN_UNTAG is clear
  49318  *     pkt_prio    egress packet priority (-1, 0 - 7)
  49319  *                 valid only when BCM_PORT_FORCE_VLAN_ENABLE is set and
  49320  *                 BCM_PORT_FORCE_VLAN_UNTAG is clear
  49321  *     flags       bit fields
  49322  *                 BCM_PORT_FORCE_VLAN_ENABLE - enable force vlan on this
  49323  *                                              port
  49324  *                 BCM_PORT_FORCE_VLAN_UNTAG - egress untagged when force
  49325  *                                             vlan is enabled on this port
  49326  *
  49327  * Return:
  49328  *     BCM_E_XXX
  49329  */
  49330 int
  49331 bcm_esw_port_force_vlan_get(int unit, bcm_port_t port, bcm_vlan_t *vlan,
  49332                             int *pkt_prio, uint32 *flags)
  49333 {
  49334     int rv = BCM_E_UNAVAIL;
  49335 
  49336     /* Make sure port module is initialized. */
  49337     PORT_INIT(unit);
  49338 
  49339 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
  49340     if (BCM_GPORT_IS_VLAN_PORT(port) ||
  49341         BCM_GPORT_IS_NIV_PORT(port) ||
  49342         BCM_GPORT_IS_EXTENDER_PORT(port)) {
  49343         return bcm_td_vp_force_vlan_get(unit, port, vlan, flags);
  49344     }
  49345 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  49346 
  49347     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  49348 
  49349 #if defined(BCM_TRX_SUPPORT)
  49350     if (SOC_REG_FIELD_VALID(unit, EGR_PVLAN_EPORT_CONTROLr, PVLAN_UNTAGf)) {
  49351         rv = _bcm_trx_port_force_vlan_get(unit, port, vlan, pkt_prio, flags);
  49352     }
  49353 #endif /* defined(BCM_TRX_SUPPORT) */
  49354 
  49355     return rv;
  49356 }
  49357 
  49358 /*
  49359  * Function:
  49360  *     bcm_port_phy_control_set
  49361  * Description:
  49362  *     Set PHY specific properties
  49363  * Parameters:
  49364  *     unit        device number
  49365  *     port        port number
  49366  *     type        configuration type
  49367  *     value       new value for the configuration
  49368  * Return:
  49369  *     BCM_E_XXX
  49370  */
  49371 int
  49372 bcm_esw_port_phy_control_set(int unit, bcm_port_t port,
  49373                              bcm_port_phy_control_t type, uint32 value)
  49374 {
  49375     int rv;
  49376     bcm_port_t local_port = 0;
  49377     int phy_lane = -1;
  49378     int phyn = 0, sys_side = 0;
  49379 
  49380     /* Make sure port module is initialized. */
  49381     PORT_INIT(unit);
  49382 
  49383     if (SOC_USE_PORTCTRL(unit)) {
  49384         BCM_IF_ERROR_RETURN
  49385             (bcmi_esw_portctrl_phy_control_set(unit, port, type, value));
  49386 #ifdef BCM_TOMAHAWK_SUPPORT
  49387         /* If FEC/CL91/CL108 is enabled/disabled on the 25/27/50/53G ports, we will need to update ASF parameters */
  49388         if (SOC_IS_TOMAHAWKX(unit)) {
  49389             if ((type == _SHR_PORT_PHY_CONTROL_FORWARD_ERROR_CORRECTION_CL91)
  49390                 || (type == _SHR_PORT_PHY_CONTROL_FORWARD_ERROR_CORRECTION_CL108)) {
  49391                 bcm_port_info_t port_info;
  49392 
  49393                 bcm_port_info_t_init(&port_info);
  49394                 BCM_IF_ERROR_RETURN(bcm_esw_port_info_get(unit, port, &port_info));
  49395 
  49396                 if ((port_info.speed == 25000) || (port_info.speed == 27000) ||
  49397                         (port_info.speed == 50000) || (port_info.speed == 53000) ||
  49398                         (port_info.speed == 100000) || (port_info.speed == 106000)){
  49399                     int mode;
  49400 
  49401                     BCM_IF_ERROR_RETURN(bcm_esw_port_asf_mode_get(unit, port, &mode));
  49402                     BCM_IF_ERROR_RETURN(bcm_esw_port_asf_mode_set(unit, port, mode));
  49403                 }
  49404             }
  49405         }
  49406 #endif
  49407         return BCM_E_NONE;
  49408     }
  49409 
  49410     if(BCM_PHY_GPORT_IS_PHYN(port)) {
  49411         local_port = BCM_PHY_GPORT_PHYN_PORT_PORT_GET(port);
  49412         phyn = BCM_PHY_GPORT_PHYN_PORT_PHYN_GET(port);
  49413         phy_lane = -1;
  49414     } else if(BCM_PHY_GPORT_IS_PHYN_LANE(port)) {
  49415         local_port = BCM_PHY_GPORT_PHYN_LANE_PORT_PORT_GET(port);
  49416         phyn = BCM_PHY_GPORT_PHYN_LANE_PORT_PHYN_GET(port);
  49417         phy_lane = BCM_PHY_GPORT_PHYN_LANE_PORT_LANE_GET(port);
  49418     } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE(port)) {
  49419         local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PORT_GET(port);
  49420         phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PHYN_GET(port);
  49421         sys_side = TRUE;
  49422         phy_lane = -1;
  49423     } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE_LANE(port)) {
  49424         local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PORT_GET(port);
  49425         phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PHYN_GET(port);
  49426         phy_lane = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_LANE_GET(port);
  49427         sys_side = TRUE;
  49428     } else if (BCM_PHY_GPORT_IS_LANE(port)) {
  49429         local_port = BCM_PHY_GPORT_LANE_PORT_PORT_GET(port);
  49430         phy_lane = BCM_PHY_GPORT_LANE_PORT_LANE_GET(port);
  49431     } else {
  49432         BCM_IF_ERROR_RETURN
  49433             (_bcm_esw_port_gport_validate(unit, port, &local_port));
  49434 
  49435         PORT_LOCK(unit);
  49436         rv = soc_phyctrl_control_set(unit, local_port, (soc_phy_control_t) type, value);
  49437         if (BCM_SUCCESS(rv)) {
  49438             PORT_INFO_RX_LOS_SET(unit, local_port, type, value);
  49439         }
  49440         PORT_UNLOCK(unit);
  49441 
  49442 #ifdef BCM_TOMAHAWK_SUPPORT
  49443         /* If FEC/CL91/CL108 is enabled/disabled on the 25/27/50/53G ports, we will need to update ASF parameters */
  49444         if (SOC_IS_TOMAHAWKX(unit)) {
  49445             if ((type == _SHR_PORT_PHY_CONTROL_FORWARD_ERROR_CORRECTION_CL91)
  49446                 || (type == _SHR_PORT_PHY_CONTROL_FORWARD_ERROR_CORRECTION_CL108)) {
  49447                 bcm_port_info_t port_info;
  49448 
  49449                 bcm_port_info_t_init(&port_info);
  49450                 BCM_IF_ERROR_RETURN(bcm_esw_port_info_get(unit, port, &port_info));
  49451 
  49452                 if ((port_info.speed == 25000) || (port_info.speed == 27000) ||
  49453                         (port_info.speed == 50000) || (port_info.speed == 53000) ||
  49454                         (port_info.speed == 100000) || (port_info.speed == 106000)){
  49455                     int mode;
  49456 
  49457                     BCM_IF_ERROR_RETURN(bcm_esw_port_asf_mode_get(unit, port, &mode));
  49458                     BCM_IF_ERROR_RETURN(bcm_esw_port_asf_mode_set(unit, port, mode));
  49459                 }
  49460             }
  49461         }
  49462 #endif
  49463         return rv;
  49464     }
  49465 
  49466     if (!SOC_PORT_VALID(unit, local_port)) {
  49467         return BCM_E_PORT;
  49468     }
  49469 
  49470     PORT_LOCK(unit);
  49471     rv = soc_phyctrl_redirect_control_set(unit, local_port, phyn, phy_lane,
  49472                                           sys_side, (soc_phy_control_t) type, value);
  49473     if (BCM_SUCCESS(rv)) {
  49474         PORT_INFO_RX_LOS_SET(unit, local_port, type, value);
  49475     }
  49476     PORT_UNLOCK(unit);
  49477 
  49478     return rv;
  49479 }
  49480 
  49481 /*
  49482  * Function:
  49483  *     bcm_esw_port_phy_control_get
  49484  * Description:
  49485  *     Set PHY specific properties
  49486  * Parameters:
  49487  *     unit        device number
  49488  *     port        port number
  49489  *     type        configuration type
  49490  *     value       value for the configuration
  49491  * Return:
  49492  *     BCM_E_XXX
  49493  */
  49494 int
  49495 bcm_esw_port_phy_control_get(int unit, bcm_port_t port,
  49496                              bcm_port_phy_control_t type, uint32 *value)
  49497 {
  49498     int rv;
  49499     bcm_port_t local_port;
  49500     int phy_lane = -1;
  49501     int phyn = 0, sys_side = 0;
  49502 
  49503     if (NULL == value) {
  49504         return BCM_E_PARAM;
  49505     }
  49506 
  49507     /* Make sure port module is initialized. */
  49508     PORT_INIT(unit);
  49509 
  49510     if (SOC_USE_PORTCTRL(unit)) {
  49511         return bcmi_esw_portctrl_phy_control_get(unit, port, type, value);
  49512     }
  49513 
  49514     if(BCM_PHY_GPORT_IS_PHYN(port)) {
  49515         local_port = BCM_PHY_GPORT_PHYN_PORT_PORT_GET(port);
  49516         phyn = BCM_PHY_GPORT_PHYN_PORT_PHYN_GET(port);
  49517         phy_lane = -1;
  49518     } else if(BCM_PHY_GPORT_IS_PHYN_LANE(port)) {
  49519         local_port = BCM_PHY_GPORT_PHYN_LANE_PORT_PORT_GET(port);
  49520         phyn = BCM_PHY_GPORT_PHYN_LANE_PORT_PHYN_GET(port);
  49521         phy_lane = BCM_PHY_GPORT_PHYN_LANE_PORT_LANE_GET(port);
  49522     } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE(port)) {
  49523         local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PORT_GET(port);
  49524         phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PHYN_GET(port);
  49525         sys_side = TRUE;
  49526         phy_lane = -1;
  49527     } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE_LANE(port)) {
  49528         local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PORT_GET(port);
  49529         phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PHYN_GET(port);
  49530         phy_lane = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_LANE_GET(port);
  49531         sys_side = TRUE;
  49532     } else if (BCM_PHY_GPORT_IS_LANE(port)) {
  49533         local_port = BCM_PHY_GPORT_LANE_PORT_PORT_GET(port);
  49534         phy_lane = BCM_PHY_GPORT_LANE_PORT_LANE_GET(port);
  49535     } else {
  49536         BCM_IF_ERROR_RETURN
  49537             (_bcm_esw_port_gport_validate(unit, port, &port));
  49538 
  49539         PORT_LOCK(unit);
  49540         rv = soc_phyctrl_control_get(unit, port, (soc_phy_control_t) type, value);
  49541         PORT_UNLOCK(unit);
  49542         return rv;
  49543     }
  49544 
  49545     if (!SOC_PORT_VALID(unit, local_port)) {
  49546         return BCM_E_PORT;
  49547     }
  49548 
  49549     PORT_LOCK(unit);
  49550     rv = soc_phyctrl_redirect_control_get(unit, local_port, phyn, phy_lane,
  49551                                           sys_side, (soc_phy_control_t) type, value);
  49552     PORT_UNLOCK(unit);
  49553 
  49554     return rv;
  49555 }
  49556 
  49557 /*
  49558  * Function:
  49559  *      bcm_esw_port_phy_firmware_set
  49560  * Purpose:
  49561  *      Write the firmware to the PHY device's non-volatile storage.
  49562  * Parameters:
  49563  *      unit - (IN) Unit number.
  49564  *      port - (IN) Port number
  49565  *      flags - (IN) PHY spcific flags, such as BCM_PORT_PHY_INTERNAL
  49566  *      offset - (IN) Offset to the firmware data array
  49567  *      array - (IN)  The firmware data array
  49568  *      length - (IN) The length of the firmware data array
  49569  * Returns:
  49570  *      BCM_E_XXX
  49571  * Notes:
  49572  */
  49573 int
  49574 bcm_esw_port_phy_firmware_set(int unit, bcm_port_t port, uint32 flags,
  49575                               int offset, uint8 *array, int length)
  49576 {
  49577     int rv;
  49578 
  49579     /* Make sure port module is initialized. */
  49580     PORT_INIT(unit);
  49581 
  49582     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  49583 
  49584     PORT_LOCK(unit);
  49585     rv = soc_phyctrl_firmware_set(unit, port, flags,offset,array,length);
  49586     PORT_UNLOCK(unit);
  49587 
  49588     return rv;
  49589 }
  49590 
  49591 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  49592 /*
  49593  * Function    : _bcm_esw_port_subport_index_get
  49594  * Description : Get the subport index for the specified mod port.
  49595  *
  49596  * Parameters  : (IN)  unit             - BCM device number
  49597  *               (IN) modport        - GPORT ID
  49598  *               (OUT)  subport_index - subport index
  49599  * Returns     : BCM_E_XXX
  49600  */
  49601 int
  49602 _bcm_esw_port_subport_index_get(int unit, bcm_gport_t modport,
  49603                                 int *subport_index)
  49604 {
  49605     int id_out = 0;
  49606     bcm_module_t mod_out = 0;
  49607     bcm_port_t port_out = 0;
  49608     bcm_trunk_t tgid_out = 0;
  49609     int base_index = 0;
  49610     int result = FALSE;
  49611     modid_base_ptr_entry_t modid_base_entry;
  49612     soc_info_t *si = &SOC_INFO(unit);
  49613     int i = 0, valid = 0, modid = 0;
  49614 
  49615     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, modport,
  49616                             &mod_out, &port_out, &tgid_out, &id_out));
  49617     if ((-1 != tgid_out) || (-1 != id_out)) {
  49618         return BCM_E_PARAM;
  49619     }
  49620 
  49621     if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) {
  49622         for (i = 0; i < si->num_modules; i++) {
  49623             if (src_modid_base_index_bk[unit]->multi_nexthop_module_id_list[i]
  49624                 == mod_out) {
  49625                 BCM_IF_ERROR_RETURN(
  49626                     _bcm_esw_stk_get_mod_config_by_type(unit,
  49627                     BCM_MODID_TYPE_MULTI_NEXT_HOPS, i + 1, &modid, &valid,
  49628                     &base_index));
  49629                 if ((valid == 1) && (modid == mod_out)) {
  49630                     if (port_out >
  49631                         src_modid_base_index_bk[unit]->num_ports[modid]) {
  49632                         return BCM_E_PARAM;
  49633                     }
  49634                     *subport_index = base_index + port_out;
  49635                     return BCM_E_NONE;
  49636                 }
  49637             }
  49638         }
  49639     }
  49640 
  49641     /* Check modport in one of additional module */
  49642     BCM_IF_ERROR_RETURN (
  49643         _bcm_esw_my_modid_additional_check(unit, mod_out, &result));
  49644     if(result == FALSE) {
  49645         return BCM_E_PORT;
  49646     }
  49647     MODULE_ID_LOWER_6_BITS(mod_out); /* lower 6 bit */
  49648     SOC_IF_ERROR_RETURN(
  49649         READ_MODID_BASE_PTRm(unit, MEM_BLOCK_ANY, mod_out,
  49650         &modid_base_entry));
  49651     base_index = soc_MODID_BASE_PTRm_field32_get(
  49652                     unit, &modid_base_entry, MODID_BASEf);
  49653     *subport_index = base_index; /* the index is indicated by module base ptr */
  49654 
  49655     return BCM_E_NONE;
  49656 }
  49657 
  49658 /*
  49659  * Function    : _bcm_esw_modport_local_get
  49660  * Description : Get the physical port for the specified mod port.
  49661  *
  49662  * Parameters  : (IN)     unit                 - BCM device number
  49663  *                     (IN)     modport          - Gport number
  49664  *                     (OUT)  local_port        - port number
  49665  *
  49666  * Returns     : BCM_E_XXX
  49667  */
  49668 int _bcm_esw_modport_local_get(int unit, bcm_gport_t modport, bcm_port_t *local_port)
  49669 {
  49670     int subport_index = 0;
  49671     modport_map_subport_entry_t modport_map_subport_entry;
  49672 
  49673     /* Make sure port module is initialized. */
  49674     PORT_INIT(unit);
  49675 
  49676     /* Parameter check */
  49677     if (!BCM_GPORT_IS_MODPORT(modport)) {
  49678         return BCM_E_PARAM;
  49679     }
  49680 
  49681     if(local_port == NULL) {
  49682         return BCM_E_PARAM;
  49683     }
  49684 
  49685     SOC_IF_ERROR_RETURN(
  49686         _bcm_esw_port_subport_index_get(unit, modport, &subport_index));
  49687 
  49688     SOC_IF_ERROR_RETURN(
  49689         READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, subport_index,
  49690                                   &modport_map_subport_entry));
  49691     *local_port = soc_MODPORT_MAP_SUBPORTm_field32_get(
  49692                      unit, &modport_map_subport_entry, DESTf);
  49693 
  49694     return BCM_E_NONE;
  49695 }
  49696 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  49697 
  49698 /*
  49699  * Function    : bcm_esw_port_local_get
  49700  * Description : Get the local port from the given GPORT ID.
  49701  *
  49702  * Parameters  : (IN)  unit         - BCM device number
  49703  *               (IN)  gport        - global port identifier
  49704  *               (OUT) local_port   - local port encoded in gport
  49705  * Returns     : BCM_E_XXX
  49706  */
  49707 int
  49708 bcm_esw_port_local_get(int unit, bcm_gport_t gport, bcm_port_t *local_port)
  49709 {
  49710     bcm_module_t my_mod, encap_mod;
  49711     bcm_port_t encap_port;
  49712     int num_modid, isLocal = 0;
  49713     soc_info_t *si = &SOC_INFO(unit);
  49714 
  49715 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  49716     int rv = BCM_E_NONE;
  49717 #endif
  49718 
  49719 #if defined(BCM_KATANA2_SUPPORT)
  49720     bcm_trunk_t trunk_id = BCM_TRUNK_INVALID;
  49721     int         id = -1;
  49722     int         pp_port = 0;
  49723     int         min_pp_port = SOC_INFO(unit).pp_port_index_min;
  49724     int         max_pp_port = SOC_INFO(unit).pp_port_index_max;
  49725 #endif /* BCM_KATANA2_SUPPORT */
  49726 
  49727     /* Make sure port module is initialized. */
  49728     PORT_INIT(unit);
  49729 
  49730     BCM_IF_ERROR_RETURN(bcm_esw_stk_modid_count(unit, &num_modid));
  49731     if ((!num_modid) && !BCM_GPORT_IS_DEVPORT(gport) ){
  49732         /* Only devport gport can be supported on device with no modid */
  49733         return BCM_E_UNAVAIL;
  49734     }
  49735 
  49736     if (BCM_GPORT_IS_LOCAL(gport)) {
  49737          *local_port = BCM_GPORT_LOCAL_GET(gport);
  49738     } else if (BCM_GPORT_IS_LOCAL_CPU(gport)) {
  49739         *local_port = CMIC_PORT(unit);
  49740     } else if (BCM_GPORT_IS_DEVPORT(gport)) {
  49741         *local_port = BCM_GPORT_DEVPORT_PORT_GET(gport);
  49742         if (unit != BCM_GPORT_DEVPORT_DEVID_GET(gport)) {
  49743             return BCM_E_PORT;
  49744         }
  49745     } else if (BCM_GPORT_IS_MODPORT(gport) || BCM_GPORT_IS_PROXY(gport)) {
  49746         BCM_IF_ERROR_RETURN(
  49747             bcm_esw_stk_my_modid_get(unit, &my_mod));
  49748 
  49749         if (BCM_GPORT_IS_MODPORT(gport)) {
  49750             encap_mod = BCM_GPORT_MODPORT_MODID_GET(gport);
  49751             encap_port = BCM_GPORT_MODPORT_PORT_GET(gport);
  49752         } else {
  49753             encap_mod = BCM_GPORT_PROXY_MODID_GET(gport);
  49754             encap_port = BCM_GPORT_PROXY_PORT_GET(gport);
  49755         }
  49756 
  49757         if (encap_mod == my_mod){
  49758             *local_port = encap_port;
  49759         } else if ((num_modid > 1) &&
  49760                    !si->coe_stacking_mode) {
  49761             BCM_IF_ERROR_RETURN(
  49762                 _bcm_esw_modid_is_local(unit, encap_mod, &isLocal));
  49763             if (isLocal) {
  49764 #if defined(BCM_TOMAHAWK_SUPPORT)
  49765                 /* Call asymmetric dual modid unmapping function */
  49766                 if (soc_feature(unit, soc_feature_asymmetric_dual_modid)) {
  49767                     BCM_IF_ERROR_RETURN (
  49768                         _bcm_esw_stk_asymmetric_dual_modmap_map(unit,
  49769                                 BCM_STK_MODMAP_SET, &encap_mod, &encap_port));
  49770                     *local_port = encap_port;
  49771                 } else
  49772 #endif /* BCM_TOMAHAWK_SUPPORT */
  49773                 {
  49774                     *local_port = encap_port +
  49775                         (encap_mod - my_mod) * (SOC_MODPORT_MAX(unit) + 1);
  49776                 }
  49777             } else {
  49778                 return BCM_E_PORT;
  49779             }
  49780         } else {
  49781 
  49782 #if defined(BCM_KATANA2_SUPPORT)
  49783             if (soc_feature(unit, soc_feature_linkphy_coe) ||
  49784                 soc_feature(unit, soc_feature_subtag_coe)) {
  49785                 if (_bcm_kt2_mod_is_coe_mod_check(unit, encap_mod) == BCM_E_NONE) {
  49786                     BCM_IF_ERROR_RETURN(
  49787                         _bcm_kt2_modport_to_pp_port_get(unit,
  49788                             encap_mod, encap_port, &pp_port));
  49789 #if defined BCM_METROLITE_SUPPORT
  49790                     if (soc_feature(unit, soc_feature_discontinuous_pp_port)) {
  49791                         if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) {
  49792                             *local_port = pp_port;
  49793                             return BCM_E_NONE;
  49794                         }
  49795                     } else
  49796 #endif
  49797                     {
  49798                     if ((pp_port >= min_pp_port) && (pp_port <= max_pp_port)) {
  49799                         *local_port = pp_port;
  49800                         return BCM_E_NONE;
  49801                     }
  49802                 }
  49803                 }
  49804             } else 
  49805 #endif
  49806 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  49807             if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  49808                 _bcm_xgs5_subport_coe_mod_port_local(unit, encap_mod, encap_port)) {
  49809                 BCM_IF_ERROR_RETURN(
  49810                 _bcmi_coe_subport_mod_port_physical_port_get(unit, encap_mod,
  49811                                                         encap_port, local_port));
  49812             }
  49813             /* Call modport to local function */
  49814             else if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) {
  49815                 BCM_IF_ERROR_RETURN (
  49816                     _bcm_esw_modport_local_get(unit, gport, &encap_port));
  49817                 *local_port = encap_port;
  49818             } else
  49819 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  49820             {
  49821                 return BCM_E_PORT;
  49822             }
  49823         }
  49824         if (soc_feature(unit, soc_feature_sysport_remap)) {
  49825             BCM_XLATE_SYSPORT_S2P(unit, local_port);
  49826         }
  49827         if (!SOC_PORT_VALID(unit, *local_port)) {
  49828             return BCM_E_PORT;
  49829         }
  49830     } else if (BCM_GPORT_IS_SUBPORT_PORT(gport)) {
  49831 
  49832 #if defined(BCM_HGPROXY_COE_SUPPORT)
  49833         if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  49834             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) {
  49835             return _bcmi_coe_subport_physical_port_get(unit, gport, local_port);
  49836         } else
  49837 #endif /* BCM_HGPROXY_COE_SUPPORT */
  49838 #if defined(BCM_KATANA2_SUPPORT)
  49839         if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, gport)) {
  49840             pp_port = BCM_GPORT_SUBPORT_PORT_GET(gport);
  49841             BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_mod));
  49842             BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, gport, &encap_mod,
  49843                                     &encap_port, &trunk_id, &id));
  49844             if (_bcm_kt2_mod_is_coe_mod_check(unit, encap_mod) == BCM_E_NONE) {
  49845 #if defined BCM_METROLITE_SUPPORT
  49846                 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) {
  49847                     if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) {
  49848                         *local_port = pp_port;
  49849                         return BCM_E_NONE;
  49850                     }
  49851                 } else
  49852 #endif
  49853                 {
  49854                 if ((pp_port >= min_pp_port) && (pp_port <= max_pp_port)) {
  49855                     *local_port = pp_port;
  49856                     return BCM_E_NONE;
  49857                 }
  49858             }
  49859         }
  49860         }
  49861 #endif
  49862         return BCM_E_PORT;
  49863     } else if (BCM_GPORT_IS_VLAN_PORT(gport)) {
  49864         *local_port = BCM_GPORT_VLAN_PORT_ID_GET(gport);
  49865     } else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) {
  49866         *local_port = BCM_GPORT_EXTENDER_PORT_ID_GET(gport);
  49867     } else if (BCM_GPORT_IS_NIV_PORT(gport)) {
  49868         *local_port = BCM_GPORT_NIV_PORT_ID_GET(gport);
  49869     } else if (BCM_GPORT_IS_VXLAN_PORT(gport)) {
  49870         *local_port = BCM_GPORT_VXLAN_PORT_ID_GET(gport);
  49871     } else if (BCM_GPORT_IS_FLOW_PORT(gport)) {
  49872         *local_port = BCM_GPORT_FLOW_PORT_ID_GET(gport);
  49873     } else if (BCM_GPORT_IS_L2GRE_PORT(gport)) {
  49874         *local_port = BCM_GPORT_L2GRE_PORT_ID_GET(gport);
  49875     } else if (BCM_GPORT_IS_MIM_PORT(gport)) {
  49876         *local_port = BCM_GPORT_MIM_PORT_ID_GET(gport);
  49877     } else if (BCM_GPORT_IS_MPLS_PORT(gport)) {
  49878         *local_port = BCM_GPORT_MPLS_PORT_ID_GET(gport);
  49879     } else if (BCM_GPORT_IS_TRUNK(gport)) {
  49880 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  49881         if (soc_feature(unit, soc_feature_vp_lag)) {
  49882             rv = _bcm_esw_trunk_tid_to_vp_lag_vp(unit,
  49883                      BCM_GPORT_TRUNK_GET(gport),local_port);
  49884             return (rv != BCM_E_NONE) ? BCM_E_PORT : BCM_E_NONE;
  49885         }
  49886 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */
  49887         return BCM_E_PORT;
  49888     } else if (BCM_GPORT_IS_VP_GROUP(gport)) {
  49889         *local_port = BCM_GPORT_VP_GROUP_GET(gport);
  49890     } else {
  49891         return BCM_E_PORT;
  49892     }
  49893 
  49894     return BCM_E_NONE;
  49895 }
  49896 
  49897 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  49898 
  49899 /*
  49900  * Function    : _bcm_esw_modid_is_coe_mod
  49901  * Description : Identifies if given modid is a CoE module
  49902  *
  49903  * Parameters  : (IN)   unit      - BCM device number
  49904  *               (IN)   modnd     - Module ID
  49905  * Returns     : BCM_E_NONE, if it is a CoE Module
  49906  *               BCM_E_NOT_FOUND, if it is not a CoE Module
  49907  */
  49908 
  49909 int
  49910 _bcm_esw_modid_is_coe_mod(int unit, bcm_module_t modid)
  49911 {
  49912     bcm_stk_modid_config_t mod_cfg;
  49913     mod_cfg.modid = modid;
  49914 
  49915 	mod_cfg.modid_type = bcmStkModidTypeCoe;
  49916 
  49917     /* Also check if this is one of the CoE modules */
  49918     return bcm_esw_stk_modid_config_get(unit, &mod_cfg);
  49919 }
  49920 #endif
  49921 
  49922 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  49923 /*
  49924  * Function    : _bcm_esw_modid_is_multi_nexthop_mod
  49925  * Description : Identifies if given modid is a Multi Next Hop module
  49926  *
  49927  * Parameters  : (IN)   unit      - BCM device number
  49928  *               (IN)   modnd     - Module ID
  49929  * Returns     : BCM_E_NONE, if it is a Multi Next Hop Module
  49930  *               BCM_E_NOT_FOUND, if it is not a Multi Next Hop Module
  49931  */
  49932 
  49933 int
  49934 _bcm_esw_modid_is_multi_nexthop_mod(int unit, bcm_module_t modid)
  49935 {
  49936     bcm_stk_modid_config_t mod_cfg;
  49937 
  49938     if ((modid < 0) || (modid > SOC_MODID_MAX(unit))) {
  49939         return BCM_E_PARAM;
  49940     }
  49941     mod_cfg.modid = modid;
  49942     mod_cfg.modid_type = bcmStkModidTypeMultiNextHops;
  49943 
  49944     /* Also check if this is one of the Multi Next Hop modules */
  49945     return bcm_esw_stk_modid_config_get(unit, &mod_cfg);
  49946 }
  49947 
  49948 /*
  49949   * Function    : _bcm_esw_is_multi_nexthop_mod_port
  49950   * Description : Identifies if given modid is a Multi Next Hop module port
  49951   *
  49952   * Parameters  : (IN)   unit - BCM device number
  49953   *               (IN)   modid - Mod Id value
  49954   *               (IN)   port - Port Id value
  49955   * Returns : TRUE if is Multi Next Hop module port, FALSE otherwise
  49956   */
  49957 int
  49958 _bcm_esw_is_multi_nexthop_mod_port(int unit, bcm_module_t modid,
  49959                                          bcm_port_t port)
  49960 {
  49961     int rv = BCM_E_NONE;
  49962     int result = FALSE;
  49963 
  49964     if(_bcm_esw_modid_is_multi_nexthop_mod(unit, modid) == BCM_E_NONE) {
  49965         if (port <= src_modid_base_index_bk[unit]->num_ports[modid]) {
  49966             return TRUE;
  49967         }
  49968     } else {
  49969         rv = _bcm_esw_my_modid_additional_check(unit, modid, &result);
  49970         if (BCM_FAILURE(rv)) {
  49971             return FALSE;
  49972         }
  49973         return result;
  49974     }
  49975     return FALSE;
  49976 }
  49977 #endif
  49978 
  49979 /*
  49980  * Function    : _bcm_esw_modid_is_local
  49981  * Description : Identifies if given modid is local on a given unit
  49982  *
  49983  * Parameters  : (IN)   unit      - BCM device number
  49984  *               (IN)   modnd     - Module ID
  49985  *               (OUT)  result    - TRUE if modid is local, FALSE otherwise
  49986  * Returns     : BCM_E_XXX
  49987  */
  49988 int
  49989 _bcm_esw_modid_is_local(int unit, bcm_module_t modid, int *result)
  49990 {
  49991     bcm_module_t    mymodid;
  49992     int             rv;
  49993     soc_info_t *si=&SOC_INFO(unit);
  49994 
  49995     /* Input parameters check. */
  49996     if (NULL == result) {
  49997         return (BCM_E_PARAM);
  49998     }
  49999 
  50000     COMPILER_REFERENCE(si);
  50001 
  50002     /* Get local module id. */
  50003     rv = bcm_esw_stk_my_modid_get(unit, &mymodid);
  50004     if (BCM_E_UNAVAIL == rv) {
  50005         if (BCM_MODID_INVALID == modid) {
  50006             *result = TRUE;
  50007         } else {
  50008 #if defined(BCM_HGPROXY_COE_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  50009             /* If hg_proxy or if (subtag/linkPhy-Coe && stacking-mode)
  50010                check the local modid */
  50011             if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  50012                 ((soc_feature(unit, soc_feature_subtag_coe) ||
  50013                   (soc_feature(unit, soc_feature_linkphy_coe))) &&
  50014                   si->coe_stacking_mode)) &&
  50015                 (_bcm_esw_modid_is_coe_mod(unit, modid) == BCM_E_NONE)) {
  50016                     *result = TRUE;
  50017             } else
  50018 #endif
  50019             {
  50020                 *result = FALSE;
  50021             }
  50022         }
  50023         return (BCM_E_NONE);
  50024     }
  50025 
  50026     if (mymodid == modid) {
  50027         *result = TRUE;
  50028     } else if ((modid > mymodid) && (modid < mymodid + NUM_MODID(unit))) {
  50029         *result = TRUE;
  50030     }
  50031 #if defined(BCM_HGPROXY_COE_SUPPORT)  || defined(BCM_KATANA2_SUPPORT)
  50032     /* If hg_proxy or if (subtag/linkPhy-Coe && stacking-mode)
  50033        check the local modid */
  50034     else if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) ||
  50035         ((soc_feature(unit, soc_feature_subtag_coe) ||
  50036           (soc_feature(unit, soc_feature_linkphy_coe))) &&
  50037           si->coe_stacking_mode)) &&
  50038         (_bcm_esw_modid_is_coe_mod(unit, modid) == BCM_E_NONE)) {
  50039 			*result = TRUE;
  50040 	}
  50041 #endif /* BCM_HGPROXY_COE_SUPPORT || BCM_KATANA2_SUPPORT */
  50042     else {
  50043         *result = FALSE;
  50044     }
  50045 
  50046     return (BCM_E_NONE);
  50047 }
  50048 
  50049 
  50050 /*
  50051  * Function    : _bcm_gport_modport_hw2api_map
  50052  * Description : Remaps module and port from HW space to API space
  50053  *
  50054  * Parameters  : (IN)  unit      - BCM device number
  50055  *               (IN)  mod_in    - Module ID to map
  50056  *               (IN)  port_in   - Physical port to map
  50057  *               (OUT)  mod_out  - Module ID after mapping
  50058  *               (OUT)  port_out - Port number after mapping
  50059  * Returns     : BCM_E_XXX
  50060  * Notes       : If mod_out == NULL then port_out will be local physical port.
  50061  */
  50062 int
  50063 _bcm_gport_modport_hw2api_map(int unit, bcm_module_t mod_in, bcm_port_t port_in,
  50064                               bcm_module_t *mod_out, bcm_port_t *port_out)
  50065 {
  50066     if (port_out == NULL) {
  50067         return (BCM_E_PARAM);
  50068     }
  50069 
  50070     if (NUM_MODID(unit) == 1) { /* HW device has single modid */
  50071         if (mod_out != NULL) {
  50072             *mod_out = mod_in;
  50073         }
  50074         *port_out = port_in;
  50075 
  50076         return (BCM_E_NONE);
  50077     }
  50078     /* Here only for devices with multiple modid NUM_MODID(unit) > 1 */
  50079     if (mod_out == NULL) {  /* physical port requested */
  50080         int             isLocal = 0;
  50081         bcm_module_t    mymodid;
  50082         BCM_IF_ERROR_RETURN(
  50083             _bcm_esw_modid_is_local(unit, mod_in, &isLocal));
  50084         if (isLocal != TRUE) {
  50085             return (BCM_E_PARAM);
  50086         }
  50087         BCM_IF_ERROR_RETURN (bcm_esw_stk_my_modid_get(unit, &mymodid));
  50088 
  50089 #if defined(BCM_TOMAHAWK_SUPPORT)
  50090         /* Call asymmetric dual modid unmapping function */
  50091         if (soc_feature(unit, soc_feature_asymmetric_dual_modid)) {
  50092             BCM_IF_ERROR_RETURN (
  50093                 _bcm_esw_stk_asymmetric_dual_modmap_map(unit,
  50094                             BCM_STK_MODMAP_SET, &mod_in, &port_in));
  50095             *port_out = port_in;
  50096         } else
  50097 #endif /* BCM_TOMAHAWK_SUPPORT */
  50098         {
  50099             *port_out = port_in +
  50100                 (mod_in - mymodid) * (SOC_MODPORT_MAX(unit) + 1);
  50101         }
  50102     } else {    /* NUM_MODID(unit) > 1 and not local physical port */
  50103 #if defined(BCM_TOMAHAWK_SUPPORT)
  50104         /* Call asymmetric dual modid mapping function */
  50105         if (soc_feature(unit, soc_feature_asymmetric_dual_modid)) {
  50106             BCM_IF_ERROR_RETURN (
  50107                 _bcm_esw_stk_asymmetric_dual_modmap_map(unit,
  50108                             BCM_STK_MODMAP_GET, &mod_in, &port_in));
  50109             *mod_out = mod_in;
  50110             *port_out = port_in;
  50111         } else
  50112 #endif /* BCM_TOMAHAWK_SUPPORT */
  50113         {
  50114             *port_out = port_in % (SOC_MODPORT_MAX(unit) + 1);
  50115             *mod_out = mod_in + port_in / (SOC_MODPORT_MAX(unit) + 1);
  50116         }
  50117     }
  50118 
  50119     return (BCM_E_NONE);
  50120 }
  50121 
  50122 /*
  50123  * Function    : bcm_port_gport_get
  50124  * Description : Get the GPORT ID for the specified physical port.
  50125  *
  50126  * Parameters  : (IN)  unit      - BCM device number
  50127  *               (IN)  port      - Port number
  50128  *               (OUT) gport     - GPORT ID
  50129  * Returns     : BCM_E_XXX
  50130  * Notes:
  50131  *     Always returns a MODPORT gport or an error.
  50132  */
  50133 int
  50134 bcm_esw_port_gport_get(int unit, bcm_port_t port, bcm_gport_t *gport)
  50135 {
  50136     int                 rv;
  50137     _bcm_gport_dest_t   dest;
  50138 
  50139     /* Make sure port module is initialized. */
  50140     PORT_INIT(unit);
  50141 
  50142     _bcm_gport_dest_t_init(&dest);
  50143 
  50144     PORT_PARAM_CHECK(unit, port);
  50145 
  50146     rv = bcm_esw_stk_my_modid_get(unit, &dest.modid);
  50147 
  50148     if (BCM_FAILURE(rv)) {
  50149         return BCM_E_UNAVAIL;
  50150     }
  50151 
  50152     if (soc_feature(unit, soc_feature_sysport_remap)) {
  50153         BCM_XLATE_SYSPORT_P2S(unit, &port);
  50154     }
  50155 
  50156     dest.port = port;
  50157     dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
  50158 
  50159     /* In this case we can safely assume that a port is in hw format */
  50160     /* since it is a physical port number */
  50161     BCM_IF_ERROR_RETURN
  50162         (_bcm_gport_modport_hw2api_map(unit, dest.modid, dest.port,
  50163                                        &(dest.modid), &(dest.port)));
  50164 
  50165     return _bcm_esw_gport_construct(unit, &dest, gport);
  50166 }
  50167 
  50168 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  50169 /*
  50170  * Function    : bcm_port_gport_add
  50171  * Description : Add the GPORT ID for the specified physical port.
  50172  *
  50173  * Parameters  : (IN)  unit             - BCM device number
  50174  *               (IN)  local_port     - Port number
  50175  *               (IN)  modport       - GPORT ID
  50176  * Returns     : BCM_E_XXX
  50177  */
  50178 int
  50179 _bcm_esw_port_gport_add(int unit, bcm_port_t local_port,
  50180                                bcm_gport_t modport)
  50181 {
  50182     int subport_index = 0;
  50183     bcm_port_t old_local_port = 0;
  50184     modport_map_subport_entry_t modport_map_subport_entry;
  50185 
  50186     /* Make sure port module is initialized. */
  50187     PORT_INIT(unit);
  50188 
  50189     /* Parameter check */
  50190     PORT_PARAM_CHECK(unit, local_port);
  50191     if (!BCM_GPORT_IS_MODPORT(modport)) {
  50192         return BCM_E_PARAM;
  50193     }
  50194 
  50195     SOC_IF_ERROR_RETURN(
  50196         _bcm_esw_port_subport_index_get(unit, modport, &subport_index));
  50197 
  50198     SOC_IF_ERROR_RETURN
  50199         (READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, subport_index,
  50200                                        &modport_map_subport_entry));
  50201     old_local_port = soc_MODPORT_MAP_SUBPORTm_field32_get(unit,
  50202                                        &modport_map_subport_entry, DESTf);
  50203     if(old_local_port == local_port) {
  50204         return BCM_E_NONE;
  50205     }
  50206     if(old_local_port) {
  50207         return BCM_E_RESOURCE;
  50208     }
  50209 
  50210     soc_MODPORT_MAP_SUBPORTm_field32_set (unit,
  50211                          &modport_map_subport_entry, DESTf, local_port);
  50212     soc_MODPORT_MAP_SUBPORTm_field32_set (unit,
  50213                          &modport_map_subport_entry, ISTRUNKf, 0);
  50214     soc_MODPORT_MAP_SUBPORTm_field32_set (unit,
  50215                          &modport_map_subport_entry, ENABLEf, 1);
  50216     SOC_IF_ERROR_RETURN
  50217         (WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, subport_index,
  50218                                         &modport_map_subport_entry));
  50219 
  50220     return BCM_E_NONE;
  50221 }
  50222 
  50223 /*
  50224  * Function    : bcm_port_gport_get_all
  50225  * Description : Get all the extra GPORT ID for the specified physical port.
  50226  *
  50227  * Parameters  : (IN)     unit                 - BCM device number
  50228  *                     (IN)     local_port        - Port number
  50229  *                     (IN)     modport_max   - size of gport array
  50230  *                     (OUT)  gport_array      - Gport number
  50231  *                     (OUT)  count              - GPORT count
  50232  * Returns     : BCM_E_XXX
  50233  * Notes:
  50234  *     Always returns MODPORT gports or an error.
  50235  */
  50236 int _bcm_esw_port_gport_get_all(int unit, bcm_port_t local_port, int size,
  50237                                       bcm_gport_t *gport_array, int *count)
  50238 {
  50239     int rv = BCM_E_NONE;
  50240     int mod_idx = 0;
  50241     int port_idx = 0;
  50242     int base_index = 0;
  50243     bcm_gport_t modport = 0;
  50244     _bcm_gport_dest_t dest;
  50245     bcm_port_t egress_port = 0;
  50246     bcm_stk_modid_config_t mod_cfg;
  50247     modid_base_ptr_entry_t modid_base_entry;
  50248     modport_map_subport_entry_t modport_map_subport_entry;
  50249     soc_info_t *si = &SOC_INFO(unit);
  50250     int i = 0, valid = 0, modid = 0, n_ports = 0;
  50251 
  50252     /* Make sure port module is initialized. */
  50253     PORT_INIT(unit);
  50254 
  50255     /* Parameter check */
  50256     PORT_PARAM_CHECK(unit, local_port);
  50257     if (size < 0 || count == NULL) {
  50258         return BCM_E_PARAM;
  50259     }
  50260 	
  50261     if ((size > 0) && gport_array == NULL) {
  50262         return BCM_E_PARAM;
  50263     }
  50264 
  50265     mod_cfg.modid_type = bcmStkModidTypeMultiNextHops;
  50266     mod_cfg.modid = BCM_MODID_INVALID;
  50267     BCM_IF_ERROR_RETURN(bcm_esw_stk_modid_config_get(unit, &mod_cfg));
  50268 	
  50269     *count = 0;
  50270     if (size == 0) {
  50271         if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) {
  50272             for (i = 0; i < si->num_modules; i++) {
  50273                 if (src_modid_base_index_bk[unit]->multi_nexthop_module_id_list[i] ==
  50274                     BCM_MODID_INVALID) {
  50275                     continue;
  50276                 }
  50277                 BCM_IF_ERROR_RETURN(
  50278                     _bcm_esw_stk_get_mod_config_by_type(unit,
  50279                     BCM_MODID_TYPE_MULTI_NEXT_HOPS, i + 1, &modid, &valid,
  50280                     &base_index));
  50281                 if (valid == 0) {
  50282                     continue;
  50283                 }
  50284                 n_ports = src_modid_base_index_bk[unit]->num_ports[modid];
  50285                 for (port_idx = base_index; port_idx < base_index + n_ports;
  50286                      port_idx++) {
  50287                      SOC_IF_ERROR_RETURN
  50288                          (READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, port_idx,
  50289                                                     &modport_map_subport_entry));
  50290                      /* Check if index is used. */
  50291                      egress_port = soc_MODPORT_MAP_SUBPORTm_field32_get(unit,
  50292                                                  &modport_map_subport_entry, DESTf);
  50293                      if(egress_port == local_port) {/*  Entry found. */
  50294                          (*count)++;
  50295                      }
  50296                 }
  50297             }
  50298         }
  50299 
  50300         for (mod_idx = mod_cfg.modid; mod_idx < mod_cfg.modid + mod_cfg.num_mods;
  50301              mod_idx ++) {
  50302             MODULE_ID_LOWER_6_BITS(mod_idx); /* lower 6 bit */
  50303             SOC_IF_ERROR_RETURN(
  50304                 READ_MODID_BASE_PTRm(unit, MEM_BLOCK_ANY, mod_idx,
  50305                 &modid_base_entry));
  50306             base_index =
  50307                 soc_MODID_BASE_PTRm_field32_get(unit, &modid_base_entry,
  50308                 MODID_BASEf);
  50309             SOC_IF_ERROR_RETURN(
  50310                 READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, base_index,
  50311                 &modport_map_subport_entry));
  50312             /* Check if index is used. */
  50313             egress_port =
  50314                 soc_MODPORT_MAP_SUBPORTm_field32_get(unit,
  50315                 &modport_map_subport_entry, DESTf);
  50316             if (egress_port == local_port) {/*  Entry found. */
  50317                 (*count)++;
  50318             }
  50319         }
  50320         return BCM_E_NONE;
  50321     }
  50322 
  50323     _bcm_gport_dest_t_init(&dest);
  50324     if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) {
  50325         for (i = 0; i < si->num_modules; i++) {
  50326             if (src_modid_base_index_bk[unit]->multi_nexthop_module_id_list[i] ==
  50327                 BCM_MODID_INVALID) {
  50328                 continue;
  50329             }
  50330             BCM_IF_ERROR_RETURN(
  50331                 _bcm_esw_stk_get_mod_config_by_type(unit,
  50332                 BCM_MODID_TYPE_MULTI_NEXT_HOPS, i + 1, &modid, &valid,
  50333                 &base_index));
  50334             if (valid == 0) {
  50335                 continue;
  50336             }
  50337             n_ports = src_modid_base_index_bk[unit]->num_ports[modid];
  50338             for (port_idx = base_index; port_idx < base_index + n_ports;
  50339                  port_idx++) {
  50340                 if ((*count) < size) {
  50341                     SOC_IF_ERROR_RETURN
  50342                         (READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, port_idx,
  50343                                                    &modport_map_subport_entry));
  50344                     /* Check if index is used. */
  50345                     egress_port = soc_MODPORT_MAP_SUBPORTm_field32_get(unit,
  50346                                                 &modport_map_subport_entry, DESTf);
  50347                     if (egress_port == local_port) {
  50348                         /*  Entry found. */
  50349                         dest.port = port_idx - base_index;
  50350                         dest.modid = modid;
  50351                         dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
  50352                         rv = _bcm_esw_gport_construct(unit, &dest, &modport);
  50353                         gport_array[(*count)++] = modport;
  50354                     }
  50355                 }
  50356             }
  50357         }
  50358     }
  50359 
  50360     for (mod_idx = mod_cfg.modid; mod_idx < mod_cfg.modid + mod_cfg.num_mods;
  50361          mod_idx ++) {
  50362         MODULE_ID_LOWER_6_BITS(mod_idx); /* lower 6 bit */
  50363         SOC_IF_ERROR_RETURN
  50364             (READ_MODID_BASE_PTRm(unit, MEM_BLOCK_ANY, mod_idx, &modid_base_entry));
  50365         base_index = soc_MODID_BASE_PTRm_field32_get(unit,
  50366                                        &modid_base_entry, MODID_BASEf);
  50367         if ((*count) < size) {
  50368             SOC_IF_ERROR_RETURN(
  50369                 READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, base_index,
  50370                 &modport_map_subport_entry));
  50371             /* Check if index is used. */
  50372             egress_port =
  50373                 soc_MODPORT_MAP_SUBPORTm_field32_get(unit,
  50374                 &modport_map_subport_entry, DESTf);
  50375             if (egress_port == local_port) {
  50376                 /*  Entry found. */
  50377                 dest.port = BCM_PORT_INVALID;
  50378                 dest.modid = mod_idx;
  50379                 dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
  50380                 rv = _bcm_esw_gport_construct(unit, &dest, &modport);
  50381                 gport_array[(*count)++] = modport;
  50382             }
  50383         }
  50384     }
  50385 
  50386     return rv;
  50387 }
  50388 
  50389 /*
  50390  * Function    : bcm_port_gport_delete
  50391  * Description : Delete the mapping of the specified GPORT.
  50392  *
  50393  * Parameters  : (IN)  unit             - BCM device number
  50394  *                     (IN) modport        - GPORT ID
  50395  * Returns     : BCM_E_XXX
  50396  */
  50397 int
  50398 _bcm_esw_port_gport_delete(int unit, bcm_port_t local_port, bcm_gport_t modport)
  50399 {
  50400     int subport_index = 0;
  50401     modport_map_subport_entry_t modport_map_subport_entry;
  50402 
  50403     /* Make sure port module is initialized. */
  50404     PORT_INIT(unit);
  50405 
  50406     /* Parameter check */
  50407     PORT_PARAM_CHECK(unit, local_port);
  50408     if (!BCM_GPORT_IS_MODPORT(modport)) {
  50409         return BCM_E_PARAM;
  50410     }
  50411 
  50412     SOC_IF_ERROR_RETURN(
  50413         _bcm_esw_port_subport_index_get(unit, modport, &subport_index));
  50414 
  50415     SOC_IF_ERROR_RETURN
  50416         (READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, subport_index,
  50417                                    &modport_map_subport_entry));
  50418     soc_MODPORT_MAP_SUBPORTm_field32_set(unit,
  50419                                    &modport_map_subport_entry, DESTf, 0);
  50420     soc_MODPORT_MAP_SUBPORTm_field32_set (unit,
  50421                                    &modport_map_subport_entry, ISTRUNKf, 0);
  50422     soc_MODPORT_MAP_SUBPORTm_field32_set (unit,
  50423                                  &modport_map_subport_entry, ENABLEf, 0);
  50424     SOC_IF_ERROR_RETURN
  50425         (WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, subport_index,
  50426                                         &modport_map_subport_entry));
  50427 
  50428     return BCM_E_NONE;
  50429 }
  50430 
  50431 /*
  50432  * Function    : bcm_port_gport_delete_all
  50433  * Description : Delete all the extra mapping of the specified physical port.
  50434  *
  50435  * Parameters  : (IN)  unit             - BCM device number
  50436  *                     (IN) local_port      - PORT ID
  50437  * Returns     : BCM_E_XXX
  50438  */
  50439 int
  50440 _bcm_esw_port_gport_delete_all(int unit, bcm_port_t local_port)
  50441 {
  50442     int mod_idx = 0;
  50443     int port_idx = 0;
  50444     int base_index = 0;
  50445     bcm_port_t egress_port = 0;
  50446     bcm_stk_modid_config_t mod_cfg;
  50447     modid_base_ptr_entry_t modid_base_entry;
  50448     modport_map_subport_entry_t modport_map_subport_entry;
  50449     soc_info_t *si = &SOC_INFO(unit);
  50450     int i = 0, valid = 0, modid = 0, n_ports = 0;
  50451 
  50452     /* Make sure port module is initialized. */
  50453     PORT_INIT(unit);
  50454 
  50455     /* Parameter check */
  50456     PORT_PARAM_CHECK(unit, local_port);
  50457 
  50458     mod_cfg.modid_type = bcmStkModidTypeMultiNextHops;
  50459     mod_cfg.modid = BCM_MODID_INVALID;
  50460     BCM_IF_ERROR_RETURN(
  50461         bcm_esw_stk_modid_config_get(unit, &mod_cfg));
  50462 	
  50463     if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) {
  50464         for (i = 0; i < si->num_modules; i++) {
  50465             if (src_modid_base_index_bk[unit]->multi_nexthop_module_id_list[i] ==
  50466                 BCM_MODID_INVALID) {
  50467                 continue;
  50468             }
  50469             BCM_IF_ERROR_RETURN(
  50470                 _bcm_esw_stk_get_mod_config_by_type(unit,
  50471                 BCM_MODID_TYPE_MULTI_NEXT_HOPS, i + 1, &modid, &valid,
  50472                 &base_index));
  50473             if (valid == 0) {
  50474                 continue;
  50475             }
  50476             n_ports = src_modid_base_index_bk[unit]->num_ports[modid];
  50477             for (port_idx = base_index; port_idx < base_index + n_ports;
  50478                  port_idx++) {
  50479                  SOC_IF_ERROR_RETURN
  50480                      (READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, port_idx,
  50481                                                 &modport_map_subport_entry));
  50482                  /* Check if index is used. */
  50483                  egress_port = soc_MODPORT_MAP_SUBPORTm_field32_get(unit,
  50484                                              &modport_map_subport_entry, DESTf);
  50485                  if(egress_port == local_port) {
  50486                      /*  Entry found. */
  50487                      soc_MODPORT_MAP_SUBPORTm_field32_set(
  50488                          unit, &modport_map_subport_entry, DESTf, 0);
  50489                      soc_MODPORT_MAP_SUBPORTm_field32_set(
  50490                          unit, &modport_map_subport_entry, ENABLEf, 0);
  50491                      SOC_IF_ERROR_RETURN
  50492                          (WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, port_idx,
  50493                                                      &modport_map_subport_entry));
  50494                  }
  50495             }
  50496         }
  50497     }
  50498 
  50499     for (mod_idx = mod_cfg.modid; mod_idx < mod_cfg.modid + mod_cfg.num_mods; 
  50500          mod_idx ++) {
  50501         MODULE_ID_LOWER_6_BITS(mod_idx); /* lower 6 bit */
  50502         SOC_IF_ERROR_RETURN
  50503             (READ_MODID_BASE_PTRm(unit, MEM_BLOCK_ANY, mod_idx, &modid_base_entry));
  50504         base_index = soc_MODID_BASE_PTRm_field32_get(unit,
  50505                                            &modid_base_entry, MODID_BASEf);
  50506         SOC_IF_ERROR_RETURN(
  50507             READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, base_index,
  50508             &modport_map_subport_entry));
  50509         /* Check if index is used. */
  50510         egress_port =
  50511             soc_MODPORT_MAP_SUBPORTm_field32_get(unit,
  50512             &modport_map_subport_entry, DESTf);
  50513         if (egress_port == local_port) {
  50514             /*  Entry found. */
  50515             soc_MODPORT_MAP_SUBPORTm_field32_set(
  50516                 unit, &modport_map_subport_entry, DESTf, 0);
  50517             soc_MODPORT_MAP_SUBPORTm_field32_set(
  50518                 unit, &modport_map_subport_entry, ENABLEf, 0);
  50519             SOC_IF_ERROR_RETURN(
  50520                 WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, port_idx,
  50521                 &modport_map_subport_entry));
  50522         }
  50523     }
  50524 
  50525     return BCM_E_NONE;
  50526 }
  50527 
  50528 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  50529 
  50530 /*
  50531  * Function    : bcm_port_gport_add
  50532  * Description : Add the GPORT ID for the specified physical port.
  50533  *
  50534  * Parameters  : (IN)  unit             - BCM device number
  50535  *                     (IN)  local_port     - Port number
  50536  *                     (IN)  modport       - GPORT ID
  50537  * Returns     : BCM_E_XXX
  50538  */
  50539 int
  50540 bcm_esw_port_gport_add(int unit, bcm_port_t local_port,
  50541                                bcm_gport_t modport)
  50542 {
  50543     int rv = BCM_E_UNAVAIL;
  50544 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  50545     if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) {
  50546         rv = _bcm_esw_port_gport_add(unit, local_port, modport);
  50547     }	
  50548 #endif
  50549     return rv;
  50550 }
  50551 
  50552 /*
  50553  * Function    : bcm_port_gport_get_all
  50554  * Description : Get all the extra GPORT ID for the specified physical port.
  50555  *
  50556  * Parameters  : (IN)     unit                 - BCM device number
  50557  *                     (IN)     local_port        - Port number
  50558  *                     (IN)     modport_max   - size of gport array
  50559  *                     (OUT)  gport_array      - Gport number
  50560  *                     (OUT)  count              - GPORT count
  50561  * Returns     : BCM_E_XXX
  50562  * Notes:
  50563  */
  50564 int bcm_esw_port_gport_get_all(int unit, bcm_port_t local_port, int size,
  50565                                       bcm_gport_t *gport_array, int *count)
  50566 {
  50567     int rv = BCM_E_UNAVAIL;
  50568 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  50569     if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) {
  50570         if (size < 0 || count == NULL) {
  50571             return BCM_E_PARAM;
  50572         }
  50573 
  50574         if ((size > 0) && gport_array == NULL) {
  50575             return BCM_E_PARAM;
  50576         }
  50577 
  50578         rv = _bcm_esw_port_gport_get_all(unit, local_port, size, gport_array, count);
  50579     }	
  50580 #endif
  50581     return rv;
  50582 }
  50583 
  50584 /*
  50585  * Function    : bcm_port_gport_delete
  50586  * Description : Delete the mapping of the specified GPORT.
  50587  *
  50588  * Parameters  : (IN)  unit             - BCM device number
  50589  *                     (IN) modport        - GPORT ID
  50590  * Returns     : BCM_E_XXX
  50591  */
  50592 int
  50593 bcm_esw_port_gport_delete(int unit, bcm_port_t local_port, bcm_gport_t modport)
  50594 {
  50595     int rv = BCM_E_UNAVAIL;
  50596 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  50597     if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) {
  50598         rv = _bcm_esw_port_gport_delete(unit, local_port, modport);
  50599     }
  50600 #endif
  50601     return rv;
  50602 }
  50603 
  50604 /*
  50605  * Function    : bcm_port_gport_delete_all
  50606  * Description : Delete all the extra mapping of the specified physical port.
  50607  *
  50608  * Parameters  : (IN)  unit             - BCM device number
  50609  *                     (IN) local_port      - PORT ID
  50610  * Returns     : BCM_E_XXX
  50611  */
  50612 int
  50613 bcm_esw_port_gport_delete_all(int unit, bcm_port_t local_port)
  50614 {
  50615     int rv = BCM_E_UNAVAIL;
  50616 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  50617     if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) {
  50618         rv = _bcm_esw_port_gport_delete_all(unit, local_port);
  50619     }
  50620 #endif
  50621     return rv;
  50622 }
  50623 
  50624 /*
  50625  * Function:
  50626  *      bcm_esw_port_gport_is_free
  50627  * Purpose:
  50628  *      Request if the given gport value is available on the device
  50629  * Parameters:
  50630  *      unit - (IN) Unit number.
  50631  *      gport - (IN) GPORT ID.
  50632  * Returns:
  50633  *      BCM_E_NONE -    gport is valid and available on the device
  50634  *      BCM_E_EXISTS -  gport is valid but already in use
  50635  *                      on this device
  50636  *      BCM_E_PARAM -   gport is not valid on this device
  50637  *      BCM_E_UNAVAIL - Feature unavailable
  50638  * Notes:
  50639  */
  50640 int
  50641 bcm_esw_port_gport_is_free(int unit, bcm_gport_t gport)
  50642 {
  50643 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
  50644     int             rv = BCM_E_PARAM;
  50645     int             vp = 0, vp_idx, rv_vp = 0, is_vp = FALSE;
  50646     int             vp_count = 1;     /* Required consecutive VP's */
  50647 
  50648     /* Make sure port module is initialized. */
  50649     PORT_INIT(unit);
  50650 
  50651     if (!soc_mem_is_valid(unit, SOURCE_VPm)) {
  50652         /* No virtual ports at this time. */
  50653         return BCM_E_UNAVAIL;
  50654     }
  50655 
  50656 #if defined(BCM_MPLS_SUPPORT)
  50657     if (BCM_GPORT_IS_MPLS_PORT(gport) &&
  50658              soc_feature(unit, soc_feature_mpls)) {
  50659         is_vp = TRUE;
  50660         vp = BCM_GPORT_MPLS_PORT_ID_GET(gport);
  50661         if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
  50662             rv_vp = -1;
  50663         } else {
  50664             rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeMpls);
  50665         }
  50666     } else
  50667 #endif /* BCM_MPLS_SUPPORT */
  50668     if (BCM_GPORT_IS_MIM_PORT(gport) &&
  50669              soc_feature(unit, soc_feature_mim)) {
  50670         is_vp = TRUE;
  50671         vp = BCM_GPORT_MIM_PORT_ID_GET(gport);
  50672         if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
  50673             rv_vp = -1;
  50674         } else {
  50675             rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeMim);
  50676         }
  50677     } else if (BCM_GPORT_IS_L2GRE_PORT(gport) &&
  50678              soc_feature(unit, soc_feature_l2gre)) {
  50679         is_vp = TRUE;
  50680         vp = BCM_GPORT_L2GRE_PORT_ID_GET(gport);
  50681         if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
  50682             rv_vp = -1;
  50683         } else {
  50684             rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre);
  50685         }
  50686     } else if (BCM_GPORT_IS_VXLAN_PORT(gport) &&
  50687              soc_feature(unit, soc_feature_vxlan)) {
  50688         is_vp = TRUE;
  50689         vp = BCM_GPORT_VXLAN_PORT_ID_GET(gport);
  50690         if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
  50691             rv_vp = -1;
  50692         } else {
  50693             rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan);
  50694         }
  50695     } else if (BCM_GPORT_IS_FLOW_PORT(gport) &&
  50696              soc_feature(unit, soc_feature_flex_flow)) {
  50697         is_vp = TRUE;
  50698         vp = BCM_GPORT_FLOW_PORT_ID_GET(gport);
  50699         if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
  50700             rv_vp = -1;
  50701         } else {
  50702             rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeFlow);
  50703         }
  50704     } else if (BCM_GPORT_IS_WLAN_PORT(gport) &&
  50705              soc_feature(unit, soc_feature_wlan)) {
  50706         is_vp = TRUE;
  50707         vp = BCM_GPORT_WLAN_PORT_ID_GET(gport);
  50708         if (SOC_MEM_IS_VALID(unit, WLAN_SVP_TABLEm)) {
  50709             if (vp > soc_mem_index_count(unit, WLAN_SVP_TABLEm)) {
  50710                 rv_vp = -1;
  50711             } else {
  50712                 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeWlan);
  50713             }
  50714             
  50715         } else if (SOC_MEM_IS_VALID(unit, SOURCE_VP_ATTRIBUTES_2m)) {
  50716             if (vp > soc_mem_index_count(unit, SOURCE_VP_ATTRIBUTES_2m)) {
  50717                 rv_vp = -1;
  50718             } else {
  50719                 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeWlan);
  50720             }
  50721         } else {
  50722             rv_vp = -1;
  50723         }
  50724     } else if (BCM_GPORT_IS_TRILL_PORT(gport) &&
  50725              soc_feature(unit, soc_feature_trill)) {
  50726         is_vp = TRUE;
  50727         vp = BCM_GPORT_TRILL_PORT_ID_GET(gport);
  50728         if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
  50729             rv_vp = -1;
  50730         } else {
  50731             rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeTrill);
  50732         }
  50733     } else if (BCM_GPORT_IS_VLAN_PORT(gport) &&
  50734              soc_feature(unit, soc_feature_vlan_vp)) {
  50735         is_vp = TRUE;
  50736         vp = BCM_GPORT_VLAN_PORT_ID_GET(gport);
  50737         if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
  50738             rv_vp = -1;
  50739         } else {
  50740             rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeVlan);
  50741         }
  50742     } else if (BCM_GPORT_IS_NIV_PORT(gport) &&
  50743              soc_feature(unit, soc_feature_niv)) {
  50744         is_vp = TRUE;
  50745         vp = BCM_GPORT_NIV_PORT_ID_GET(gport);
  50746         if (vp > soc_mem_index_count(unit, SOURCE_VPm)) {
  50747             rv_vp = -1;
  50748         } else {
  50749             rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeNiv);
  50750         }
  50751     }
  50752 #if defined(BCM_TRIUMPH2_SUPPORT)
  50753     else if ((BCM_GPORT_IS_SUBPORT_GROUP(gport) ||
  50754               BCM_GPORT_IS_SUBPORT_PORT(gport)) &&
  50755              soc_feature(unit, soc_feature_subport_enhanced)) {
  50756         /* No TR/SC support for now */
  50757         rv_vp = _bcm_tr2_subport_gport_used(unit, gport);
  50758         if (BCM_E_NOT_FOUND == rv_vp) {
  50759             rv = BCM_E_NONE;
  50760             /* Now we need to check if the VP is in use by something else,
  50761              * using the logic below. */
  50762             is_vp = TRUE;
  50763             rv_vp = 0;
  50764             if (BCM_GPORT_IS_SUBPORT_GROUP(gport)) {
  50765                 vp = BCM_GPORT_SUBPORT_GROUP_GET(gport);
  50766                 vp = (vp / 8) * 8;
  50767                 vp_count = 8;
  50768             } else {
  50769                 vp = BCM_GPORT_SUBPORT_PORT_GET(gport);
  50770             }
  50771         } else if (BCM_E_NONE == rv_vp) {
  50772             rv = BCM_E_EXISTS;
  50773         } else {
  50774             rv = rv_vp;
  50775         }
  50776     }
  50777 #endif /* BCM_TRIUMPH2_SUPPORT */
  50778 
  50779     if (is_vp) {
  50780         if (0 == rv_vp) {
  50781             /* Double-check no other protocol is using this VP */
  50782             for (vp_idx = 0; vp_idx < vp_count; vp_idx++) {
  50783                 rv_vp = _bcm_vp_used_get(unit, vp + vp_idx, _bcmVpTypeAny);
  50784                 if (0 == rv_vp) {
  50785                     rv = BCM_E_NONE;
  50786                 } else {
  50787                     rv = BCM_E_EXISTS;
  50788                     break;
  50789                 }
  50790             }
  50791         } else if (-1 != rv_vp) {
  50792             rv =  BCM_E_EXISTS;
  50793         } /* else parameter error */
  50794     }
  50795     /* subport */
  50796 
  50797     return rv;
  50798 #else
  50799     return BCM_E_UNAVAIL;
  50800 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */
  50801 }
  50802 
  50803 /*
  50804  * Function:
  50805  *      bcm_esw_port_gport_free_range_get
  50806  * Purpose:
  50807  *      Retrieve the minimum and maximum unallocated gport values for
  50808  *       a given gport type.
  50809  * Parameters:
  50810  *      unit - (IN) Unit number.
  50811  *      gport_type - (IN) One of BCM_GPORT_TYPE_* or BCM_GPORT_*_PORT values.
  50812  *      gport_min - (OUT) Minimum available gport value of type gport_type
  50813  *      gport_max - (OUT) Maximum available gport value of type gport_type
  50814  * Returns:
  50815  *      BCM_E_NONE -      Valid gports range of requested type returned
  50816  *      BCM_E_NOT_FOUND - No available gports of this type
  50817  *      BCM_E_PARAM -     Gport type is not valid on this device
  50818  *      BCM_E_UNAVAIL -   Feature unavailable
  50819  * Notes:
  50820  */
  50821 int
  50822 bcm_esw_port_gport_free_range_get(int unit, uint32 gport_type,
  50823                                   bcm_gport_t *gport_min,
  50824                                   bcm_gport_t *gport_max)
  50825 {
  50826 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
  50827     bcm_gport_t     dev_min, dev_max, gport, free_min, free_max;
  50828     int             rv = BCM_E_PARAM;
  50829     int             svp_max;
  50830 
  50831     /* Make sure port module is initialized. */
  50832     PORT_INIT(unit);
  50833 
  50834     if (soc_mem_is_valid(unit, SOURCE_VPm)) {
  50835         svp_max = soc_mem_index_max(unit, SOURCE_VPm);
  50836     } else {
  50837         /* No virtual ports at this time. */
  50838         return BCM_E_UNAVAIL;
  50839     }
  50840 
  50841     switch (gport_type) {
  50842     case BCM_GPORT_MPLS_PORT:
  50843         BCM_GPORT_MPLS_PORT_ID_SET(dev_min, 0);
  50844         BCM_GPORT_MPLS_PORT_ID_SET(dev_max, svp_max);
  50845         break;
  50846     case BCM_GPORT_MIM_PORT:
  50847         BCM_GPORT_MIM_PORT_ID_SET(dev_min, 0);
  50848         BCM_GPORT_MIM_PORT_ID_SET(dev_max, svp_max);
  50849         break;
  50850     case BCM_GPORT_L2GRE_PORT:
  50851         BCM_GPORT_L2GRE_PORT_ID_SET(dev_min, 0);
  50852         BCM_GPORT_L2GRE_PORT_ID_SET(dev_max, svp_max);
  50853         break;
  50854     case BCM_GPORT_VXLAN_PORT:
  50855         BCM_GPORT_VXLAN_PORT_ID_SET(dev_min, 0);
  50856         BCM_GPORT_VXLAN_PORT_ID_SET(dev_max, svp_max);
  50857         break;
  50858     case BCM_GPORT_WLAN_PORT:
  50859         BCM_GPORT_WLAN_PORT_ID_SET(dev_min, 0);
  50860         BCM_GPORT_WLAN_PORT_ID_SET(dev_max, svp_max);
  50861         break;
  50862     case BCM_GPORT_TRILL_PORT:
  50863         BCM_GPORT_TRILL_PORT_ID_SET(dev_min, 0);
  50864         BCM_GPORT_TRILL_PORT_ID_SET(dev_max, svp_max);
  50865         break;
  50866     case BCM_GPORT_VLAN_PORT:
  50867         BCM_GPORT_VLAN_PORT_ID_SET(dev_min, 0);
  50868         BCM_GPORT_VLAN_PORT_ID_SET(dev_max, svp_max);
  50869         break;
  50870     case BCM_GPORT_NIV_PORT:
  50871         BCM_GPORT_NIV_PORT_ID_SET(dev_min, 0);
  50872         BCM_GPORT_NIV_PORT_ID_SET(dev_max, svp_max);
  50873         break;
  50874     case BCM_GPORT_SUBPORT_GROUP:
  50875         BCM_GPORT_SUBPORT_GROUP_SET(dev_min, 0);
  50876         BCM_GPORT_SUBPORT_GROUP_SET(dev_max, svp_max);
  50877         break;
  50878     case BCM_GPORT_SUBPORT_PORT:
  50879         BCM_GPORT_SUBPORT_PORT_SET(dev_min, 0);
  50880         BCM_GPORT_SUBPORT_PORT_SET(dev_max, svp_max);
  50881         break;
  50882     default:
  50883         /* Not a supported gport type at this time */
  50884         return rv;
  50885     }
  50886 
  50887     free_min = free_max = 0; /* Invalid multicast group */
  50888     for (gport = dev_min; gport <= dev_max; gport++) {
  50889         rv = bcm_esw_port_gport_is_free(unit, gport);
  50890         if (BCM_SUCCESS(rv)) {
  50891             if (0 == free_min) {
  50892                 free_min = gport;
  50893             }
  50894             free_max = gport;
  50895         } else if (BCM_E_EXISTS == rv) {
  50896             /* Nothing to do but clear the error */
  50897             rv = BCM_E_NONE;
  50898         } else if (BCM_E_PARAM == rv) {
  50899             /* Range is less than expected, stop iterating */
  50900             rv = BCM_E_NONE;
  50901             break;
  50902         } else {
  50903             /* Real error, return */
  50904             break;
  50905         }
  50906     }
  50907 
  50908     if (BCM_SUCCESS(rv)) {
  50909         if (0 == free_min) {
  50910             /* No available groups of this type */
  50911             return BCM_E_NOT_FOUND;
  50912         } else {
  50913             /* Copy the results */
  50914             *gport_min = free_min;
  50915             *gport_max = free_max;
  50916         }
  50917     }
  50918 
  50919     return rv;
  50920 
  50921 #else
  50922     return BCM_E_UNAVAIL;
  50923 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */
  50924 }
  50925 
  50926 #if defined(BCM_TRIUMPH2_SUPPORT)
  50927 int
  50928 _bcm_esw_port_flex_stat_index_set(int unit, bcm_gport_t port, int fs_idx,
  50929                                   uint32 flags)
  50930 {
  50931     bcm_port_t loc_port;
  50932     int rv;
  50933 
  50934     rv = bcm_esw_port_local_get(unit, port, &loc_port);
  50935     if (BCM_FAILURE(rv)) {
  50936         return BCM_E_NOT_FOUND;  /* Local port disabled */
  50937     }
  50938 
  50939     PORT_LOCK(unit); /* Keep port tables in sync */
  50940     rv = BCM_E_NONE;
  50941     if (flags & _BCM_FLEX_STAT_HW_INGRESS) {
  50942         rv = soc_mem_field32_modify(unit, PORT_TABm, loc_port, VINTF_CTR_IDXf,
  50943                                 fs_idx);
  50944     }
  50945 
  50946     if (flags & _BCM_FLEX_STAT_HW_EGRESS) {
  50947         if (BCM_SUCCESS(rv)) {
  50948 #ifdef BCM_TRIDENT_SUPPORT
  50949             if (SOC_IS_TD_TT(unit)) {
  50950                 rv = soc_mem_field32_modify(unit, EGR_PORTm, loc_port,
  50951                                         VINTF_CTR_IDXf,  fs_idx);
  50952             } else
  50953 #endif /* BCM_TRIDENT_SUPPORT */
  50954             {
  50955                 rv = soc_reg_field32_modify(unit, EGR_PORT_64r, loc_port,
  50956                                         VINTF_CTR_IDXf, fs_idx);
  50957             }
  50958         }
  50959     }
  50960     PORT_UNLOCK(unit);
  50961     return rv;
  50962 }
  50963 
  50964 STATIC int
  50965 _bcm_esw_port_stat_param_verify(int unit, bcm_gport_t port)
  50966 {
  50967     int vp;
  50968 
  50969     if (BCM_GPORT_IS_MPLS_PORT(port)) {
  50970 #if defined(BCM_MPLS_SUPPORT) && defined(INCLUDE_L3)
  50971         vp = BCM_GPORT_MPLS_PORT_ID_GET(port);
  50972         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
  50973             return BCM_E_PARAM;
  50974         }
  50975 #endif
  50976     } else if (BCM_GPORT_IS_NIV_PORT(port)) {
  50977 #if defined(BCM_MPLS_SUPPORT) && defined(INCLUDE_L3)
  50978         vp = BCM_GPORT_NIV_PORT_ID_GET(port);
  50979 	    if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv)) {
  50980 	        return BCM_E_PARAM;
  50981 	    }
  50982 #endif
  50983     } else if (BCM_GPORT_IS_SUBPORT_GROUP(port) ||
  50984                BCM_GPORT_IS_SUBPORT_PORT(port)) {
  50985 
  50986 #if defined(BCM_HGPROXY_COE_SUPPORT)
  50987         if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  50988             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  50989             return bcm_esw_port_local_get(unit, port, &vp);
  50990         }
  50991 #endif
  50992 #if defined(BCM_KATANA2_SUPPORT)
  50993         if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port)){
  50994             return bcm_esw_port_local_get(unit, port, &vp);
  50995         }
  50996 #endif
  50997 #if defined(INCLUDE_L3)
  50998         if (BCM_FAILURE(_bcm_tr2_subport_gport_used(unit, port))) {
  50999             return BCM_E_PARAM;
  51000         }
  51001     } else if (BCM_GPORT_IS_MIM_PORT(port)) {
  51002         vp = BCM_GPORT_MIM_PORT_ID_GET(port);
  51003         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
  51004             return BCM_E_PARAM;
  51005         }
  51006     } else if (BCM_GPORT_IS_WLAN_PORT(port)) {
  51007         vp = BCM_GPORT_WLAN_PORT_ID_GET(port);
  51008         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) {
  51009             return BCM_E_PARAM;
  51010         }
  51011 #endif
  51012     } else {
  51013         BCM_IF_ERROR_RETURN(
  51014             bcm_esw_port_local_get(unit, port, &vp));
  51015     }
  51016 
  51017     return BCM_E_NONE;
  51018 }
  51019 STATIC int
  51020 _bcm_esw_port_stat_param_valid(int unit, bcm_gport_t port)
  51021 {
  51022     PORT_INIT(unit);
  51023 
  51024     if (!soc_feature(unit, soc_feature_gport_service_counters)) {
  51025            return BCM_E_UNAVAIL;
  51026     }
  51027     return _bcm_esw_port_stat_param_verify(unit, port);
  51028 }
  51029 
  51030 STATIC _bcm_flex_stat_t
  51031 _bcm_esw_port_stat_to_flex_stat(bcm_port_stat_t stat)
  51032 {
  51033     _bcm_flex_stat_t flex_stat;
  51034 
  51035     switch (stat) {
  51036     case bcmPortStatIngressPackets:
  51037         flex_stat = _bcmFlexStatIngressPackets;
  51038         break;
  51039     case bcmPortStatIngressBytes:
  51040         flex_stat = _bcmFlexStatIngressBytes;
  51041         break;
  51042     case bcmPortStatEgressPackets:
  51043         flex_stat = _bcmFlexStatEgressPackets;
  51044         break;
  51045     case bcmPortStatEgressBytes:
  51046         flex_stat = _bcmFlexStatEgressBytes;
  51047         break;
  51048     default:
  51049         flex_stat = _bcmFlexStatNum;
  51050     }
  51051 
  51052     return flex_stat;
  51053 }
  51054 
  51055 /* Requires "idx" variable */
  51056 #define BCM_PORT_VALUE_ARRAY_VALID(unit, nstat, value_arr) \
  51057     for (idx = 0; idx < nstat; idx++) { \
  51058         if (NULL == value_arr + idx) { \
  51059             return (BCM_E_PARAM); \
  51060         } \
  51061     }
  51062 
  51063 STATIC int
  51064 _bcm_port_stat_array_convert(int unit, int nstat, bcm_port_stat_t *stat_arr,
  51065                              _bcm_flex_stat_t *fs_arr)
  51066 {
  51067     int idx;
  51068 
  51069     if ((nstat <= 0) || (nstat > _bcmFlexStatNum)) {
  51070         return BCM_E_PARAM;
  51071     }
  51072     if ((NULL == stat_arr) || (NULL == fs_arr)) {
  51073          return (BCM_E_PARAM);
  51074     }
  51075 
  51076     for (idx = 0; idx < nstat; idx++) {
  51077         fs_arr[idx] = _bcm_esw_port_stat_to_flex_stat(stat_arr[idx]);
  51078     }
  51079     return BCM_E_NONE;
  51080 }
  51081 #endif /* BCM_TRIUMPH2_SUPPORT */
  51082 
  51083 /*
  51084  * Function:
  51085  *      bcm_esw_port_stat_enable_set
  51086  * Purpose:
  51087  *      Enable/disable packet and byte counters for the selected
  51088  *      gport.
  51089  * Parameters:
  51090  *      unit - (IN) Unit number.
  51091  *      port - (IN) GPORT ID
  51092  *      enable - (IN) Non-zero to enable counter collection, zero to disable.
  51093  * Returns:
  51094  *      BCM_E_XXX
  51095  * Notes:
  51096  */
  51097 int
  51098 bcm_esw_port_stat_enable_set(int unit, bcm_gport_t port, int enable)
  51099 {
  51100 #if defined(BCM_TRIUMPH2_SUPPORT)
  51101 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  51102   uint32                     num_of_tables=0;
  51103   uint32                     num_stat_counter_ids=0;
  51104   bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  51105   bcm_stat_object_t          object=bcmStatObjectIngPort;
  51106   uint32                     stat_counter_id[
  51107                                      BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]={0};
  51108   uint32                     num_entries=0;
  51109   int                        index=0;
  51110 
  51111 #endif
  51112 
  51113   /* Make sure port module is initialized. */
  51114   PORT_INIT(unit);
  51115 
  51116   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  51117     BCM_IF_ERROR_RETURN
  51118         (_bcm_esw_port_stat_param_valid(unit, port));
  51119     return _bcm_esw_flex_stat_enable_set(unit, _bcmFlexStatTypeGport,
  51120                              _bcm_esw_port_flex_stat_hw_index_set,
  51121                                          NULL, port, enable,0);
  51122   }
  51123 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  51124   BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info(
  51125                         unit,port,&num_of_tables,&table_info[0]));
  51126     if (enable ) {
  51127        for(index=0;index < num_of_tables ;index++) {
  51128 	   if(table_info[index].direction == bcmStatFlexDirectionIngress) {
  51129               BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_ingress_object(
  51130                                   unit,table_info[index].table,
  51131                                   table_info[index].index,NULL,&object));
  51132            } else {
  51133               BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_egress_object(
  51134                                   unit,table_info[index].table,
  51135                                   table_info[index].index,NULL,&object));
  51136            }
  51137            BCM_IF_ERROR_RETURN(bcm_esw_stat_group_create(
  51138                                unit,object,bcmStatGroupModeSingle,
  51139                                &stat_counter_id[table_info[index].direction],
  51140                                &num_entries));
  51141            BCM_IF_ERROR_RETURN(bcm_esw_port_stat_attach(
  51142                                unit,port,
  51143                                stat_counter_id[table_info[index].direction]));
  51144        }
  51145        return BCM_E_NONE;
  51146   } else {
  51147       BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_counter_id(
  51148                            unit, num_of_tables,&table_info[0],
  51149                            &num_stat_counter_ids,&stat_counter_id[0]));
  51150       if ((stat_counter_id[bcmStatFlexDirectionIngress] == 0) &&
  51151           (stat_counter_id[bcmStatFlexDirectionEgress] == 0)) {
  51152           return BCM_E_PARAM;
  51153       }
  51154       BCM_IF_ERROR_RETURN(bcm_esw_port_stat_detach(unit,port));
  51155       if (stat_counter_id[bcmStatFlexDirectionIngress] != 0) {
  51156           BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy(
  51157                                 unit,
  51158                                 stat_counter_id[bcmStatFlexDirectionIngress]));
  51159       }
  51160       if (stat_counter_id[bcmStatFlexDirectionEgress] != 0) {
  51161           BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy(
  51162                                 unit,
  51163                                 stat_counter_id[bcmStatFlexDirectionEgress]));
  51164       }
  51165       return BCM_E_NONE;
  51166     }
  51167 #else
  51168     return BCM_E_UNAVAIL;
  51169 #endif
  51170 #else
  51171     return BCM_E_UNAVAIL;
  51172 #endif
  51173 }
  51174 
  51175 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  51176 /*
  51177  * Function:
  51178  *      _bcm_esw_port_stat_get_table_info
  51179  * Description:
  51180  *      Provides relevant flex table information(table-name,index with
  51181  *      direction)  for given gport.
  51182  *
  51183  * Parameters:
  51184  *      unit             - (IN) unit number
  51185  *      port             - (IN) GPORT ID
  51186  *      num_of_tables    - (OUT) Number of flex counter tables
  51187  *      table_info       - (OUT) Flex counter tables information
  51188  *
  51189  * Return Value:
  51190  *      BCM_E_XXX
  51191  * Notes:
  51192  */
  51193 STATIC
  51194 bcm_error_t _bcm_esw_port_stat_get_table_info(
  51195                    int                        unit,
  51196                    bcm_gport_t                port,
  51197                    uint32                     *num_of_tables,
  51198                    bcm_stat_flex_table_info_t *table_info)
  51199 {
  51200 #if defined(INCLUDE_L3)
  51201 	int         vp=0;
  51202 	int         rv=0;
  51203 	int         nh_index=0;
  51204         int         vp_base=0;
  51205         int         vt_index =-1;
  51206 	bcm_vlan_t  ovid = 0;
  51207 	uint32      port_class = 0;
  51208 	bcm_port_t  egress_port = 0;
  51209 	ing_l3_next_hop_entry_t ing_nh={{0}};
  51210 	egr_vlan_xlate_entry_t 	egr_vent={{0}};
  51211 	ing_dvp_table_entry_t   dvp={{0}};
  51212 	egr_l3_next_hop_entry_t egr_nh={{0}};
  51213     source_vp_entry_t       svp;
  51214     int                     l3_idx=0;
  51215     egr_l3_intf_entry_t     l3_intf;
  51216 
  51217 #endif
  51218 	bcm_port_t  loc_port=0;
  51219 
  51220         (*num_of_tables) = 0;
  51221 
  51222 	if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  51223 		return BCM_E_UNAVAIL;
  51224 	}
  51225     BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_param_verify(unit, port));
  51226 	if (BCM_GPORT_IS_MPLS_PORT(port) ||
  51227 	    BCM_GPORT_IS_NIV_PORT(port)) {
  51228 #if defined(BCM_MPLS_SUPPORT) && defined(INCLUDE_L3)
  51229 	if (BCM_GPORT_IS_MPLS_PORT(port)) {
  51230 		vp = BCM_GPORT_MPLS_PORT_ID_GET(port);
  51231 		if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
  51232 			return BCM_E_NOT_FOUND;
  51233 		}
  51234     }
  51235     if (BCM_GPORT_IS_NIV_PORT(port)) {
  51236         vp = BCM_GPORT_NIV_PORT_ID_GET(port);
  51237 		if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv)) {
  51238 		    return BCM_E_NOT_FOUND;
  51239 		}
  51240 	}
  51241 
  51242     /* Ingress Side */
  51243     table_info[*num_of_tables].table=SOURCE_VPm;
  51244     table_info[*num_of_tables].index=vp;
  51245     table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress;
  51246     (*num_of_tables)++;
  51247 	/* Egress Side */
  51248 	if (BCM_SUCCESS(READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp))) {
  51249 	    nh_index = soc_mem_field32_get(unit, ING_DVP_TABLEm, &dvp,
  51250                                            NEXT_HOP_INDEXf);
  51251 			if (BCM_SUCCESS(soc_mem_read(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY,
  51252                                          nh_index,&egr_nh))) {
  51253                 table_info[*num_of_tables].table= EGR_L3_NEXT_HOPm;
  51254                                     table_info[*num_of_tables].index=nh_index;
  51255             table_info[*num_of_tables].direction = bcmStatFlexDirectionEgress;
  51256             (*num_of_tables)++;
  51257 				}
  51258 			}
  51259                 return BCM_E_NONE;
  51260 #endif/* BCM_MPLS_SUPPORT  && INCLUDE_L3*/
  51261 	} else if (BCM_GPORT_IS_SUBPORT_GROUP(port) ||
  51262                BCM_GPORT_IS_SUBPORT_PORT(port)) {
  51263 
  51264 
  51265 #if defined(BCM_HGPROXY_COE_SUPPORT)
  51266         if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  51267             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
  51268 
  51269             if(BCM_FAILURE(bcm_esw_port_local_get(unit, port, &loc_port))) {
  51270                 return BCM_E_NOT_FOUND;  /* Local port disabled */
  51271             }
  51272             table_info[*num_of_tables].table = PORT_TABm;
  51273             table_info[*num_of_tables].index =loc_port;
  51274             table_info[*num_of_tables].direction = bcmStatFlexDirectionIngress;
  51275             (*num_of_tables)++;
  51276             table_info[*num_of_tables].table = EGR_PORTm;
  51277             table_info[*num_of_tables].index = loc_port;
  51278             table_info[*num_of_tables].direction = bcmStatFlexDirectionEgress;
  51279             (*num_of_tables)++;
  51280             return BCM_E_NONE;
  51281         }
  51282 #endif
  51283 #if defined(BCM_KATANA2_SUPPORT)
  51284         if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port)){
  51285             if(BCM_FAILURE(bcm_esw_port_local_get(unit, port, &loc_port))) {
  51286                 return BCM_E_NOT_FOUND;  /* Local port disabled */
  51287             }
  51288             table_info[*num_of_tables].table = PORT_TABm;
  51289             table_info[*num_of_tables].index =loc_port;
  51290             table_info[*num_of_tables].direction = bcmStatFlexDirectionIngress;
  51291             (*num_of_tables)++;
  51292             table_info[*num_of_tables].table = EGR_PORTm;
  51293             table_info[*num_of_tables].index = loc_port;
  51294             table_info[*num_of_tables].direction = bcmStatFlexDirectionEgress;
  51295             (*num_of_tables)++;
  51296             return BCM_E_NONE;
  51297         }
  51298 #endif /* BCM_KATANA2_SUPPORT */
  51299 #if defined(INCLUDE_L3)
  51300 		if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
  51301                    l3_idx = BCM_GPORT_SUBPORT_PORT_GET(port) & 0xfff;
  51302                    BCM_IF_ERROR_RETURN(soc_mem_read(
  51303                                        unit, EGR_L3_INTFm, MEM_BLOCK_ALL,
  51304                                        l3_idx, &l3_intf));
  51305                    vp = soc_mem_field32_get(unit,EGR_L3_INTFm, &l3_intf, IVIDf);
  51306                    BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(
  51307                                        unit,MEM_BLOCK_ALL,vp,&svp));
  51308                    vp_base = soc_SOURCE_VPm_field32_get(unit, &svp, DVPf);
  51309                    /* vp = BCM_GPORT_SUBPORT_PORT_GET(port); */
  51310 			/* Get the base group VP */
  51311                    /* vp_base = vp & ~(0x7); */
  51312 			/* Get the group's next-hop index */
  51313                    BCM_IF_ERROR_RETURN(READ_ING_DVP_TABLEm(
  51314                                        unit, MEM_BLOCK_ALL, vp_base, &dvp));
  51315                    nh_index = soc_ING_DVP_TABLEm_field32_get(
  51316                                        unit, &dvp, NEXT_HOP_INDEXf);
  51317                    /*Get the group's OVID from the group's egress NextHopEntry*/
  51318                    BCM_IF_ERROR_RETURN(soc_mem_read(
  51319                                        unit, EGR_L3_NEXT_HOPm,
  51320                                              MEM_BLOCK_ALL, nh_index, &egr_nh));
  51321                    ovid = soc_mem_field32_get(
  51322                                   unit, EGR_L3_NEXT_HOPm, &egr_nh, OVIDf);
  51323 			/* Get the egress port class */
  51324                    BCM_IF_ERROR_RETURN (soc_mem_read(
  51325                                         unit, ING_L3_NEXT_HOPm,
  51326                                               MEM_BLOCK_ANY,nh_index, &ing_nh));
  51327 			if (!soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, Tf)) {
  51328 			egress_port = soc_ING_L3_NEXT_HOPm_field32_get(
  51329                                           unit, &ing_nh, PORT_NUMf);
  51330 				BCM_IF_ERROR_RETURN(bcm_esw_port_class_get(
  51331                                     unit, egress_port,
  51332                                     bcmPortClassVlanTranslateEgress,
  51333                                     &port_class));
  51334 			}
  51335 			sal_memset(&egr_vent, 0, sizeof(egr_vent));
  51336 			soc_EGR_VLAN_XLATEm_field32_set(unit, &egr_vent, VALIDf, 1);
  51337                    soc_EGR_VLAN_XLATEm_field32_set(unit, &egr_vent, OVIDf,ovid);
  51338 			if (soc_feature(unit, soc_feature_subport_enhanced)) {
  51339                        soc_EGR_VLAN_XLATEm_field32_set(unit,&egr_vent,IVIDf,vp);
  51340     			}
  51341                    soc_EGR_VLAN_XLATEm_field32_set(
  51342                                        unit,&egr_vent,ENTRY_TYPEf, 0x01);
  51343 		   soc_EGR_VLAN_XLATEm_field32_set(
  51344                                       unit,&egr_vent,PORT_GROUP_IDf,port_class);
  51345 			MEM_LOCK(unit, EGR_VLAN_XLATEm);
  51346 		   rv = soc_mem_search(unit,EGR_VLAN_XLATEm,MEM_BLOCK_ALL,
  51347                                        &vt_index, &egr_vent, &egr_vent, 0);
  51348 			if (rv < 0) {
  51349 				MEM_UNLOCK(unit, EGR_VLAN_XLATEm);
  51350 				return rv;
  51351 			}
  51352 			rv = soc_mem_write(unit, EGR_VLAN_XLATEm,
  51353                                            MEM_BLOCK_ALL, vt_index,&egr_vent);
  51354 			if (BCM_FAILURE(rv)) {
  51355                             MEM_UNLOCK(unit, EGR_VLAN_XLATEm);
  51356                             return rv;
  51357 			}
  51358                         table_info[*num_of_tables].table= EGR_VLAN_XLATEm;
  51359                         table_info[*num_of_tables].index=vt_index;
  51360                         table_info[*num_of_tables].direction=
  51361                                                   bcmStatFlexDirectionEgress;
  51362                         (*num_of_tables)++;
  51363                         MEM_UNLOCK(unit, EGR_VLAN_XLATEm);
  51364                         return BCM_E_NONE;
  51365 		} else { /*BCM_GPORT_IS_SUBPORT_GROUP(port) */
  51366 #if defined(BCM_TRIUMPH2_SUPPORT)
  51367 			vp_base = BCM_GPORT_SUBPORT_GROUP_GET(port);
  51368 			BCM_IF_ERROR_RETURN(_bcm_tr2_subport_gport_used(unit,port));
  51369                         table_info[*num_of_tables].table= SOURCE_VPm;
  51370                         table_info[*num_of_tables].index=vp_base;
  51371                         table_info[*num_of_tables].direction=
  51372                                                   bcmStatFlexDirectionIngress;
  51373                         (*num_of_tables)++;
  51374                         return BCM_E_NONE;
  51375 #endif
  51376 		}
  51377 	} else if (BCM_GPORT_IS_MIM_PORT(port)) {
  51378 		vp = BCM_GPORT_MIM_PORT_ID_GET(port);
  51379 		/*MIM_LOCK(unit); */
  51380 		if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
  51381         		/*MIM_UNLOCK(unit); */
  51382         		return BCM_E_NOT_FOUND;
  51383     		}
  51384 		/* Ingress side */
  51385                 table_info[*num_of_tables].table= SOURCE_VPm;
  51386                 table_info[*num_of_tables].index=vp;
  51387                 table_info[*num_of_tables].direction=
  51388                                            bcmStatFlexDirectionIngress;
  51389                 (*num_of_tables)++;
  51390 		/* Egress side */
  51391                if (BCM_SUCCESS(READ_ING_DVP_TABLEm(
  51392                                     unit, MEM_BLOCK_ANY, vp, &dvp))) {
  51393 			nh_index = soc_mem_field32_get(unit, ING_DVP_TABLEm, &dvp,
  51394                                            NEXT_HOP_INDEXf);
  51395                    if (BCM_SUCCESS(soc_mem_read(
  51396                                        unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY,
  51397                                          nh_index,&egr_nh))) {
  51398                             table_info[*num_of_tables].table= EGR_L3_NEXT_HOPm;
  51399                             table_info[*num_of_tables].index=nh_index;
  51400                             table_info[*num_of_tables].direction=
  51401                                                    bcmStatFlexDirectionEgress;
  51402                             (*num_of_tables)++;
  51403 			}
  51404 		}
  51405                 return BCM_E_NONE;
  51406 	} else if (BCM_GPORT_IS_WLAN_PORT(port)) {
  51407 		vp = BCM_GPORT_WLAN_PORT_ID_GET(port);
  51408 		/*WLAN_LOCK(unit); */
  51409 		if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) {
  51410         		/*WLAN_UNLOCK(unit); */
  51411         		return BCM_E_NOT_FOUND;
  51412     		}
  51413 		/*Ingress Side */
  51414                 table_info[*num_of_tables].table= SOURCE_VPm;
  51415                 table_info[*num_of_tables].index=vp;
  51416                table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress;
  51417                 (*num_of_tables)++;
  51418                BCM_IF_ERROR_RETURN(READ_ING_DVP_TABLEm(
  51419                                         unit, MEM_BLOCK_ANY, vp, &dvp));
  51420                nh_index = soc_ING_DVP_TABLEm_field32_get(
  51421                                   unit, &dvp, NEXT_HOP_INDEXf);
  51422                 table_info[*num_of_tables].table= EGR_L3_NEXT_HOPm;
  51423                 table_info[*num_of_tables].index=nh_index;
  51424                 table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress;
  51425                 (*num_of_tables)++;
  51426                 return BCM_E_NONE;
  51427 	} else if (BCM_GPORT_IS_VLAN_PORT(port)) {
  51428                 vp = BCM_GPORT_VLAN_PORT_ID_GET(port);
  51429 
  51430                 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan))) {
  51431                        return BCM_E_NOT_FOUND;
  51432                 }
  51433 
  51434                 /*Ingress Side */
  51435                 table_info[*num_of_tables].table= SOURCE_VPm;
  51436                 table_info[*num_of_tables].index=vp;
  51437                 table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress;
  51438                 (*num_of_tables)++;
  51439                 BCM_IF_ERROR_RETURN(READ_ING_DVP_TABLEm(
  51440                                         unit, MEM_BLOCK_ANY, vp, &dvp));
  51441                 nh_index = soc_ING_DVP_TABLEm_field32_get(
  51442                                   unit, &dvp, NEXT_HOP_INDEXf);
  51443                 table_info[*num_of_tables].table= EGR_L3_NEXT_HOPm;
  51444                 table_info[*num_of_tables].index=nh_index;
  51445                 table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress;
  51446                 (*num_of_tables)++;
  51447                 return BCM_E_NONE;
  51448 #endif
  51449         } else {
  51450 		if(BCM_FAILURE(bcm_esw_port_local_get(unit, port, &loc_port))) {
  51451 			return BCM_E_NOT_FOUND;  /* Local port disabled */
  51452 		}
  51453 		/*PORT_LOCK(unit); */
  51454 #if defined(BCM_TRIDENT3_SUPPORT)
  51455                 if (SOC_IS_TRIDENT3X(unit)) {
  51456                     table_info[*num_of_tables].table = LPORT_TABm;
  51457                     table_info[*num_of_tables].index = loc_port;
  51458                     table_info[*num_of_tables].direction = bcmStatFlexDirectionIngress;
  51459                     (*num_of_tables)++;
  51460                     if (soc_mem_field_valid(unit, EGR_PORTm, EGR_LPORT_PROFILE_IDXf) &&
  51461                         soc_mem_is_valid(unit, EGR_LPORT_PROFILEm)) {
  51462                         table_info[*num_of_tables].table = EGR_LPORT_PROFILEm;
  51463                         table_info[*num_of_tables].index = loc_port;
  51464                         table_info[*num_of_tables].direction = bcmStatFlexDirectionEgress;
  51465                         (*num_of_tables)++;
  51466                     } else {
  51467                         return BCM_E_NOT_FOUND;
  51468                     }
  51469                 } else
  51470 #endif
  51471                 {
  51472                 table_info[*num_of_tables].table= PORT_TABm;
  51473                 table_info[*num_of_tables].index=loc_port;
  51474                 table_info[*num_of_tables].direction= bcmStatFlexDirectionIngress;
  51475                 (*num_of_tables)++;
  51476                 table_info[*num_of_tables].table= EGR_PORTm;
  51477                 table_info[*num_of_tables].index=loc_port;
  51478                 table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress;
  51479                 (*num_of_tables)++;
  51480                 }
  51481                 return BCM_E_NONE;
  51482 	}
  51483 	return BCM_E_NOT_FOUND;
  51484 }
  51485 #endif
  51486 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  51487 /*
  51488  * Function:
  51489  *      _bcm_esw_port_stat_attach
  51490  * Description:
  51491  *      Attach counter entries to the given GPORT
  51492  *
  51493  * Parameters:
  51494  *      unit             - (IN) unit number
  51495  *      port             - (IN) GPORT ID
  51496  *      stat_counter_id  - (IN) Stat Counter ID.
  51497  *
  51498  * Return Value:
  51499  *      BCM_E_XXX
  51500  * Notes:
  51501  */
  51502 int _bcm_esw_port_stat_attach(
  51503             int	        unit,
  51504             bcm_gport_t	port,
  51505             uint32      stat_counter_id)
  51506 {
  51507     soc_mem_t                 table=0;
  51508     bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress;
  51509     uint32                    pool_number=0;
  51510     uint32                    base_index=0;
  51511     bcm_stat_flex_mode_t      offset_mode=0;
  51512     bcm_stat_object_t         object=bcmStatObjectIngPort;
  51513     bcm_stat_group_mode_t     group_mode= bcmStatGroupModeSingle;
  51514     uint32                    count=0;
  51515     uint32                     actual_num_tables=0;
  51516     uint32                     num_of_tables=0;
  51517     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  51518     uint8                     skip_table_check = 0;
  51519 
  51520     _bcm_esw_stat_get_counter_id_info(
  51521                   unit, stat_counter_id,
  51522                   &group_mode,&object,&offset_mode,&pool_number,&base_index);
  51523     BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit,object,&direction));
  51524     BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit,group_mode));
  51525     BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_table_info(
  51526                         unit,object,1,&actual_num_tables,&table,&direction));
  51527 
  51528     BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info(
  51529                    unit, port,&num_of_tables,&table_info[0]));
  51530     skip_table_check = soc_property_get(unit, spn_FLEX_STAT_SHARE_ENABLE, 0);
  51531     for (count=0; count < num_of_tables ; count++) {
  51532       if ( (table_info[count].direction == direction) &&
  51533            ((table_info[count].table == table) || (skip_table_check)) ) {
  51534            if(direction == bcmStatFlexDirectionIngress) {
  51535               return _bcm_esw_stat_flex_attach_ingress_table_counters(
  51536                      unit,
  51537                      table_info[count].table,
  51538                      table_info[count].index,
  51539                      offset_mode,
  51540                      base_index,
  51541                      pool_number);
  51542            } else {
  51543               return _bcm_esw_stat_flex_attach_egress_table_counters(
  51544                      unit,
  51545                      table_info[count].table,
  51546                      table_info[count].index,
  51547                      0,
  51548                      offset_mode,
  51549                      base_index,
  51550                      pool_number);
  51551            }
  51552       }
  51553     }
  51554     return BCM_E_NOT_FOUND;
  51555 }
  51556 #endif
  51557 
  51558 /*
  51559  * Function:
  51560  *      bcm_esw_port_stat_attach
  51561  * Description:
  51562  *      Attach counter entries to the given GPORT
  51563  *
  51564  * Parameters:
  51565  *      unit             - (IN) unit number
  51566  *      port             - (IN) GPORT ID
  51567  *      stat_counter_id  - (IN) Stat Counter ID.
  51568  *
  51569  * Return Value:
  51570  *      BCM_E_XXX
  51571  * Notes:
  51572  */
  51573 int bcm_esw_port_stat_attach(
  51574             int         unit,
  51575             bcm_gport_t port,
  51576             uint32      stat_counter_id)
  51577 {
  51578 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  51579     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  51580         return _bcm_esw_port_stat_attach(unit,port,stat_counter_id);
  51581     } else
  51582 #endif
  51583 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  51584     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  51585         _bcm_flex_stat_type_t fs_type;
  51586         uint32 fs_inx;
  51587         uint32 flag;
  51588         int rv;
  51589 
  51590         fs_type = _BCM_FLEX_STAT_TYPE(stat_counter_id);
  51591         fs_inx  = _BCM_FLEX_STAT_COUNT_INX(stat_counter_id);
  51592 
  51593         if (!((fs_type == _bcmFlexStatTypeGport ||
  51594             fs_type == _bcmFlexStatTypeEgressGport) && fs_inx)) {
  51595             return BCM_E_PARAM;
  51596         }
  51597         BCM_IF_ERROR_RETURN
  51598             (_bcm_esw_port_stat_param_valid(unit, port));
  51599 
  51600         flag = fs_type==_bcmFlexStatTypeGport? _BCM_FLEX_STAT_HW_INGRESS:
  51601                          _BCM_FLEX_STAT_HW_EGRESS;
  51602 
  51603         rv = _bcm_esw_flex_stat_enable_set(unit, fs_type,
  51604                              _bcm_esw_port_flex_stat_hw_index_set,
  51605                                       INT_TO_PTR(flag),
  51606                                       port, TRUE,fs_inx);
  51607         return rv;
  51608     } else
  51609 #endif
  51610     {
  51611         return BCM_E_UNAVAIL;
  51612     }
  51613 }
  51614 
  51615 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  51616 /*
  51617  * Function:
  51618  *      _bcm_esw_port_stat_detach
  51619  * Description:
  51620  *      Detach counter entries to the given GPORT
  51621  *
  51622  * Parameters:
  51623  *      unit             - (IN) unit number
  51624  *      port             - (IN) GPORT ID
  51625  *
  51626  * Return Value:
  51627  *      BCM_E_XXX
  51628  * Notes:
  51629  */
  51630 int _bcm_esw_port_stat_detach(
  51631             int	        unit,
  51632             bcm_gport_t	port)
  51633 {
  51634     uint32                     count=0;
  51635     uint32                     num_of_tables=0;
  51636     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  51637     bcm_error_t                rv = BCM_E_NONE;
  51638     bcm_error_t                err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE};
  51639 
  51640     BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info(
  51641                    unit, port,&num_of_tables,&table_info[0]));
  51642 
  51643     for (count=0; count < num_of_tables ; count++) {
  51644       if (table_info[count].direction == bcmStatFlexDirectionIngress) {
  51645            rv = _bcm_esw_stat_flex_detach_ingress_table_counters(
  51646                          unit,
  51647                          table_info[count].table,
  51648                          table_info[count].index);
  51649            if (BCM_E_NONE != rv &&
  51650                 BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) {
  51651                 err_code[bcmStatFlexDirectionIngress] = rv;
  51652            }
  51653       } else {
  51654            rv = _bcm_esw_stat_flex_detach_egress_table_counters(
  51655                           unit,
  51656                           0,
  51657                           table_info[count].table,
  51658                           table_info[count].index);
  51659            if (BCM_E_NONE != rv &&
  51660                 BCM_E_NONE == err_code[bcmStatFlexDirectionEgress]) {
  51661                 err_code[bcmStatFlexDirectionEgress] = rv;
  51662            }
  51663       }
  51664     }
  51665 
  51666     BCM_STAT_FLEX_DETACH_RETURN(err_code)
  51667 }
  51668 
  51669 /*
  51670  * Function:
  51671  *      _bcm_esw_port_stat_detach_with_id
  51672  * Description:
  51673  *      Detach counter entries to the given GPORT with a given stat counter id
  51674  *
  51675  * Parameters:
  51676  *      unit             - (IN) unit number
  51677  *      port             - (IN) GPORT ID
  51678  *      stat_counter_id  - (IN) Stat Counter ID
  51679  *
  51680  * Return Value:
  51681  *      BCM_E_XXX
  51682  * Notes:
  51683  */
  51684 bcm_error_t _bcm_esw_port_stat_detach_with_id(
  51685             int	        unit,
  51686             bcm_gport_t	port,
  51687             uint32 stat_counter_id)
  51688 {
  51689     uint32                     count=0;
  51690     uint32                     num_of_tables=0;
  51691     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  51692     bcm_error_t                rv = BCM_E_NONE;
  51693     bcm_error_t                err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE};
  51694     bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress;
  51695     uint32                    pool_number=0;
  51696     uint32                    base_index=0;
  51697     bcm_stat_flex_mode_t      offset_mode=0;
  51698     bcm_stat_object_t         object=bcmStatObjectIngPort;
  51699     bcm_stat_group_mode_t     group_mode= bcmStatGroupModeSingle;
  51700     uint32                     actual_num_tables=0;
  51701     soc_mem_t                 table=0;
  51702 
  51703     _bcm_esw_stat_get_counter_id_info(unit, stat_counter_id, &group_mode, &object,
  51704                                       &offset_mode, &pool_number, &base_index);
  51705     BCM_IF_ERROR_RETURN
  51706         (_bcm_esw_stat_validate_object(unit, object, &direction));
  51707     BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit, group_mode));
  51708     BCM_IF_ERROR_RETURN
  51709         (_bcm_esw_stat_flex_get_table_info(unit, object, 1, &actual_num_tables,
  51710                                            &table, &direction));
  51711 
  51712     BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info(
  51713                    unit, port,&num_of_tables,&table_info[0]));
  51714 
  51715     for (count=0; count < num_of_tables ; count++) {
  51716         if((table_info[count].direction == direction) &&
  51717              (table_info[count].table == table)) {
  51718            if(direction == bcmStatFlexDirectionIngress) {
  51719                rv = _bcm_esw_stat_flex_detach_ingress_table_counters(
  51720                              unit,
  51721                              table_info[count].table,
  51722                              table_info[count].index);
  51723                if (BCM_E_NONE != rv &&
  51724                     BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) {
  51725                     err_code[bcmStatFlexDirectionIngress] = rv;
  51726                }
  51727             } else {
  51728                rv = _bcm_esw_stat_flex_detach_egress_table_counters(
  51729                               unit,
  51730                               0,
  51731                               table_info[count].table,
  51732                               table_info[count].index);
  51733                if (BCM_E_NONE != rv &&
  51734                     BCM_E_NONE == err_code[bcmStatFlexDirectionEgress]) {
  51735                     err_code[bcmStatFlexDirectionEgress] = rv;
  51736                }
  51737             }
  51738         }
  51739     }
  51740     
  51741     BCM_STAT_FLEX_DETACH_RETURN(err_code)
  51742 }
  51743 #endif
  51744 
  51745 /*
  51746  * Function:
  51747  *      bcm_esw_port_stat_detach
  51748  * Description:
  51749  *      Detach counter entries to the given GPORT
  51750  *
  51751  * Parameters:
  51752  *      unit             - (IN) unit number
  51753  *      port             - (IN) GPORT ID
  51754  *
  51755  * Return Value:
  51756  *      BCM_E_XXX
  51757  * Notes:
  51758  */
  51759 int bcm_esw_port_stat_detach(
  51760             int         unit,
  51761             bcm_gport_t port)
  51762 {
  51763 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  51764     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  51765         return _bcm_esw_port_stat_detach(unit,port);
  51766     } else
  51767 #endif
  51768 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  51769     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  51770         uint32 flag;
  51771         int rv;
  51772         int rv1;
  51773 
  51774         BCM_IF_ERROR_RETURN
  51775             (_bcm_esw_port_stat_param_valid(unit, port));
  51776 
  51777         /* no count_id, detach all counters associated with this port.*/
  51778         flag= _BCM_FLEX_STAT_HW_INGRESS;
  51779         rv = _bcm_esw_flex_stat_enable_set(unit, _bcmFlexStatTypeGport,
  51780                              _bcm_esw_port_flex_stat_hw_index_set,
  51781                                       INT_TO_PTR(flag),
  51782                                       port, FALSE,1);
  51783         flag= _BCM_FLEX_STAT_HW_EGRESS;
  51784         rv1 = _bcm_esw_flex_stat_enable_set(unit,
  51785                          _bcmFlexStatTypeEgressGport,
  51786                          _bcm_esw_port_flex_stat_hw_index_set,
  51787                                   INT_TO_PTR(flag),
  51788                                   port, FALSE,1);
  51789         if (BCM_SUCCESS(rv) && BCM_SUCCESS(rv1)) {
  51790             return BCM_E_NONE;
  51791         } else {
  51792             return BCM_E_NOT_FOUND;
  51793         }
  51794     } else
  51795 #endif
  51796     {
  51797         return BCM_E_UNAVAIL;
  51798     }
  51799 }
  51800 
  51801 /*
  51802  * Function:
  51803  *      bcm_esw_port_stat_detach_with_id
  51804  * Description:
  51805  *      Detach counter entries to the given GPORT with a given stat counter id
  51806  *
  51807  * Parameters:
  51808  *      unit             - (IN) unit number
  51809  *      port             - (IN) GPORT ID
  51810  *      stat_counter_id  - (IN) Stat Counter ID
  51811  *
  51812  * Return Value:
  51813  *      BCM_E_XXX
  51814  * Notes:
  51815  */
  51816 bcm_error_t bcm_esw_port_stat_detach_with_id(
  51817             int         unit,
  51818             bcm_gport_t port,
  51819             uint32 stat_counter_id)
  51820 {
  51821 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  51822     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  51823         return _bcm_esw_port_stat_detach_with_id(unit, port, stat_counter_id);
  51824     } else
  51825 #endif
  51826     {
  51827         return BCM_E_UNAVAIL;
  51828     }
  51829 }
  51830 
  51831 
  51832 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  51833 /*
  51834  * Function:
  51835  *      _bcm_esw_port_stat_counter_get
  51836  * Description:
  51837  *      retrieve set of counter statistic values for the given GPORT
  51838  *      if sync_mode is set, sync the sw accumulated count
  51839  *      with hw count value first, else return sw count.
  51840  *
  51841  * Parameters:
  51842  *      unit             - (IN) unit number
  51843  *      port             - (IN) GPORT ID
  51844  *      stat             - (IN) Type of the counter to retrieve
  51845  *                              I.e. ingress/egress byte/packet)
  51846  *      num_entries      - (IN) Number of counter Entries
  51847  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  51848  *      counter_values   - (OUT) Pointer to counter values
  51849  *
  51850  * Return Value:
  51851  *      BCM_E_XXX
  51852  * Notes:
  51853  */
  51854 int _bcm_esw_port_stat_counter_get(
  51855             int	             unit,
  51856             int	             sync_mode,
  51857             bcm_gport_t      port,
  51858             bcm_port_stat_t  stat,
  51859             uint32           num_entries,
  51860             uint32           *counter_indexes,
  51861             bcm_stat_value_t *counter_values)
  51862 {
  51863     uint32                          table_count=0;
  51864     uint32                          index_count=0;
  51865     uint32                          num_of_tables=0;
  51866     bcm_stat_flex_direction_t       direction=bcmStatFlexDirectionIngress;
  51867     uint32                          byte_flag=0;
  51868     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  51869 
  51870     if ((stat == bcmPortStatIngressPackets) ||
  51871         (stat == bcmPortStatIngressBytes)) {
  51872          direction = bcmStatFlexDirectionIngress;
  51873     } else {
  51874          direction = bcmStatFlexDirectionEgress;
  51875     }
  51876     if ((stat == bcmPortStatIngressPackets) ||
  51877         (stat == bcmPortStatEgressPackets)) {
  51878         byte_flag=0;
  51879     } else {
  51880         byte_flag=1;
  51881     }
  51882 
  51883     BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info(
  51884                    unit, port,&num_of_tables,&table_info[0]));
  51885 
  51886     for (table_count=0; table_count < num_of_tables ; table_count++) {
  51887       if (table_info[table_count].direction == direction) {
  51888           for (index_count=0; index_count < num_entries ; index_count++) {
  51889                /*ctr_offset_info.offset_index = counter_indexes[index_count];*/
  51890             BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_get(
  51891                          unit, sync_mode,
  51892                          table_info[table_count].index,
  51893                          table_info[table_count].table,
  51894                          0,
  51895                          byte_flag,
  51896                          counter_indexes[index_count],
  51897                          &counter_values[index_count]));
  51898           }
  51899       }
  51900     }
  51901     return BCM_E_NONE;
  51902 }
  51903 #endif
  51904 
  51905 /*
  51906  * Function:
  51907  *      _bcm_esw_port_flex_stat_counter_get
  51908  * Description:
  51909  *      retrieve set of counter statistic values for the given GPORT
  51910  *      if sync_mode is set, sync the sw accumulated count
  51911  *      with hw count value first, else return sw count.
  51912  * Parameters:
  51913  *      unit             - (IN) unit number
  51914  *      sync_mode        - (IN) hwcount is to be synced to sw count
  51915  *      port             - (IN) GPORT ID
  51916  *      stat             - (IN) Type of the counter to retrieve
  51917  *                              I.e. ingress/egress byte/packet)
  51918  *      num_entries      - (IN) Number of counter Entries
  51919  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  51920  *      counter_values   - (OUT) Pointer to counter values
  51921  *
  51922  * Return Value:
  51923  *      BCM_E_XXX
  51924  * Notes:
  51925  */
  51926 int _bcm_esw_port_flex_stat_counter_get(int              unit,
  51927                                         int              sync_mode,
  51928                                         bcm_gport_t      port,
  51929                                         bcm_port_stat_t  stat,
  51930                                         uint32           num_entries,
  51931                                         uint32           *counter_indexes,
  51932                                         bcm_stat_value_t *counter_values)
  51933 {
  51934 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  51935     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  51936         return _bcm_esw_port_stat_counter_get(unit, sync_mode, port, stat,
  51937                                               num_entries, counter_indexes,
  51938                                               counter_values);
  51939     } else
  51940 #endif
  51941 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  51942     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  51943         uint64 val;
  51944         int rv = BCM_E_NONE;
  51945 
  51946         rv =  _bcm_esw_flex_stat_get(unit, sync_mode,
  51947                ((stat == bcmPortStatIngressPackets) ||
  51948                 (stat == bcmPortStatIngressBytes)) ?
  51949                  _bcmFlexStatTypeGport:_bcmFlexStatTypeEgressGport,
  51950                 port,
  51951                 _bcm_esw_port_stat_to_flex_stat(stat), &val);
  51952 
  51953         if ((stat == bcmPortStatIngressPackets) ||
  51954             (stat == bcmPortStatEgressPackets)) {
  51955             counter_values->packets = COMPILER_64_LO(val);
  51956         } else {
  51957             COMPILER_64_SET(counter_values->bytes,
  51958                       COMPILER_64_HI(val),
  51959                       COMPILER_64_LO(val));
  51960         }
  51961         return rv;
  51962 
  51963     } else
  51964 #endif
  51965     {
  51966         return BCM_E_UNAVAIL;
  51967     }
  51968 
  51969 }
  51970 
  51971 
  51972 /*
  51973  * Function:
  51974  *      bcm_esw_port_stat_counter_get
  51975  * Description:
  51976  *      retrieve set of counter statistic values for the given GPORT
  51977  * Parameters:
  51978  *      unit             - (IN) unit number
  51979  *      port             - (IN) GPORT ID
  51980  *      stat             - (IN) Type of the counter to retrieve
  51981  *                              I.e. ingress/egress byte/packet)
  51982  *      num_entries      - (IN) Number of counter Entries
  51983  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  51984  *      counter_values   - (OUT) Pointer to counter values
  51985  *
  51986  * Return Value:
  51987  *      BCM_E_XXX
  51988  * Notes:
  51989  */
  51990 
  51991 int bcm_esw_port_stat_counter_get(int              unit,
  51992                                   bcm_gport_t      port,
  51993                                   bcm_port_stat_t  stat,
  51994                                   uint32           num_entries,
  51995                                   uint32           *counter_indexes,
  51996                                   bcm_stat_value_t *counter_values)
  51997 {
  51998     int rv = BCM_E_UNAVAIL;
  51999 
  52000     rv = _bcm_esw_port_flex_stat_counter_get(unit, 0, port, stat, num_entries,
  52001                                              counter_indexes, counter_values);
  52002 
  52003     return rv;
  52004 }
  52005 
  52006 
  52007 /*
  52008  * Function:
  52009  *      bcm_esw_port_stat_counter_sync_get
  52010  * Description:
  52011  *      retrieve set of counter statistic values for the given GPORT
  52012  *      sw accumulated counters synced with hw count.
  52013  * Parameters:
  52014  *      unit             - (IN) unit number
  52015  *      port             - (IN) GPORT ID
  52016  *      stat             - (IN) Type of the counter to retrieve
  52017  *                              I.e. ingress/egress byte/packet)
  52018  *      num_entries      - (IN) Number of counter Entries
  52019  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  52020  *      counter_values   - (OUT) Pointer to counter values
  52021  *
  52022  * Return Value:
  52023  *      BCM_E_XXX
  52024  * Notes:
  52025  */
  52026 
  52027 int bcm_esw_port_stat_counter_sync_get(int              unit,
  52028                                        bcm_gport_t      port,
  52029                                        bcm_port_stat_t  stat,
  52030                                        uint32           num_entries,
  52031                                        uint32           *counter_indexes,
  52032                                        bcm_stat_value_t *counter_values)
  52033 {
  52034     int rv = BCM_E_UNAVAIL;
  52035 
  52036     rv = _bcm_esw_port_flex_stat_counter_get(unit, 1, port, stat, num_entries,
  52037                                         counter_indexes, counter_values);
  52038 
  52039     return rv;
  52040 }
  52041 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52042 /*
  52043  * Function:
  52044  *      _bcm_esw_port_stat_counter_set
  52045  * Description:
  52046  *      set counter statistic values for the given GPORT
  52047  *
  52048  * Parameters:
  52049  *      unit             - (IN) unit number
  52050  *      port             - (IN) GPORT ID
  52051  *      stat             - (IN) Type of the counter to retrieve
  52052  *                              I.e. ingress/egress byte/packet)
  52053  *      num_entries      - (IN) Number of counter Entries
  52054  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  52055  *      counter_values   - (IN) Pointer to counter values
  52056  *
  52057  * Return Value:
  52058  *      BCM_E_XXX
  52059  * Notes:
  52060  */
  52061 int _bcm_esw_port_stat_counter_set(
  52062             int	             unit,
  52063             bcm_gport_t      port,
  52064             bcm_port_stat_t  stat,
  52065             uint32           num_entries,
  52066             uint32           *counter_indexes,
  52067             bcm_stat_value_t *counter_values)
  52068 {
  52069     uint32                          table_count=0;
  52070     uint32                          index_count=0;
  52071     uint32                          num_of_tables=0;
  52072     bcm_stat_flex_direction_t       direction=bcmStatFlexDirectionIngress;
  52073     uint32                          byte_flag=0;
  52074     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  52075 
  52076     if ((stat == bcmPortStatIngressPackets) ||
  52077         (stat == bcmPortStatIngressBytes)) {
  52078          direction = bcmStatFlexDirectionIngress;
  52079     } else {
  52080          direction = bcmStatFlexDirectionEgress;
  52081     }
  52082     if ((stat == bcmPortStatIngressPackets) ||
  52083         (stat == bcmPortStatEgressPackets)) {
  52084         byte_flag=0;
  52085     } else {
  52086         byte_flag=1;
  52087     }
  52088 
  52089     BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info(
  52090                    unit, port,&num_of_tables,&table_info[0]));
  52091 
  52092     for (table_count=0; table_count < num_of_tables ; table_count++) {
  52093       if (table_info[table_count].direction == direction) {
  52094           for (index_count=0; index_count < num_entries ; index_count++) {
  52095             BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_set(
  52096                                 unit,
  52097                                 table_info[table_count].index,
  52098                                 table_info[table_count].table,
  52099                                 0,
  52100                                 byte_flag,
  52101                                 counter_indexes[index_count],
  52102                                 &counter_values[index_count]));
  52103           }
  52104       }
  52105     }
  52106     return BCM_E_NONE;
  52107 }
  52108 #endif
  52109 /*
  52110  * Function:
  52111  *      bcm_esw_port_stat_counter_set
  52112  * Description:
  52113  *      set counter statistic values for the given GPORT
  52114  *
  52115  * Parameters:
  52116  *      unit             - (IN) unit number
  52117  *      port             - (IN) GPORT ID
  52118  *      stat             - (IN) Type of the counter to retrieve
  52119  *                              I.e. ingress/egress byte/packet)
  52120  *      num_entries      - (IN) Number of counter Entries
  52121  *      counter_indexes  - (IN) Pointer to Counter indexes entries
  52122  *      counter_values   - (IN) Pointer to counter values
  52123  *
  52124  * Return Value:
  52125  *      BCM_E_XXX
  52126  * Notes:
  52127  */
  52128 int bcm_esw_port_stat_counter_set(
  52129             int              unit,
  52130             bcm_gport_t      port,
  52131             bcm_port_stat_t  stat,
  52132             uint32           num_entries,
  52133             uint32           *counter_indexes,
  52134             bcm_stat_value_t *counter_values)
  52135 {
  52136     /* Make sure port module is initialized. */
  52137     PORT_INIT(unit);
  52138 
  52139 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52140     if (soc_feature(unit,soc_feature_advanced_flex_counter)) {
  52141         return _bcm_esw_port_stat_counter_set(unit,port,stat,
  52142                       num_entries,counter_indexes,counter_values);
  52143     } else
  52144 #endif
  52145 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
  52146     if (soc_feature(unit,soc_feature_gport_service_counters)) {
  52147         uint64 val;
  52148         int rv = BCM_E_NONE;
  52149 
  52150         if ((stat == bcmPortStatIngressPackets) ||
  52151             (stat == bcmPortStatEgressPackets)) {
  52152             COMPILER_64_SET(val,0,counter_values->packets);
  52153         } else {
  52154             COMPILER_64_SET(val,
  52155                       COMPILER_64_HI(counter_values->bytes),
  52156                       COMPILER_64_LO(counter_values->bytes));
  52157         }
  52158         rv =  _bcm_esw_flex_stat_set(unit,
  52159                ((stat == bcmPortStatIngressPackets) ||
  52160                 (stat == bcmPortStatIngressBytes)) ?
  52161                  _bcmFlexStatTypeGport:_bcmFlexStatTypeEgressGport,
  52162                 port,
  52163                 _bcm_esw_port_stat_to_flex_stat(stat), val);
  52164 
  52165         return rv;
  52166 
  52167     } else
  52168 #endif
  52169     {
  52170         return BCM_E_UNAVAIL;
  52171     }
  52172 }
  52173 /*
  52174  * Function:
  52175  *      bcm_esw_port_stat_id_get
  52176  * Description:
  52177  *      Get stat counter id associated with given gport
  52178  *
  52179  * Parameters:
  52180  *      unit             - (IN) unit number
  52181  *      port             - (IN) GPORT ID
  52182  *      stat             - (IN) Type of the counter to retrieve
  52183  *                              I.e. ingress/egress byte/packet)
  52184  *      Stat_counter_id  - (OUT) Stat Counter ID
  52185  * Return Value:
  52186  *      BCM_E_XXX
  52187  * Notes:
  52188  */
  52189 int bcm_esw_port_stat_id_get(
  52190             int              unit,
  52191             bcm_gport_t      port,
  52192             bcm_port_stat_t  stat,
  52193             uint32           *stat_counter_id)
  52194 {
  52195 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52196     bcm_stat_flex_direction_t  direction=bcmStatFlexDirectionIngress;
  52197     uint32                     num_of_tables=0;
  52198     bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION];
  52199     uint32                     index=0;
  52200     uint32                     num_stat_counter_ids=0;
  52201 
  52202     /* Make sure port module is initialized. */
  52203     PORT_INIT(unit);
  52204 
  52205     if ((stat == bcmPortStatIngressPackets) ||
  52206         (stat == bcmPortStatIngressBytes)) {
  52207          direction = bcmStatFlexDirectionIngress;
  52208     } else {
  52209          direction = bcmStatFlexDirectionEgress;
  52210     }
  52211     BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info(
  52212                         unit,port,&num_of_tables,&table_info[0]));
  52213     for (index=0; index < num_of_tables ; index++) {
  52214          if (table_info[index].direction == direction)
  52215              return _bcm_esw_stat_flex_get_counter_id(
  52216                                   unit, 1, &table_info[index],
  52217                                   &num_stat_counter_ids,stat_counter_id);
  52218     }
  52219     return BCM_E_NOT_FOUND;
  52220 #else
  52221     return BCM_E_UNAVAIL;
  52222 #endif
  52223 }
  52224 
  52225 
  52226 /*
  52227  * Function:
  52228  *      _bcm_esw_port_stat_get
  52229  * Purpose:
  52230  *      Get 64-bit counter value for specified port statistic type.
  52231  *      if sync_mode is set, sync the sw accumulated count
  52232  *      with hw count value first, else return sw count.
  52233  * Parameters:
  52234  *      unit        - (IN) Unit number.
  52235  *      sync_mode   - (IN) hwcount is to be synced to sw count
  52236  *      port        - (IN) GPORT ID
  52237  *      stat        - (IN) Type of the counter to retrieve.
  52238  *      val         - (OUT) Pointer to a counter value.
  52239  * Returns:
  52240  *      BCM_E_XXX
  52241  * Notes:
  52242  */
  52243 int
  52244 _bcm_esw_port_stat_get(int unit, int sync_mode, bcm_gport_t port,
  52245                        bcm_port_stat_t stat, uint64 *val)
  52246 {
  52247 #if defined(BCM_TRIUMPH2_SUPPORT)
  52248 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52249   uint32           counter_indexes=0;
  52250   bcm_stat_value_t counter_values={0};
  52251 #endif
  52252 
  52253   /* Make sure port module is initialized. */
  52254   PORT_INIT(unit);
  52255 
  52256 #if defined(BCM_PREEMPTION_SUPPORT)
  52257   if (soc_feature(unit, soc_feature_preemption_cnt)) {
  52258     bcm_port_t local_port;
  52259     BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port));
  52260     return bcmi_esw_preemption_counter_get(unit, sync_mode, local_port,
  52261                                            stat, val);
  52262   }
  52263 #endif /* BCM_PREEMPTION_SUPPORT */
  52264 
  52265   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  52266     BCM_IF_ERROR_RETURN
  52267         (_bcm_esw_port_stat_param_valid(unit, port));
  52268     return _bcm_esw_flex_stat_get(unit, sync_mode, _bcmFlexStatTypeGport, port,
  52269                                   _bcm_esw_port_stat_to_flex_stat(stat), val);
  52270   }
  52271 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52272   BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_counter_get(unit, sync_mode, port,
  52273                                                      stat, 1, &counter_indexes,
  52274                                                      &counter_values));
  52275   if ((stat == bcmPortStatIngressPackets) ||
  52276       (stat == bcmPortStatEgressPackets)) {
  52277       COMPILER_64_SET(*val,
  52278                       COMPILER_64_HI(counter_values.packets64),
  52279                       COMPILER_64_LO(counter_values.packets64));
  52280   } else {
  52281       COMPILER_64_SET(*val,
  52282                       COMPILER_64_HI(counter_values.bytes),
  52283                       COMPILER_64_LO(counter_values.bytes));
  52284   }
  52285   return BCM_E_NONE;
  52286 #else
  52287     return BCM_E_UNAVAIL;
  52288 #endif
  52289 #else
  52290     return BCM_E_UNAVAIL;
  52291 #endif
  52292 }
  52293 
  52294 
  52295 /*
  52296  * Function:
  52297  *      bcm_esw_port_stat_get
  52298  * Purpose:
  52299  *      Get 64-bit counter value for specified port statistic type.
  52300  * Parameters:
  52301  *      unit - (IN) Unit number.
  52302  *      port - (IN) GPORT ID
  52303  *      stat - (IN) Type of the counter to retrieve.
  52304  *      val - (OUT) Pointer to a counter value.
  52305  * Returns:
  52306  *      BCM_E_XXX
  52307  * Notes:
  52308  */
  52309 int
  52310 bcm_esw_port_stat_get(int unit, bcm_gport_t port, bcm_port_stat_t stat,
  52311                       uint64 *val)
  52312 {
  52313     int rv = BCM_E_UNAVAIL;
  52314 
  52315     rv = _bcm_esw_port_stat_get(unit, 0, port, stat, val);
  52316 
  52317     return rv;
  52318 }
  52319 
  52320 
  52321 /*
  52322  * Function:
  52323  *      bcm_esw_port_stat_sync_get
  52324  * Purpose:
  52325  *      Get 64-bit counter value for specified port statistic type.
  52326  *      sw accumulated counters synced with hw count.
  52327  * Parameters:
  52328  *      unit - (IN) Unit number.
  52329  *      port - (IN) GPORT ID
  52330  *      stat - (IN) Type of the counter to retrieve.
  52331  *      val - (OUT) Pointer to a counter value.
  52332  * Returns:
  52333  *      BCM_E_XXX
  52334  * Notes:
  52335  */
  52336 int
  52337 bcm_esw_port_stat_sync_get(int unit, bcm_gport_t port, bcm_port_stat_t stat,
  52338                       uint64 *val)
  52339 {
  52340     int rv = BCM_E_UNAVAIL;
  52341 
  52342     rv = _bcm_esw_port_stat_get(unit, 1, port, stat, val);
  52343 
  52344     return rv;
  52345 }
  52346 
  52347 /*
  52348  * Function:
  52349  *      _bcm_esw_port_stat_get32
  52350  * Purpose:
  52351  *      Get lower 32-bit counter value for specified port statistic
  52352  *      type.
  52353  *      if sync_mode is set, sync the sw accumulated count
  52354  *      with hw count value first, else return sw count.
  52355  * Parameters:
  52356  *      unit        - (IN) Unit number.
  52357  *      sync_mode   - (IN) hwcount is to be synced to sw count
  52358  *      port        - (IN) GPORT ID
  52359  *      stat        - (IN) Type of the counter to retrieve.
  52360  *      val         - (OUT) Pointer to a counter value.
  52361  * Returns:
  52362  *      BCM_E_XXX
  52363  * Notes:
  52364  */
  52365 int
  52366 _bcm_esw_port_stat_get32(int unit, int sync_mode, bcm_gport_t port,
  52367                          bcm_port_stat_t stat, uint32 *val)
  52368 {
  52369 #if defined(BCM_TRIUMPH2_SUPPORT)
  52370 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52371   uint32           counter_indexes=0;
  52372   bcm_stat_value_t counter_values={0};
  52373 #endif
  52374 
  52375   /* Make sure port module is initialized. */
  52376   PORT_INIT(unit);
  52377 
  52378 #if defined(BCM_PREEMPTION_SUPPORT)
  52379   if (soc_feature(unit, soc_feature_preemption_cnt)) {
  52380     bcm_port_t local_port;
  52381     BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port));
  52382     return bcmi_esw_preemption_counter_get32(unit, sync_mode, local_port,
  52383                                              stat, val);
  52384   }
  52385 #endif /* BCM_PREEMPTION_SUPPORT */
  52386 
  52387   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  52388     BCM_IF_ERROR_RETURN
  52389         (_bcm_esw_port_stat_param_valid(unit, port));
  52390     return _bcm_esw_flex_stat_get32(unit, sync_mode,
  52391                                     _bcmFlexStatTypeGport, port,
  52392                                     _bcm_esw_port_stat_to_flex_stat(stat), val);
  52393   }
  52394 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52395   BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_counter_get(unit, sync_mode,
  52396                                                      port, stat, 1,
  52397                                                      &counter_indexes,
  52398                                                      &counter_values));
  52399   if ((stat == bcmPortStatIngressPackets) ||
  52400       (stat == bcmPortStatEgressPackets)) {
  52401       *val = counter_values.packets;
  52402   } else {
  52403       /* Ignoring Hi bytes value */
  52404       *val = COMPILER_64_LO(counter_values.bytes);
  52405   }
  52406   return BCM_E_NONE;
  52407 #else
  52408     return BCM_E_UNAVAIL;
  52409 #endif
  52410 #else
  52411     return BCM_E_UNAVAIL;
  52412 #endif
  52413 }
  52414 
  52415 
  52416 /*
  52417  * Function:
  52418  *      bcm_esw_port_stat_get32
  52419  * Purpose:
  52420  *      Get lower 32-bit counter value for specified port statistic
  52421  *      type.
  52422  * Parameters:
  52423  *      unit - (IN) Unit number.
  52424  *      port - (IN) GPORT ID
  52425  *      stat - (IN) Type of the counter to retrieve.
  52426  *      val - (OUT) Pointer to a counter value.
  52427  * Returns:
  52428  *      BCM_E_XXX
  52429  * Notes:
  52430  */
  52431 int
  52432 bcm_esw_port_stat_get32(int unit, bcm_gport_t port,
  52433                         bcm_port_stat_t stat, uint32 *val)
  52434 {
  52435     int rv = BCM_E_UNAVAIL;
  52436 
  52437     rv = _bcm_esw_port_stat_get32(unit, 0, port, stat, val);
  52438 
  52439     return rv;
  52440 
  52441 }
  52442 
  52443 
  52444 /*
  52445  * Function:
  52446  *      bcm_esw_port_stat_sync_get32
  52447  * Purpose:
  52448  *      Get lower 32-bit counter value for specified port statistic
  52449  *      type. sw accumulated counters synced with hw count.
  52450  * Parameters:
  52451  *      unit - (IN) Unit number.
  52452  *      port - (IN) GPORT ID
  52453  *      stat - (IN) Type of the counter to retrieve.
  52454  *      val - (OUT) Pointer to a counter value.
  52455  * Returns:
  52456  *      BCM_E_XXX
  52457  * Notes:
  52458  */
  52459 int
  52460 bcm_esw_port_stat_sync_get32(int unit, bcm_gport_t port,
  52461                              bcm_port_stat_t stat, uint32 *val)
  52462 {
  52463     int rv = BCM_E_UNAVAIL;
  52464 
  52465     rv = _bcm_esw_port_stat_get32(unit, 1, port, stat, val);
  52466 
  52467     return rv;
  52468 }
  52469 
  52470 /*
  52471  * Function:
  52472  *      bcm_esw_port_stat_set
  52473  * Purpose:
  52474  *      Set 64-bit counter value for specified port statistic type.
  52475  * Parameters:
  52476  *      unit - (IN) Unit number.
  52477  *      port - (IN) GPORT ID
  52478  *      stat - (IN) Type of the counter to retrieve.
  52479  *      val - (IN) New counter value.
  52480  * Returns:
  52481  *      BCM_E_XXX
  52482  * Notes:
  52483  */
  52484 int
  52485 bcm_esw_port_stat_set(int unit, bcm_gport_t port, bcm_port_stat_t stat,
  52486                       uint64 val)
  52487 {
  52488 #if defined(BCM_TRIUMPH2_SUPPORT)
  52489 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52490   uint32           counter_indexes=0;
  52491   bcm_stat_value_t counter_values={0};
  52492 #endif
  52493 
  52494   /* Make sure port module is initialized. */
  52495   PORT_INIT(unit);
  52496 
  52497 #if defined(BCM_PREEMPTION_SUPPORT)
  52498   if (soc_feature(unit, soc_feature_preemption_cnt)) {
  52499     bcm_port_t local_port;
  52500     BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port));
  52501     return bcmi_esw_preemption_counter_set(unit, local_port,
  52502                                            stat, val);
  52503   }
  52504 #endif /* BCM_PREEMPTION_SUPPORT */
  52505 
  52506   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  52507     BCM_IF_ERROR_RETURN
  52508         (_bcm_esw_port_stat_param_valid(unit, port));
  52509     return _bcm_esw_flex_stat_set(unit, _bcmFlexStatTypeGport, port,
  52510                            _bcm_esw_port_stat_to_flex_stat(stat), val);
  52511   }
  52512 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52513   if ((stat == bcmPortStatIngressPackets) ||
  52514       (stat == bcmPortStatEgressPackets)) {
  52515       counter_values.packets = COMPILER_64_LO(val);
  52516   } else {
  52517       COMPILER_64_SET(counter_values.bytes,
  52518                       COMPILER_64_HI(val),
  52519                       COMPILER_64_LO(val));
  52520   }
  52521   BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_set(
  52522                         unit,port,stat, 1, &counter_indexes, &counter_values));
  52523   return BCM_E_NONE;
  52524 #else
  52525     return BCM_E_UNAVAIL;
  52526 #endif
  52527 #else
  52528     return BCM_E_UNAVAIL;
  52529 #endif
  52530 }
  52531 
  52532 /*
  52533  * Function:
  52534  *      bcm_esw_port_stat_set32
  52535  * Purpose:
  52536  *      Set lower 32-bit counter value for specified port statistic
  52537  *      type.
  52538  * Parameters:
  52539  *      unit - (IN) Unit number.
  52540  *      port - (IN) GPORT ID
  52541  *      stat - (IN) Type of the counter to retrieve.
  52542  *      val - (IN) New counter value.
  52543  * Returns:
  52544  *      BCM_E_XXX
  52545  * Notes:
  52546  */
  52547 int
  52548 bcm_esw_port_stat_set32(int unit, bcm_gport_t port,
  52549                         bcm_port_stat_t stat, uint32 val)
  52550 {
  52551 #if defined(BCM_TRIUMPH2_SUPPORT)
  52552 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52553   uint32           counter_indexes=0;
  52554   bcm_stat_value_t counter_values={0};
  52555 #endif
  52556 
  52557   /* Make sure port module is initialized. */
  52558   PORT_INIT(unit);
  52559 
  52560 #if defined(BCM_PREEMPTION_SUPPORT)
  52561   if (soc_feature(unit, soc_feature_preemption_cnt)) {
  52562     bcm_port_t local_port;
  52563     BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port));
  52564     return bcmi_esw_preemption_counter_set32(unit, local_port,
  52565                                              stat, val);
  52566   }
  52567 #endif /* BCM_PREEMPTION_SUPPORT */
  52568 
  52569 
  52570   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  52571     BCM_IF_ERROR_RETURN
  52572         (_bcm_esw_port_stat_param_valid(unit, port));
  52573     return _bcm_esw_flex_stat_set32(unit, _bcmFlexStatTypeGport, port,
  52574                            _bcm_esw_port_stat_to_flex_stat(stat), val);
  52575   }
  52576 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52577   if ((stat == bcmPortStatIngressPackets) ||
  52578       (stat == bcmPortStatEgressPackets)) {
  52579       counter_values.packets = val;
  52580   } else {
  52581       /* Ignoring high value */
  52582       COMPILER_64_SET(counter_values.bytes,0,val);
  52583   }
  52584   BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_set(
  52585                         unit,port,stat, 1, &counter_indexes, &counter_values));
  52586   return BCM_E_NONE;
  52587 #else
  52588     return BCM_E_UNAVAIL;
  52589 #endif
  52590 #else
  52591     return BCM_E_UNAVAIL;
  52592 #endif
  52593 }
  52594 
  52595 /*
  52596  * Function:
  52597  *      bcm_esw_port_stat_multi_get
  52598  * Purpose:
  52599  *      Get 64-bit counter value for multiple port statistic types.
  52600  * Parameters:
  52601  *      unit - (IN) Unit number.
  52602  *      port - (IN) GPORT ID
  52603  *      nstat - (IN) Number of elements in stat array
  52604  *      stat_arr - (IN) Collected statistics descriptors array
  52605  *      value_arr - (OUT) Collected counters values
  52606  * Returns:
  52607  *      BCM_E_XXX
  52608  * Notes:
  52609  */
  52610 int
  52611 bcm_esw_port_stat_multi_get(int unit, bcm_gport_t port, int nstat,
  52612                             bcm_port_stat_t *stat_arr,
  52613                             uint64 *value_arr)
  52614 {
  52615 #if defined(BCM_TRIUMPH2_SUPPORT)
  52616     _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */
  52617     int idx;
  52618 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52619   uint32           counter_indexes=0;
  52620   bcm_stat_value_t counter_values={0};
  52621 #endif
  52622 
  52623   /* Make sure port module is initialized. */
  52624   PORT_INIT(unit);
  52625 
  52626 #if defined(BCM_PREEMPTION_SUPPORT)
  52627   if (soc_feature(unit, soc_feature_preemption_cnt)) {
  52628     bcm_port_t local_port;
  52629     BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port));
  52630     return bcmi_esw_preemption_counter_multi_get(unit, 0, local_port, nstat,
  52631                                                  stat_arr, value_arr);
  52632   }
  52633 #endif /* BCM_PREEMPTION_SUPPORT */
  52634 
  52635   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  52636     BCM_IF_ERROR_RETURN
  52637         (_bcm_esw_port_stat_param_valid(unit, port));
  52638     BCM_IF_ERROR_RETURN
  52639         (_bcm_port_stat_array_convert(unit, nstat, stat_arr, fs_arr));
  52640     BCM_PORT_VALUE_ARRAY_VALID(unit, nstat, value_arr);
  52641 
  52642     return _bcm_esw_flex_stat_multi_get(unit, _bcmFlexStatTypeGport, port,
  52643                                         nstat, fs_arr, value_arr);
  52644   }
  52645 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52646   for (idx=0;idx < nstat ; idx ++) {
  52647       BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_get(
  52648                              unit, port, stat_arr[idx],
  52649                              1, &counter_indexes, &counter_values));
  52650       if ((stat_arr[idx] == bcmPortStatIngressPackets) ||
  52651           (stat_arr[idx] == bcmPortStatEgressPackets)) {
  52652           COMPILER_64_SET(value_arr[idx],
  52653                           COMPILER_64_HI(counter_values.packets64),
  52654                           COMPILER_64_LO(counter_values.packets64));
  52655       } else {
  52656           COMPILER_64_SET(value_arr[idx],
  52657                           COMPILER_64_HI(counter_values.bytes),
  52658                           COMPILER_64_LO(counter_values.bytes));
  52659       }
  52660   }
  52661   return BCM_E_NONE;
  52662 #else
  52663     return BCM_E_UNAVAIL;
  52664 #endif
  52665 #else
  52666     return BCM_E_UNAVAIL;
  52667 #endif
  52668 }
  52669 
  52670 /*
  52671  * Function:
  52672  *      bcm_esw_port_stat_multi_get32
  52673  * Purpose:
  52674  *      Get lower 32-bit counter value for multiple port statistic
  52675  *      types.
  52676  * Parameters:
  52677  *      unit - (IN) Unit number.
  52678  *      port - (IN) GPORT ID
  52679  *      nstat - (IN) Number of elements in stat array
  52680  *      stat_arr - (IN) Collected statistics descriptors array
  52681  *      value_arr - (OUT) Collected counters values
  52682  * Returns:
  52683  *      BCM_E_XXX
  52684  * Notes:
  52685  */
  52686 int
  52687 bcm_esw_port_stat_multi_get32(int unit, bcm_gport_t port, int nstat,
  52688                               bcm_port_stat_t *stat_arr,
  52689                               uint32 *value_arr)
  52690 {
  52691 #if defined(BCM_TRIUMPH2_SUPPORT)
  52692     _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */
  52693     int idx;
  52694 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52695   uint32           counter_indexes=0;
  52696   bcm_stat_value_t counter_values={0};
  52697 #endif
  52698 
  52699   /* Make sure port module is initialized. */
  52700   PORT_INIT(unit);
  52701 
  52702 #if defined(BCM_PREEMPTION_SUPPORT)
  52703   if (soc_feature(unit, soc_feature_preemption_cnt)) {
  52704     bcm_port_t local_port;
  52705     BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port));
  52706     return bcmi_esw_preemption_counter_multi_get32(unit, 0, local_port, nstat,
  52707                                                    stat_arr, value_arr);
  52708   }
  52709 #endif /* BCM_PREEMPTION_SUPPORT */
  52710 
  52711 
  52712   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  52713     BCM_IF_ERROR_RETURN
  52714         (_bcm_esw_port_stat_param_valid(unit, port));
  52715     BCM_IF_ERROR_RETURN
  52716         (_bcm_port_stat_array_convert(unit, nstat, stat_arr, fs_arr));
  52717     BCM_PORT_VALUE_ARRAY_VALID(unit, nstat, value_arr);
  52718 
  52719     return _bcm_esw_flex_stat_multi_get32(unit, _bcmFlexStatTypeGport, port,
  52720                                           nstat, fs_arr, value_arr);
  52721   }
  52722 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52723   for (idx=0;idx < nstat ; idx ++) {
  52724       BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_get(
  52725                              unit, port, stat_arr[idx],
  52726                              1, &counter_indexes, &counter_values));
  52727       if ((stat_arr[idx] == bcmPortStatIngressPackets) ||
  52728           (stat_arr[idx] == bcmPortStatEgressPackets)) {
  52729           value_arr[idx] = counter_values.packets;
  52730       } else {
  52731           value_arr[idx] = COMPILER_64_LO(counter_values.bytes);
  52732       }
  52733   }
  52734   return BCM_E_NONE;
  52735 #else
  52736     return BCM_E_UNAVAIL;
  52737 #endif
  52738 #else
  52739     return BCM_E_UNAVAIL;
  52740 #endif
  52741 }
  52742 
  52743 /*
  52744  * Function:
  52745  *      bcm_esw_port_stat_multi_set
  52746  * Purpose:
  52747  *      Set 64-bit counter value for multiple port statistic types.
  52748  * Parameters:
  52749  *      unit - (IN) Unit number.
  52750  *      port - (IN) GPORT ID
  52751  *      nstat - (IN) Number of elements in stat array
  52752  *      stat_arr - (IN) New statistics descriptors array
  52753  *      value_arr - (IN) New counters values
  52754  * Returns:
  52755  *      BCM_E_XXX
  52756  * Notes:
  52757  */
  52758 int
  52759 bcm_esw_port_stat_multi_set(int unit, bcm_gport_t port, int nstat,
  52760                             bcm_port_stat_t *stat_arr,
  52761                             uint64 *value_arr)
  52762 {
  52763 #if defined(BCM_TRIUMPH2_SUPPORT)
  52764     _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */
  52765     int idx;
  52766 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52767   uint32           counter_indexes=0;
  52768   bcm_stat_value_t counter_values={0};
  52769 #endif
  52770 
  52771   /* Make sure port module is initialized. */
  52772   PORT_INIT(unit);
  52773 
  52774 #if defined(BCM_PREEMPTION_SUPPORT)
  52775   if (soc_feature(unit, soc_feature_preemption_cnt)) {
  52776     bcm_port_t local_port;
  52777     BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port));
  52778     return bcmi_esw_preemption_counter_multi_set(unit, local_port, nstat,
  52779                                                  stat_arr, value_arr);
  52780   }
  52781 #endif /* BCM_PREEMPTION_SUPPORT */
  52782 
  52783   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  52784     BCM_IF_ERROR_RETURN
  52785         (_bcm_esw_port_stat_param_valid(unit, port));
  52786     BCM_IF_ERROR_RETURN
  52787         (_bcm_port_stat_array_convert(unit, nstat, stat_arr, fs_arr));
  52788     BCM_PORT_VALUE_ARRAY_VALID(unit, nstat, value_arr);
  52789 
  52790     return _bcm_esw_flex_stat_multi_set(unit, _bcmFlexStatTypeGport, port,
  52791                                           nstat, fs_arr, value_arr);
  52792   }
  52793 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52794   for (idx=0;idx < nstat ; idx ++) {
  52795       if ((stat_arr[idx] == bcmPortStatIngressPackets) ||
  52796           (stat_arr[idx] == bcmPortStatEgressPackets)) {
  52797           counter_values.packets = COMPILER_64_LO(value_arr[idx]);
  52798       } else {
  52799           COMPILER_64_SET(counter_values.bytes,
  52800                           COMPILER_64_HI(value_arr[idx]),
  52801                           COMPILER_64_LO(value_arr[idx]));
  52802       }
  52803       BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_set(
  52804                              unit, port, stat_arr[idx],
  52805                              1, &counter_indexes, &counter_values));
  52806   }
  52807   return BCM_E_NONE;
  52808 #else
  52809     return BCM_E_UNAVAIL;
  52810 #endif
  52811 #else
  52812     return BCM_E_UNAVAIL;
  52813 #endif
  52814 }
  52815 
  52816 /*
  52817  * Function:
  52818  *      bcm_esw_port_stat_multi_set32
  52819  * Purpose:
  52820  *      Set lower 32-bit counter value for multiple port statistic
  52821  *      types.
  52822  * Parameters:
  52823  *      unit - (IN) Unit number.
  52824  *      port - (IN) GPORT ID
  52825  *      nstat - (IN) Number of elements in stat array
  52826  *      stat_arr - (IN) New statistics descriptors array
  52827  *      value_arr - (IN) New counters values
  52828  * Returns:
  52829  *      BCM_E_XXX
  52830  * Notes:
  52831  */
  52832 int
  52833 bcm_esw_port_stat_multi_set32(int unit, bcm_gport_t port, int nstat,
  52834                               bcm_port_stat_t *stat_arr,
  52835                               uint32 *value_arr)
  52836 {
  52837 #if defined(BCM_TRIUMPH2_SUPPORT)
  52838     _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */
  52839     int idx;
  52840 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52841   uint32           counter_indexes=0;
  52842   bcm_stat_value_t counter_values={0};
  52843 #endif
  52844 
  52845   /* Make sure port module is initialized. */
  52846   PORT_INIT(unit);
  52847 
  52848 #if defined(BCM_PREEMPTION_SUPPORT)
  52849   if (soc_feature(unit, soc_feature_preemption_cnt)) {
  52850     bcm_port_t local_port;
  52851     BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port));
  52852     return bcmi_esw_preemption_counter_multi_set32(unit, local_port, nstat,
  52853                                                    stat_arr, value_arr);
  52854   }
  52855 #endif /* BCM_PREEMPTION_SUPPORT */
  52856 
  52857   if (!soc_feature(unit,soc_feature_advanced_flex_counter)) {
  52858     BCM_IF_ERROR_RETURN
  52859         (_bcm_esw_port_stat_param_valid(unit, port));
  52860     BCM_IF_ERROR_RETURN
  52861         (_bcm_port_stat_array_convert(unit, nstat, stat_arr, fs_arr));
  52862     BCM_PORT_VALUE_ARRAY_VALID(unit, nstat, value_arr);
  52863 
  52864     return _bcm_esw_flex_stat_multi_set32(unit, _bcmFlexStatTypeGport, port,
  52865                                           nstat, fs_arr, value_arr);
  52866   }
  52867 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  52868   for (idx=0;idx < nstat ; idx ++) {
  52869       if ((stat_arr[idx] == bcmPortStatIngressPackets) ||
  52870           (stat_arr[idx] == bcmPortStatEgressPackets)) {
  52871           counter_values.packets = value_arr[idx];
  52872       } else {
  52873           COMPILER_64_SET(counter_values.bytes,0,value_arr[idx]);
  52874       }
  52875       BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_set(
  52876                              unit, port, stat_arr[idx],
  52877                              1, &counter_indexes, &counter_values));
  52878   }
  52879   return BCM_E_NONE;
  52880 #else
  52881     return BCM_E_UNAVAIL;
  52882 #endif
  52883 #else
  52884     return BCM_E_UNAVAIL;
  52885 #endif
  52886 }
  52887 
  52888 /*
  52889  * Function    : _bcm_gport_dest_t_init
  52890  * Description : Initialize gport_dest structure
  52891  * Parameters  : (IN/OUT)  gport_dest - Structure to initialize
  52892  * Returns     : None
  52893  */
  52894 
  52895 void
  52896 _bcm_gport_dest_t_init(_bcm_gport_dest_t *gport_dest)
  52897 {
  52898     sal_memset(gport_dest, 0, sizeof (_bcm_gport_dest_t));
  52899 }
  52900 
  52901 
  52902 /*
  52903  * Function    : _bcm_esw_gport_construct
  52904  * Description : Internal function to construct a gport from
  52905  *                given parameters
  52906  * Parameters  : (IN)  unit       - BCM device number
  52907  *               (IN)  gport_dest - Structure that contains destination
  52908  *                                   to encode into a gport
  52909  *               (OUT) gport      - Global port identifier
  52910  * Returns     : BCM_E_XXX
  52911  * Notes       : The modid and port are translated from the
  52912  *               local modid/port space to application space
  52913  */
  52914 int
  52915 _bcm_esw_gport_construct(int unit, _bcm_gport_dest_t *gport_dest, bcm_gport_t *gport)
  52916 {
  52917 
  52918     bcm_gport_t     l_gport = 0;
  52919     bcm_module_t    mod_out;
  52920     bcm_port_t      port_out;
  52921 
  52922     if ((NULL == gport_dest) || (NULL == gport) ){
  52923         return BCM_E_PARAM;
  52924     }
  52925 
  52926     switch (gport_dest->gport_type) {
  52927         case _SHR_GPORT_TYPE_TRUNK:
  52928             SOC_GPORT_TRUNK_SET(l_gport, gport_dest->tgid);
  52929             break;
  52930         case _SHR_GPORT_TYPE_LOCAL_CPU:
  52931             l_gport = BCM_GPORT_LOCAL_CPU;
  52932             break;
  52933         case _SHR_GPORT_TYPE_BLACK_HOLE:
  52934             l_gport = BCM_GPORT_BLACK_HOLE;
  52935             break;
  52936         case _SHR_GPORT_TYPE_LOCAL:
  52937             SOC_GPORT_LOCAL_SET(l_gport, gport_dest->port);
  52938             break;
  52939         case _SHR_GPORT_TYPE_SUBPORT_GROUP:
  52940             SOC_GPORT_SUBPORT_GROUP_SET(l_gport, gport_dest->subport_id);
  52941             break;
  52942         case _SHR_GPORT_TYPE_MPLS_PORT:
  52943             BCM_GPORT_MPLS_PORT_ID_SET(l_gport, gport_dest->mpls_id);
  52944             break;
  52945         case _SHR_GPORT_TYPE_MIM_PORT:
  52946             BCM_GPORT_MIM_PORT_ID_SET(l_gport, gport_dest->mim_id);
  52947             break;
  52948         case _SHR_GPORT_TYPE_WLAN_PORT:
  52949             BCM_GPORT_WLAN_PORT_ID_SET(l_gport, gport_dest->wlan_id);
  52950             break;
  52951         case _SHR_GPORT_TYPE_TRILL_PORT:
  52952             BCM_GPORT_TRILL_PORT_ID_SET(l_gport, gport_dest->trill_id);
  52953             break;
  52954         case _SHR_GPORT_TYPE_NIV_PORT:
  52955             BCM_GPORT_NIV_PORT_ID_SET(l_gport, gport_dest->niv_id);
  52956             break;
  52957         case _SHR_GPORT_TYPE_L2GRE_PORT:
  52958             BCM_GPORT_L2GRE_PORT_ID_SET(l_gport, gport_dest->l2gre_id);
  52959             break;
  52960         case _SHR_GPORT_TYPE_VXLAN_PORT:
  52961             BCM_GPORT_VXLAN_PORT_ID_SET(l_gport, gport_dest->vxlan_id);
  52962             break;
  52963         case _SHR_GPORT_TYPE_FLOW_PORT:
  52964             BCM_GPORT_FLOW_PORT_ID_SET(l_gport, gport_dest->flow_id);
  52965             break;
  52966         case _SHR_GPORT_TYPE_VLAN_PORT:
  52967             BCM_GPORT_VLAN_PORT_ID_SET(l_gport, gport_dest->vlan_vp_id);
  52968             break;
  52969         case _SHR_GPORT_TYPE_EXTENDER_PORT:
  52970             BCM_GPORT_EXTENDER_PORT_ID_SET(l_gport, gport_dest->extender_id);
  52971             break;
  52972         case _SHR_GPORT_TYPE_DEVPORT:
  52973             BCM_GPORT_DEVPORT_SET(l_gport, unit, gport_dest->port);
  52974             break;
  52975         case _SHR_GPORT_TYPE_MODPORT:
  52976             BCM_IF_ERROR_RETURN (
  52977                 _bcm_gport_modport_hw2api_map(unit, gport_dest->modid,
  52978                                               gport_dest->port, &mod_out,
  52979                                               &port_out));
  52980             SOC_GPORT_MODPORT_SET(l_gport, mod_out, port_out);
  52981             break;
  52982         default:
  52983             return BCM_E_PARAM;
  52984     }
  52985 
  52986     *gport = l_gport;
  52987     return BCM_E_NONE;
  52988 }
  52989 
  52990 /*
  52991  * Function    : _bcm_esw_gport_resolve
  52992  * Description : Internal function to get modid, port, and trunk_id
  52993  *               from a bcm_gport_t (global port)
  52994  * Parameters  : (IN)  unit      - BCM device number
  52995  *               (IN)  gport     - Global port identifier
  52996  *               (OUT) modid     - Module ID
  52997  *               (OUT) port      - Port number
  52998  *               (OUT) trunk_id  - Trunk ID
  52999  *               (OUT) id        - HW ID
  53000  * Returns     : BCM_E_XXX
  53001  * Notes       : The modid and port are translated from the
  53002  *               application space to local modid/port space if applicable,
  53003  *               on units without modid (Fabric) modid will be -1 and port
  53004  *               will be a local physical port.
  53005  */
  53006 int
  53007 _bcm_esw_gport_resolve(int unit, bcm_gport_t gport,
  53008                        bcm_module_t *modid, bcm_port_t *port,
  53009                        bcm_trunk_t *trunk_id, int *id)
  53010 {
  53011     int             local_id, rv = BCM_E_NONE;
  53012     bcm_module_t    mod_in, local_modid;
  53013     bcm_port_t      port_in, local_port;
  53014     bcm_trunk_t     local_tgid;
  53015 #ifdef BCM_KATANA_SUPPORT
  53016     int extended_queue_id = 0;
  53017 #endif
  53018 
  53019     local_modid = -1;
  53020     local_port = -1;
  53021     local_id = -1;
  53022     local_tgid = BCM_TRUNK_INVALID;
  53023 
  53024     if (BCM_GPORT_IS_TRUNK(gport)) {
  53025         local_tgid = SOC_GPORT_TRUNK_GET(gport);
  53026     } else if (BCM_GPORT_IS_LOCAL_CPU(gport)) {
  53027         rv = bcm_esw_stk_my_modid_get(unit, &local_modid);
  53028         if (BCM_FAILURE(rv) && !SOC_IS_XGS_FABRIC(unit)) {
  53029             return rv;
  53030         }
  53031         local_port = CMIC_PORT(unit);
  53032     } else if (BCM_GPORT_IS_LOCAL(gport)) {
  53033         BCM_IF_ERROR_RETURN
  53034             (bcm_esw_stk_my_modid_get(unit, &local_modid));
  53035         local_port = SOC_GPORT_LOCAL_GET(gport);
  53036         if (soc_feature(unit, soc_feature_sysport_remap)) {
  53037             BCM_XLATE_SYSPORT_P2S(unit, &local_port);
  53038         }
  53039         if (!SOC_PORT_ADDRESSABLE(unit, local_port)) {
  53040             return BCM_E_PORT;
  53041         }
  53042     } else if (BCM_GPORT_IS_DEVPORT(gport)) {
  53043         rv = bcm_esw_stk_my_modid_get(unit, &local_modid);
  53044         if (BCM_FAILURE(rv)) {
  53045             if (!SOC_IS_XGS_FABRIC(unit)) {
  53046                 return rv;
  53047             }
  53048         }
  53049         if (unit != SOC_GPORT_DEVPORT_DEVID_GET(gport)) {
  53050             return BCM_E_PORT;
  53051         }
  53052         local_port = SOC_GPORT_DEVPORT_PORT_GET(gport);
  53053 
  53054         if (!SOC_PORT_ADDRESSABLE(unit, local_port)) {
  53055             return BCM_E_PORT;
  53056         }
  53057     } else if (BCM_GPORT_IS_MODPORT(gport)) {
  53058         mod_in = SOC_GPORT_MODPORT_MODID_GET(gport);
  53059         port_in = SOC_GPORT_MODPORT_PORT_GET(gport);
  53060 
  53061         if (NUM_MODID(unit) > 1) {
  53062 #if defined(BCM_TOMAHAWK_SUPPORT)
  53063             /* Call asymmetric dual modid unmapping function */
  53064             if (soc_feature(unit, soc_feature_asymmetric_dual_modid)) {
  53065                 BCM_IF_ERROR_RETURN (
  53066                     _bcm_esw_stk_asymmetric_dual_modmap_map(unit,
  53067                                 BCM_STK_MODMAP_GET, &mod_in, &port_in));
  53068             } else
  53069 #endif /* BCM_TOMAHAWK_SUPPORT */
  53070             if ((NUM_MODID(unit) > 1) && (port_in > SOC_INFO(unit).modport_max)) {
  53071                 mod_in = mod_in + 1;
  53072                 port_in = port_in - (SOC_INFO(unit).modport_max + 1);
  53073             }
  53074         }
  53075         PORT_DUALMODID_VALID(unit, port_in);
  53076         rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET,
  53077                                     mod_in, port_in, &local_modid, &local_port);
  53078 
  53079         if (!SOC_MODID_ADDRESSABLE(unit, local_modid)) {
  53080             return BCM_E_BADID;
  53081         }
  53082         if (!SOC_PORT_ADDRESSABLE(unit, local_port)) {
  53083             return BCM_E_PORT;
  53084         }
  53085     } else if (BCM_GPORT_IS_PROXY(gport)) {
  53086         mod_in = BCM_GPORT_PROXY_MODID_GET(gport);
  53087         port_in = BCM_GPORT_PROXY_PORT_GET(gport);
  53088         PORT_DUALMODID_VALID(unit, port_in);
  53089         rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET,
  53090                                     mod_in, port_in, &local_modid, &local_port);
  53091 
  53092         if (!SOC_MODID_ADDRESSABLE(unit, local_modid)) {
  53093             return BCM_E_BADID;
  53094         }
  53095         if (!SOC_PORT_ADDRESSABLE(unit, local_port)) {
  53096             return BCM_E_PORT;
  53097         }
  53098     }
  53099 #if defined(BCM_TRIUMPH_SUPPORT) && defined(BCM_MPLS_SUPPORT) && \
  53100     defined(INCLUDE_L3)
  53101     else if (BCM_GPORT_IS_MPLS_PORT(gport)) {
  53102         if (SOC_IS_TR_VL(unit)) {
  53103             rv = _bcm_tr_mpls_port_resolve(unit, gport, &local_modid,
  53104                                            &local_port, &local_tgid,
  53105                                            &local_id);
  53106         }
  53107     }
  53108 #endif
  53109 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \
  53110      && defined(INCLUDE_L3))
  53111     else if (BCM_GPORT_IS_MIM_PORT(gport)) {
  53112         if (soc_feature(unit, soc_feature_mim)) {
  53113             rv = _bcm_tr2_mim_port_resolve(unit, gport, &local_modid,
  53114                                           &local_port, &local_tgid,
  53115                                           &local_id);
  53116         }
  53117     } else if (BCM_GPORT_IS_WLAN_PORT(gport)) {
  53118         if (soc_feature(unit, soc_feature_wlan)) {
  53119 #if defined(BCM_TRIUMPH3_SUPPORT)
  53120             if (SOC_IS_TRIUMPH3(unit)) {
  53121                 rv = _bcm_tr3_wlan_port_resolve(unit, gport, &local_modid,
  53122                                                &local_port, &local_tgid,
  53123                                                &local_id);
  53124             } else
  53125 #endif /* BCM_TRIUMPH3_SUPPORT */
  53126             {
  53127                 rv = _bcm_tr2_wlan_port_resolve(unit, gport, &local_modid,
  53128                                                &local_port, &local_tgid,
  53129                                                &local_id);
  53130             }
  53131         }
  53132     }
  53133 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
  53134 #if defined (BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
  53135     else if (BCM_GPORT_IS_L2GRE_PORT(gport)) {
  53136         if (soc_feature(unit, soc_feature_l2gre)) {
  53137             rv = _bcm_tr3_l2gre_port_resolve(unit, gport, -1, &local_modid,
  53138                                           &local_port, &local_tgid,
  53139                                           &local_id);
  53140         }
  53141     }
  53142 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */
  53143 #if defined (BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3)
  53144     else if (BCM_GPORT_IS_VXLAN_PORT(gport)) {
  53145         if (soc_feature(unit, soc_feature_vxlan)) {
  53146             rv = _bcm_td2_vxlan_port_resolve(unit, gport, -1, &local_modid,
  53147                                           &local_port, &local_tgid,
  53148                                           &local_id);
  53149         }
  53150     }
  53151 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */
  53152 #if defined (BCM_GREYHOUND2_SUPPORT) && defined(INCLUDE_L3)
  53153     else if (BCM_GPORT_IS_VXLAN_PORT(gport)) {
  53154         if (soc_feature(unit, soc_feature_vxlan_lite)) {
  53155             rv = bcmi_gh2_vxlan_port_resolve(unit, gport, -1, &local_modid,
  53156                                              &local_port, &local_tgid,
  53157                                              &local_id);
  53158         }
  53159     }
  53160 #endif /* BCM_GREYHOUND2_SUPPORT && INCLUDE_L3 */
  53161 #if defined (BCM_TRIDENT3_SUPPORT) && defined(INCLUDE_L3)
  53162     else if (BCM_GPORT_IS_FLOW_PORT(gport)) {
  53163         if (soc_feature(unit, soc_feature_flex_flow)) {
  53164             rv = _bcm_td3_flow_port_resolve(unit, gport, -1, &local_modid,
  53165                                           &local_port, &local_tgid,
  53166                                           &local_id);
  53167         }
  53168     }
  53169 #endif /* BCM_TRIDENT3_SUPPORT && INCLUDE_L3 */
  53170 #if defined (BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
  53171     else if (BCM_GPORT_IS_TRILL_PORT(gport)) {
  53172         if (soc_feature(unit, soc_feature_trill)) {
  53173             rv = _bcm_td_trill_port_resolve(unit, gport, -1, &local_modid,
  53174                                           &local_port, &local_tgid,
  53175                                           &local_id);
  53176         }
  53177     }
  53178 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  53179 #if defined (BCM_TRX_SUPPORT) && defined(INCLUDE_L3)
  53180     else if (BCM_GPORT_IS_SUBPORT_GROUP(gport)) {
  53181         if (SOC_IS_TRX(unit)) {
  53182 
  53183 #if defined (BCM_HGPROXY_COE_SUPPORT)
  53184 			if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) {
  53185 				rv = _bcmi_xgs5_subport_group_resolve(unit, gport, &local_modid,
  53186 												   &local_port, &local_tgid,
  53187 												   &local_id);
  53188 			} else
  53189 #endif /* defined (BCM_HGPROXY_COE_SUPPORT) */
  53190 
  53191 #if defined (BCM_KATANA2_SUPPORT)
  53192             if (SOC_IS_KATANA2(unit)) {
  53193                 rv = bcm_kt2_subport_group_resolve(unit, gport, &local_modid,
  53194                                                    &local_port, &local_tgid,
  53195                                                    &local_id);
  53196             } else
  53197 #endif /* defined (BCM_KATANA2_SUPPORT) */
  53198             if (soc_feature(unit, soc_feature_subport_enhanced)) {
  53199 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  53200                 rv = _bcm_tr2_subport_group_resolve(unit, gport, &local_modid,
  53201                                                     &local_port, &local_tgid,
  53202                                                     &local_id);
  53203 #endif /* defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) */
  53204             } else if (soc_feature(unit, soc_feature_subport)) {
  53205                 rv = _bcm_tr_subport_group_resolve(unit, gport, &local_modid,
  53206                                                    &local_port, &local_tgid,
  53207                                                    &local_id);
  53208             }
  53209         }
  53210     } else if (BCM_GPORT_IS_SUBPORT_PORT(gport)) {
  53211         if (SOC_IS_TRX(unit)) {
  53212 
  53213 #if defined (BCM_HGPROXY_COE_SUPPORT)
  53214             if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) {
  53215                 rv = _bcm_xgs5_subport_port_resolve(unit, gport, &local_modid,
  53216                                                    &local_port, &local_tgid, 
  53217                                                    &local_id);
  53218             } else
  53219 #endif /* defined (BCM_HGPROXY_COE_SUPPORT) */
  53220 
  53221 #if defined (BCM_KATANA2_SUPPORT)
  53222             if (SOC_IS_KATANA2(unit)) {
  53223 
  53224                 rv = bcm_kt2_subport_port_resolve(unit, gport, &local_modid,
  53225                                                    &local_port, &local_tgid,
  53226                                                    &local_id);
  53227             } else
  53228 #endif /* defined (BCM_KATANA2_SUPPORT) */
  53229             if (soc_feature(unit, soc_feature_subport_enhanced)) {
  53230 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  53231                 rv = _bcm_tr2_subport_port_resolve(unit, gport, &local_modid,
  53232                                                    &local_port, &local_tgid,
  53233                                                    &local_id);
  53234 #endif /* defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) */
  53235             } else if (soc_feature(unit, soc_feature_subport)) {
  53236                 rv = _bcm_tr_subport_port_resolve(unit, gport, &local_modid,
  53237                                                   &local_port, &local_tgid,
  53238                                                   &local_id);
  53239             }
  53240         }
  53241     }
  53242 #endif /* BCM_TRX_SUPPORT && INCLUDE_L3 */
  53243 #ifdef BCM_TRIUMPH_SUPPORT
  53244     else if (BCM_GPORT_IS_SCHEDULER(gport)) {
  53245 #if defined (BCM_TOMAHAWK3_SUPPORT)
  53246         if (SOC_IS_TOMAHAWK3(unit)) {
  53247             rv = _bcm_th3_cosq_port_resolve(unit, gport, &local_modid,
  53248                                            &local_port, &local_tgid,
  53249                                            &local_id, NULL);
  53250         } else
  53251 #endif /* BCM_TOMAHAWK3_SUPPORT */
  53252 #if defined (BCM_TOMAHAWK_SUPPORT)
  53253         if (SOC_IS_TOMAHAWKX(unit)) {
  53254             rv = _bcm_th_cosq_port_resolve(unit, gport, &local_modid,
  53255                                            &local_port, &local_tgid,
  53256                                            &local_id, NULL);
  53257         } else
  53258 #endif /* BCM_TOMAHAWK_SUPPORT */
  53259 #ifdef BCM_HELIX5_SUPPORT
  53260         if (SOC_IS_HELIX5(unit)) {
  53261             rv = _bcm_hx5_cosq_port_resolve(unit, gport, &local_modid,
  53262                                             &local_port, &local_tgid,
  53263                                             &local_id, NULL);
  53264         } else
  53265 #endif /* BCM_HELIX5_SUPPORT */
  53266 #if defined (BCM_MONTEREY_SUPPORT)
  53267         if (SOC_IS_MONTEREY(unit)) {
  53268             rv = _bcm_mn_cosq_port_resolve(unit, gport, &local_modid,
  53269                                            &local_port, &local_tgid,
  53270                                            &local_id, NULL);
  53271         } else
  53272 #endif
  53273 #ifdef BCM_TRIDENT3_SUPPORT
  53274         if (SOC_IS_TRIDENT3X(unit)) {
  53275             rv = _bcm_td3_cosq_port_resolve(unit, gport, &local_modid,
  53276                                             &local_port, &local_tgid,
  53277                                             &local_id, NULL);
  53278         } else
  53279 #endif /* BCM_TRIDENT3_SUPPORT */
  53280 #if defined (BCM_APACHE_SUPPORT)
  53281         if (SOC_IS_APACHE(unit)) {
  53282             rv = _bcm_ap_cosq_port_resolve(unit, gport, &local_modid,
  53283                                            &local_port, &local_tgid, 
  53284                                            &local_id, NULL);
  53285         } else
  53286 #endif
  53287 #if defined (BCM_TRIDENT2_SUPPORT)
  53288         if (SOC_IS_TD2_TT2(unit)) {
  53289             rv = _bcm_td2_cosq_port_resolve(unit, gport, &local_modid,
  53290                                            &local_port, &local_tgid,
  53291                                            &local_id, NULL);
  53292         } else
  53293 #endif /* BCM_TRIDENT2_SUPPORT */
  53294 #if defined (BCM_TRIDENT_SUPPORT)
  53295         if (SOC_IS_TD_TT(unit)) {
  53296             rv = _bcm_td_cosq_port_resolve(unit, gport, &local_modid,
  53297                                            &local_port, &local_tgid,
  53298                                            &local_id);
  53299         } else
  53300 #endif /* BCM_TRIDENT_SUPPORT */
  53301 #if defined (BCM_TRIUMPH3_SUPPORT)
  53302         if (SOC_IS_TRIUMPH3(unit)) {
  53303             rv = _bcm_tr3_cosq_port_resolve(unit, gport, &local_modid,
  53304                                             &local_port, &local_tgid,
  53305                                             &local_id, NULL);
  53306         } else
  53307 #endif /* BCM_TRIUMPH3_SUPPORT */
  53308 #if defined (BCM_TRIUMPH2_SUPPORT)
  53309         if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  53310             SOC_IS_VALKYRIE2(unit)) {
  53311             rv = _bcm_tr2_cosq_port_resolve(unit, gport, &local_modid,
  53312                                             &local_port, &local_tgid,
  53313                                             &local_id);
  53314         } else
  53315 #endif /* BCM_TRIUMPH2_SUPPORT */
  53316 #if defined (BCM_GREYHOUND2_SUPPORT)
  53317         if (SOC_IS_GREYHOUND2(unit)) {
  53318             rv = bcmi_gh2_cosq_port_resolve(unit, gport, &local_modid,
  53319                                             &local_port, &local_tgid,
  53320                                             &local_id);
  53321         } else
  53322 #endif /* BCM_GREYHOUND2_SUPPORT */
  53323         if (SOC_IS_TR_VL(unit)) {
  53324             rv = _bcm_tr_cosq_port_resolve(unit, gport, &local_modid,
  53325                                            &local_port, &local_tgid,
  53326                                            &local_id);
  53327         }
  53328     }
  53329 #endif /* BCM_TRIUMPH_SUPPORT */
  53330 #ifdef BCM_KATANA_SUPPORT
  53331     else if ((SOC_IS_KATANAX(unit)) &&
  53332              ((BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) ||
  53333               (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport)) ||
  53334               (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)))) {
  53335         if (soc_feature(unit, soc_feature_extended_queueing)) {
  53336 #if defined(BCM_KATANA2_SUPPORT)
  53337             if (SOC_IS_KATANA2(unit)) {
  53338                  rv = _bcm_kt2_cosq_port_resolve(unit, gport, &local_modid,
  53339                                        &local_port, &local_tgid,
  53340                                        &local_id, &extended_queue_id);
  53341             } else
  53342 #endif
  53343             if (SOC_IS_KATANA(unit)){
  53344                  rv = _bcm_kt_cosq_port_resolve(unit, gport, &local_modid,
  53345                                        &local_port, &local_tgid,
  53346                                        &local_id, &extended_queue_id);
  53347             }
  53348             local_tgid = extended_queue_id;
  53349         }
  53350     }
  53351 #endif /* BCM_KATANA_SUPPORT */
  53352 
  53353 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  53354     defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  53355     else if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) ||
  53356              BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) {
  53357 #if defined (BCM_TOMAHAWK3_SUPPORT)
  53358         if (SOC_IS_TOMAHAWK3(unit)) {
  53359             rv = _bcm_th3_cosq_port_resolve(unit, gport, &local_modid,
  53360                                            &local_port, &local_tgid,
  53361                                            &local_id, NULL);
  53362         } else
  53363 #endif /* BCM_TOMAHAWK3_SUPPORT */
  53364 #if defined (BCM_TOMAHAWK_SUPPORT)
  53365         if (SOC_IS_TOMAHAWKX(unit)) {
  53366             rv = _bcm_th_cosq_port_resolve(unit, gport, &local_modid,
  53367                                            &local_port, &local_tgid,
  53368                                            &local_id, NULL);
  53369         } else
  53370 #endif /* BCM_TOMAHAWK_SUPPORT */
  53371 #ifdef BCM_HELIX5_SUPPORT
  53372         if (SOC_IS_HELIX5(unit)) {
  53373             rv = _bcm_hx5_cosq_port_resolve(unit, gport, &local_modid,
  53374                                             &local_port, &local_tgid,
  53375                                             &local_id, NULL);
  53376         } else
  53377 #endif /* BCM_HELIX5_SUPPORT */
  53378 #if defined (BCM_MONTEREY_SUPPORT)
  53379         if (SOC_IS_MONTEREY(unit)) {
  53380             rv = _bcm_mn_cosq_port_resolve(unit, gport, &local_modid,
  53381                                            &local_port, &local_tgid,
  53382                                            &local_id, NULL);
  53383         } else
  53384 #endif
  53385 
  53386 #ifdef BCM_TRIDENT3_SUPPORT
  53387         if (SOC_IS_TRIDENT3X(unit)) {
  53388             rv = _bcm_td3_cosq_port_resolve(unit, gport, &local_modid,
  53389                                             &local_port, &local_tgid,
  53390                                             &local_id, NULL);
  53391         } else
  53392 #endif /* BCM_TRIDENT3_SUPPORT */
  53393 #if defined(BCM_APACHE_SUPPORT)
  53394         if (SOC_IS_APACHE(unit)) {
  53395             rv = _bcm_ap_cosq_port_resolve(unit, gport, &local_modid,
  53396                                            &local_port, &local_tgid,
  53397                                            &local_id, NULL);
  53398         } else
  53399 #endif /* BCM_APACHE_SUPPORT */
  53400 #if defined(BCM_TRIDENT2_SUPPORT)
  53401         if (SOC_IS_TD2_TT2(unit)) {
  53402             rv = _bcm_td2_cosq_port_resolve(unit, gport, &local_modid,
  53403                                            &local_port, &local_tgid,
  53404                                            &local_id, NULL);
  53405         } else
  53406 #endif /* BCM_TRIDENT2_SUPPORT */
  53407 #if defined(BCM_TRIDENT_SUPPORT)
  53408         if (SOC_IS_TD_TT(unit)) {
  53409             rv = _bcm_td_cosq_port_resolve(unit, gport, &local_modid,
  53410                                            &local_port, &local_tgid,
  53411                                            &local_id);
  53412         } else
  53413 #endif /* BCM_TRIDENT_SUPPORT */
  53414 #if defined(BCM_TRIUMPH3_SUPPORT)
  53415         if (SOC_IS_TRIUMPH3(unit)) {
  53416             rv = _bcm_tr3_cosq_port_resolve(unit, gport, &local_modid,
  53417                                            &local_port, &local_tgid,
  53418                                            &local_id, NULL);
  53419         } else
  53420 #endif
  53421 #if defined (BCM_GREYHOUND2_SUPPORT)
  53422         if (SOC_IS_GREYHOUND2(unit)) {
  53423             rv = bcmi_gh2_cosq_port_resolve(unit, gport, &local_modid,
  53424                                             &local_port, &local_tgid,
  53425                                             &local_id);
  53426         } else
  53427 #endif /* BCM_GREYHOUND2_SUPPORT */
  53428         {
  53429             return BCM_E_UNAVAIL;
  53430         }
  53431     }
  53432 #endif /* BCM_TRIDENT_SUPPORT || BCM_TRIUMPH3_SUPPORT */
  53433 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  53434     else if (BCM_GPORT_IS_VLAN_PORT(gport)) {
  53435         if (soc_feature(unit, soc_feature_vlan_vp)) {
  53436 #if defined(BCM_ENDURO_SUPPORT)
  53437             if (SOC_IS_ENDURO(unit)) {
  53438                 rv = _bcm_enduro_vlan_port_resolve(unit, gport, &local_modid,
  53439                                           &local_port, &local_tgid,
  53440                                           &local_id);
  53441             } else
  53442 #endif /* BCM_ENDURO_SUPPORT */
  53443             {
  53444                 rv = _bcm_tr2_vlan_port_resolve(unit, gport, &local_modid,
  53445                                           &local_port, &local_tgid,
  53446                                           &local_id);
  53447             }
  53448         }
  53449     }
  53450 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
  53451 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3)
  53452     else if (BCM_GPORT_IS_NIV_PORT(gport)) {
  53453         if (soc_feature(unit, soc_feature_niv)) {
  53454             rv = _bcm_trident_niv_port_resolve(unit, gport, &local_modid,
  53455                     &local_port, &local_tgid,
  53456                     &local_id);
  53457         }
  53458     }
  53459 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */
  53460 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3)
  53461     else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) {
  53462         if (soc_feature(unit, soc_feature_port_extension)) {
  53463             rv = _bcm_tr3_extender_port_resolve(unit, gport, &local_modid,
  53464                     &local_port, &local_tgid,
  53465                     &local_id);
  53466         }
  53467     }
  53468 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */
  53469     else if (BCM_GPORT_IS_BLACK_HOLE(gport)) {
  53470          local_modid = BCM_MODID_INVALID;
  53471          local_tgid = BCM_TRUNK_INVALID;
  53472          local_port = BCM_GPORT_INVALID;
  53473          local_id = -1;
  53474          rv = BCM_E_NONE;
  53475     }
  53476     else {
  53477          /* BCM_GPORT_INVALID should return an error */
  53478          return BCM_E_PORT;
  53479     }
  53480     *modid = local_modid;
  53481     *port = local_port;
  53482     *trunk_id = local_tgid;
  53483     *id = local_id;
  53484     return (rv);
  53485 }
  53486 
  53487 /*
  53488  * Function    : _bcm_esw_port_is_local_subport
  53489  * Description : Internal function to check whehter a gport or (mod,port)
  53490  *               is local subport.
  53491  * Parameters  : (IN)  unit      - BCM device number
  53492  *               (IN)  gport     - Global port identifier
  53493  *               (IN)  modid     - Module ID
  53494  *               (IN)  port      - Port number
  53495  *               (OUT) is_local_subport     - True/False
  53496  *               (OUT) phy_port             - physical port of subport
  53497  * Returns     : BCM_E_XXX
  53498  * Note: all gport, modid, port parameters are required.
  53499  */
  53500 int
  53501 _bcm_esw_port_is_local_subport(int unit, bcm_gport_t gport,
  53502                                bcm_module_t modid, bcm_port_t port,
  53503                                int *is_local_subport, bcm_port_t *phy_port)
  53504 {
  53505 #if defined(BCM_KATANA2_SUPPORT)
  53506     int pp_port;
  53507     int min_subport = SOC_INFO(unit).pp_port_index_min;
  53508     int max_subport = SOC_INFO(unit).pp_port_index_max;
  53509 #endif
  53510 
  53511     if ((is_local_subport == NULL) || (phy_port == NULL)) {
  53512         return BCM_E_PARAM;
  53513     }
  53514 
  53515     *is_local_subport = FALSE;
  53516 
  53517 #if defined(BCM_HGPROXY_COE_SUPPORT)
  53518     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  53519         BCM_GPORT_IS_SET(gport) &&
  53520         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) {
  53521 
  53522         if(_bcm_xgs5_subport_coe_gport_local(unit, gport)) {
  53523             *is_local_subport = TRUE;
  53524         }
  53525 
  53526         if (*is_local_subport == FALSE) {
  53527             return BCM_E_PORT;
  53528         }
  53529 
  53530         BCM_IF_ERROR_RETURN(
  53531             _bcmi_coe_subport_physical_port_get(unit, gport, phy_port));
  53532     } else if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  53533                _bcm_xgs5_subport_coe_mod_port_local(unit, modid, port)) {
  53534         *is_local_subport = TRUE;
  53535         BCM_IF_ERROR_RETURN(
  53536             _bcmi_coe_subport_mod_port_physical_port_get(
  53537                 unit, modid, port, phy_port));
  53538     } else
  53539 #endif
  53540 
  53541 #if defined(BCM_KATANA2_SUPPORT)
  53542     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  53543         soc_feature(unit, soc_feature_subtag_coe)) {
  53544         if (BCM_GPORT_IS_SET(gport) &&
  53545             _BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, gport)) {
  53546             pp_port = BCM_GPORT_SUBPORT_PORT_GET(gport);
  53547             if ((_bcm_kt2_mod_is_coe_mod_check(unit, modid) == BCM_E_NONE) ||
  53548                 (soc_feature(unit, soc_feature_general_cascade) &&
  53549                  SOC_PBMP_MEMBER(SOC_INFO(unit).general_pp_port_pbm, pp_port))) {
  53550 #if defined BCM_METROLITE_SUPPORT
  53551                 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) {
  53552                     if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) {
  53553                         *is_local_subport = TRUE;
  53554                         *phy_port = pp_port;
  53555                     }
  53556                 } else
  53557 #endif
  53558                 {
  53559                     if ((pp_port >= min_subport) &&
  53560                         (pp_port <= max_subport)) {
  53561                         *is_local_subport = TRUE;
  53562                         *phy_port = pp_port;
  53563                     }
  53564                 }
  53565             }
  53566             if (*is_local_subport == FALSE) {
  53567                 return BCM_E_PORT;
  53568             }
  53569         }
  53570     } else
  53571 #endif
  53572     {
  53573         return BCM_E_NONE;
  53574     }
  53575 
  53576     return BCM_E_NONE;
  53577 }
  53578 
  53579 /*
  53580  * Function:
  53581  *      _bcm_esw_port_gport_get_from_modport
  53582  * Purpose:
  53583  *      Get a gport for all port.
  53584  *      For non-COE port, it returns modport gport.
  53585  *      For COE subport, it returns Coe subport gport.
  53586  * Parameters:
  53587  *      unit  - (IN) Unit number.
  53588  *      modid - (IN) Module id.
  53589  *      port  - (IN) Port id.
  53590  * Returns:
  53591  *      gport
  53592  * Notes:
  53593  */
  53594 bcm_gport_t
  53595 _bcm_esw_port_gport_get_from_modport(int unit, bcm_module_t modid, bcm_port_t port)
  53596 {
  53597     bcm_gport_t gport;
  53598 
  53599 #if defined(BCM_HGPROXY_COE_SUPPORT)
  53600      if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
  53601          _bcm_xgs5_subport_coe_mod_port_local(unit, modid, port)) {
  53602          _BCM_SUBPORT_COE_PORT_ID_SET(gport, modid, port);
  53603          _BCM_SUBPORT_COE_PORT_TYPE_SET(gport,_BCM_SUBPORT_COE_TYPE_SUBTAG);
  53604      } else
  53605 #endif
  53606      {
  53607          BCM_GPORT_MODPORT_SET(gport, modid, port);
  53608      }
  53609 
  53610      return gport;
  53611 }
  53612 
  53613 /* Check if a given port is a valid controlling port for the Flex-port
  53614    feature.
  53615 */
  53616 
  53617 unsigned
  53618 _bcm_esw_valid_flex_port_controlling_port(int unit, bcm_port_t port)
  53619 {
  53620     uint16 dev_id;
  53621     uint8  rev_id;
  53622 
  53623     if (!SOC_PORT_VALID(unit, port))  return (FALSE);
  53624 
  53625     soc_cm_get_id(unit, &dev_id, &rev_id);
  53626 
  53627     if (dev_id == BCM56636_DEVICE_ID) {
  53628         /* Device is a BCM56636 */
  53629 
  53630         /* Only valid controlling ports are 42 and 50
  53631 	   (ports 30, 34 and 38 come up in gigE, and
  53632 	   therefore are not valid Flex-port controlling ports).
  53633 	*/
  53634 
  53635         if (port != 42 && port != 50)  return (FALSE);
  53636     } else 
  53637 #if defined(BCM_METROLITE_SUPPORT)
  53638         if (SOC_IS_METROLITE(unit)) {
  53639             if ((port != 1) && (port != 5) && (port != 9)) {
  53640                 return (FALSE);
  53641             }
  53642         } else
  53643 #endif
  53644 #if defined(BCM_SABER2_SUPPORT)
  53645     if (SOC_IS_SABER2(unit)) {
  53646          if ((port != 1) && (port != 5) && (port != 9)
  53647              && (port != 13) && (port != 17) && (port != 21)
  53648              && (port != 25)) {
  53649              return (FALSE);
  53650          }
  53651     } else
  53652 #endif
  53653 #if defined(BCM_KATANA2_SUPPORT)
  53654      if (SOC_IS_KATANA2(unit)) {
  53655          if ((port != 1) && (port != 5) && (port != 9)
  53656              && (port != 13) && (port != 17) && (port != 21)
  53657              && (port != 25) && (port != 26) && (port != 27)
  53658              && (port != 28)) {
  53659              return (FALSE);
  53660          }
  53661      } else
  53662 #endif
  53663      {
  53664         if ((port != 30) && (port != 34) && (port != 38)
  53665   	         && (port != 42) && (port != 46) && (port != 50)) {
  53666              return (FALSE);
  53667 	    }
  53668     }
  53669     return (TRUE);
  53670 }
  53671 
  53672 
  53673 /*
  53674  * Function:
  53675  *      bcm_port_subsidiary_ports_get
  53676  * Purpose:
  53677  *      Given a controlling port, this API returns the set of ancillary ports
  53678  *      belonging to the group (port block) that can be configured to operate
  53679  *      either as a single high-speed port or multiple GE ports. If the input
  53680  *      port is not a controlling port, BCM_E_PORT error will be returned.
  53681  * Parameters:
  53682  *      unit - (IN) Unit number.
  53683  *      port - (IN) Port
  53684  *      pbmp - (OUT) Ports associated with the hot-swap group
  53685  * Returns:
  53686  *      BCM_E_XXX
  53687  * Notes:
  53688  */
  53689 int
  53690 bcm_esw_port_subsidiary_ports_get(int unit, bcm_port_t port, bcm_pbmp_t *pbmp)
  53691 {
  53692     int rv = BCM_E_UNAVAIL;
  53693 
  53694     /* Make sure port module is initialized. */
  53695     PORT_INIT(unit);
  53696 
  53697     if (!soc_feature(unit, soc_feature_flex_port)) {
  53698         return BCM_E_UNAVAIL;
  53699     }
  53700 
  53701 #if defined(BCM_TRIDENT3_SUPPORT)
  53702     if (SOC_IS_TRIDENT3X(unit)) {
  53703         return (soc_td3_subsidiary_ports_get(unit, port, pbmp));
  53704     }
  53705 #endif
  53706 #if defined(BCM_TOMAHAWK_SUPPORT)
  53707     if (SOC_IS_TOMAHAWKX(unit)) {
  53708         return (soc_th_subsidiary_ports_get(unit, port, pbmp));
  53709     }
  53710 #endif
  53711 #if defined(BCM_MONTEREY_SUPPORT)
  53712     if (SOC_IS_MONTEREY(unit)) {
  53713         return (soc_monterey_subsidiary_ports_get(unit, port, pbmp));
  53714     }
  53715 #endif
  53716 #if defined(BCM_APACHE_SUPPORT)
  53717     if (SOC_IS_APACHE(unit)) {
  53718         return (soc_apache_subsidiary_ports_get(unit, port, pbmp));
  53719     }
  53720 #endif
  53721 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  53722     if (SOC_IS_TRIDENT2PLUS(unit)) {
  53723         return(soc_td2p_subsidiary_ports_get(unit, port, pbmp));
  53724     }
  53725 #endif
  53726 
  53727 #if defined(BCM_TRIDENT2_SUPPORT)
  53728     if (SOC_IS_TD2_TT2(unit)) {
  53729         soc_info_t *si = &SOC_INFO(unit);
  53730         int i, port_num_lanes_max;
  53731         int phy_port, phy_port_base, port_base, lp;
  53732         bcm_pbmp_t pbm;
  53733 
  53734         if (!SOC_PORT_VALID(unit, port)) {
  53735             return BCM_E_PORT;
  53736         }
  53737         /* coverity[overrun-local : FALSE] */
  53738         phy_port = si->port_l2p_mapping[port];
  53739         if (phy_port == -1) {
  53740             return BCM_E_PORT;
  53741         }
  53742 
  53743         phy_port_base = (phy_port & ~0x3) + 1;
  53744         if (phy_port != phy_port_base) {
  53745             return BCM_E_PORT;
  53746         }
  53747 
  53748         port_base = si->port_p2l_mapping[phy_port_base];
  53749 
  53750         if (si->port_speed_max[port_base] > 20000) {
  53751             port_num_lanes_max = 4;
  53752         } else if (si->port_speed_max[port_base] > 10000) {
  53753             port_num_lanes_max = 2;
  53754         } else {
  53755             port_num_lanes_max = 1;
  53756         }
  53757 
  53758         BCM_PBMP_CLEAR(pbm);
  53759         /* Get the subsidiary ports bitmap */
  53760         for (i = 1; i < port_num_lanes_max; i++) {
  53761             lp = si->port_p2l_mapping[phy_port_base + i];
  53762             if (lp != -1
  53763                 && BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), lp)) {
  53764                 BCM_PBMP_PORT_ADD(pbm, lp);
  53765             }
  53766         }
  53767 
  53768         if (BCM_PBMP_IS_NULL(pbm)) { /* No Subsidiary ports */
  53769             return BCM_E_PORT;
  53770         }
  53771 
  53772         /* Add base port to subsidiary ports bitmap */
  53773         BCM_PBMP_PORT_ADD(pbm, port_base);
  53774         BCM_PBMP_ASSIGN(*pbmp, pbm);
  53775 
  53776         rv = BCM_E_NONE;
  53777     }
  53778 #endif /* BCM_TRIDENT2_SUPPORT */
  53779 
  53780 #if defined(BCM_TRIUMPH3_SUPPORT)
  53781     if (SOC_IS_TRIUMPH3(unit)) {
  53782         soc_info_t *si = &SOC_INFO(unit);
  53783         int i, phy_port, phy_port_base, lp;
  53784         bcm_pbmp_t pbm;
  53785 
  53786         BCM_PBMP_CLEAR(pbm);
  53787 
  53788         if ( !(IS_XW_PORT(unit,port) || IS_CL_PORT(unit, port) || IS_XT_PORT(unit,port)) ||
  53789              !_bcm_tr3_port_is_control_port(unit, port) || !soc_tr3_port_is_flex_port(unit, port)) {
  53790             return BCM_E_PORT;
  53791         }
  53792         /* coverity[overrun-local : FALSE] */
  53793         phy_port = si->port_l2p_mapping[port];
  53794         if (phy_port == -1) {
  53795             return BCM_E_PORT;
  53796         }
  53797         phy_port_base = (phy_port & ~0x3) + 1;
  53798         if (phy_port != phy_port_base) {
  53799             return BCM_E_PORT;
  53800         }
  53801         BCM_PBMP_CLEAR(pbm);
  53802         for (i = 0; i < _SOC_TR3_LANES_PER_PHY; i++) {
  53803             /* coverity[overrun-local : FALSE] */
  53804             lp = si->port_p2l_mapping[phy_port_base + i];
  53805             if (lp != -1 && 
  53806                 (si->port_speed_max[lp] != 0) &&
  53807                 BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), lp)) {
  53808                 BCM_PBMP_PORT_ADD(pbm, lp);
  53809             }
  53810         }
  53811 
  53812 
  53813         BCM_PBMP_ASSIGN(*pbmp, pbm);
  53814         return BCM_E_NONE;
  53815     }
  53816 #endif /* BCM_TRIUMPH3_SUPPORT */
  53817 
  53818 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
  53819     if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) &&
  53820         !SOC_IS_TD_TT(unit)) {
  53821         int i;
  53822 
  53823         if (!_bcm_esw_valid_flex_port_controlling_port(unit, port)) {
  53824             return (BCM_E_PORT);
  53825         }
  53826 
  53827         BCM_PBMP_CLEAR(*pbmp);
  53828         if ((SOC_IS_KATANA2(unit)) && (!SOC_IS_SABER2(unit))) {
  53829             if (port == 25) {
  53830                 BCM_PBMP_PORT_ADD(*pbmp, 25);
  53831                 for (i = 0; i < 3; i++) {
  53832                     if(SOC_PORT_VALID(unit, 35 + i)) {
  53833                         BCM_PBMP_PORT_ADD(*pbmp, 35 + i);
  53834                     }
  53835                 }
  53836                 return (BCM_E_NONE);
  53837              } else if (port == 26) {
  53838                  BCM_PBMP_PORT_ADD(*pbmp, 26);
  53839                  for (i = 0; i < 3; i++) {
  53840                       if(SOC_PORT_VALID(unit, 38 + i)) {
  53841                          BCM_PBMP_PORT_ADD(*pbmp, 38 + i);
  53842                       }
  53843                  }
  53844                  return (BCM_E_NONE);
  53845              } else if (port == 27) {
  53846                  BCM_PBMP_PORT_ADD(*pbmp, 27);
  53847                  for (i = 0; i < 3; i++) {
  53848                       if(SOC_PORT_VALID(unit, 32 + i)) {
  53849                          BCM_PBMP_PORT_ADD(*pbmp, 32 + i);
  53850                       }
  53851                  }
  53852                  return (BCM_E_NONE);
  53853              }
  53854         }
  53855         
  53856         for (i = 0; i < 4; i++) {
  53857             /* coverity[overrun-local : FALSE] */
  53858             if (SOC_PORT_VALID(unit, port + i)) {
  53859                 BCM_PBMP_PORT_ADD(*pbmp, port + i);
  53860             }
  53861         }
  53862         rv = BCM_E_NONE;
  53863     }
  53864 #endif
  53865 
  53866     return rv;
  53867 }
  53868 
  53869 /*
  53870  * Function:
  53871  *      _bcm_esw_port_e2ecc_hg_pbm_convert
  53872  * Purpose:
  53873  *      Convert Higig port to E2ECC Higig port bitmap.
  53874  * Parameters:
  53875  *      port - (IN) Higig port number.
  53876  *      converted_hg_pbm - (OUT) Converted Higig port bitmap.
  53877  * Returns:
  53878  *      BCM_E_xxx
  53879  */
  53880 STATIC int
  53881 _bcm_esw_port_e2ecc_hg_pbm_convert(bcm_port_t port, uint32 *converted_hg_pbm)
  53882 {
  53883     int    hg_pbm_index;
  53884 
  53885     /* In Triumph2, the mapping between HG_PBM[9:0] and physical port number is:
  53886      *
  53887      * HG_PBM index:  |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
  53888      * Physical Port: | 50 | 46 | 42 | 38 | 34 | 30 | 29 | 28 | 27 | 26 |
  53889      */
  53890     switch (port)
  53891     {
  53892         case 26:
  53893         case 27:
  53894         case 28:
  53895         case 29:
  53896         case 30:
  53897             hg_pbm_index = port - 26;
  53898             break;
  53899         case 34:
  53900         case 38:
  53901         case 42:
  53902         case 46:
  53903         case 50:
  53904             hg_pbm_index = 5 + (port - 34) / 4;
  53905             break;
  53906         default:
  53907             LOG_ERROR(BSL_LS_BCM_PORT,
  53908                       (BSL_META("Error: Port %d is an invalid Higig port"), port));
  53909             return BCM_E_PARAM;
  53910     }
  53911 
  53912     *converted_hg_pbm = (1 << hg_pbm_index);
  53913 
  53914     return BCM_E_NONE;
  53915 }
  53916 
  53917 STATIC int
  53918 _bcm_esw_port_drop_status_enable_set(int unit, bcm_port_t port, int enable)
  53919 {
  53920     uint32 rval;
  53921     int idx;
  53922 
  53923 #if defined(BCM_MONTEREY_SUPPORT)
  53924     if (SOC_IS_MONTEREY(unit)) {
  53925         return bcm_mn_cosq_drop_status_enable_set(unit, port, enable);
  53926     }
  53927 #endif /* BCM_TRIDENT2_SUPPORT */
  53928 #if defined(BCM_APACHE_SUPPORT)
  53929     if (SOC_IS_APACHE(unit)) {
  53930         return bcm_ap_cosq_drop_status_enable_set(unit, port, enable);
  53931     }
  53932 #endif /* BCM_TRIDENT2_SUPPORT */
  53933 #if defined(BCM_TRIDENT2_SUPPORT)
  53934     if (SOC_IS_TD2_TT2(unit)) {
  53935         return bcm_td2_cosq_drop_status_enable_set(unit, port, enable);
  53936     }
  53937 #endif /* BCM_TRIDENT2_SUPPORT */
  53938 
  53939 #if defined(BCM_TRIDENT_SUPPORT)
  53940     if (SOC_IS_TD_TT(unit)) {
  53941         return bcm_td_cosq_drop_status_enable_set(unit, port, enable);
  53942     }
  53943 #endif /* BCM_TRIDENT_SUPPORT */
  53944 
  53945 #if defined(BCM_TRIUMPH3_SUPPORT)
  53946     if (SOC_IS_TRIUMPH3(unit)) {
  53947         return bcm_tr3_cosq_drop_status_enable_set(unit, port, enable);
  53948     }
  53949 #endif /* BCM_TRIUMPH3_SUPPORT */
  53950 
  53951 #if defined(BCM_KATANA_SUPPORT)
  53952     if (SOC_IS_KATANA(unit)) {
  53953         return bcm_kt_cosq_drop_status_enable_set(unit, port, enable);
  53954     }
  53955 #endif /* BCM_KATANA_SUPPORT */
  53956 #if defined(BCM_KATANA2_SUPPORT)
  53957     if (SOC_IS_KATANA2(unit)) {
  53958         return bcm_kt2_cosq_drop_status_enable_set(unit, port, enable);
  53959     }
  53960 #endif /* BCM_KATANA2_SUPPORT */
  53961 #if defined(BCM_HURRICANE3_SUPPORT)
  53962     if (SOC_IS_HURRICANE3(unit)) {
  53963         return bcm_hr3_cosq_drop_status_enable_set(unit, port, enable);
  53964     }
  53965 #endif /* BCM_HURRICANE3_SUPPORT */
  53966 #if defined(BCM_GREYHOUND2_SUPPORT)
  53967     if (SOC_IS_GREYHOUND2(unit)) {
  53968         return bcmi_gh2_cosq_drop_status_enable_set(unit, port, enable);
  53969     }
  53970 #endif /* BCM_GREYHOUND2_SUPPORT */
  53971 
  53972     for (idx = 0; idx < 8; idx++) {
  53973         if (SOC_IS_SC_CQ(unit)) {
  53974             SOC_IF_ERROR_RETURN(READ_OP_QUEUE_CONFIGr(unit, port, idx, &rval));
  53975             soc_reg_field_set(unit, OP_QUEUE_CONFIGr, &rval,
  53976                               Q_E2E_DS_ENABLEf, enable ? 1 : 0);
  53977             SOC_IF_ERROR_RETURN(WRITE_OP_QUEUE_CONFIGr(unit, port, idx, rval));
  53978         } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  53979                    SOC_IS_VALKYRIE2(unit)) {
  53980             SOC_IF_ERROR_RETURN
  53981                 (READ_OP_QUEUE_CONFIG1_CELLr(unit, port, idx, &rval));
  53982             soc_reg_field_set(unit, OP_QUEUE_CONFIG1_CELLr, &rval,
  53983                               Q_E2E_DS_EN_CELLf, enable ? 1 : 0);
  53984             SOC_IF_ERROR_RETURN
  53985                 (WRITE_OP_QUEUE_CONFIG1_CELLr(unit, port, idx, rval));
  53986 
  53987             SOC_IF_ERROR_RETURN
  53988                 (READ_OP_QUEUE_CONFIG1_PACKETr(unit, port, idx, &rval));
  53989             soc_reg_field_set(unit, OP_QUEUE_CONFIG1_PACKETr, &rval,
  53990                               Q_E2E_DS_EN_PACKETf, enable ? 1 : 0);
  53991             SOC_IF_ERROR_RETURN
  53992                 (WRITE_OP_QUEUE_CONFIG1_PACKETr(unit, port, idx, rval));
  53993         }
  53994     }
  53995 
  53996     SOC_IF_ERROR_RETURN(READ_OP_THR_CONFIGr(unit, &rval));
  53997     soc_reg_field_set(unit, OP_THR_CONFIGr, &rval, EARLY_E2E_SELECTf,
  53998                       enable ? 1 : 0);
  53999     SOC_IF_ERROR_RETURN(WRITE_OP_THR_CONFIGr(unit, rval));
  54000 
  54001     return BCM_E_NONE;
  54002 }
  54003 
  54004 /*
  54005  * Function:
  54006  *     _bcm_esw_port_e2e_tx_enable_set
  54007  * Purpose:
  54008  *      Set E2E Tx Enable
  54009  * Parameters:
  54010  *      unit - (IN) SOC unit number.
  54011  *      port - (IN) Port number.
  54012  *      enable - (IN) Whether to enable or disable
  54013  * Returns:
  54014  *      BCM_E_xxx
  54015  */
  54016 STATIC int
  54017 _bcm_esw_port_e2e_tx_enable_set(int unit, bcm_port_t port, int enable)
  54018 {
  54019     uint64 rval64;
  54020 
  54021     if (SOC_USE_PORTCTRL(unit)) {
  54022         return bcmi_esw_portctrl_e2e_tx_enable_set(unit, port, enable);
  54023     }
  54024 
  54025     if (IS_CL_PORT(unit, port)) {
  54026         SOC_IF_ERROR_RETURN(READ_CLMAC_E2E_CTRLr(unit, port, &rval64));
  54027         soc_reg64_field32_set(unit, CLMAC_E2E_CTRLr, &rval64,
  54028                 E2E_ENABLEf, enable);
  54029         SOC_IF_ERROR_RETURN(WRITE_CLMAC_E2E_CTRLr(unit, port, rval64));
  54030     } else {
  54031     SOC_IF_ERROR_RETURN(READ_XLMAC_E2E_CTRLr(unit, port, &rval64));
  54032     soc_reg64_field32_set(unit, XLMAC_E2E_CTRLr, &rval64,
  54033             E2E_ENABLEf, enable);
  54034     SOC_IF_ERROR_RETURN(WRITE_XLMAC_E2E_CTRLr(unit, port, rval64));
  54035     }
  54036     return BCM_E_NONE;
  54037 }
  54038 
  54039 /*
  54040  * Function:
  54041  *      _bcm_esw_port_e2ecc_tx
  54042  * Purpose:
  54043  *      Configure E2ECC message transmission.
  54044  * Parameters:
  54045  *      unit - (IN) Unit number.
  54046  *      port - (IN) Local port number.
  54047  *      config - (IN) Congestion configuration.
  54048  * Returns:
  54049  *      BCM_E_xxx
  54050  */
  54051 STATIC int
  54052 _bcm_esw_port_e2ecc_tx(int unit, bcm_port_t port,
  54053                        bcm_port_congestion_config_t *config)
  54054 {
  54055     uint32 regval;
  54056     uint32 hg_pbm, converted_hg_pbm, new_hg_pbm;
  54057     int    value_a, value_b;
  54058     int    time_unit_sel, time_units;
  54059     int    src_modid, src_pid;
  54060     soc_higig_e2ecc_hdr_t e2ecc_hdr;
  54061     int blk, blk_num = -1, bindex = 0;
  54062     if (config->flags & BCM_PORT_CONGESTION_CONFIG_TX) {
  54063         /* If BCM_PORT_CONGESTION_CONFIG_TX flag is set, enable E2ECC transmission. */
  54064 
  54065         /* Set chip-wide E2ECC enable bit */
  54066         if (SOC_IS_SC_CQ(unit)) {
  54067             SOC_IF_ERROR_RETURN(READ_E2E_HOL_ENr(unit, &regval));
  54068             if (soc_reg_field_get(unit, E2E_HOL_ENr, regval, ENf) == 0) {
  54069                 soc_reg_field_set(unit, E2E_HOL_ENr, &regval, ENf, 1);
  54070                 SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_ENr(unit, regval));
  54071             }
  54072         } else {
  54073             SOC_IF_ERROR_RETURN(READ_E2ECC_HOL_ENr(unit, &regval));
  54074             if (soc_reg_field_get(unit, E2ECC_HOL_ENr, regval, ENf) == 0) {
  54075                 soc_reg_field_set(unit, E2ECC_HOL_ENr, &regval, ENf, 1);
  54076                 SOC_IF_ERROR_RETURN(WRITE_E2ECC_HOL_ENr(unit, regval));
  54077             }
  54078         }
  54079 
  54080 
  54081         /* In Trident E2E_HOL_ENf is not present. MMY E2ECC_HOL_EN is used */
  54082         /* (Checked with Architecture) */
  54083         if (soc_reg_field_valid(unit, XPORT_CONFIGr, E2E_HOL_ENf)) {
  54084             /* Set per-port E2ECC TX enable bit */
  54085             SOC_IF_ERROR_RETURN(READ_XPORT_CONFIGr(unit, port, &regval));
  54086             if (soc_reg_field_get(unit, XPORT_CONFIGr,
  54087                                   regval, E2E_HOL_ENf) == 0) {
  54088                 soc_reg_field_set(unit, XPORT_CONFIGr, &regval,
  54089                                   E2E_HOL_ENf, 1);
  54090                 SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, regval));
  54091             }
  54092         }
  54093 
  54094         if (soc_reg_field_valid(unit, XPORT_MODE_REGr, E2E_HOL_ENf)) {
  54095             /* Set per-port E2ECC TX enable bit */
  54096             SOC_IF_ERROR_RETURN(READ_XPORT_MODE_REGr(unit, port, &regval));
  54097             if (soc_reg_field_get(unit, XPORT_MODE_REGr,
  54098                                   regval, E2E_HOL_ENf) == 0) {
  54099                 soc_reg_field_set(unit, XPORT_MODE_REGr, &regval,
  54100                                   E2E_HOL_ENf, 1);
  54101                 SOC_IF_ERROR_RETURN(WRITE_XPORT_MODE_REGr(unit, port, regval));
  54102             }
  54103         }
  54104 
  54105         /* Set per-queue E2ECC enable bits */
  54106         BCM_IF_ERROR_RETURN
  54107             (_bcm_esw_port_drop_status_enable_set(unit, port, TRUE));
  54108 
  54109         /* Set the Higig port bitmap used to transmit E2ECC messages */
  54110         if (SOC_IS_SC_CQ(unit)) {
  54111             SOC_IF_ERROR_RETURN(READ_E2E_HOL_PBMr(unit, &regval));
  54112             hg_pbm = soc_reg_field_get(unit, E2E_HOL_PBMr, regval, PORT_BITMAPf);
  54113 
  54114             converted_hg_pbm = 1 << port;
  54115 
  54116             if (!(hg_pbm & converted_hg_pbm)) {
  54117                 new_hg_pbm = hg_pbm | converted_hg_pbm;
  54118                 soc_reg_field_set(unit, E2E_HOL_PBMr, &regval, PORT_BITMAPf, new_hg_pbm);
  54119                 SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_PBMr(unit, regval));
  54120             }
  54121         } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) ||
  54122                    SOC_IS_VALKYRIE2(unit)) {
  54123             SOC_IF_ERROR_RETURN(READ_E2ECC_HOL_PBMr(unit, &regval));
  54124             hg_pbm = soc_reg_field_get(unit, E2ECC_HOL_PBMr, regval, HG_PBMf);
  54125 
  54126             SOC_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_hg_pbm_convert(port, &converted_hg_pbm));
  54127 
  54128             if (!(hg_pbm & converted_hg_pbm)) {
  54129                 new_hg_pbm = hg_pbm | converted_hg_pbm;
  54130                 soc_reg_field_set(unit, E2ECC_HOL_PBMr, &regval, HG_PBMf, new_hg_pbm);
  54131                 SOC_IF_ERROR_RETURN(WRITE_E2ECC_HOL_PBMr(unit, regval));
  54132             }
  54133         } else { /* TD_TT, KATANAX, TR3 */
  54134             if (soc_feature(unit, soc_feature_logical_port_num)) {
  54135                 blk = SOC_PORT_BLOCK(unit, SOC_INFO(unit).port_l2p_mapping[port]);
  54136                 bindex = SOC_PORT_BINDEX(unit, SOC_INFO(unit).port_l2p_mapping[port]);
  54137             } else{
  54138                 blk = SOC_PORT_BLOCK(unit, port);
  54139                 bindex = SOC_PORT_BINDEX(unit, port);
  54140             }
  54141 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
  54142             if (SOC_IS_TRIDENT2X(unit)) {
  54143                 blk_num = SOC_INFO(unit).port_serdes[port];
  54144             } else
  54145 #endif 
  54146             {  
  54147             blk_num = SOC_BLOCK_INFO(unit, blk).number;
  54148             }  
  54149             /* In TR3 E2ECC is implemented only in blocks CL, XL1 */
  54150             if (!SOC_IS_TRIUMPH3(unit) || (IS_CL_PORT(unit, port) || (blk == 13))) {
  54151                 if (SOC_IS_TRIUMPH3(unit)) {
  54152                     if (IS_CL_PORT(unit, port)) {
  54153                         blk_num = (blk_num ?  4 + bindex/4 : bindex/4);
  54154                         bindex = bindex%4;
  54155                     } else {
  54156                         blk_num = 3;
  54157                     }
  54158                 }
  54159 #if defined(BCM_KATANA2_SUPPORT)
  54160                 if (SOC_IS_KATANA2(unit)) {
  54161                     /* In KT2 E2ECC is implemented only in blocks 6..9 */
  54162                     blk_num = (blk_num >= 6) ? (blk_num - 6) : blk_num ;
  54163                 }
  54164 #endif
  54165                 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_ENABLE_BMPr(unit, blk_num,
  54166                                                               &regval));
  54167                 if (!(regval & (1 << bindex))) {
  54168                     new_hg_pbm = soc_reg_field_get(unit, E2ECC_TX_ENABLE_BMPr, regval,
  54169                                                    TX_ENABLE_BMPf);
  54170                     /* new_hg_pbm &= ~(1 << bindex); */
  54171                     new_hg_pbm |= (1 << bindex);
  54172                     soc_reg_field_set(unit, E2ECC_TX_ENABLE_BMPr, &regval,
  54173                                       TX_ENABLE_BMPf, new_hg_pbm);
  54174                     SOC_IF_ERROR_RETURN
  54175                         (WRITE_E2ECC_TX_ENABLE_BMPr(unit, blk_num, regval));
  54176                 }
  54177             }
  54178 
  54179 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
  54180             if (SOC_IS_TD2_TT2(unit)) {
  54181                 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 1));
  54182 
  54183                 /* DMVOQ congestion bytes max length is 64 bytes,
  54184                                As a result
  54185                  DMVOQ feature can support upto 64 ports*/
  54186                 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_PORTS_NUMr(unit, &regval));
  54187                 soc_reg_field_set(unit, E2ECC_TX_PORTS_NUMr, &regval,
  54188                         TX_PORTS_NUMf, BCM_MAX_PORTS_SUPPORT_FOR_DMVOQ);
  54189                 SOC_IF_ERROR_RETURN(WRITE_E2ECC_TX_PORTS_NUMr(unit, regval));
  54190 
  54191                 /* By default congestion states of 4 cos values are transmitted
  54192                    inorder to transmit the congestion state for all the
  54193                    8 cos values
  54194                    if num_coq > 8 following configuration is done */
  54195                 if (!SOC_IS_TRIUMPH3(unit) && !SOC_IS_MONTEREY(unit) && NUM_COS(unit) >= 8) {
  54196                     uint64 rval64 ;
  54197                     uint64  fval64;
  54198                     COMPILER_64_ZERO(fval64);
  54199                     COMPILER_64_SET(fval64, 0xffffffff, 0xffffffff);
  54200                     soc_reg64_field_set(unit, OOBFC_ENG_PORT_QSEL0_64r ,
  54201                             &rval64,
  54202                             ENG_PORT_QSELf, fval64);
  54203                     SOC_IF_ERROR_RETURN(WRITE_OOBFC_ENG_PORT_QSEL0_64r(unit,
  54204                                 rval64));
  54205                 }
  54206             }
  54207 #endif
  54208 #if defined(BCM_HURRICANE3_SUPPORT)
  54209             if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) {
  54210                 uint32 max_bitmap;
  54211                 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_PORTS_NUMr(unit, &regval));
  54212                 /* max Congestion bitmap number of E2ECC message */
  54213                 if (SOC_IS_HURRICANE3(unit)) {
  54214                     max_bitmap = 36;
  54215                 } else { /* GREYHOUND2 */
  54216                     max_bitmap = 64;
  54217                 }
  54218                 soc_reg_field_set(unit, E2ECC_TX_PORTS_NUMr, &regval,
  54219                         TX_PORTS_NUMf, max_bitmap);
  54220                 SOC_IF_ERROR_RETURN(WRITE_E2ECC_TX_PORTS_NUMr(unit, regval));
  54221 
  54222                 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 1));
  54223             }
  54224 #endif
  54225 
  54226             if (SOC_IS_KATANAX(unit)) {
  54227                 SOC_IF_ERROR_RETURN(READ_OP_THR_CONFIGr(unit, &regval));
  54228                 soc_reg_field_set(unit, OP_THR_CONFIGr, &regval, E2ECC_HOL_ENf, 1);
  54229                 SOC_IF_ERROR_RETURN(WRITE_OP_THR_CONFIGr(unit, regval));
  54230                 if (SOC_IS_SABER2(unit)) {
  54231                     SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 1));
  54232                 }
  54233             }
  54234         }
  54235 
  54236         /* Configuring the E2ECC min timer so that during congestion, back-to-back
  54237          * E2ECC messages are generated as fast as hardware allows.
  54238          */
  54239         if (SOC_IS_SC_CQ(unit)) {
  54240 
  54241             SOC_IF_ERROR_RETURN(READ_E2E_MIN_TX_TIMERr(unit, &regval));
  54242             if (soc_reg_field_get(unit, E2E_MIN_TX_TIMERr, regval, TIMERf) != 0) {
  54243                 soc_reg_field_set(unit, E2E_MIN_TX_TIMERr, &regval, TIMERf, 0);
  54244                 soc_reg_field_set(unit, E2E_MIN_TX_TIMERr, &regval, LGf, 0);
  54245                 SOC_IF_ERROR_RETURN(WRITE_E2E_MIN_TX_TIMERr(unit, regval));
  54246             }
  54247         } else {
  54248             SOC_IF_ERROR_RETURN(READ_E2ECC_MIN_TX_TIMERr(unit, &regval));
  54249             if (soc_reg_field_get(unit, E2ECC_MIN_TX_TIMERr, regval, TIMERf) != 0) {
  54250                 soc_reg_field_set(unit, E2ECC_MIN_TX_TIMERr, &regval, TIMERf, 0);
  54251                 soc_reg_field_set(unit, E2ECC_MIN_TX_TIMERr, &regval, LGf, 0);
  54252                 SOC_IF_ERROR_RETURN(WRITE_E2ECC_MIN_TX_TIMERr(unit, regval));
  54253             }
  54254         }
  54255 
  54256         /* In the absence of congestion, an E2ECC message is still generated to refresh
  54257          * congestion status when the E2ECC max timer expires. This timer is specified
  54258          * in units of 250ns or 25us, and up to 1023 time units can be specified.
  54259          * The selection of time unit and the number of time units is computed as follows:
  54260          *
  54261          * Let E2ECC message refresh rate = N messages/sec, and N != 0,
  54262          * then A = # of 250ns time units = 1 sec / N / 250ns = 4000000 / N,
  54263          * and B = # of 25us time units = 1 sec / N / 25us = 40000 / N = A / 100.
  54264          *
  54265          * If A < 1, configure the minimum allowed timer value: time unit = 250ns,
  54266          * # of time units = 1.
  54267          *
  54268          * If A is between 1 and 1023, configure the timer as: time unit = 250ns,
  54269          * # of time units = A.
  54270          *
  54271          * If A > 1023 and B <= 1023, configure the timer as: time unit = 25us,
  54272          * # of time units = B.
  54273          *
  54274          * If B > 1023, configure the maximum allowed timer value: time unit = 25us,
  54275          * # of time units = 1023.
  54276          *
  54277          * Note: If N = 0, # of time units will be set to 0, and E2ECC message refresh
  54278          *       is effectively disabled. E2ECC message will be generated only when
  54279          *       there is a change in congestion status.
  54280          */
  54281 
  54282         if (config->packets_per_sec == 0) {
  54283             time_unit_sel = 0;
  54284             time_units = 0;
  54285         } else {
  54286             value_a = 4000000 / config->packets_per_sec;
  54287             value_b = value_a / 100;
  54288             if (value_a < 1) {
  54289                 time_unit_sel = 0;
  54290                 time_units = 1;
  54291             } else if (value_a <= 1023) {
  54292                 time_unit_sel = 0;
  54293                 time_units = value_a;
  54294             } else if ((value_a > 1023) && (value_b <= 1023)) {
  54295                 time_unit_sel = 1;
  54296                 time_units = value_b;
  54297             } else { /* value_b > 1023 */
  54298                 time_unit_sel = 1;
  54299                 time_units = 1023;
  54300             }
  54301         }
  54302 
  54303         if (SOC_IS_SC_CQ(unit)) {
  54304             SOC_IF_ERROR_RETURN(READ_E2E_MAX_TX_TIMERr(unit, &regval));
  54305             soc_reg_field_set(unit, E2E_MAX_TX_TIMERr, &regval, LGf,
  54306                               time_unit_sel);
  54307             soc_reg_field_set(unit, E2E_MAX_TX_TIMERr, &regval, TIMERf,
  54308                               time_units);
  54309             SOC_IF_ERROR_RETURN(WRITE_E2E_MAX_TX_TIMERr(unit, regval));
  54310         } else {
  54311             SOC_IF_ERROR_RETURN(READ_E2ECC_MAX_TX_TIMERr(unit, &regval));
  54312             soc_reg_field_set(unit, E2ECC_MAX_TX_TIMERr, &regval, LGf,
  54313                               time_unit_sel);
  54314             soc_reg_field_set(unit, E2ECC_MAX_TX_TIMERr, &regval, TIMERf,
  54315                               time_units);
  54316             SOC_IF_ERROR_RETURN(WRITE_E2ECC_MAX_TX_TIMERr(unit, regval));
  54317         }
  54318 
  54319         /* Configure per-port E2ECC message header */
  54320 
  54321         if (BCM_GPORT_IS_MODPORT(config->src_port)) {
  54322             src_modid = BCM_GPORT_MODPORT_MODID_GET(config->src_port);
  54323             src_pid = BCM_GPORT_MODPORT_PORT_GET(config->src_port);
  54324         } else {
  54325             LOG_ERROR(BSL_LS_BCM_PORT,
  54326                       (BSL_META_U(unit,
  54327                                   "Error: src_port %d is not of type modid:port.\n"), config->src_port));
  54328             return BCM_E_PARAM;
  54329         }
  54330 
  54331         sal_memset(&e2ecc_hdr, 0, sizeof(soc_higig_e2ecc_hdr_t));
  54332 
  54333         e2ecc_hdr.overlay1.words[0] =
  54334                     (SOC_HIGIG_START << 24) |                              /* K.SOP[7:0] */
  54335                     (((1 << 4) | (config->traffic_class & 0x0F)) << 16) |  /* MC and TC[3:0] */
  54336                     (config->multicast_id & 0xFFFF);                       /* MGID[15:0] */
  54337 
  54338         e2ecc_hdr.overlay1.words[1] =
  54339                     ((src_modid & 0xFF) << 24) |                           /* SRC_MODID[7:0] */
  54340                     ((src_pid & 0xFF) << 16) |                             /* SRC_PID[7:0] */
  54341                     ((config->color & 0x03) << 6);                         /* DP[1:0] */
  54342 
  54343         /* e2ecc_hdr.overlay1.words[2] is all zeroes. */
  54344 
  54345         if (config->flags & BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL) {
  54346             /* In case of DMVOQ, we are sending opcode as Multicast
  54347                so that packet is accepted at different modules */
  54348             e2ecc_hdr.overlay1.words[3] =
  54349                 ((config->pri & 0x07) << 29) |   /* VID_HIGH[7:5] */
  54350                 ((config->cfi & 0x01) << 28) |   /* VID_HIGH[4] */
  54351                 ((config->vlan & 0xfff) << 16) | /* VID_HIGH[3:0], VID_LOW[7:0] */
  54352                 ((SOC_HIGIG_OP_MC & 0x07) << 8);  /* OPCODE[2:0] */
  54353         } else {
  54354             e2ecc_hdr.overlay1.words[3] =
  54355                 ((config->pri & 0x07) << 29) |   /* VID_HIGH[7:5] */
  54356                 ((config->cfi & 0x01) << 28) |   /* VID_HIGH[4] */
  54357                 ((config->vlan & 0xfff) << 16) | /* VID_HIGH[3:0], VID_LOW[7:0] */
  54358                 ((SOC_HIGIG_OP_BC & 0x07) << 8);  /* OPCODE[2:0] */
  54359         }
  54360 
  54361         e2ecc_hdr.overlay1.words[4] =
  54362                     (config->dest_mac[0] << 24) |                          /* MAC-DA[47:40] */
  54363                     (config->dest_mac[1] << 16) |                          /* MAC-DA[39:32] */
  54364                     (config->dest_mac[2] << 8) |                           /* MAC-DA[31:24] */
  54365                     (config->dest_mac[3]);                                 /* MAC-DA[23:16] */
  54366 
  54367         e2ecc_hdr.overlay1.words[5] =
  54368                     (config->dest_mac[4] << 24) |                          /* MAC-DA[15:8] */
  54369                     (config->dest_mac[5] << 16) |                          /* MAC-DA[7:0] */
  54370                     (config->src_mac[0] << 8) |                            /* MAC-SA[47:40] */
  54371                     (config->src_mac[1]);                                  /* MAC-SA[39:32] */
  54372 
  54373         e2ecc_hdr.overlay1.words[6] =
  54374                     (config->src_mac[2] << 24) |                           /* MAC-SA[31:24] */
  54375                     (config->src_mac[3] << 16) |                           /* MAC-SA[23:16] */
  54376                     (config->src_mac[4] << 8) |                            /* MAC-SA[15:8] */
  54377                     (config->src_mac[5]);                                  /* MAC-SA[7:0] */
  54378 
  54379         e2ecc_hdr.overlay1.words[7] =
  54380                     ((config->ethertype & 0xFFFF) << 16) |                 /* Ethertype[15:0] */
  54381                     (config->opcode & 0xFFFF);                             /* Opcode[7:0] */
  54382 
  54383         BCM_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_hdr_set(unit, port, &e2ecc_hdr));
  54384 
  54385         /* Enable QE interop mode */
  54386         if (SOC_IS_SC_CQ(unit)) {
  54387             SOC_IF_ERROR_RETURN(READ_GLOBAL_SHARED_FILL_STATE_CONFIGr(unit, &regval));
  54388             if (soc_reg_field_get(unit, GLOBAL_SHARED_FILL_STATE_CONFIGr, regval,
  54389                                   GLOBAL_SHARED_FILL_STATE_ENf) == 0) {
  54390                 soc_reg_field_set(unit, GLOBAL_SHARED_FILL_STATE_CONFIGr, &regval,
  54391                                   GLOBAL_SHARED_FILL_STATE_ENf, 1);
  54392                 SOC_IF_ERROR_RETURN(WRITE_GLOBAL_SHARED_FILL_STATE_CONFIGr(unit, regval));
  54393             }
  54394         } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || SOC_IS_VALKYRIE2(unit)) {
  54395             SOC_IF_ERROR_RETURN(READ_QE_INTEROP_CONFIGr(unit, &regval));
  54396             if (soc_reg_field_get(unit, QE_INTEROP_CONFIGr, regval, QE_INTEROP_ENf) == 0) {
  54397                 soc_reg_field_set(unit, QE_INTEROP_CONFIGr, &regval, QE_INTEROP_ENf, 1);
  54398                 SOC_IF_ERROR_RETURN(WRITE_QE_INTEROP_CONFIGr(unit, regval));
  54399             }
  54400         } else if (SOC_IS_TD2_TT2(unit)) {
  54401             SOC_IF_ERROR_RETURN
  54402                 (soc_reg_field32_modify(unit,
  54403                                         INTFO_E2ECC_POOL_STATE_REPORT_ENABLEr,
  54404                                         REG_PORT_ANY, ENf, 1));
  54405         } else if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)) {
  54406             SOC_IF_ERROR_RETURN(READ_THDO_INTEROP_CONFIGr(unit, &regval));
  54407             if (soc_reg_field_get(unit, THDO_INTEROP_CONFIGr, regval,
  54408                                   GLOBAL_CNG_STATE_REPORT_ENABLEf) == 0) {
  54409                 soc_reg_field_set(unit, THDO_INTEROP_CONFIGr, &regval,
  54410                                   GLOBAL_CNG_STATE_REPORT_ENABLEf, 1);
  54411                 SOC_IF_ERROR_RETURN(WRITE_THDO_INTEROP_CONFIGr(unit, regval));
  54412             }
  54413         }
  54414 
  54415     } else {
  54416         /* If BCM_PORT_CONGESTION_CONFIG_TX flag is not set, disable E2ECC transmission. */
  54417 
  54418         if (soc_reg_field_valid(unit, XPORT_CONFIGr, E2E_HOL_ENf)) {
  54419             /* Clear per-port E2ECC TX enable bit */
  54420             SOC_IF_ERROR_RETURN(READ_XPORT_CONFIGr(unit, port, &regval));
  54421             if (soc_reg_field_get(unit, XPORT_CONFIGr, regval, E2E_HOL_ENf) == 1) {
  54422                 soc_reg_field_set(unit, XPORT_CONFIGr, &regval, E2E_HOL_ENf, 0);
  54423                 SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, regval));
  54424             }
  54425         }
  54426 
  54427         if (soc_reg_field_valid(unit, XPORT_MODE_REGr, E2E_HOL_ENf)) {
  54428             /* Clear per-port E2ECC TX enable bit */
  54429             SOC_IF_ERROR_RETURN(READ_XPORT_MODE_REGr(unit, port, &regval));
  54430             if (soc_reg_field_get(unit, XPORT_MODE_REGr, regval, E2E_HOL_ENf) == 1) {
  54431                 soc_reg_field_set(unit, XPORT_MODE_REGr, &regval, E2E_HOL_ENf, 0);
  54432                 SOC_IF_ERROR_RETURN(WRITE_XPORT_MODE_REGr(unit, port, regval));
  54433             }
  54434         }
  54435 
  54436         /* Clear per-queue E2ECC enable bits */
  54437         BCM_IF_ERROR_RETURN
  54438             (_bcm_esw_port_drop_status_enable_set(unit, port, FALSE));
  54439 
  54440         /* Clear the bit corresponding to the given Higig port in the Higig port bitmap
  54441          * used to transmit E2ECC messages
  54442          */
  54443         if (SOC_IS_SC_CQ(unit)) {
  54444             SOC_IF_ERROR_RETURN(READ_E2E_HOL_PBMr(unit, &regval));
  54445             hg_pbm = soc_reg_field_get(unit, E2E_HOL_PBMr, regval, PORT_BITMAPf);
  54446 
  54447             converted_hg_pbm = 1 << port;
  54448 
  54449             if (hg_pbm & converted_hg_pbm) {
  54450                 new_hg_pbm = hg_pbm & ~converted_hg_pbm;
  54451                 soc_reg_field_set(unit, E2E_HOL_PBMr, &regval, PORT_BITMAPf, new_hg_pbm);
  54452                 SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_PBMr(unit, regval));
  54453             }
  54454         } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || SOC_IS_VALKYRIE2(unit)) {
  54455             SOC_IF_ERROR_RETURN(READ_E2ECC_HOL_PBMr(unit, &regval));
  54456             hg_pbm = soc_reg_field_get(unit, E2ECC_HOL_PBMr, regval, HG_PBMf);
  54457 
  54458             SOC_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_hg_pbm_convert(port, &converted_hg_pbm));
  54459 
  54460             if (hg_pbm & converted_hg_pbm) {
  54461                 new_hg_pbm = hg_pbm & ~converted_hg_pbm;
  54462                 soc_reg_field_set(unit, E2ECC_HOL_PBMr, &regval, HG_PBMf, new_hg_pbm);
  54463                 SOC_IF_ERROR_RETURN(WRITE_E2ECC_HOL_PBMr(unit, regval));
  54464             }
  54465         } else if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || 
  54466                    SOC_IS_TRIUMPH3(unit) || SOC_IS_HURRICANE3(unit) ||
  54467                    SOC_IS_GREYHOUND2(unit)) {
  54468             if (soc_feature(unit, soc_feature_logical_port_num)) {
  54469                 blk = SOC_PORT_BLOCK(unit, SOC_INFO(unit).port_l2p_mapping[port]);
  54470                 bindex = SOC_PORT_BINDEX(unit, SOC_INFO(unit).port_l2p_mapping[port]);
  54471             } else{
  54472                 blk = SOC_PORT_BLOCK(unit, port);
  54473                 bindex = SOC_PORT_BINDEX(unit, port);
  54474             }
  54475 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
  54476            if (SOC_IS_TRIDENT2X(unit)) {
  54477                blk_num = SOC_INFO(unit).port_serdes[port];
  54478             } else
  54479 #endif
  54480             {
  54481             blk_num = SOC_BLOCK_INFO(unit, blk).number;
  54482             }	 
  54483             /* In TR3 E2ECC is implemented only in blocks CL, XL1 */
  54484             if (!SOC_IS_TRIUMPH3(unit) || (IS_CL_PORT(unit, port) || (blk == 13))) {
  54485                 if (SOC_IS_TRIUMPH3(unit)) {
  54486                     if (IS_CL_PORT(unit, port)) {
  54487                         blk_num = (blk_num ?  4 + bindex/4 : bindex/4);
  54488                         bindex = bindex%4;
  54489                     } else {
  54490                         blk_num = 3;
  54491                     }
  54492                 }
  54493 #if defined(BCM_KATANA2_SUPPORT)
  54494                 if (SOC_IS_KATANA2(unit)) {
  54495                     /* In KT2 E2ECC is implemented only in blocks 6..9 */
  54496                     blk_num = (blk_num >= 6) ? (blk_num - 6) : blk_num ;
  54497                     if (SOC_IS_SABER2(unit)) {
  54498                         SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 0));
  54499                     }
  54500                 }
  54501 #endif
  54502                 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_ENABLE_BMPr(unit, blk_num,
  54503                                                               &regval));
  54504                 if (regval & (1 << bindex)) {
  54505                     new_hg_pbm = soc_reg_field_get(unit, E2ECC_TX_ENABLE_BMPr, regval,
  54506                                                    TX_ENABLE_BMPf);
  54507                     new_hg_pbm &= ~(1 << bindex);
  54508                     soc_reg_field_set(unit, E2ECC_TX_ENABLE_BMPr, &regval,
  54509                                       TX_ENABLE_BMPf, new_hg_pbm);
  54510                     SOC_IF_ERROR_RETURN
  54511                         (WRITE_E2ECC_TX_ENABLE_BMPr(unit, blk_num, regval));
  54512                 }
  54513             }
  54514 
  54515             if (SOC_IS_TD2_TT2(unit) || SOC_IS_HURRICANE3(unit) ||
  54516                 SOC_IS_GREYHOUND2(unit)) {
  54517                 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 0));
  54518             }
  54519         }
  54520 
  54521         /* Clear per-port registers holding the E2ECC message header */
  54522         sal_memset(&e2ecc_hdr, 0, sizeof(soc_higig_e2ecc_hdr_t));
  54523         BCM_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_hdr_set(unit, port, &e2ecc_hdr));
  54524     }
  54525 
  54526     return BCM_E_NONE;
  54527 }
  54528 
  54529 /*
  54530  * Function:
  54531  *      _bcm_esw_port_e2ecc_rx
  54532  * Purpose:
  54533  *      Configure E2ECC message reception.
  54534  * Parameters:
  54535  *      unit - (IN) Unit number.
  54536  *      port - (IN) Local port number.
  54537  *      config - (IN) Congestion configuration.
  54538  * Returns:
  54539  *      BCM_E_xxx
  54540  */
  54541 STATIC int
  54542 _bcm_esw_port_e2ecc_rx(int unit, bcm_port_t port,
  54543                        bcm_port_congestion_config_t *config)
  54544 {
  54545     uint32 regval;
  54546     uint64 regval64;
  54547     uint32 field_val;
  54548 
  54549     if (config->flags & BCM_PORT_CONGESTION_CONFIG_RX) {
  54550         /* If BCM_PORT_CONGESTION_CONFIG_RX flag is set, enable E2ECC reception. */
  54551 
  54552         /* Make sure chip-wide E2ECC reception disable bit is cleared */
  54553         SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, &regval64));
  54554         if (soc_reg64_field32_get(unit, ING_CONFIG_64r, regval64,
  54555                                   DISABLE_E2E_HOL_CHECKf) == 1) {
  54556             soc_reg64_field32_set(unit, ING_CONFIG_64r, &regval64,
  54557                                   DISABLE_E2E_HOL_CHECKf, 0);
  54558             SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, regval64));
  54559         }
  54560 
  54561         /* Set per-port E2ECC RX enable bit */
  54562         SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &regval));
  54563         if (soc_reg_field_get(unit, IE2E_CONTROLr, regval,
  54564                               HOL_ENABLEf) == 0) {
  54565             soc_reg_field_set(unit, IE2E_CONTROLr, &regval, HOL_ENABLEf, 1);
  54566             SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval));
  54567         }
  54568 
  54569         /* Configure E2ECC receive MAC-DA, Length/Type, and Opcode */
  54570 
  54571         field_val = (config->dest_mac[0] << 8) |    /* MAC-DA[47:40] */
  54572                     (config->dest_mac[1]);          /* MAC-DA[39:32] */
  54573         SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_DA_MSr(unit, &regval));
  54574         soc_reg_field_set(unit, E2E_HOL_RX_DA_MSr, &regval, DAf, field_val);
  54575         SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_RX_DA_MSr(unit, regval));
  54576 
  54577         field_val = (config->dest_mac[2] << 24) |    /* MAC-DA[31:24] */
  54578                     (config->dest_mac[3] << 16) |    /* MAC-DA[23:16] */
  54579                     (config->dest_mac[4] << 8) |     /* MAC-DA[15:8] */
  54580                     (config->dest_mac[5]);           /* MAC-DA[7:0] */
  54581         SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_DA_LSr(unit, &regval));
  54582         soc_reg_field_set(unit, E2E_HOL_RX_DA_LSr, &regval, DAf, field_val);
  54583         SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_RX_DA_LSr(unit, regval));
  54584 
  54585         SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_LENGTH_TYPEr(unit, &regval));
  54586         soc_reg_field_set(unit, E2E_HOL_RX_LENGTH_TYPEr, &regval, LENGTH_TYPEf, config->ethertype);
  54587         SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_RX_LENGTH_TYPEr(unit, regval));
  54588 
  54589         SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_OPCODEr(unit, &regval));
  54590         soc_reg_field_set(unit, E2E_HOL_RX_OPCODEr, &regval, OPCODEf, config->opcode);
  54591         SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_RX_OPCODEr(unit, regval));
  54592 
  54593     } else {
  54594         /* If BCM_PORT_CONGESTION_CONFIG_RX flag is not set, disable E2ECC reception. */
  54595 
  54596         /* Clear per-port E2ECC RX enable bit */
  54597         SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &regval));
  54598         if (soc_reg_field_get(unit, IE2E_CONTROLr, regval, HOL_ENABLEf) == 1) {
  54599             soc_reg_field_set(unit, IE2E_CONTROLr, &regval, HOL_ENABLEf, 0);
  54600             SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval));
  54601         }
  54602     }
  54603 
  54604     return BCM_E_NONE;
  54605 }
  54606 
  54607 STATIC int
  54608 _bcm_tr3_port_hcfc(int unit, bcm_port_t port,
  54609                    bcm_port_congestion_config_t *config)
  54610 {
  54611 #if defined(BCM_TRIUMPH3_SUPPORT)
  54612     soc_reg_t reg;
  54613     int enable;
  54614     uint32 rval;
  54615     uint64 rval64, fval64, tmp;
  54616 
  54617     enable = config->flags & BCM_PORT_CONGESTION_CONFIG_TX ? 1 : 0;
  54618     BCM_IF_ERROR_RETURN
  54619         (_bcm_esw_port_drop_status_enable_set(unit, port, enable));
  54620 
  54621     /* Configure egress status reporting */
  54622     reg = OOBFC_ENG_PORT_EN_64r;
  54623     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64));
  54624     fval64 = soc_reg64_field_get(unit, reg, rval64, ENG_PORT_ENf);
  54625     COMPILER_64_SET(tmp, 0, 1);
  54626     COMPILER_64_SHL(tmp, port);
  54627     COMPILER_64_AND(fval64, tmp);
  54628     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64));
  54629 
  54630     SOC_IF_ERROR_RETURN(READ_OOBFC_GCSr(unit, &rval));
  54631     soc_reg_field_set(unit, OOBFC_GCSr, &rval, GCS_ENf, 0);
  54632     SOC_IF_ERROR_RETURN(WRITE_OOBFC_GCSr(unit, rval));
  54633 
  54634     return BCM_E_NONE;
  54635 #else
  54636     return BCM_E_UNAVAIL;
  54637 #endif
  54638 }
  54639 
  54640 
  54641 /*
  54642  * Function:
  54643  *      _bcm_esw_port_hcfc_tx
  54644  * Purpose:
  54645  *      configure the port hcfc egress status to enable 
  54646  * Parameters:
  54647  *      unit - (IN) Unit number.
  54648  *      port - (IN) Port number
  54649  *      config - (IN) Configuration
  54650  * Returns:
  54651  *      BCM_E_xxx
  54652  * Notes:
  54653  */
  54654 STATIC int
  54655 _bcm_esw_port_hcfc_tx(int unit, bcm_port_t port,
  54656                    bcm_port_congestion_config_t *config)
  54657 {
  54658     soc_reg_t reg, reg0, reg1;
  54659     int enable, len;
  54660     uint64 rval64, fval64;
  54661     uint32 fval_hi, fval_lo;
  54662 
  54663     if (!SOC_PORT_VALID(unit, port)) {
  54664         return BCM_E_PORT;
  54665     }
  54666 
  54667     if (SOC_REG_IS_VALID(unit, OOBFC_ENG_PORT_EN0_64r)) {
  54668         reg0 = OOBFC_ENG_PORT_EN0_64r;
  54669         reg1 = OOBFC_ENG_PORT_EN1_64r;
  54670     } else {
  54671         reg0 = OOBFC_ENG_PORT_EN_0_64r;
  54672         reg1 = OOBFC_ENG_PORT_EN_1_64r;
  54673     }
  54674     if (!(SOC_REG_IS_VALID(unit, reg0)) || !(SOC_REG_IS_VALID(unit, reg1))) {
  54675         return BCM_E_PORT;
  54676     }
  54677 
  54678     /* Configure egress status reporting */
  54679     len = soc_reg_field_length(unit, reg0, ENG_PORT_ENf);
  54680     if (len < 1) {
  54681         return BCM_E_PORT;
  54682     }
  54683     if (port < len) { /* First half of logical ports (not mmu port) */
  54684         reg = reg0;
  54685     } else {          /* Second half of logical ports (not mmu port) */
  54686         reg = reg1;
  54687     }
  54688     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64));
  54689     fval64 = soc_reg64_field_get(unit, reg, rval64, ENG_PORT_ENf);
  54690     fval_hi = COMPILER_64_HI(fval64);
  54691     fval_lo = COMPILER_64_LO(fval64);
  54692     enable = config->flags & BCM_PORT_CONGESTION_CONFIG_TX ? 1 : 0;
  54693     if (enable) {
  54694         if (port < len) {
  54695             if (port < 32) {
  54696                 fval_lo |= (1 << port);
  54697             } else {
  54698                 /* coverity[large_shift : FALSE] */
  54699                 fval_hi |= (1 << (port - 32));
  54700             }
  54701         } else {
  54702             int port_offset = port - len;
  54703             if ( port_offset < 32 ) {
  54704                 fval_lo |= (1 << port_offset);
  54705             } else {
  54706                 fval_hi |= (1 << (port_offset - 32));
  54707             }
  54708         }
  54709     } else {
  54710         if (port < len) {
  54711             if (port < 32) {
  54712                 fval_lo &= ~(1 << port);
  54713             } else {
  54714                 /* coverity[large_shift : FALSE] */
  54715                 fval_hi &= ~(1 << (port - 32));
  54716             }
  54717         } else {
  54718             int port_offset = port - len;
  54719             if ( port_offset < 32 ) {
  54720                 fval_lo &= ~(1 << port_offset);
  54721             } else {
  54722                 fval_hi &= ~(1 << (port_offset - 32));
  54723             }
  54724         }
  54725     }
  54726     COMPILER_64_SET(fval64, fval_hi, fval_lo);
  54727     soc_reg64_field_set(unit, reg, &rval64, ENG_PORT_ENf, fval64);
  54728     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64));
  54729 
  54730     return BCM_E_NONE;
  54731 }
  54732 
  54733 /*
  54734  * Function:
  54735  *      _bcm_esw_port_hcfc_rx
  54736  * Purpose:
  54737  *      configure the port hcfc ingress status to enable 
  54738  * Parameters:
  54739  *      unit - (IN) Unit number.
  54740  *      port - (IN) Port number
  54741  *      config - (IN) Configuration
  54742  * Returns:
  54743  *      BCM_E_xxx
  54744  * Notes:
  54745  */
  54746 STATIC int
  54747 _bcm_esw_port_hcfc_rx(int unit, bcm_port_t port,
  54748                    bcm_port_congestion_config_t *config)
  54749 {
  54750     soc_reg_t reg, reg0, reg1;
  54751     int enable, len;
  54752     uint64 rval64, fval64;
  54753     uint32 fval_hi, fval_lo;
  54754    
  54755     if (!SOC_PORT_VALID(unit, port)) {
  54756         return BCM_E_PORT;
  54757     }
  54758 
  54759     if (SOC_REG_IS_VALID(unit, OOBFC_ING_PORT_EN0_64r)) {
  54760         reg0 = OOBFC_ING_PORT_EN0_64r;
  54761         reg1 = OOBFC_ING_PORT_EN1_64r;
  54762     } else {
  54763         reg0 = OOBFC_ING_PORT_EN_0_64r;
  54764         reg1 = OOBFC_ING_PORT_EN_1_64r;
  54765     }
  54766     if (!(SOC_REG_IS_VALID(unit, reg0)) || !(SOC_REG_IS_VALID(unit, reg1))) {
  54767         return BCM_E_PORT;
  54768     }
  54769 
  54770     /* Configure ingress status reporting */
  54771     len = soc_reg_field_length(unit, reg0, ING_PORT_ENf);
  54772     if (len < 1) {
  54773         return BCM_E_PORT;
  54774     }
  54775     if (port < len) { /* First half of logical ports (not mmu port) */
  54776         reg = reg0;
  54777     } else {          /* Second half of logical ports (not mmu port) */
  54778         reg = reg1;
  54779     }
  54780     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64));
  54781     fval64 = soc_reg64_field_get(unit, reg, rval64, ING_PORT_ENf);
  54782     fval_hi = COMPILER_64_HI(fval64);
  54783     fval_lo = COMPILER_64_LO(fval64);
  54784 
  54785     enable = config->flags & BCM_PORT_CONGESTION_CONFIG_RX ? 1 : 0;
  54786     if (enable) {
  54787         if (port < len) {
  54788             if (port < 32) {
  54789                 fval_lo |= (1 << port);
  54790             } else {
  54791                 /* coverity[large_shift : FALSE] */
  54792                 fval_hi |= (1 << (port - 32));
  54793             }
  54794         } else {
  54795             int port_offset = port - len;
  54796             if ( port_offset < 32 ) {
  54797                 fval_lo |= (1 << port_offset);
  54798             } else {
  54799                 fval_hi |= (1 << (port_offset - 32));
  54800             }
  54801         }
  54802     } else {
  54803         if (port < len) {
  54804             if (port < 32) {
  54805                 fval_lo &= ~(1 << port);
  54806             } else {
  54807                 /* coverity[large_shift : FALSE] */
  54808                 fval_hi &= ~(1 << (port - 32));
  54809             }
  54810         } else {
  54811             int port_offset = port - len;
  54812             if ( port_offset < 32 ) {
  54813                 fval_lo &= ~(1 << port_offset);
  54814             } else {
  54815                 fval_hi &= ~(1 << (port_offset - 32));
  54816             }
  54817         }
  54818     }
  54819     COMPILER_64_SET(fval64, fval_hi, fval_lo);
  54820     soc_reg64_field_set(unit, reg, &rval64, ING_PORT_ENf, fval64);
  54821     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64));
  54822 
  54823     return BCM_E_NONE;
  54824 }
  54825 
  54826 
  54827 STATIC int
  54828 _bcm_esw_port_hcfc(int unit, bcm_port_t port,
  54829                    bcm_port_congestion_config_t *config)
  54830 {
  54831     int enable;
  54832     uint32 rval;
  54833 
  54834     enable = config->flags & BCM_PORT_CONGESTION_CONFIG_TX ? 1 : 0;
  54835     BCM_IF_ERROR_RETURN
  54836         (_bcm_esw_port_drop_status_enable_set(unit, port, enable));
  54837 
  54838     BCM_IF_ERROR_RETURN(_bcm_esw_port_hcfc_tx(unit, port, config));
  54839 
  54840     BCM_IF_ERROR_RETURN(_bcm_esw_port_hcfc_rx(unit, port, config));
  54841 
  54842     SOC_IF_ERROR_RETURN(READ_OOBFC_GCSr(unit, &rval));
  54843     soc_reg_field_set(unit, OOBFC_GCSr, &rval, GCS_ENf, 0);
  54844     SOC_IF_ERROR_RETURN(WRITE_OOBFC_GCSr(unit, rval));
  54845 
  54846     return BCM_E_NONE;
  54847 }
  54848 
  54849 #ifdef BCM_KATANA2_SUPPORT
  54850 STATIC int
  54851 _bcm_esw_port_coe_e2ecc(int unit, bcm_port_t port,
  54852                        bcm_port_congestion_config_t *config)
  54853 {
  54854 
  54855     uint32 regval = 0;
  54856     int en;
  54857     int e2ecc_strict = -1;
  54858     uint32 field_val;
  54859     int index;
  54860     mmu_intfi_st_trans_tbl_entry_t st_trans_entry;
  54861     uint16      dev_id;
  54862     uint8       rev_id;
  54863 
  54864     soc_cm_get_id(unit, &dev_id, &rev_id);
  54865 
  54866     en = config->flags & BCM_PORT_CONGESTION_CONFIG_RX ? 1 : 0;
  54867 
  54868     if ((config->flags &
  54869          BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE)) {
  54870         e2ecc_strict = 0;
  54871     } else if (config->flags &
  54872                BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) {
  54873         e2ecc_strict = 1;
  54874     } else {
  54875         return BCM_E_PARAM;
  54876     }
  54877     if ((rev_id == BCM56450_A0_REV_ID) && (!SOC_IS_SABER2(unit))) {
  54878        if (e2ecc_strict) {
  54879            /* E2ECC STRICT mode only valid for BCM56450_B0 onwards
  54880             */
  54881            return BCM_E_UNAVAIL;
  54882        }
  54883     } else if ((rev_id >= BCM56450_B0_REV_ID) || SOC_IS_SABER2(unit)) {
  54884         /* setting of strict/flex mode is valid only when flow control is
  54885          * enabled
  54886          */
  54887         e2ecc_strict = (en ? e2ecc_strict : 0);
  54888         SOC_IF_ERROR_RETURN(
  54889                    READ_COE_FLOW_CONTROL_CONFIGr (unit, port, &regval));
  54890         /* Enable the Flow control and E2ECC mode
  54891          * 1. When there is enable request
  54892          * 2. When flow control is already enabled
  54893          *    and there is change in E2ECC_mode from
  54894          *    strict to flex or vice versa
  54895          */
  54896         if ((en != soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr,
  54897                   regval, FLOW_CONTROL_FORMATf)) ||
  54898               (en && (soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr,
  54899                   regval, FLOW_CONTROL_FORMATf) == 1) &&
  54900                (e2ecc_strict != soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr,
  54901                regval, E2ECC_MODEf)))) {
  54902             soc_reg_field_set(unit, COE_FLOW_CONTROL_CONFIGr, &regval,
  54903                         FLOW_CONTROL_FORMATf, en);
  54904             soc_reg_field_set(unit, COE_FLOW_CONTROL_CONFIGr, &regval,
  54905                         E2ECC_MODEf, e2ecc_strict);
  54906             SOC_IF_ERROR_RETURN(
  54907               WRITE_COE_FLOW_CONTROL_CONFIGr (unit, port, regval));
  54908         }
  54909     }
  54910 
  54911     if (en) {
  54912         /* Configure E2ECC-FC receive MAC-DA, Length/Type, and Opcode */
  54913         field_val = (config->dest_mac[0] << 8) |    /* MAC-DA[47:40] */
  54914                     (config->dest_mac[1]);          /* MAC-DA[39:32] */
  54915         SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_MSr(unit, &regval));
  54916         soc_reg_field_set(unit, ING_VOQFC_MACDA_MSr, &regval, DAf, field_val);
  54917         SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_MACDA_MSr(unit, regval));
  54918 
  54919         field_val = (config->dest_mac[2] << 24) |    /* MAC-DA[31:24] */
  54920                     (config->dest_mac[3] << 16) |    /* MAC-DA[23:16] */
  54921                     (config->dest_mac[4] << 8) |     /* MAC-DA[15:8] */
  54922                     (config->dest_mac[5]);           /* MAC-DA[7:0] */
  54923 
  54924         SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_LSr(unit, &regval));
  54925         soc_reg_field_set(unit, ING_VOQFC_MACDA_LSr, &regval, DAf, field_val);
  54926         SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_MACDA_LSr(unit, regval));
  54927 
  54928 
  54929         SOC_IF_ERROR_RETURN(READ_ING_VOQFC_IDr(unit, &regval));
  54930         soc_reg_field_set(unit, ING_VOQFC_IDr, &regval,
  54931                           LENGTH_TYPEf, config->ethertype);
  54932 
  54933         soc_reg_field_set(unit, ING_VOQFC_IDr, &regval,
  54934                            OPCODEf, config->opcode);
  54935         SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_IDr(unit, regval));
  54936 
  54937         /*
  54938          * Hardcoding the MMU_INTFI_ST_TRANS_TBL so the
  54939          * congestion data is written as it is
  54940          * in FC_ST_TABLE
  54941          */
  54942 
  54943         for (index=0 ; index < soc_mem_index_count(unit,
  54944                     MMU_INTFI_ST_TRANS_TBLm); index++) {
  54945             SOC_IF_ERROR_RETURN(READ_MMU_INTFI_ST_TRANS_TBLm(
  54946                         unit, MEM_BLOCK_ALL,index,
  54947                         &st_trans_entry));
  54948             soc_mem_field32_set(unit, MMU_INTFI_ST_TRANS_TBLm,
  54949                     &st_trans_entry, FC_ST_XLATEf,index%256);
  54950             SOC_IF_ERROR_RETURN(WRITE_MMU_INTFI_ST_TRANS_TBLm(
  54951                         unit, MEM_BLOCK_ALL, index,
  54952                         &st_trans_entry));
  54953         }
  54954 
  54955         /*
  54956          * Hardcoding FC_WIDTH to 3 so that 8 bits are read at time
  54957          */
  54958         SOC_IF_ERROR_RETURN
  54959             (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  54960                                     FC_WIDTHf, 3));
  54961         /*
  54962          * In case of COE E2ECC merger block should be disabled
  54963          */
  54964 
  54965         SOC_IF_ERROR_RETURN
  54966             (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  54967                                     MERGE_ENf, 0));
  54968         /*
  54969          * Hardcode the INTFI_MAP_L0/L1/L2_TBL_ADDR,
  54970          * so that state machine reads
  54971          * all the L1,L2,L3 Nodes in a cycle
  54972          */
  54973 
  54974 
  54975         SOC_IF_ERROR_RETURN
  54976             (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY,
  54977                                     FC_MAP_TBL_ADDR_ENf, 0));
  54978         SOC_IF_ERROR_RETURN
  54979             (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY,
  54980                                     FC_MAP_TBL_START_ADDRf, 0));
  54981         if (SOC_IS_SABER2(unit)) {
  54982     #ifdef BCM_METROLITE_SUPPORT
  54983             if (SOC_IS_METROLITE(unit))  {
  54984                 SOC_IF_ERROR_RETURN 
  54985                 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY,
  54986                                         FC_MAP_TBL_END_ADDRf, 0x1f)); 
  54987             } else 
  54988     #endif 
  54989             SOC_IF_ERROR_RETURN
  54990                 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY,
  54991                                        FC_MAP_TBL_END_ADDRf, 0x3f));
  54992         } else {
  54993             SOC_IF_ERROR_RETURN
  54994                 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY,
  54995                                        FC_MAP_TBL_END_ADDRf, 0xff));
  54996         }
  54997         SOC_IF_ERROR_RETURN
  54998             (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY,
  54999                                     FC_MAP_TBL_ADDR_ENf, 0));
  55000         SOC_IF_ERROR_RETURN
  55001             (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY,
  55002                                     FC_MAP_TBL_START_ADDRf, 0));
  55003         if (SOC_IS_SABER2(unit)) {
  55004     #ifdef BCM_METROLITE_SUPPORT
  55005             if (SOC_IS_METROLITE(unit))  {
  55006                 SOC_IF_ERROR_RETURN
  55007                 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY,
  55008                                         FC_MAP_TBL_END_ADDRf, 0x7));
  55009             } else
  55010     #endif 
  55011             SOC_IF_ERROR_RETURN
  55012                 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY,
  55013                                         FC_MAP_TBL_END_ADDRf, 0xf));
  55014         } else {
  55015             SOC_IF_ERROR_RETURN
  55016                 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY,
  55017                                         FC_MAP_TBL_END_ADDRf, 0x3f));
  55018         }
  55019         SOC_IF_ERROR_RETURN
  55020             (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY,
  55021                                     FC_MAP_TBL_ADDR_ENf, 0));
  55022         SOC_IF_ERROR_RETURN
  55023             (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY,
  55024                                     FC_MAP_TBL_START_ADDRf, 0));
  55025         if (SOC_IS_SABER2(unit)) {
  55026     #ifdef BCM_METROLITE_SUPPORT
  55027             if (SOC_IS_METROLITE(unit))  {
  55028                 SOC_IF_ERROR_RETURN
  55029                 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY,
  55030                                         FC_MAP_TBL_END_ADDRf, 0x3));
  55031             } else 
  55032     #endif
  55033             SOC_IF_ERROR_RETURN
  55034                 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY,
  55035                                         FC_MAP_TBL_END_ADDRf, 0x7));
  55036         } else {
  55037             SOC_IF_ERROR_RETURN
  55038                 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY,
  55039                                         FC_MAP_TBL_END_ADDRf, 0x1f));
  55040         }
  55041 
  55042         if (e2ecc_strict == 0) {
  55043             SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &regval));
  55044             if (en != soc_reg_field_get(unit, IE2E_CONTROLr, regval,
  55045                                 VOQFC_ENABLEf)) {
  55046                 soc_reg_field_set(unit, IE2E_CONTROLr, &regval,
  55047                                   VOQFC_ENABLEf, en);
  55048                 SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval));
  55049             }
  55050         } else {
  55051             SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &regval));
  55052             if (soc_reg_field_get(unit, IE2E_CONTROLr, regval,
  55053                                 VOQFC_ENABLEf)) {
  55054                 soc_reg_field_set(unit, IE2E_CONTROLr, &regval,
  55055                                   VOQFC_ENABLEf, 0);
  55056                 SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval));
  55057             }
  55058         }
  55059     } else {
  55060         if (e2ecc_strict == 0) {
  55061             SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &regval));
  55062             if (soc_reg_field_get(unit, IE2E_CONTROLr, regval,
  55063                                 VOQFC_ENABLEf)) {
  55064                 soc_reg_field_set(unit, IE2E_CONTROLr, &regval,
  55065                                   VOQFC_ENABLEf, 0);
  55066                 SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval));
  55067             }
  55068         }
  55069     }
  55070 
  55071     return BCM_E_NONE;
  55072 }
  55073 #endif
  55074 
  55075 /*
  55076  * Function:
  55077  *      _bcm_esw_port_dmvoqfc_rx
  55078  * Purpose:
  55079  *      Configure VOQFC message reception.
  55080  * Parameters:
  55081  *      unit - (IN) Unit number.
  55082  *      port - (IN) Local port number.
  55083  *      config - (IN) Congestion configuration.
  55084  * Returns:
  55085  *      BCM_E_xxx
  55086  */
  55087 STATIC int
  55088 _bcm_esw_port_dmvoqfc_rx(int unit, bcm_port_t port,
  55089                        bcm_port_congestion_config_t *config)
  55090 {
  55091     uint32 regval;
  55092     uint32 field_val;
  55093     int     en, cos_mode;
  55094 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT) || \
  55095     defined(BCM_TRIUMPH3_SUPPORT)
  55096     int index;
  55097 #endif
  55098 #if defined(BCM_TRIDENT2_SUPPORT)
  55099     uint64 rval;
  55100 #endif
  55101 #if defined(BCM_TRIUMPH3_SUPPORT)
  55102     uint32 rval1;
  55103     mmu_intfi_st_trans_tbl_entry_t st_trans_entry;
  55104 #endif
  55105 
  55106     en = config->flags & BCM_PORT_CONGESTION_CONFIG_RX ? 1 : 0;
  55107     cos_mode = config->flags & BCM_PORT_CONGESTION_CONFIG_RX ? 1 : 0;
  55108     SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &regval));
  55109     if (en != soc_reg_field_get(unit, IE2E_CONTROLr, regval,
  55110                                 VOQFC_ENABLEf)) {
  55111         soc_reg_field_set(unit, IE2E_CONTROLr, &regval, VOQFC_ENABLEf, en);
  55112         SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval));
  55113     }
  55114 #ifdef BCM_TRIDENT2_SUPPORT
  55115     if (SOC_IS_TD2_TT2(unit)) {
  55116         SOC_IF_ERROR_RETURN(READ_ING_COS_MODE_64r(unit, port, &rval));
  55117         if (cos_mode != soc_reg64_field32_get(unit, ING_COS_MODE_64r, rval,
  55118                     QUEUE_MODEf)) {
  55119             soc_reg64_field32_set(unit, ING_COS_MODE_64r, &rval, QUEUE_MODEf, cos_mode);
  55120             SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODE_64r(unit, port, rval));
  55121         }
  55122         /*
  55123          *  FC_WIDTH is set to 2 so that 4 bits of i
  55124          * congestion data is read on each cycle
  55125          */
  55126         SOC_IF_ERROR_RETURN
  55127             (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  55128                                     FC_WIDTHf, 2));
  55129         /*
  55130          * MERGE_EN is set to 1, to merge the congestion state
  55131          * received from different ports of the same module
  55132          */
  55133 
  55134         SOC_IF_ERROR_RETURN
  55135             (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  55136                                     MERGE_ENf, 1));
  55137         /* MODE_SEL is set to 1 to specify the message is of type
  55138          *  DMVOQ
  55139          */
  55140         SOC_IF_ERROR_RETURN
  55141             (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  55142                                     MODE_SELf, 1));
  55143 #ifdef BCM_APACHE_SUPPORT
  55144         if (SOC_IS_APACHE(unit)) {
  55145             if (config->flags & BCM_PORT_CONGESTION_CONFIG_DESTMODPORT_FLOW_CONTROL) {
  55146                 /*
  55147                 * MERGE_EN is set to 0, in case of DPVOQ.
  55148                 */
  55149 
  55150                 SOC_IF_ERROR_RETURN
  55151                     (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  55152                                             MERGE_ENf, 0));
  55153                 /* MODE_SEL is set to 0 to specify the message is of type
  55154                 *  DPVOQ
  55155                 */
  55156                 SOC_IF_ERROR_RETURN
  55157                     (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  55158                                             MODE_SELf, 0));
  55159             }
  55160         }
  55161 #endif
  55162         /* DMVOQ congestion bytes max length is 64 bytes,
  55163          * as a result
  55164          * DMVOQ feature can support upto 64 ports
  55165          */
  55166 
  55167         for (index = 0 ; index < SOC_REG_NUMELS(unit, CONGESTION_STATE_BYTESr)
  55168                 ; index++) {
  55169             soc_reg_field_set(unit, CONGESTION_STATE_BYTESr, &regval,
  55170                     DATAf, BCM_MAX_PORTS_SUPPORT_FOR_DMVOQ);
  55171             SOC_IF_ERROR_RETURN(WRITE_CONGESTION_STATE_BYTESr(unit,
  55172                         index, regval));
  55173         }
  55174 
  55175     } else
  55176 #endif
  55177 #ifdef BCM_KATANA2_SUPPORT
  55178      if (SOC_IS_KATANA2(unit)) {
  55179         SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, &regval));
  55180         if (cos_mode != soc_reg_field_get(unit, ING_COS_MODEr, regval,
  55181                     COS_MODEf)) {
  55182             soc_reg_field_set(unit, ING_COS_MODEr, &regval, COS_MODEf, cos_mode);
  55183             SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODEr(unit, port, regval));
  55184         }
  55185 
  55186         /*
  55187          * Hardcoding FC_WIDTH to 3 so that 8 bits are read at time
  55188          */
  55189         SOC_IF_ERROR_RETURN
  55190             (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  55191                                     FC_WIDTHf, 3));
  55192         if (config->flags & BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL) {
  55193         /*
  55194          * In case of DMVOQ we need to merge all the congestion bytes
  55195          * of the ports so enabling MERGE_EN
  55196          */
  55197 
  55198         SOC_IF_ERROR_RETURN
  55199             (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  55200                                     MERGE_ENf, 1));
  55201         }
  55202         /*
  55203          * Hardcode the INTFI_MAP_L0/L1/L2_TBL_ADDR,
  55204          * so that state machine reads
  55205          * all the L1,L2,L3 Nodes in a cycle
  55206          */
  55207 
  55208         SOC_IF_ERROR_RETURN
  55209             (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY,
  55210                                     FC_MAP_TBL_ADDR_ENf, 0));
  55211         SOC_IF_ERROR_RETURN
  55212             (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY,
  55213                                     FC_MAP_TBL_START_ADDRf, 0));
  55214         SOC_IF_ERROR_RETURN
  55215             (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY,
  55216                                    FC_MAP_TBL_END_ADDRf, 
  55217                                    ((soc_mem_index_count(unit, LLS_L2_PARENTm)) / 16) - 1));
  55218         SOC_IF_ERROR_RETURN
  55219             (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY,
  55220                                     FC_MAP_TBL_ADDR_ENf, 0));
  55221         SOC_IF_ERROR_RETURN
  55222             (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY,
  55223                                     FC_MAP_TBL_START_ADDRf, 0));
  55224         SOC_IF_ERROR_RETURN
  55225             (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY,
  55226                                     FC_MAP_TBL_END_ADDRf, 
  55227                                    ((soc_mem_index_count(unit, LLS_L1_PARENTm)) / 16) - 1 ));
  55228         SOC_IF_ERROR_RETURN
  55229             (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY,
  55230                                     FC_MAP_TBL_ADDR_ENf, 0));
  55231         SOC_IF_ERROR_RETURN
  55232             (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY,
  55233                                     FC_MAP_TBL_START_ADDRf, 0));
  55234         SOC_IF_ERROR_RETURN
  55235             (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY,
  55236                                     FC_MAP_TBL_END_ADDRf, 
  55237                                    ((soc_mem_index_count(unit, LLS_L0_PARENTm)) / 
  55238                                     (SOC_IS_METROLITE(unit) ? 32: 16)) - 1));
  55239 
  55240         /* Though the number of ports supported in KT2 is 41, we're setting the
  55241            max to 64 to support stacked systems. */
  55242         for (index = 0 ; index < SOC_REG_NUMELS(unit, CONGESTION_STATE_BYTESr)
  55243                 ; index++) {
  55244             soc_reg_field_set(unit, CONGESTION_STATE_BYTESr, &regval,
  55245                     DATAf, BCM_MAX_PORTS_SUPPORT_FOR_DMVOQ);
  55246             SOC_IF_ERROR_RETURN(WRITE_CONGESTION_STATE_BYTESr(unit,
  55247                         index, regval));
  55248         }
  55249 
  55250     } else 
  55251 #endif
  55252 #ifdef BCM_TRIUMPH3_SUPPORT
  55253     if (SOC_IS_TRIUMPH3(unit)) {
  55254         SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, &rval1));
  55255         if (cos_mode != soc_reg_field_get(unit, ING_COS_MODEr, rval1,
  55256                     QUEUE_MODEf)) {
  55257             soc_reg_field_set(unit, ING_COS_MODEr, &rval1, QUEUE_MODEf, cos_mode);
  55258             SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODEr(unit, port, rval1));
  55259         }
  55260         /* 
  55261          * Hardcoding the MMU_INTFI_ST_TRANS_TBL so the 
  55262          * congestion data is written as it is
  55263          * in FC_ST_TABLE, This we are doing so that 
  55264          * congestion data is updated as it is how
  55265          * it recevied
  55266          */
  55267 
  55268         for (index=0 ; index < soc_mem_index_count(unit, 
  55269                     MMU_INTFI_ST_TRANS_TBLm); index++) { 
  55270             SOC_IF_ERROR_RETURN(READ_MMU_INTFI_ST_TRANS_TBLm(
  55271                         unit, MEM_BLOCK_ALL,index,
  55272                         &st_trans_entry));
  55273             soc_mem_field32_set(unit, MMU_INTFI_ST_TRANS_TBLm,
  55274                     &st_trans_entry, FC_ST_XLATEf,index%16);
  55275             SOC_IF_ERROR_RETURN(WRITE_MMU_INTFI_ST_TRANS_TBLm(
  55276                         unit, MEM_BLOCK_ALL, index,
  55277                         &st_trans_entry));
  55278         }
  55279         /*
  55280          *  FC_WIDTH is set to 2 so that 4 bits of i
  55281          * congestion data is read on each cycle
  55282          */
  55283         SOC_IF_ERROR_RETURN
  55284             (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  55285                                     FC_WIDTHf, 2));
  55286         /*
  55287          * MERGE_EN is set to 1, to merge the congestion state 
  55288          * received from different ports of the same module
  55289          */
  55290 
  55291         SOC_IF_ERROR_RETURN
  55292             (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY,
  55293                                     MERGE_ENf, 1));
  55294         /* DMVOQ congestion bytes max length is 64 bytes,
  55295          * as a result  
  55296          * DMVOQ feature can support upto 64 ports
  55297          */
  55298 
  55299         for (index = 0; index < SOC_REG_NUMELS(unit, CONGESTION_STATE_BYTESr)
  55300                 ; index++) {
  55301             soc_reg_field_set(unit, CONGESTION_STATE_BYTESr, &regval,
  55302                     DATAf, BCM_MAX_PORTS_SUPPORT_FOR_DMVOQ);
  55303             SOC_IF_ERROR_RETURN(WRITE_CONGESTION_STATE_BYTESr(unit, 
  55304                         index, regval));
  55305         }
  55306 
  55307     } else
  55308 #endif
  55309     {
  55310         SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, &regval));
  55311         if (cos_mode != soc_reg_field_get(unit, ING_COS_MODEr, regval,
  55312                     QUEUE_MODEf)) {
  55313             soc_reg_field_set(unit, ING_COS_MODEr, &regval, QUEUE_MODEf, cos_mode);
  55314             SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODEr(unit, port, regval));
  55315         }
  55316     }
  55317 
  55318     if (en) {
  55319         /* Configure DMVOQFC receive MAC-DA, Length/Type, and Opcode */
  55320         field_val = (config->dest_mac[0] << 8) |    /* MAC-DA[47:40] */
  55321                     (config->dest_mac[1]);          /* MAC-DA[39:32] */
  55322         SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_MSr(unit, &regval));
  55323         soc_reg_field_set(unit, ING_VOQFC_MACDA_MSr, &regval, DAf, field_val);
  55324         SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_MACDA_MSr(unit, regval));
  55325 
  55326         field_val = (config->dest_mac[2] << 24) |    /* MAC-DA[31:24] */
  55327                     (config->dest_mac[3] << 16) |    /* MAC-DA[23:16] */
  55328                     (config->dest_mac[4] << 8) |     /* MAC-DA[15:8] */
  55329                     (config->dest_mac[5]);           /* MAC-DA[7:0] */
  55330 
  55331         SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_LSr(unit, &regval));
  55332         soc_reg_field_set(unit, ING_VOQFC_MACDA_LSr, &regval, DAf, field_val);
  55333         SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_MACDA_LSr(unit, regval));
  55334 
  55335 
  55336         SOC_IF_ERROR_RETURN(READ_ING_VOQFC_IDr(unit, &regval));
  55337         soc_reg_field_set(unit, ING_VOQFC_IDr, &regval,
  55338                           LENGTH_TYPEf, config->ethertype);
  55339 
  55340         soc_reg_field_set(unit, ING_VOQFC_IDr, &regval, OPCODEf, config->opcode);
  55341         SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_IDr(unit, regval));
  55342     }
  55343 
  55344     return BCM_E_NONE;
  55345 }
  55346 /*
  55347  * Function:
  55348  *      _bcm_esw_port_dmvoqfc_tx
  55349  * Purpose:
  55350  *      Configure VOQFC message reception.
  55351  * Parameters:
  55352  *      unit - (IN) Unit number.
  55353  *      port - (IN) Local port number.
  55354  *      config - (IN) Congestion configuration.
  55355  * Returns:
  55356  *      BCM_E_xxx
  55357  */
  55358 STATIC int
  55359 _bcm_esw_port_dmvoqfc_tx(int unit, bcm_port_t port,
  55360                        bcm_port_congestion_config_t *config)
  55361 {
  55362     /*
  55363      * Trident/Titan VOQFC message generation is same as E2ECC, except for
  55364      * ethertype and opcode.
  55365      */
  55366     if (SOC_IS_TD_TT(unit) || SOC_IS_KATANA2(unit)
  55367             || SOC_IS_TD2_TT2(unit) || SOC_IS_TRIUMPH3(unit)) {
  55368         BCM_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_tx(unit, port, config));
  55369         return BCM_E_NONE;
  55370     }
  55371 
  55372     return BCM_E_UNAVAIL;
  55373 }
  55374 
  55375 /*
  55376  * Function:
  55377  *      bcm_port_congestion_config_set
  55378  * Purpose:
  55379  *      Set end-to-end congestion control.
  55380  * Parameters:
  55381  *      unit - (IN) Unit number.
  55382  *      port - (IN) Gport number.
  55383  *      config - (IN) Structure containing the congestion configuration.
  55384  * Returns:
  55385  *      BCM_E_xxx
  55386  */
  55387 int
  55388 bcm_esw_port_congestion_config_set(int unit, bcm_gport_t port,
  55389                                    bcm_port_congestion_config_t *config)
  55390 {
  55391     bcm_port_t local_port;
  55392 
  55393     /* Make sure port module is initialized. */
  55394     PORT_INIT(unit);
  55395 
  55396     if (soc_feature(unit, soc_feature_e2ecc)) {
  55397         /* Check for parameters */
  55398 
  55399         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &local_port));
  55400 
  55401         if (!IS_HG_PORT(unit, local_port)) {
  55402             if(SOC_IS_KATANA2(unit) || SOC_IS_TRIDENT2PLUS(unit) || 
  55403                 SOC_IS_APACHE(unit) ) {
  55404                if ((config->flags &
  55405                     BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) ||
  55406                     (config->flags &
  55407                     BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE) || 
  55408                     (config->flags &
  55409                      BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE)) 
  55410                          {
  55411                     if (!IS_SUBTAG_PORT(unit, local_port)) {
  55412                         LOG_ERROR(BSL_LS_BCM_PORT,
  55413                                   (BSL_META_U(unit,
  55414                                 "E2ECC COE is applicable on subports only."
  55415                                 "Port %d is not a subport.\n"),
  55416                                 local_port));
  55417                         return BCM_E_PORT;
  55418                     }
  55419                 } else if ((config->flags &
  55420                             BCM_PORT_CONGESTION_CONFIG_TX) &&
  55421                            (config->flags &
  55422                            BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL)) {
  55423                     if ((IS_GE_PORT(unit, local_port)) ||
  55424                         (IS_XE_PORT(unit, local_port)))  {
  55425                         /* Set per-queue E2ECC enable bits */
  55426                         BCM_IF_ERROR_RETURN
  55427                             (_bcm_esw_port_drop_status_enable_set(unit,
  55428                                                        port, TRUE));
  55429                         /* Make sure port module is initialized. */
  55430                         PORT_INIT(unit);
  55431 
  55432                         /* Lock is needed to modify bcm_port_info */
  55433                         PORT_LOCK(unit);
  55434 
  55435                         /* Allocate per-port congestion configuration state on demand */
  55436                         if (PORT(unit, local_port).e2ecc_config == NULL) {
  55437                             PORT(unit, local_port).e2ecc_config = sal_alloc(sizeof(bcm_port_congestion_config_t),
  55438                                     "bcm_port_congestion_config");
  55439                             if (PORT(unit, local_port).e2ecc_config == NULL) {
  55440                                 LOG_ERROR(BSL_LS_BCM_PORT,
  55441                                         (BSL_META_U(unit,
  55442                                                     "Error: unable to allocate memory for bcm_port_congestion_config.\n")));
  55443                                 PORT_UNLOCK(unit);
  55444                                 return BCM_E_MEMORY;
  55445                             }
  55446                         }
  55447 
  55448                         /* Store E2ECC configuration */
  55449                         *(PORT(unit, local_port).e2ecc_config) = *(config);
  55450 
  55451                         PORT_UNLOCK(unit);
  55452                         return BCM_E_NONE;
  55453                     }
  55454                     LOG_ERROR(BSL_LS_BCM_PORT,
  55455                               (BSL_META_U(unit,
  55456                                "Applicable on Ge/Xe only "
  55457                                "for enabling dmvoq transmitting only.\n ")));
  55458                     return BCM_E_PARAM;
  55459                 } else {
  55460                     if (((SOC_IS_TRIDENT2PLUS(unit)) || SOC_IS_APACHE(unit)) &&
  55461                           (config->flags & BCM_PORT_CONGESTION_CONFIG_HCFC)) {
  55462                         LOG_ERROR(BSL_LS_BCM_PORT,
  55463                              (BSL_META_U(unit,
  55464                           "Error: unit %d port %d is not a Higig port. "
  55465                           "E2ECC messages can only be transmitted to "
  55466                           "or received from Higig ports.\n"),
  55467                           unit, local_port));
  55468                         return BCM_E_PARAM;
  55469                     }
  55470                 }
  55471             } else {
  55472                 LOG_ERROR(BSL_LS_BCM_PORT,
  55473                      (BSL_META_U(unit,
  55474                   "Error: unit %d port %d is not a Higig port. "
  55475                   "E2ECC messages can only be transmitted to or received from "
  55476                   "Higig ports.\n"), unit, local_port));
  55477                 return BCM_E_PARAM;
  55478             }
  55479         }
  55480 
  55481         if (config == NULL) {
  55482             return BCM_E_PARAM;
  55483         }
  55484 
  55485         if (!((config->flags & BCM_PORT_CONGESTION_CONFIG_E2ECC) ||
  55486             (config->flags & BCM_PORT_CONGESTION_CONFIG_HCFC) ||
  55487             (config->flags & BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL) ||
  55488             (config->flags & BCM_PORT_CONGESTION_CONFIG_DESTMODPORT_FLOW_CONTROL) ||
  55489             (config->flags & BCM_PORT_CONGESTION_CONFIG_MAX_SPLIT4) ||
  55490             (config->flags & BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) ||
  55491             (config->flags & BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE)   ||
  55492             (config->flags & BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE))) {
  55493             return BCM_E_PARAM;
  55494         }
  55495 
  55496         if (config->packets_per_sec < 0) {
  55497             return BCM_E_PARAM;
  55498         }
  55499 
  55500         switch (config->flags &
  55501                 (BCM_PORT_CONGESTION_CONFIG_E2ECC |
  55502                  BCM_PORT_CONGESTION_CONFIG_HCFC |
  55503                  BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL |
  55504                  BCM_PORT_CONGESTION_CONFIG_DESTMODPORT_FLOW_CONTROL |
  55505                  BCM_PORT_CONGESTION_CONFIG_MAX_SPLIT4 |
  55506                  BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE |
  55507                  BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE   |
  55508                  BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE)) {
  55509         case BCM_PORT_CONGESTION_CONFIG_E2ECC:
  55510         case BCM_PORT_CONGESTION_CONFIG_MAX_SPLIT4:
  55511             /* Handle E2ECC message transmission */
  55512             BCM_IF_ERROR_RETURN
  55513                 (_bcm_esw_port_e2ecc_tx(unit, local_port, config));
  55514 
  55515             /* Handle E2ECC message reception */
  55516             BCM_IF_ERROR_RETURN
  55517                 (_bcm_esw_port_e2ecc_rx(unit, local_port, config));
  55518             break;
  55519 
  55520         case BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE:
  55521         case BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE:
  55522         case BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE:
  55523              /* COE flow control using E2ECC messages
  55524               * KT2 supports E2E-CC message reception on
  55525               * COE ports.
  55526               */
  55527 #ifdef BCM_KATANA2_SUPPORT
  55528              if (SOC_IS_KATANA2(unit)) {
  55529                  BCM_IF_ERROR_RETURN
  55530                          (_bcm_esw_port_coe_e2ecc(unit, local_port, config));
  55531 
  55532              }
  55533 #endif
  55534 
  55535              
  55536 
  55537              /* COE flow control using E2ECC messages
  55538               * TD2+ supports E2E-CC message reception on
  55539               * COE ports, only in STRICT mode. 
  55540               */
  55541 #ifdef BCM_TRIDENT2PLUS_SUPPORT
  55542              if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) {
  55543                  if (((config->flags &
  55544                     BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) ||
  55545                     (config->flags &
  55546                     BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE)) &&
  55547                     (config->flags &
  55548                             BCM_PORT_CONGESTION_CONFIG_RX))
  55549                  { 
  55550                  BCM_IF_ERROR_RETURN
  55551                          (bcm_td2p_port_coe_e2ecc(unit, local_port, config));
  55552                  } else {
  55553                     return BCM_E_PARAM;
  55554                  }     
  55555 
  55556              }
  55557 #endif
  55558        break;
  55559 
  55560         case BCM_PORT_CONGESTION_CONFIG_HCFC:
  55561             if (SOC_IS_TRIUMPH3(unit)) {
  55562                 BCM_IF_ERROR_RETURN(_bcm_tr3_port_hcfc(unit, local_port, config));
  55563             } else {
  55564                 BCM_IF_ERROR_RETURN(_bcm_esw_port_hcfc(unit, local_port, config));
  55565             }
  55566             break;
  55567 
  55568         case BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL:
  55569             if ((!SOC_IS_TD_TT(unit)) && (!SOC_IS_KATANA2(unit)) &&
  55570                     (!SOC_IS_TD2_TT2(unit)) && (!SOC_IS_TRIUMPH3(unit))) {
  55571                 return BCM_E_PARAM;
  55572             }
  55573 
  55574             /* Handle VOQFC message reception */
  55575             BCM_IF_ERROR_RETURN
  55576                 (_bcm_esw_port_dmvoqfc_rx(unit, local_port, config));
  55577 
  55578             /* Handle E2ECC message transmission */
  55579             BCM_IF_ERROR_RETURN
  55580                 (_bcm_esw_port_dmvoqfc_tx(unit, local_port, config));
  55581             break;
  55582         case BCM_PORT_CONGESTION_CONFIG_DESTMODPORT_FLOW_CONTROL:
  55583             if (!SOC_IS_KATANA2(unit) && !(SOC_IS_APACHE(unit))) {
  55584                 return BCM_E_PARAM;
  55585             }
  55586 
  55587             /* Handle VOQFC message reception */
  55588             BCM_IF_ERROR_RETURN
  55589                 (_bcm_esw_port_dmvoqfc_rx(unit, local_port, config));
  55590 
  55591             /* Handle E2ECC message transmission */
  55592             BCM_IF_ERROR_RETURN
  55593                 (_bcm_esw_port_dmvoqfc_tx(unit, local_port, config));
  55594             break;
  55595         default:
  55596             return BCM_E_PARAM;
  55597         }
  55598         /* Make sure port module is initialized. */
  55599         PORT_INIT(unit);
  55600 
  55601         /* Lock is needed to modify bcm_port_info */
  55602         PORT_LOCK(unit);
  55603 
  55604         /* Allocate per-port congestion configuration state on demand */
  55605         if (PORT(unit, local_port).e2ecc_config == NULL) {
  55606             PORT(unit, local_port).e2ecc_config = sal_alloc(sizeof(bcm_port_congestion_config_t),
  55607                     "bcm_port_congestion_config");
  55608             if (PORT(unit, local_port).e2ecc_config == NULL) {
  55609                 LOG_ERROR(BSL_LS_BCM_PORT,
  55610                         (BSL_META_U(unit,
  55611                                     "Error: unable to allocate memory for bcm_port_congestion_config.\n")));
  55612                 PORT_UNLOCK(unit);
  55613                 return BCM_E_MEMORY;
  55614             }
  55615         }
  55616 
  55617         /* Store E2ECC configuration */
  55618         *(PORT(unit, local_port).e2ecc_config) = *(config);
  55619 
  55620         PORT_UNLOCK(unit);
  55621 
  55622 
  55623         return BCM_E_NONE;
  55624     } else {
  55625         return BCM_E_UNAVAIL;
  55626     }
  55627 
  55628 }
  55629 
  55630 /*
  55631  * Function:
  55632  *      bcm_port_congestion_config_get
  55633  * Purpose:
  55634  *      Get end-to-end congestion control configuration.
  55635  * Parameters:
  55636  *      unit - (IN) Unit number.
  55637  *      port - (IN) Gport number.
  55638  *      config - (OUT) Structure containing the congestion configuration.
  55639  * Returns:
  55640  *      BCM_E_xxx
  55641  */
  55642 
  55643 int
  55644 bcm_esw_port_congestion_config_get(int unit, bcm_gport_t port,
  55645                                    bcm_port_congestion_config_t *config)
  55646 {
  55647     bcm_port_t local_port;
  55648 
  55649     /* Make sure port module is initialized. */
  55650     PORT_INIT(unit);
  55651 
  55652     if (soc_feature(unit, soc_feature_e2ecc)) {
  55653         /* Check for parameters */
  55654 
  55655         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &local_port));
  55656         if (!IS_HG_PORT(unit, local_port)) {
  55657             if (SOC_IS_KATANA2(unit) || SOC_IS_TRIDENT2PLUS(unit) ||
  55658                 SOC_IS_APACHE(unit)) {
  55659                 if ((config->flags &
  55660                      BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) ||
  55661                     (config->flags &
  55662                      BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE)   ||
  55663                     (config->flags &
  55664                      BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE)) {
  55665                 if (!IS_SUBTAG_PORT(unit, local_port)) {
  55666                         LOG_ERROR(
  55667                             BSL_LS_BCM_PORT,
  55668                       (BSL_META_U(unit,
  55669                                         "Error: unit %d port %d is not a Higig "
  55670                                         "port or Subtag port. E2ECC messages "
  55671                                         "can be transmitted to or received from "
  55672                                         "Higig ports or can be received on "
  55673                                         "Subtag port.\n"),
  55674                         unit, local_port));
  55675                     return BCM_E_PORT;
  55676                  }
  55677                      if ((SOC_IS_TRIDENT2PLUS(unit)|| SOC_IS_APACHE(unit)) &&
  55678                            ((config->flags &
  55679                              BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE))) { 
  55680                             return BCM_E_PARAM;  
  55681                       
  55682                      } else  if ((SOC_IS_TRIDENT2PLUS(unit)|| SOC_IS_APACHE(unit)) &&
  55683                            ((config->flags &
  55684                              BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) || 
  55685                            (config->flags &
  55686                              BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE)) &&  
  55687                             (config->flags &
  55688                             BCM_PORT_CONGESTION_CONFIG_TX)) { 
  55689                             return BCM_E_PARAM;  
  55690                      } 
  55691                 } else if ((config->flags &
  55692                             BCM_PORT_CONGESTION_CONFIG_TX) &&
  55693                            (config->flags &
  55694                             BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL)) {
  55695                     if (!(IS_GE_PORT(unit, local_port)) &&
  55696                         !(IS_XE_PORT(unit, local_port)))  {
  55697                         LOG_ERROR(
  55698                             BSL_LS_BCM_PORT,
  55699                             (BSL_META_U(unit,
  55700                                         "Applicable on Ge/Xe only for enabling "
  55701                                         "dmvoq transmitting only.\n ")));
  55702                         return BCM_E_PARAM;
  55703                     }
  55704                 } else if ((SOC_IS_TRIDENT2PLUS(unit)|| SOC_IS_APACHE(unit)) &&
  55705                            (config->flags & BCM_PORT_CONGESTION_CONFIG_HCFC)) {
  55706                     LOG_ERROR(
  55707                         BSL_LS_BCM_PORT,
  55708                         (BSL_META_U(unit,
  55709                                     "Error: unit %d port %d is not a Higig port. "
  55710                                     "E2ECC messages can only be transmitted to "
  55711                                     "or received from Higig ports.\n"),
  55712                          unit, local_port));
  55713                        return BCM_E_PARAM;
  55714                 } 
  55715             } else {
  55716                 LOG_ERROR(
  55717                     BSL_LS_BCM_PORT,
  55718                (BSL_META_U(unit,
  55719                 "Error: unit %d port %d is not a Higig port. "
  55720                                 "E2ECC messages can only be transmitted to "
  55721                                 "or received from Higig ports.\n"),
  55722                      unit, local_port));
  55723                return BCM_E_PARAM;
  55724             }
  55725         }
  55726         if (config == NULL) {
  55727             return BCM_E_PARAM;
  55728         }
  55729 
  55730         /* Make sure port module is initialized. */
  55731         PORT_INIT(unit);
  55732 
  55733         if (PORT(unit, local_port).e2ecc_config == NULL) {
  55734             LOG_ERROR(BSL_LS_BCM_PORT,
  55735                       (BSL_META_U(unit,
  55736                                   "Error: Port %d bcm_port_congestion_config was not set.\n"),
  55737                                   local_port));
  55738             return BCM_E_NOT_FOUND;
  55739         }
  55740 
  55741         /* Retrieve E2ECC configuration */
  55742         *config = *(PORT(unit, local_port).e2ecc_config);
  55743 
  55744         return BCM_E_NONE;
  55745 
  55746     } else {
  55747         return BCM_E_UNAVAIL;
  55748     }
  55749 }
  55750 
  55751 /*
  55752  * Function:
  55753  *      bcm_port_match_add
  55754  * Purpose:
  55755  *      Add a match to an existing port
  55756  * Parameters:
  55757  *      unit - (IN) Unit number.
  55758  *      port - (IN) Port or gport
  55759  *      match - (IN) Match criteria
  55760  * Returns:
  55761  *      BCM_E_xxx
  55762  * Notes:
  55763  */
  55764 int
  55765 bcm_esw_port_match_add(
  55766     int unit,
  55767     bcm_gport_t port,
  55768     bcm_port_match_info_t *match)
  55769 {
  55770 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
  55771     int vp=0, rv = BCM_E_NONE;
  55772     bcm_gport_t gp = 0;
  55773 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_MPLS_SUPPORT)
  55774     _bcm_vp_info_t vp_info;
  55775 #endif    
  55776 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
  55777     bcm_vxlan_port_t vxlan_port;
  55778     bcm_l2gre_port_t l2gre_port;
  55779 #endif
  55780     int existing_updated = 0;
  55781 #if defined(BCM_TRIDENT3_SUPPORT)
  55782     bcm_mirror_destination_t mirror_dest;
  55783     uint32 cancun_ver;
  55784 #endif /* BCM_TRIDENT3_SUPPORT */
  55785 #if defined(BCM_TRX_SUPPORT)
  55786     bcm_vlan_match_info_t vlan_match_info;
  55787 #endif
  55788     if (match == NULL) {
  55789         return BCM_E_PARAM;
  55790     }
  55791 
  55792     /* Make sure port module is initialized. */
  55793     PORT_INIT(unit);
  55794 
  55795     if (BCM_GPORT_IS_MIM_PORT(port)) {
  55796 #if defined(BCM_TRIUMPH2_SUPPORT)
  55797         if (!soc_feature(unit, soc_feature_mim)) {
  55798             return BCM_E_UNAVAIL;
  55799         }
  55800         vp = BCM_GPORT_MIM_PORT_ID_GET(port);
  55801         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
  55802             return BCM_E_NOT_FOUND;
  55803         }
  55804         BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  55805         if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  55806             BCM_IF_ERROR_RETURN(_bcm_tr2_mim_port_phys_gport_get(unit, vp, &gp));
  55807         }
  55808 #endif
  55809     } else if  (BCM_GPORT_IS_MPLS_PORT(port)) {
  55810         if (!soc_feature(unit, soc_feature_mpls)) {
  55811             return BCM_E_UNAVAIL;
  55812         }
  55813         vp = BCM_GPORT_MPLS_PORT_ID_GET(port);
  55814         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
  55815             return BCM_E_NOT_FOUND;
  55816         }
  55817 #if defined(BCM_MPLS_SUPPORT)
  55818         BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  55819         if ((vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  55820             if (!soc_feature(unit, soc_feature_vp_sharing)) {
  55821                 return BCM_E_UNAVAIL;
  55822             }
  55823         } else {
  55824         BCM_IF_ERROR_RETURN(bcm_tr_mpls_port_phys_gport_get(unit, vp, &gp));
  55825         }
  55826 #endif
  55827     } else
  55828 #if defined(BCM_TRIDENT2_SUPPORT)
  55829     if (BCM_GPORT_IS_TRUNK(port)) {
  55830         if (!soc_feature(unit, soc_feature_vp_lag)) {
  55831             return BCM_E_UNAVAIL;
  55832         }
  55833         BCM_IF_ERROR_RETURN(
  55834             _bcm_esw_trunk_tid_to_vp_lag_vp(unit, BCM_GPORT_TRUNK_GET(port),
  55835                                             &vp));
  55836         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) {
  55837             return BCM_E_NOT_FOUND;
  55838         }
  55839         if (match->match != BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID &&
  55840             match->match != BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID_VLAN) {
  55841             return BCM_E_PARAM;
  55842         }
  55843     } else
  55844 #endif /* BCM_TRIDENT2_SUPPORT */
  55845 #if defined(BCM_TRIDENT2_SUPPORT)
  55846     if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  55847         if (!soc_feature(unit, soc_feature_vxlan)) {
  55848             return BCM_E_UNAVAIL;
  55849         }
  55850         if (match->match == BCM_PORT_MATCH_PORT
  55851             || match->match == BCM_PORT_MATCH_PORT_VLAN_RANGE
  55852             || match->match == BCM_PORT_MATCH_PORT_INNER_VLAN_RANGE
  55853             || match->match == BCM_PORT_MATCH_PORT_VLAN_STACKED_RANGE
  55854             ) {
  55855             vp = BCM_GPORT_VXLAN_PORT_ID_GET(port);
  55856             if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan))) {
  55857                 return BCM_E_NOT_FOUND;
  55858             }
  55859         } else {
  55860             if (!soc_feature(unit, soc_feature_vp_sharing)) {
  55861                 return BCM_E_UNAVAIL;
  55862             }
  55863 
  55864             vp = BCM_GPORT_VXLAN_PORT_ID_GET(port);
  55865             BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  55866 
  55867             if (vp_info.vp_type != _bcmVpTypeVxlan) {
  55868                 return BCM_E_PARAM;
  55869             }
  55870             if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  55871                 return BCM_E_PARAM;
  55872             }
  55873 
  55874             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vpn_is_valid(unit, match->vpn));
  55875         }
  55876     } else 
  55877 #endif
  55878 #if defined(BCM_TRIDENT2_SUPPORT)
  55879     if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  55880         if (!soc_feature(unit, soc_feature_l2gre)) {
  55881             return BCM_E_UNAVAIL;
  55882         }
  55883         if (match->match == BCM_PORT_MATCH_PORT) {
  55884             vp = BCM_GPORT_L2GRE_PORT_ID_GET(port);
  55885             if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre))) {
  55886                 return BCM_E_NOT_FOUND;
  55887             }
  55888         } else {
  55889             if (!soc_feature(unit, soc_feature_vp_sharing)) {
  55890                 return BCM_E_UNAVAIL;
  55891             }
  55892 
  55893             vp = BCM_GPORT_L2GRE_PORT_ID_GET(port);
  55894             BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  55895 
  55896             if (vp_info.vp_type != _bcmVpTypeL2Gre) {
  55897                 return BCM_E_PARAM;
  55898             }
  55899             if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  55900                 return BCM_E_PARAM;
  55901             }
  55902 
  55903             BCM_IF_ERROR_RETURN(_bcm_tr3_l2gre_vpn_is_valid(unit, match->vpn));
  55904         }
  55905     } else 
  55906 #endif
  55907 
  55908 
  55909 #if defined(BCM_TRIUMPH2_SUPPORT) 
  55910     if (BCM_GPORT_IS_VLAN_PORT(port)) {
  55911         if (!soc_feature(unit, soc_feature_lltag)) {
  55912             return BCM_E_UNAVAIL;
  55913         }
  55914         vp = BCM_GPORT_VLAN_PORT_ID_GET(port);
  55915         if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan))) {
  55916             return BCM_E_NOT_FOUND;
  55917         }
  55918         BCM_IF_ERROR_RETURN(bcm_tr2_vlan_port_phys_gport_get(unit, vp, &gp));
  55919     } else
  55920 #endif
  55921 #if defined(BCM_TRIDENT_SUPPORT)
  55922     if (BCM_GPORT_IS_NIV_PORT(port)) {
  55923         if (!soc_feature(unit, soc_feature_niv)) {
  55924             return BCM_E_UNAVAIL;
  55925         }
  55926         vp = BCM_GPORT_NIV_PORT_ID_GET(port);
  55927         if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv))) {
  55928             return BCM_E_PARAM;
  55929         }
  55930     } else
  55931 #endif /* BCM_TRIDENT_SUPPORT */
  55932 #if defined(BCM_TRIDENT3_SUPPORT)
  55933     if (BCM_GPORT_IS_MIRROR(port)) {
  55934         if (!soc_feature(unit, soc_feature_mirror_encap_profile)) {
  55935             return BCM_E_UNAVAIL;
  55936         }
  55937         if ((match->match == BCM_PORT_MATCH_PORT_VLAN) ||
  55938             (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE) ||
  55939             (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS)) {
  55940 
  55941             SOC_IF_ERROR_RETURN(soc_cancun_version_get(unit, &cancun_ver));
  55942             if (SOC_IS_TRIDENT3(unit) &&
  55943                 SOC_CANCUN_VERSION_5_2_UNDER_SERIES(cancun_ver)) {
  55944                 if ((match->match == BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE) ||
  55945                     (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS)) {
  55946                     LOG_ERROR(BSL_LS_BCM_PORT,
  55947                               (BSL_META_U(unit,
  55948                           "BCM_PORT_MATCH_PORT_I2E_CLASS match criteria \
  55949                            not supported in Cancun 5.1.8 release\n")));
  55950                     return BCM_E_UNAVAIL;
  55951                 }
  55952             } else {
  55953                 if (match->match == BCM_PORT_MATCH_PORT_VLAN) {
  55954                     LOG_ERROR(BSL_LS_BCM_PORT,
  55955                               (BSL_META_U(unit,
  55956                           "BCM_PORT_MATCH_PORT_VLAN match criteria \
  55957                            not supported after Cancun 5.1.8 release\n")));
  55958                     return BCM_E_UNAVAIL;
  55959                 }
  55960 
  55961                 /* check if max I2E class_id */
  55962                 if (match->match_vlan > _BCM_I2E_CLASS_ID_MAX) {
  55963                     LOG_ERROR(BSL_LS_BCM_PORT,
  55964                         (BSL_META_U(unit, " %d exceeds I2E class_id max %d\n"),
  55965                          match->match_vlan,_BCM_I2E_CLASS_ID_MAX));
  55966                     return BCM_E_PARAM;
  55967                 }
  55968             }              
  55969 
  55970             bcm_mirror_destination_t_init(&mirror_dest);
  55971             BCM_IF_ERROR_RETURN(bcm_esw_mirror_destination_get(unit, port,
  55972                                 &mirror_dest));
  55973             if (mirror_dest.flags & BCM_MIRROR_DEST_FIELD) {
  55974                 return BCM_E_PARAM;
  55975             }
  55976         } else {
  55977             return BCM_E_PARAM;
  55978         }
  55979     } else
  55980 #endif /* BCM_TRIDENT3_SUPPORT */
  55981     {
  55982         return BCM_E_PORT;
  55983     }
  55984 
  55985     switch (match->match) {
  55986     case BCM_PORT_MATCH_NONE:
  55987         rv = BCM_E_NONE;
  55988         break;
  55989 #if defined(BCM_TRIDENT2_SUPPORT)
  55990     case BCM_PORT_MATCH_PORT:
  55991         if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  55992             bcm_vxlan_port_t_init(&vxlan_port);
  55993             vxlan_port.criteria      = BCM_VXLAN_PORT_MATCH_PORT;
  55994             vxlan_port.vxlan_port_id = port;
  55995             vxlan_port.match_port    = match->port;
  55996             BCM_IF_ERROR_RETURN(
  55997                 _bcm_td2_vxlan_match_add(unit, &vxlan_port, vp, 0));
  55998         } else if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  55999             bcm_l2gre_port_t_init(&l2gre_port);
  56000             l2gre_port.criteria       = BCM_L2GRE_PORT_MATCH_PORT;
  56001             l2gre_port.l2gre_port_id   = port;
  56002             l2gre_port.match_port           = match->port;
  56003             BCM_IF_ERROR_RETURN(
  56004                 bcm_td2_l2gre_match_add(unit, &l2gre_port, vp, 0));
  56005         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  56006 #if defined(BCM_MPLS_SUPPORT)
  56007             bcm_mpls_port_t mpls_port;
  56008             bcm_mpls_port_t_init(&mpls_port);
  56009             mpls_port.criteria       = BCM_MPLS_PORT_MATCH_PORT;
  56010             mpls_port.mpls_port_id   = port;
  56011             mpls_port.port           = match->port;
  56012             BCM_IF_ERROR_RETURN(
  56013                 _bcm_tr_mpls_match_add(unit, &mpls_port, vp, 0, TRUE));
  56014 #endif
  56015         } else {
  56016             rv = BCM_E_PARAM;
  56017         }
  56018         break;
  56019 #endif
  56020 
  56021     case BCM_PORT_MATCH_PORT_I2E_CLASS:
  56022     case BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE:
  56023 #if defined(BCM_TRIDENT3_SUPPORT)
  56024         if (BCM_GPORT_IS_MIRROR(port)) {
  56025             rv = _bcm_mirror_port_match_add(unit, &mirror_dest, match->port,
  56026                                             match->match_vlan, match->match);
  56027         } else
  56028 #endif
  56029         {
  56030             rv = BCM_E_UNAVAIL;
  56031         }
  56032         break;
  56033 
  56034     case BCM_PORT_MATCH_PORT_VLAN:
  56035 #if defined(BCM_TRIDENT3_SUPPORT)
  56036         if (BCM_GPORT_IS_MIRROR(port)) {
  56037             rv = _bcm_mirror_port_match_add(unit, &mirror_dest, match->port,
  56038                                             match->match_vlan, match->match);
  56039             break;
  56040         } else
  56041 #endif /* BCM_TRIDENT3_SUPPORT */
  56042 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  56043         if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  56044             /* match_info translation to vxlan_port */
  56045             bcm_vxlan_port_t_init(&vxlan_port);
  56046             VLAN_CHK_ID(unit, match->match_vlan);
  56047             vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_VLAN;
  56048             vxlan_port.match_vlan = match->match_vlan;
  56049             vxlan_port.vxlan_port_id = port;
  56050             vxlan_port.match_port = match->port;            
  56051             
  56052             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_add(unit,
  56053                                             &vxlan_port, vp, match->vpn));
  56054             break;
  56055         } else if (BCM_GPORT_IS_MIM_PORT(port) &&
  56056             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  56057             bcm_mim_port_t mim_port;
  56058             bcm_mim_port_t_init(&mim_port);
  56059             VLAN_CHK_ID(unit, match->match_vlan);
  56060             mim_port.criteria = BCM_MIM_PORT_MATCH_PORT_VLAN;
  56061             mim_port.match_vlan = match->match_vlan;
  56062             mim_port.mim_port_id = port;
  56063             mim_port.port = match->port;
  56064             BCM_IF_ERROR_RETURN(_bcm_tr2_mim_match_add(unit, 
  56065                                  &mim_port, vp, match->vpn));
  56066             break;
  56067         } else if (BCM_GPORT_IS_MPLS_PORT(port) &&
  56068             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  56069             bcm_mpls_port_t mpls_port;
  56070             bcm_mpls_port_t_init(&mpls_port);
  56071             VLAN_CHK_ID(unit, match->match_vlan);
  56072             mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_VLAN;
  56073             mpls_port.match_vlan = match->match_vlan;
  56074             mpls_port.mpls_port_id = port;
  56075             mpls_port.port = match->port;
  56076             BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_add(unit,
  56077                                  &mpls_port, vp, match->vpn, TRUE));
  56078             break;
  56079         } else if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  56080             /* match_info translation to L2GRE_port */
  56081             bcm_l2gre_port_t_init(&l2gre_port);
  56082             VLAN_CHK_ID(unit, match->match_vlan);
  56083             l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_VLAN;
  56084             l2gre_port.match_vlan = match->match_vlan;
  56085             l2gre_port.l2gre_port_id = port;
  56086             l2gre_port.match_port = match->port;
  56087             BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_add(unit,
  56088                                             &l2gre_port, vp, match->vpn));
  56089             break;
  56090         }
  56091 #endif
  56092         
  56093         /* Add an entry in the VLAN_XLATE table */
  56094         /* Tag actions need to be adjusted by calling the
  56095            bcm_vlan_translate_action_add API for the entry we are creating */
  56096         VLAN_CHK_ID(unit, match->match_vlan);
  56097         if (BCM_GPORT_IS_MODPORT(match->port) ||
  56098             BCM_GPORT_IS_TRUNK(match->port)) {
  56099             /* Use the port from bcm_port_match_info_t instead of the physical
  56100                port from the VP */
  56101             gp = match->port;
  56102         }
  56103 
  56104         rv = _bcm_tr_vlan_translate_vp_add(unit, gp,
  56105                                             bcmVlanTranslateKeyPortOuter,
  56106                                             match->match_vlan,
  56107                                             BCM_VLAN_INVALID,
  56108                                             vp, match->action,
  56109                                             &existing_updated);
  56110         if (BCM_GPORT_IS_MIM_PORT(port)) {
  56111 #if defined(BCM_TRIUMPH2_SUPPORT)
  56112            _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1);
  56113 #endif
  56114         } else if (BCM_GPORT_IS_MPLS_PORT(port) && !existing_updated) {
  56115 #if defined(BCM_MPLS_SUPPORT)
  56116            bcm_tr_mpls_port_match_count_adjust(unit, vp, 1);
  56117 #endif
  56118         }
  56119         break;
  56120 
  56121     case BCM_PORT_MATCH_PORT_INNER_VLAN:
  56122 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  56123         if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  56124             bcm_vxlan_port_t_init(&vxlan_port);
  56125             VLAN_CHK_ID(unit, match->match_inner_vlan);
  56126             vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_INNER_VLAN;
  56127             vxlan_port.match_inner_vlan = match->match_inner_vlan;
  56128             vxlan_port.vxlan_port_id = port;
  56129             vxlan_port.match_port = match->port;
  56130 
  56131             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_add(unit,
  56132                                             &vxlan_port, vp, match->vpn));
  56133             break;
  56134         } else if (BCM_GPORT_IS_MPLS_PORT(port) &&
  56135             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  56136             bcm_mpls_port_t mpls_port;
  56137             bcm_mpls_port_t_init(&mpls_port);
  56138             VLAN_CHK_ID(unit, match->match_inner_vlan);
  56139             mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_INNER_VLAN;
  56140             mpls_port.match_inner_vlan = match->match_inner_vlan;
  56141             mpls_port.mpls_port_id = port;
  56142             mpls_port.port = match->port;
  56143             BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_add(unit,
  56144                                  &mpls_port, vp, match->vpn, TRUE));
  56145             break;
  56146         } else if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  56147             /* match_info translation to L2GRE_port */
  56148             bcm_l2gre_port_t_init(&l2gre_port);
  56149             VLAN_CHK_ID(unit, match->match_vlan);
  56150             l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_INNER_VLAN;
  56151             l2gre_port.match_inner_vlan = match->match_inner_vlan;
  56152             l2gre_port.l2gre_port_id = port;
  56153             l2gre_port.match_port = match->port;
  56154             BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_add(unit,
  56155                                             &l2gre_port, vp, match->vpn));
  56156             break;
  56157         }
  56158 #endif
  56159         /* Add an entry in the VLAN_XLATE table */
  56160         /* Tag actions need to be adjusted by calling the
  56161          * bcm_vlan_translate_action_add API for the entry we are creating */
  56162         VLAN_CHK_ID(unit, match->match_inner_vlan);
  56163         if (BCM_GPORT_IS_MODPORT(match->port) ||
  56164             BCM_GPORT_IS_TRUNK(match->port)) {
  56165             /* Use the port from bcm_port_match_info_t instead of the physical
  56166                port from the VP */
  56167             gp = match->port;
  56168         }
  56169 
  56170         rv = _bcm_tr_vlan_translate_vp_add(unit, gp,
  56171                                             bcmVlanTranslateKeyPortInner,
  56172                                             BCM_VLAN_INVALID,
  56173                                             match->match_inner_vlan,
  56174                                             vp, match->action,
  56175                                             &existing_updated);
  56176         break;
  56177 
  56178     case BCM_PORT_MATCH_PORT_VLAN16:
  56179 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  56180         if (BCM_GPORT_IS_VXLAN_PORT(port) &&
  56181             ((match->match_vlan & 0xfff) == BCM_VLAN_NONE)) {
  56182             bcm_vxlan_port_t_init(&vxlan_port);
  56183             vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_VLAN_PRI;
  56184             vxlan_port.match_vlan = match->match_vlan;
  56185             vxlan_port.vxlan_port_id = port;
  56186             vxlan_port.match_port = match->port;
  56187 
  56188             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_add(unit,
  56189                                             &vxlan_port, vp, match->vpn));
  56190             break;
  56191         } else if (BCM_GPORT_IS_MPLS_PORT(port) &&
  56192             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT) &&
  56193              ((match->match_vlan & 0xfff) == BCM_VLAN_NONE)) {
  56194             bcm_mpls_port_t mpls_port;
  56195             bcm_mpls_port_t_init(&mpls_port);
  56196             mpls_port.criteria = BCM_MPLS_PORT_MATCH_VLAN_PRI;
  56197             mpls_port.match_vlan = match->match_vlan;
  56198             mpls_port.mpls_port_id = port;
  56199             mpls_port.port = match->port;
  56200             BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_add(unit,
  56201                                  &mpls_port, vp, match->vpn, TRUE));
  56202             break;
  56203         } else if (BCM_GPORT_IS_L2GRE_PORT(port) &&
  56204             ((match->match_vlan & 0xfff) == BCM_VLAN_NONE)) {
  56205             /* match_info translation to L2GRE_port */
  56206             bcm_l2gre_port_t_init(&l2gre_port);
  56207             l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_VLAN_PRI;
  56208             l2gre_port.match_vlan = match->match_vlan;
  56209             l2gre_port.l2gre_port_id = port;
  56210             l2gre_port.match_port = match->port;
  56211             BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_add(unit,
  56212                                             &l2gre_port, vp, match->vpn));
  56213             break;
  56214         }
  56215 #endif
  56216         /* Add an entry in the VLAN_XLATE table */
  56217         /* Tag actions need to be adjusted by calling the
  56218            bcm_vlan_translate_action_add API for the entry we are creating */
  56219         if (BCM_GPORT_IS_MODPORT(match->port) ||
  56220             BCM_GPORT_IS_TRUNK(match->port)) {
  56221             /* Use the port from bcm_port_match_info_t instead of the physical
  56222                port from the VP */
  56223             gp = match->port;
  56224         }
  56225 
  56226         /* allow 16 bit VLAN id */
  56227         rv = _bcm_tr_vlan_translate_vp_add(unit, gp,
  56228                                             bcmVlanTranslateKeyPortOuterTag,
  56229                                             match->match_vlan,
  56230                                             BCM_VLAN_INVALID,
  56231                                             vp, match->action,
  56232                                             &existing_updated);
  56233         if (BCM_GPORT_IS_MIM_PORT(port)) {
  56234 #if defined(BCM_TRIUMPH2_SUPPORT)
  56235            _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1);
  56236 #endif
  56237         } else if (BCM_GPORT_IS_MPLS_PORT(port) && !existing_updated) {
  56238 #if defined(BCM_MPLS_SUPPORT)
  56239            bcm_tr_mpls_port_match_count_adjust(unit, vp, 1);
  56240 #endif
  56241         }
  56242         break;
  56243 
  56244 
  56245     case BCM_PORT_MATCH_PORT_VLAN_STACKED:
  56246 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  56247         if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  56248             /* match_info translation to vxlan_port */
  56249             bcm_vxlan_port_t_init(&vxlan_port);
  56250             VLAN_CHK_ID(unit, match->match_vlan);
  56251             VLAN_CHK_ID(unit, match->match_inner_vlan);
  56252             vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_VLAN_STACKED;
  56253             vxlan_port.match_vlan = match->match_vlan;
  56254             vxlan_port.match_inner_vlan = match->match_inner_vlan;
  56255             vxlan_port.vxlan_port_id = port;
  56256             vxlan_port.match_port = match->port;            
  56257             
  56258             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_add(unit,
  56259                                             &vxlan_port, vp, match->vpn));
  56260             break;
  56261         } else if (BCM_GPORT_IS_MIM_PORT(port) &&
  56262             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  56263             bcm_mim_port_t mim_port;
  56264             bcm_mim_port_t_init(&mim_port);
  56265             VLAN_CHK_ID(unit, match->match_vlan);
  56266             VLAN_CHK_ID(unit, match->match_inner_vlan);
  56267             mim_port.criteria = BCM_MIM_PORT_MATCH_PORT_VLAN_STACKED;
  56268             mim_port.match_vlan = match->match_vlan;
  56269             mim_port.match_inner_vlan = match->match_inner_vlan;
  56270             mim_port.mim_port_id = port;
  56271             mim_port.port = match->port;
  56272             BCM_IF_ERROR_RETURN(_bcm_tr2_mim_match_add(unit, 
  56273                                  &mim_port, vp, match->vpn));
  56274             break;
  56275         } else if (BCM_GPORT_IS_MPLS_PORT(port) &&
  56276             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  56277             bcm_mpls_port_t mpls_port;
  56278             bcm_mpls_port_t_init(&mpls_port);
  56279             VLAN_CHK_ID(unit, match->match_vlan);
  56280             VLAN_CHK_ID(unit, match->match_inner_vlan);
  56281             mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_VLAN_STACKED;
  56282             mpls_port.match_vlan = match->match_vlan;
  56283             mpls_port.match_inner_vlan = match->match_inner_vlan;
  56284             mpls_port.mpls_port_id = port;
  56285             mpls_port.port = match->port;
  56286             BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_add(unit,
  56287                                  &mpls_port, vp, match->vpn, TRUE));
  56288             break;
  56289         }  else if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  56290             /* match_info translation to L2GRE_port */
  56291             bcm_l2gre_port_t_init(&l2gre_port);
  56292             VLAN_CHK_ID(unit, match->match_vlan);
  56293             VLAN_CHK_ID(unit, match->match_inner_vlan);
  56294             l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_VLAN_STACKED;
  56295             l2gre_port.match_vlan = match->match_vlan;
  56296             l2gre_port.match_inner_vlan = match->match_inner_vlan;
  56297             l2gre_port.l2gre_port_id = port;
  56298             l2gre_port.match_port = match->port;
  56299             BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_add(unit,
  56300                                             &l2gre_port, vp, match->vpn));
  56301             break;
  56302         }
  56303 #endif
  56304         
  56305         /* Add an entry in the VLAN_XLATE table */
  56306         /* Tag actions need to be adjusted by calling the
  56307            bcm_vlan_translate_action_add API for the entry we are creating */
  56308         VLAN_CHK_ID(unit, match->match_vlan);
  56309         VLAN_CHK_ID(unit, match->match_inner_vlan);
  56310         if (BCM_GPORT_IS_MODPORT(match->port) ||
  56311             BCM_GPORT_IS_TRUNK(match->port)) {
  56312             /* Use the port from bcm_port_match_info_t instead of the physical
  56313                port from the VP */
  56314             gp = match->port;
  56315         }
  56316         rv = _bcm_tr_vlan_translate_vp_add(unit, gp,
  56317                                             bcmVlanTranslateKeyPortDouble,
  56318                                             match->match_vlan,
  56319                                             match->match_inner_vlan,
  56320                                             vp, match->action,
  56321                                             &existing_updated);
  56322         if (BCM_GPORT_IS_MIM_PORT(port)) {
  56323 #if defined(BCM_TRIUMPH2_SUPPORT)
  56324         _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1);
  56325 #endif
  56326         } else if (BCM_GPORT_IS_MPLS_PORT(port) && !existing_updated) {
  56327 #if defined(BCM_MPLS_SUPPORT)
  56328            bcm_tr_mpls_port_match_count_adjust(unit, vp, 1);
  56329 #endif
  56330         }
  56331         break;
  56332     case BCM_PORT_MATCH_PORT_VLAN_RANGE:
  56333 #if defined(BCM_TRIUMPH2_SUPPORT)
  56334         /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */
  56335         /* Tag actions need to be adjusted by calling the
  56336            bcm_vlan_translate_action_add API for the entry we are creating */
  56337         VLAN_CHK_ID(unit, match->match_vlan);
  56338         VLAN_CHK_ID(unit, match->match_vlan_max);
  56339         if (BCM_GPORT_IS_MODPORT(match->port) ||
  56340             BCM_GPORT_IS_TRUNK(match->port)) {
  56341             /* Use the port from bcm_port_match_info_t instead of the physical
  56342                port from the VP */
  56343             gp = match->port;
  56344         }
  56345 
  56346         rv = _bcm_tr2_vlan_translate_range_vp_add(unit, gp,
  56347                                                   match->match_vlan,
  56348                                                   match->match_vlan_max,
  56349                                                   BCM_VLAN_INVALID, 
  56350                                                   BCM_VLAN_INVALID,
  56351                                                   vp, match->action);
  56352         if (BCM_SUCCESS(rv)) {
  56353             if (BCM_GPORT_IS_MIM_PORT(port)) {
  56354                 _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1);
  56355             } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  56356 #if defined(BCM_MPLS_SUPPORT)
  56357                 bcm_tr_mpls_port_match_count_adjust(unit, vp, 1);
  56358 #endif
  56359             } else if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  56360 #if defined(BCM_TRIDENT2_SUPPORT)
  56361                 bcm_td2_vxlan_port_match_count_adjust(unit, vp, 1);
  56362 #endif
  56363             }
  56364         }
  56365 #endif
  56366         break;
  56367     case BCM_PORT_MATCH_PORT_INNER_VLAN_RANGE:
  56368 #if defined(BCM_TRIUMPH2_SUPPORT)
  56369         if (!soc_feature(unit, soc_feature_inner_vlan_range_check)) {
  56370             return BCM_E_UNAVAIL;
  56371         } 
  56372         /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */
  56373         /* Tag actions need to be adjusted by calling the
  56374            bcm_vlan_translate_action_add API for the entry we are creating */
  56375         VLAN_CHK_ID(unit, match->match_inner_vlan);
  56376         VLAN_CHK_ID(unit, match->match_inner_vlan_max);
  56377         if (BCM_GPORT_IS_MODPORT(match->port) ||
  56378             BCM_GPORT_IS_TRUNK(match->port)) {
  56379             /* Use the port from bcm_port_match_info_t instead of the physical
  56380                port from the VP */
  56381             gp = match->port;
  56382         }
  56383 
  56384         rv = _bcm_tr2_vlan_translate_range_vp_add(unit, gp,
  56385                                                   BCM_VLAN_INVALID,
  56386                                                   BCM_VLAN_INVALID,
  56387                                                   match->match_inner_vlan,
  56388                                                   match->match_inner_vlan_max,
  56389                                                   vp, match->action);
  56390         if (BCM_SUCCESS(rv)) {
  56391             if (BCM_GPORT_IS_MIM_PORT(port)) {
  56392                 _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1);
  56393             } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  56394 #if defined(BCM_MPLS_SUPPORT)
  56395                 bcm_tr_mpls_port_match_count_adjust(unit, vp, 1);
  56396 #endif
  56397             }
  56398         }
  56399 #endif
  56400         break;
  56401     case BCM_PORT_MATCH_PORT_VLAN_STACKED_RANGE:
  56402 #if defined(BCM_TRIUMPH2_SUPPORT)
  56403         if (!soc_feature(unit, soc_feature_inner_vlan_range_check)) {
  56404             return BCM_E_UNAVAIL;
  56405         } 
  56406         /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */
  56407         /* Tag actions need to be adjusted by calling the
  56408            bcm_vlan_translate_action_add API for the entry we are creating */
  56409         VLAN_CHK_ID(unit, match->match_vlan);
  56410         VLAN_CHK_ID(unit, match->match_vlan_max);
  56411         VLAN_CHK_ID(unit, match->match_inner_vlan);
  56412         VLAN_CHK_ID(unit, match->match_inner_vlan_max);
  56413         if (BCM_GPORT_IS_MODPORT(match->port) ||
  56414             BCM_GPORT_IS_TRUNK(match->port)) {
  56415             /* Use the port from bcm_port_match_info_t instead of the physical
  56416                port from the VP */
  56417             gp = match->port;
  56418         }
  56419 
  56420         rv = _bcm_tr2_vlan_translate_range_vp_add(unit, gp,
  56421                                                   match->match_vlan, 
  56422                                                   match->match_vlan_max,
  56423                                                   match->match_inner_vlan,
  56424                                                   match->match_inner_vlan_max,
  56425                                                   vp, match->action);
  56426         if (BCM_SUCCESS(rv)) {
  56427             if (BCM_GPORT_IS_MIM_PORT(port)) {
  56428                 _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1);
  56429             } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  56430 #if defined(BCM_MPLS_SUPPORT)
  56431                 bcm_tr_mpls_port_match_count_adjust(unit, vp, 1);
  56432 #endif
  56433             }  else if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  56434 #if defined(BCM_TRIDENT2_SUPPORT)
  56435                 bcm_td2_vxlan_port_match_count_adjust(unit, vp, 1);
  56436 #endif
  56437             }
  56438         }
  56439 #endif
  56440         break;
  56441 
  56442 #if defined(BCM_TRIUMPH3_SUPPORT)
  56443     case BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID:
  56444     case BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID_VLAN:
  56445         rv = _bcm_esw_extender_port_match_add(unit, match->port,
  56446                                               match->extended_port_vid,
  56447                                               match->match_vlan, vp);
  56448         break;
  56449 #endif
  56450 
  56451 #ifdef BCM_TRIUMPH2_SUPPORT
  56452     case BCM_PORT_MATCH_PORT_PON_TUNNEL:
  56453     case BCM_PORT_MATCH_PORT_PON_TUNNEL_VLAN:
  56454     case BCM_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN:    
  56455         if (!BCM_GPORT_IS_VLAN_PORT(port)) {
  56456             return BCM_E_UNAVAIL;
  56457         }
  56458         if (BCM_GPORT_IS_MODPORT(match->port) ||
  56459             BCM_GPORT_IS_TRUNK(match->port)) {
  56460             if (match->port != gp) {
  56461                 return BCM_E_PORT;
  56462             }
  56463         } else if (BCM_GPORT_IS_LOCAL(match->port)) {
  56464             bcm_module_t modid;
  56465             bcm_trunk_t trunk_id;
  56466             bcm_port_t port_num;
  56467             bcm_gport_t modport;
  56468             int id;
  56469 
  56470             BCM_IF_ERROR_RETURN (_bcm_esw_gport_resolve(unit, 
  56471                                                match->port, &modid, &port_num, &trunk_id, &id));
  56472             if (trunk_id != BCM_TRUNK_INVALID) {
  56473                 BCM_GPORT_TRUNK_SET(modport, trunk_id);   
  56474             } else {
  56475                 BCM_IF_ERROR_RETURN(_bcm_esw_stk_modmap_map(unit, 
  56476                                                 BCM_STK_MODMAP_GET, modid, port_num, &modid, &port_num));
  56477                 BCM_GPORT_MODPORT_SET(modport, modid, port_num);
  56478             }
  56479 
  56480             if (modport != gp) {
  56481                 return BCM_E_PORT;
  56482             }
  56483         }else {
  56484             return BCM_E_PORT;
  56485         }
  56486 
  56487         VLAN_CHK_ID(unit, match->match_pon_tunnel);
  56488         if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL) {
  56489             rv = _bcm_tr_lltag_vlan_translate_vp_add(unit, gp, bcmVlanTranslateKeyPortPonTunnel,
  56490                                               match->match_pon_tunnel,
  56491                                               BCM_VLAN_INVALID,
  56492                                               vp, 
  56493                                               match->action);
  56494         } else if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL_VLAN) {
  56495             VLAN_CHK_ID(unit, match->match_vlan);
  56496             rv = _bcm_tr_lltag_vlan_translate_vp_add(unit, gp, bcmVlanTranslateKeyPortPonTunnelOuter,
  56497                                               match->match_pon_tunnel,
  56498                                               match->match_vlan,
  56499                                               vp, 
  56500                                               match->action);
  56501         } else if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN) {
  56502             VLAN_CHK_ID(unit, match->match_inner_vlan);
  56503             rv = _bcm_tr_lltag_vlan_translate_vp_add(unit, gp, bcmVlanTranslateKeyPortPonTunnelInner,
  56504                                               match->match_pon_tunnel,
  56505                                               match->match_inner_vlan,
  56506                                               vp, 
  56507                                               match->action);
  56508         }
  56509         
  56510         if (BCM_FAILURE(rv)) {
  56511             return rv;
  56512         }
  56513 
  56514         bcm_tr2_vlan_port_match_count_adjust(unit, vp, 1);
  56515         break;
  56516 #endif 
  56517 #if defined(BCM_TRIDENT_SUPPORT)
  56518     case BCM_PORT_MATCH_PORT_NIV_PORT_VIF:
  56519     case BCM_PORT_MATCH_PORT_NIV_PORT_VIF_VLAN:
  56520         rv = _bcm_trident_niv_match_add(unit, match->port,
  56521                                         match->niv_port_vif,
  56522                                         match->match_vlan, vp);
  56523         break;
  56524 #endif /* BCM_TRIDENT_SUPPORT */
  56525 #if defined(BCM_TRX_SUPPORT)
  56526     case BCM_PORT_MATCH_MAC_PORT:
  56527     case BCM_PORT_MATCH_MAC_PORT_CLASS:
  56528         bcm_vlan_match_info_t_init(&vlan_match_info);
  56529         if (match->match == BCM_PORT_MATCH_MAC_PORT) {
  56530             vlan_match_info.match = BCM_VLAN_MATCH_MAC_PORT;
  56531             vlan_match_info.port = match->port;
  56532         } else if (match->match == BCM_PORT_MATCH_MAC_PORT_CLASS) {
  56533             vlan_match_info.match = BCM_VLAN_MATCH_MAC_PORT_CLASS;
  56534             vlan_match_info.port_class = match->port_class;
  56535         }
  56536         sal_memcpy(vlan_match_info.src_mac,
  56537                 match->src_mac, sizeof (bcm_mac_t));
  56538         rv = _bcm_trx_vlan_match_action_add(unit, 0,
  56539                 port, &vlan_match_info, match->action);
  56540         break;
  56541 #endif
  56542     default:
  56543         rv = BCM_E_PARAM;
  56544         break;
  56545     }
  56546     return rv;
  56547 #else
  56548     return BCM_E_UNAVAIL;
  56549 #endif
  56550 }
  56551 
  56552 /*
  56553  * Function:
  56554  *      bcm_port_match_delete
  56555  * Purpose:
  56556  *      Remove a match from an existing port
  56557  * Parameters:
  56558  *      unit - (IN) Unit number.
  56559  *      port - (IN) Port or gport
  56560  *      match - (IN) Match criteria
  56561  * Returns:
  56562  *      BCM_E_xxx
  56563  * Notes:
  56564  */
  56565 int
  56566 bcm_esw_port_match_delete(
  56567     int unit,
  56568     bcm_gport_t port,
  56569     bcm_port_match_info_t *match)
  56570 {
  56571 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
  56572     int vp=0, rv = BCM_E_NONE;
  56573     bcm_gport_t gp = 0;
  56574 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_MPLS_SUPPORT)
  56575     _bcm_vp_info_t vp_info;
  56576 #endif    
  56577 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
  56578     bcm_vxlan_port_t vxlan_port;
  56579     bcm_l2gre_port_t l2gre_port;
  56580 #endif
  56581 #if defined(BCM_TRIDENT3_SUPPORT)
  56582     bcm_mirror_destination_t mirror_dest;
  56583     uint32 cancun_ver;
  56584 #endif /* BCM_TRIDENT3_SUPPORT */
  56585 #if defined(BCM_TRX_SUPPORT)
  56586     bcm_vlan_match_info_t vlan_match_info;
  56587 #endif
  56588 
  56589     if (match == NULL) {
  56590         return BCM_E_PARAM;
  56591     }
  56592     /* Make sure port module is initialized. */
  56593     PORT_INIT(unit);
  56594 
  56595     if (BCM_GPORT_IS_MIM_PORT(port)) {
  56596 #if defined(BCM_TRIUMPH2_SUPPORT)
  56597         if (!soc_feature(unit, soc_feature_mim)) {
  56598             return BCM_E_UNAVAIL;
  56599         }
  56600         vp = BCM_GPORT_MIM_PORT_ID_GET(port);
  56601         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
  56602             return BCM_E_NOT_FOUND;
  56603         }
  56604         BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  56605         if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  56606             BCM_IF_ERROR_RETURN(_bcm_tr2_mim_port_phys_gport_get(unit, vp, &gp));
  56607         }
  56608 #endif
  56609     } else if  (BCM_GPORT_IS_MPLS_PORT(port)) {
  56610         if (!soc_feature(unit, soc_feature_mpls)) {
  56611             return BCM_E_UNAVAIL;
  56612         }
  56613         vp = BCM_GPORT_MPLS_PORT_ID_GET(port);
  56614         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
  56615             return BCM_E_NOT_FOUND;
  56616         }
  56617 #if defined(BCM_MPLS_SUPPORT)
  56618         BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  56619         if ((vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  56620             if (!soc_feature(unit, soc_feature_vp_sharing)) {
  56621                 return BCM_E_UNAVAIL;
  56622             }
  56623         } else {
  56624         BCM_IF_ERROR_RETURN(bcm_tr_mpls_port_phys_gport_get(unit, vp, &gp));
  56625         }
  56626 #endif
  56627     } else
  56628 #if defined(BCM_TRIDENT2_SUPPORT)
  56629     if (BCM_GPORT_IS_TRUNK(port)) {
  56630         if (!soc_feature(unit, soc_feature_vp_lag)) {
  56631             return BCM_E_UNAVAIL;
  56632         }
  56633         BCM_IF_ERROR_RETURN(
  56634             _bcm_esw_trunk_tid_to_vp_lag_vp(unit, BCM_GPORT_TRUNK_GET(port),
  56635                                             &vp));
  56636         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) {
  56637             return BCM_E_NOT_FOUND;
  56638         }
  56639         if (match->match != BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID &&
  56640             match->match != BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID_VLAN) {
  56641             return BCM_E_PARAM;
  56642         }
  56643     } else
  56644 #endif /* BCM_TRIDENT2_SUPPORT */
  56645 #if defined(BCM_TRIDENT2_SUPPORT)
  56646     if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  56647         if (!soc_feature(unit, soc_feature_vxlan)) {
  56648             return BCM_E_UNAVAIL;
  56649         }
  56650         if (match->match == BCM_PORT_MATCH_PORT
  56651             || match->match == BCM_PORT_MATCH_PORT_VLAN_RANGE
  56652             || match->match == BCM_PORT_MATCH_PORT_INNER_VLAN_RANGE
  56653             || match->match == BCM_PORT_MATCH_PORT_VLAN_STACKED_RANGE
  56654             ) {
  56655             vp = BCM_GPORT_VXLAN_PORT_ID_GET(port);
  56656             if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan))) {
  56657                 return BCM_E_NOT_FOUND;
  56658             }
  56659         } else {
  56660             if (!soc_feature(unit, soc_feature_vp_sharing)) {
  56661                 return BCM_E_UNAVAIL;
  56662             }
  56663 
  56664             vp = BCM_GPORT_VXLAN_PORT_ID_GET(port);
  56665             BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  56666             if (vp_info.vp_type != _bcmVpTypeVxlan) {
  56667                 return BCM_E_PARAM;
  56668             }
  56669             if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  56670                 return BCM_E_PARAM;
  56671             }
  56672         }
  56673     } else 
  56674 #endif
  56675 #if defined(BCM_TRIDENT2_SUPPORT)
  56676     if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  56677         if (!soc_feature(unit, soc_feature_l2gre)) {
  56678             return BCM_E_UNAVAIL;
  56679         }
  56680         if (match->match == BCM_PORT_MATCH_PORT) {
  56681             vp = BCM_GPORT_L2GRE_PORT_ID_GET(port);
  56682             if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre))) {
  56683                 return BCM_E_NOT_FOUND;
  56684             }
  56685         } else {
  56686             if (!soc_feature(unit, soc_feature_vp_sharing)) {
  56687                 return BCM_E_UNAVAIL;
  56688             }
  56689 
  56690             vp = BCM_GPORT_L2GRE_PORT_ID_GET(port);
  56691             BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  56692 
  56693             if (vp_info.vp_type != _bcmVpTypeL2Gre) {
  56694                 return BCM_E_PARAM;
  56695             }
  56696             if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  56697                 return BCM_E_PARAM;
  56698             }
  56699         }
  56700     } else 
  56701 #endif
  56702 
  56703 #if defined(BCM_TRIUMPH2_SUPPORT) 
  56704     if (BCM_GPORT_IS_VLAN_PORT(port)) {
  56705         if (!soc_feature(unit, soc_feature_lltag)) {
  56706             return BCM_E_UNAVAIL;
  56707         }
  56708         vp = BCM_GPORT_VLAN_PORT_ID_GET(port);
  56709         if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan))) {
  56710             return BCM_E_NOT_FOUND;
  56711         }
  56712         BCM_IF_ERROR_RETURN(bcm_tr2_vlan_port_phys_gport_get(unit, vp, &gp));
  56713     } else
  56714 #endif
  56715 #if defined(BCM_TRIDENT_SUPPORT)
  56716     if (BCM_GPORT_IS_NIV_PORT(port)) {
  56717         if (!soc_feature(unit, soc_feature_niv)) {
  56718             return BCM_E_UNAVAIL;
  56719         }
  56720         vp = BCM_GPORT_NIV_PORT_ID_GET(port);
  56721         if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv))) {
  56722             return BCM_E_PARAM;
  56723         }
  56724     } else
  56725 #endif /* BCM_TRIDENT_SUPPORT */
  56726 #if defined(BCM_TRIDENT3_SUPPORT)
  56727     if (BCM_GPORT_IS_MIRROR(port)) {
  56728         if (!soc_feature(unit, soc_feature_mirror_encap_profile)) {
  56729             return BCM_E_UNAVAIL;
  56730         }
  56731         if ((match->match == BCM_PORT_MATCH_PORT_VLAN) ||
  56732             (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE) ||
  56733             (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS)) {
  56734 
  56735             SOC_IF_ERROR_RETURN(soc_cancun_version_get(unit, &cancun_ver));
  56736             if (SOC_IS_TRIDENT3(unit) &&
  56737                 SOC_CANCUN_VERSION_5_2_UNDER_SERIES(cancun_ver)) {
  56738                 if ((match->match == BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE) ||
  56739                     (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS)) {
  56740                     LOG_ERROR(BSL_LS_BCM_PORT,
  56741                               (BSL_META_U(unit,
  56742                           "BCM_PORT_MATCH_PORT_I2E_CLASS match criteria \
  56743                            not supported in Cancun 5.1.8 release\n")));
  56744                     return BCM_E_UNAVAIL;
  56745                 }
  56746             } else {
  56747                 if (match->match == BCM_PORT_MATCH_PORT_VLAN) {
  56748                     LOG_ERROR(BSL_LS_BCM_PORT,
  56749                               (BSL_META_U(unit,
  56750                           "BCM_PORT_MATCH_PORT_VLAN match criteria \
  56751                            not supported after Cancun 5.1.8 release\n")));
  56752                     return BCM_E_UNAVAIL;
  56753                 }
  56754             }
  56755 
  56756             bcm_mirror_destination_t_init(&mirror_dest);
  56757             BCM_IF_ERROR_RETURN(bcm_esw_mirror_destination_get(unit, port,
  56758                                 &mirror_dest));
  56759             if (mirror_dest.flags & BCM_MIRROR_DEST_FIELD) {
  56760                 return BCM_E_PARAM;
  56761             }
  56762         } else {
  56763             return BCM_E_PARAM;
  56764         }
  56765     } else
  56766 #endif /* BCM_TRIDENT3_SUPPORT */
  56767     {
  56768         return BCM_E_PORT;
  56769     }
  56770 
  56771     switch (match->match) {
  56772     case BCM_PORT_MATCH_NONE:
  56773         rv = BCM_E_NONE;
  56774         break;
  56775 #if defined(BCM_TRIDENT2_SUPPORT)
  56776     case BCM_PORT_MATCH_PORT:
  56777         if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  56778             bcm_vxlan_port_t_init(&vxlan_port);
  56779             vxlan_port.criteria      = BCM_VXLAN_PORT_MATCH_PORT;
  56780             vxlan_port.vxlan_port_id = port;
  56781             vxlan_port.match_port    = match->port;
  56782             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0));
  56783         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  56784 #if defined(BCM_MPLS_SUPPORT)
  56785             bcm_mpls_port_t mpls_port;
  56786             bcm_mpls_port_t_init(&mpls_port);
  56787             mpls_port.criteria       = BCM_MPLS_PORT_MATCH_PORT;
  56788             mpls_port.mpls_port_id   = port;
  56789             mpls_port.port           = match->port;
  56790             BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_delete(unit, vp, &mpls_port, TRUE));
  56791 #endif
  56792         } else if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  56793             bcm_l2gre_port_t_init(&l2gre_port);
  56794             l2gre_port.criteria       = BCM_L2GRE_PORT_MATCH_PORT;
  56795             l2gre_port.l2gre_port_id   = port;
  56796             l2gre_port.match_port           = match->port;
  56797             BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_delete(unit, vp, &l2gre_port));
  56798         } else {
  56799             rv = BCM_E_PARAM;
  56800         }
  56801         break;
  56802 #endif
  56803 
  56804     case BCM_PORT_MATCH_PORT_I2E_CLASS:
  56805     case BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE:
  56806 #if defined(BCM_TRIDENT3_SUPPORT)
  56807         if (BCM_GPORT_IS_MIRROR(port)) {
  56808             rv = _bcm_mirror_port_match_delete(unit, &mirror_dest, match->port,
  56809                                             match->match_vlan, match->match);
  56810         } else
  56811 #endif
  56812         {
  56813             rv = BCM_E_UNAVAIL;
  56814         }
  56815         break;
  56816 
  56817     case BCM_PORT_MATCH_PORT_VLAN:
  56818 #if defined(BCM_TRIDENT3_SUPPORT)
  56819         if (BCM_GPORT_IS_MIRROR(port)) {
  56820             rv = _bcm_mirror_port_match_delete(unit, &mirror_dest, match->port,
  56821                                                match->match_vlan, match->match);
  56822             break;
  56823         } else
  56824 #endif /* BCM_TRIDENT3_SUPPORT */
  56825 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  56826         if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  56827             /* match_info translation to vxlan_port */
  56828             bcm_vxlan_port_t_init(&vxlan_port);
  56829             vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_VLAN;
  56830             vxlan_port.match_vlan = match->match_vlan;
  56831             vxlan_port.vxlan_port_id = port;
  56832             vxlan_port.match_port = match->port; 
  56833             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0));
  56834             break;
  56835         } else if (BCM_GPORT_IS_MIM_PORT(port) &&
  56836             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  56837             bcm_mim_port_t mim_port;
  56838             bcm_mim_port_t_init(&mim_port);
  56839             VLAN_CHK_ID(unit, match->match_vlan);
  56840             mim_port.criteria = BCM_MIM_PORT_MATCH_PORT_VLAN;
  56841             mim_port.match_vlan = match->match_vlan;
  56842             mim_port.mim_port_id = port;
  56843             mim_port.port = match->port;
  56844             BCM_IF_ERROR_RETURN(_bcm_tr2_mim_match_delete(unit, 
  56845                                  vp, mim_port));
  56846             break;
  56847         } else if (BCM_GPORT_IS_MPLS_PORT(port) &&
  56848             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  56849             bcm_mpls_port_t mpls_port;
  56850             bcm_mpls_port_t_init(&mpls_port);
  56851             VLAN_CHK_ID(unit, match->match_vlan);
  56852             mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_VLAN;
  56853             mpls_port.match_vlan = match->match_vlan;
  56854             mpls_port.mpls_port_id = port;
  56855             mpls_port.port = match->port;
  56856             BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_delete(unit,
  56857                                  vp, &mpls_port, 0));
  56858             break;
  56859         } else if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  56860             /* match_info translation to L2GRE_port */
  56861             bcm_l2gre_port_t_init(&l2gre_port);
  56862             VLAN_CHK_ID(unit, match->match_vlan);
  56863             l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_VLAN;
  56864             l2gre_port.match_vlan = match->match_vlan;
  56865             l2gre_port.l2gre_port_id = port;
  56866             l2gre_port.match_port = match->port;
  56867             BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_delete(unit,vp,
  56868                                             &l2gre_port));
  56869             break;
  56870         }
  56871 #endif
  56872         
  56873         /* Add an entry in the VLAN_XLATE table */
  56874         /* Tag actions need to be adjusted by calling the
  56875            bcm_vlan_translate_action_add API for the entry we are creating */
  56876         VLAN_CHK_ID(unit, match->match_vlan);
  56877         if (BCM_GPORT_IS_MODPORT(match->port) ||
  56878             BCM_GPORT_IS_TRUNK(match->port)) {
  56879             /* Use the port from bcm_port_match_info_t instead of the physical
  56880                port from the VP */
  56881             gp = match->port;
  56882         }
  56883         rv = _bcm_tr_vlan_translate_vp_delete(unit, gp,
  56884                                                bcmVlanTranslateKeyPortOuter,
  56885                                                match->match_vlan,
  56886                                                BCM_VLAN_INVALID,
  56887                                                vp);
  56888 
  56889         if (BCM_GPORT_IS_MIM_PORT(port)) {
  56890 #if defined(BCM_TRIUMPH2_SUPPORT)
  56891            _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1);
  56892 #endif
  56893         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  56894 #if defined(BCM_MPLS_SUPPORT)
  56895            bcm_tr_mpls_port_match_count_adjust(unit, vp, -1);
  56896 #endif
  56897         }
  56898         break;
  56899 
  56900     case BCM_PORT_MATCH_PORT_INNER_VLAN:
  56901 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  56902         if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  56903             bcm_vxlan_port_t_init(&vxlan_port);
  56904             VLAN_CHK_ID(unit, match->match_inner_vlan);
  56905             vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_INNER_VLAN;
  56906             vxlan_port.match_inner_vlan = match->match_inner_vlan;
  56907             vxlan_port.vxlan_port_id = port;
  56908             vxlan_port.match_port = match->port;
  56909 
  56910             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0));
  56911             break;
  56912         } else if (BCM_GPORT_IS_MPLS_PORT(port) &&
  56913             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  56914             bcm_mpls_port_t mpls_port;
  56915             bcm_mpls_port_t_init(&mpls_port);
  56916             VLAN_CHK_ID(unit, match->match_inner_vlan);
  56917             mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_INNER_VLAN;
  56918             mpls_port.match_inner_vlan = match->match_inner_vlan;
  56919             mpls_port.mpls_port_id = port;
  56920             mpls_port.port = match->port;
  56921             BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_delete(unit,
  56922                                  vp, &mpls_port, 0));
  56923             break;
  56924         } else if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  56925             /* match_info translation to L2GRE_port */
  56926             bcm_l2gre_port_t_init(&l2gre_port);
  56927             VLAN_CHK_ID(unit, match->match_inner_vlan);
  56928             l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_INNER_VLAN;
  56929             l2gre_port.match_inner_vlan = match->match_inner_vlan;
  56930             l2gre_port.l2gre_port_id = port;
  56931             l2gre_port.match_port = match->port;
  56932             BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_delete(unit, vp,
  56933                                             &l2gre_port));
  56934             break;
  56935         }
  56936 #endif
  56937         /* Add an entry in the VLAN_XLATE table */
  56938         /* Tag actions need to be adjusted by calling the
  56939          * bcm_vlan_translate_action_add API for the entry we are creating */
  56940         VLAN_CHK_ID(unit, match->match_inner_vlan);
  56941         if (BCM_GPORT_IS_MODPORT(match->port) ||
  56942             BCM_GPORT_IS_TRUNK(match->port)) {
  56943             /* Use the port from bcm_port_match_info_t instead of the physical
  56944                port from the VP */
  56945             gp = match->port;
  56946         }
  56947 
  56948         rv = _bcm_tr_vlan_translate_vp_delete(unit, gp,
  56949                                                bcmVlanTranslateKeyPortInner,
  56950                                                BCM_VLAN_INVALID,
  56951                                                match->match_inner_vlan,
  56952                                                vp);
  56953         break;
  56954 
  56955     case BCM_PORT_MATCH_PORT_VLAN16:
  56956 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  56957         if (BCM_GPORT_IS_VXLAN_PORT(port) &&
  56958             ((match->match_vlan & 0xfff) == BCM_VLAN_NONE)) {
  56959             bcm_vxlan_port_t_init(&vxlan_port);
  56960             vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_VLAN_PRI;
  56961             vxlan_port.match_vlan = match->match_vlan;
  56962             vxlan_port.vxlan_port_id = port;
  56963             vxlan_port.match_port = match->port;
  56964 
  56965             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0));
  56966             break;
  56967         } else if (BCM_GPORT_IS_MPLS_PORT(port) &&
  56968             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  56969             bcm_mpls_port_t mpls_port;
  56970             bcm_mpls_port_t_init(&mpls_port);
  56971             mpls_port.criteria = BCM_MPLS_PORT_MATCH_VLAN_PRI;
  56972             mpls_port.match_vlan = match->match_vlan;
  56973             mpls_port.mpls_port_id = port;
  56974             mpls_port.port = match->port;
  56975             BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_delete(unit,
  56976                                  vp, &mpls_port, 0));
  56977             break;
  56978         }  else if (BCM_GPORT_IS_L2GRE_PORT(port) &&
  56979             ((match->match_vlan & 0xfff) == BCM_VLAN_NONE)) {
  56980             /* match_info translation to L2GRE_port */
  56981             bcm_l2gre_port_t_init(&l2gre_port);
  56982             l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_VLAN_PRI;
  56983             l2gre_port.match_vlan = match->match_vlan;
  56984             l2gre_port.l2gre_port_id = port;
  56985             l2gre_port.match_port = match->port;
  56986             BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_delete(unit, vp,
  56987                                             &l2gre_port));
  56988             break;
  56989         }
  56990 #endif
  56991         /* Add an entry in the VLAN_XLATE table */
  56992         /* Tag actions need to be adjusted by calling the
  56993            bcm_vlan_translate_action_add API for the entry we are creating */
  56994         if (BCM_GPORT_IS_MODPORT(match->port) ||
  56995             BCM_GPORT_IS_TRUNK(match->port)) {
  56996             /* Use the port from bcm_port_match_info_t instead of the physical
  56997                port from the VP */
  56998             gp = match->port;
  56999         }
  57000         /* allow 16 bit VLAN id */
  57001         rv = _bcm_tr_vlan_translate_vp_delete(unit, gp,
  57002                                                bcmVlanTranslateKeyPortOuterTag,
  57003                                                match->match_vlan,
  57004                                                BCM_VLAN_INVALID,
  57005                                                vp);
  57006 
  57007         if (BCM_GPORT_IS_MIM_PORT(port)) {
  57008 #if defined(BCM_TRIUMPH2_SUPPORT)
  57009            _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1);
  57010 #endif
  57011         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  57012 #if defined(BCM_MPLS_SUPPORT)
  57013            bcm_tr_mpls_port_match_count_adjust(unit, vp, -1);
  57014 #endif
  57015         }
  57016         break;
  57017     case BCM_PORT_MATCH_PORT_VLAN_STACKED:
  57018 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  57019         if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  57020             /* match_info translation to vxlan_port */
  57021             bcm_vxlan_port_t_init(&vxlan_port);
  57022             vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_VLAN_STACKED;
  57023             vxlan_port.match_vlan = match->match_vlan;
  57024             vxlan_port.match_inner_vlan = match->match_inner_vlan;
  57025             vxlan_port.vxlan_port_id = port;
  57026             vxlan_port.match_port = match->port;            
  57027             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0));
  57028             break;
  57029         } else if (BCM_GPORT_IS_MIM_PORT(port) &&
  57030             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  57031             bcm_mim_port_t mim_port;
  57032             bcm_mim_port_t_init(&mim_port);
  57033             VLAN_CHK_ID(unit, match->match_vlan);
  57034             VLAN_CHK_ID(unit, match->match_inner_vlan);
  57035             mim_port.criteria = BCM_MIM_PORT_MATCH_PORT_VLAN_STACKED;
  57036             mim_port.match_vlan = match->match_vlan;
  57037             mim_port.match_inner_vlan = match->match_inner_vlan;
  57038             mim_port.mim_port_id = port;
  57039             mim_port.port = match->port;
  57040             BCM_IF_ERROR_RETURN(_bcm_tr2_mim_match_delete(unit, 
  57041                                  vp, mim_port));
  57042             break;
  57043         } else if (BCM_GPORT_IS_MPLS_PORT(port) &&
  57044             (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  57045             bcm_mpls_port_t mpls_port;
  57046             bcm_mpls_port_t_init(&mpls_port);
  57047             VLAN_CHK_ID(unit, match->match_vlan);
  57048             VLAN_CHK_ID(unit, match->match_inner_vlan);
  57049             mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_VLAN_STACKED;
  57050             mpls_port.match_vlan = match->match_vlan;
  57051             mpls_port.match_inner_vlan = match->match_inner_vlan;
  57052             mpls_port.mpls_port_id = port;
  57053             mpls_port.port = match->port;
  57054             BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_delete(unit,
  57055                                  vp, &mpls_port, 0));
  57056             break;
  57057         }else if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  57058             /* match_info translation to L2GRE_port */
  57059             bcm_l2gre_port_t_init(&l2gre_port);
  57060             l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_VLAN_STACKED;
  57061             l2gre_port.match_vlan = match->match_vlan;
  57062             l2gre_port.match_inner_vlan = match->match_inner_vlan;
  57063             l2gre_port.l2gre_port_id = port;
  57064             l2gre_port.match_port = match->port;
  57065             BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_delete(unit, vp,
  57066                                             &l2gre_port));
  57067             break;
  57068         }
  57069 #endif
  57070         /* Add an entry in the VLAN_XLATE table */
  57071         /* Tag actions need to be adjusted by calling the
  57072            bcm_vlan_translate_action_add API for the entry we are creating */
  57073         VLAN_CHK_ID(unit, match->match_vlan);
  57074         VLAN_CHK_ID(unit, match->match_inner_vlan);
  57075         if (BCM_GPORT_IS_MODPORT(match->port) ||
  57076             BCM_GPORT_IS_TRUNK(match->port)) {
  57077             /* Use the port from bcm_port_match_info_t instead of the physical
  57078                port from the VP */
  57079             gp = match->port;
  57080         }
  57081         rv = _bcm_tr_vlan_translate_vp_delete(unit, gp,
  57082                                                bcmVlanTranslateKeyPortDouble,
  57083                                                match->match_vlan,
  57084                                                match->match_inner_vlan,
  57085                                                vp);
  57086 
  57087         if (BCM_GPORT_IS_MIM_PORT(port)) {
  57088 #if defined(BCM_TRIUMPH2_SUPPORT)
  57089            _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1);
  57090 #endif
  57091         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  57092 #if defined(BCM_MPLS_SUPPORT)
  57093            bcm_tr_mpls_port_match_count_adjust(unit, vp, -1);
  57094 #endif
  57095         }
  57096         break;
  57097     case BCM_PORT_MATCH_PORT_VLAN_RANGE:
  57098 #if defined(BCM_TRIUMPH2_SUPPORT)
  57099         /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */
  57100         /* Tag actions need to be adjusted by calling the
  57101            bcm_vlan_translate_action_add API for the entry we are creating */
  57102         VLAN_CHK_ID(unit, match->match_vlan);
  57103         VLAN_CHK_ID(unit, match->match_vlan_max);
  57104         if (BCM_GPORT_IS_MODPORT(match->port) ||
  57105             BCM_GPORT_IS_TRUNK(match->port)) {
  57106             /* Use the port from bcm_port_match_info_t instead of the physical
  57107                port from the VP */
  57108             gp = match->port;
  57109         }
  57110         rv = _bcm_tr2_vlan_translate_range_vp_delete(unit, gp,
  57111                                                      match->match_vlan,
  57112                                                      match->match_vlan_max,
  57113                                                      BCM_VLAN_INVALID,
  57114                                                      BCM_VLAN_INVALID,                                                     
  57115                                                      vp);
  57116         if (BCM_GPORT_IS_MIM_PORT(port)) {
  57117             _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1);
  57118         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  57119 #if defined(BCM_MPLS_SUPPORT)
  57120             bcm_tr_mpls_port_match_count_adjust(unit, vp, -1);
  57121 #endif
  57122         } else if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  57123 #if defined(BCM_TRIDENT2_SUPPORT)
  57124             bcm_td2_vxlan_port_match_count_adjust(unit, vp, -1);
  57125 #endif
  57126         }
  57127 #endif
  57128         break;
  57129     case BCM_PORT_MATCH_PORT_INNER_VLAN_RANGE:
  57130 #if defined(BCM_TRIUMPH2_SUPPORT)
  57131         if (!soc_feature(unit, soc_feature_inner_vlan_range_check)) {
  57132             return BCM_E_UNAVAIL;
  57133         } 
  57134         /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */
  57135         /* Tag actions need to be adjusted by calling the
  57136            bcm_vlan_translate_action_add API for the entry we are creating */
  57137         VLAN_CHK_ID(unit, match->match_inner_vlan);
  57138         VLAN_CHK_ID(unit, match->match_inner_vlan_max);
  57139         if (BCM_GPORT_IS_MODPORT(match->port) ||
  57140             BCM_GPORT_IS_TRUNK(match->port)) {
  57141             /* Use the port from bcm_port_match_info_t instead of the physical
  57142                port from the VP */
  57143             gp = match->port;
  57144         }
  57145         rv = _bcm_tr2_vlan_translate_range_vp_delete(unit, gp,
  57146                                                      BCM_VLAN_INVALID,
  57147                                                      BCM_VLAN_INVALID,            
  57148                                                      match->match_inner_vlan,
  57149                                                      match->match_inner_vlan_max,
  57150                                                      vp);
  57151         if (BCM_GPORT_IS_MIM_PORT(port)) {
  57152             _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1);
  57153         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  57154 #if defined(BCM_MPLS_SUPPORT)
  57155             bcm_tr_mpls_port_match_count_adjust(unit, vp, -1);
  57156 #endif
  57157         }
  57158 #endif
  57159         break;
  57160     case BCM_PORT_MATCH_PORT_VLAN_STACKED_RANGE:
  57161 #if defined(BCM_TRIUMPH2_SUPPORT)
  57162         if (!soc_feature(unit, soc_feature_inner_vlan_range_check)) {
  57163             return BCM_E_UNAVAIL;
  57164         } 
  57165         /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */
  57166         /* Tag actions need to be adjusted by calling the
  57167            bcm_vlan_translate_action_add API for the entry we are creating */
  57168         VLAN_CHK_ID(unit, match->match_vlan);
  57169         VLAN_CHK_ID(unit, match->match_vlan_max);
  57170         VLAN_CHK_ID(unit, match->match_inner_vlan);
  57171         VLAN_CHK_ID(unit, match->match_inner_vlan_max);
  57172         if (BCM_GPORT_IS_MODPORT(match->port) ||
  57173             BCM_GPORT_IS_TRUNK(match->port)) {
  57174             /* Use the port from bcm_port_match_info_t instead of the physical
  57175                port from the VP */
  57176             gp = match->port;
  57177         }
  57178         rv = _bcm_tr2_vlan_translate_range_vp_delete(unit, gp,
  57179                                                      match->match_vlan,
  57180                                                      match->match_vlan_max,
  57181                                                      match->match_inner_vlan,
  57182                                                      match->match_inner_vlan_max,                                                     
  57183                                                      vp);
  57184         if (BCM_GPORT_IS_MIM_PORT(port)) {
  57185             _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1);
  57186         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  57187 #if defined(BCM_MPLS_SUPPORT)
  57188             bcm_tr_mpls_port_match_count_adjust(unit, vp, -1);
  57189 #endif
  57190         } else if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  57191 #if defined(BCM_TRIDENT2_SUPPORT)
  57192             bcm_td2_vxlan_port_match_count_adjust(unit, vp, -1);
  57193 #endif
  57194         }
  57195 #endif
  57196         break;
  57197 
  57198 #if defined(BCM_TRIUMPH3_SUPPORT)
  57199     case BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID:
  57200     case BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID_VLAN:
  57201         rv = _bcm_esw_extender_port_match_delete(unit, match->port,
  57202                                                  match->extended_port_vid,
  57203                                                  match->match_vlan, vp);
  57204         break;
  57205 #endif
  57206 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  57207     case BCM_PORT_MATCH_PORT_PCP_VLAN:
  57208         if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  57209             /* match_info translation to vxlan_port */
  57210             bcm_vxlan_port_t_init(&vxlan_port);
  57211             VLAN_CHK_ID(unit, match->match_vlan);
  57212             if ((match->match_vlan & 0x0fff) != 0) {
  57213                 return BCM_E_UNAVAIL;
  57214             }
  57215             vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_VLAN_PRI;
  57216             vxlan_port.match_vlan = (match->match_vlan & 0xf000);
  57217             vxlan_port.vxlan_port_id = port;
  57218             vxlan_port.match_port = match->port; 
  57219             BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0));
  57220             break;
  57221         } else {
  57222             rv = BCM_E_PARAM;
  57223         }
  57224         break;
  57225 #endif
  57226 #ifdef BCM_TRIUMPH2_SUPPORT
  57227         case BCM_PORT_MATCH_PORT_PON_TUNNEL:
  57228         case BCM_PORT_MATCH_PORT_PON_TUNNEL_VLAN:
  57229         case BCM_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN:    
  57230             if (!BCM_GPORT_IS_VLAN_PORT(port)) {
  57231                 return BCM_E_UNAVAIL;
  57232             }
  57233             if (match->port != gp) {
  57234                 return BCM_E_PORT;
  57235             }
  57236     
  57237             VLAN_CHK_ID(unit, match->match_pon_tunnel);
  57238             if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL) {
  57239                 rv = _bcm_tr_lltag_vlan_translate_vp_delete(unit, gp, bcmVlanTranslateKeyPortPonTunnel,
  57240                                                   match->match_pon_tunnel,
  57241                                                   BCM_VLAN_INVALID,
  57242                                                   vp);
  57243             } else if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL_VLAN) {
  57244                 VLAN_CHK_ID(unit, match->match_vlan);
  57245                 rv = _bcm_tr_lltag_vlan_translate_vp_delete(unit, gp, bcmVlanTranslateKeyPortPonTunnelOuter,
  57246                                                   match->match_pon_tunnel,
  57247                                                   match->match_vlan,
  57248                                                   vp);
  57249             } else if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN) {
  57250                 VLAN_CHK_ID(unit, match->match_pon_tunnel);
  57251                 rv = _bcm_tr_lltag_vlan_translate_vp_delete(unit, gp, bcmVlanTranslateKeyPortPonTunnelInner,
  57252                                                   match->match_pon_tunnel,
  57253                                                   match->match_inner_vlan,
  57254                                                   vp);
  57255             }
  57256             
  57257             if (BCM_FAILURE(rv)) {
  57258                 return rv;
  57259             }
  57260     
  57261             bcm_tr2_vlan_port_match_count_adjust(unit, vp, -1);
  57262             break;
  57263 #endif 
  57264 #if defined(BCM_TRIDENT_SUPPORT)
  57265     case BCM_PORT_MATCH_PORT_NIV_PORT_VIF:
  57266     case BCM_PORT_MATCH_PORT_NIV_PORT_VIF_VLAN:
  57267         rv = _bcm_trident_niv_match_delete(unit, match->port,
  57268                                            match->niv_port_vif,
  57269                                            match->match_vlan, NULL);
  57270     break;
  57271 #endif /* BCM_TRIDENT_SUPPORT */
  57272 #if defined(BCM_TRX_SUPPORT)
  57273     case BCM_PORT_MATCH_MAC_PORT:
  57274     case BCM_PORT_MATCH_MAC_PORT_CLASS:
  57275         bcm_vlan_match_info_t_init(&vlan_match_info);
  57276         if (match->match == BCM_PORT_MATCH_MAC_PORT) {
  57277             vlan_match_info.match = BCM_VLAN_MATCH_MAC_PORT;
  57278             vlan_match_info.port = match->port;
  57279         } else if (match->match == BCM_PORT_MATCH_MAC_PORT_CLASS) {
  57280             vlan_match_info.match = BCM_VLAN_MATCH_MAC_PORT_CLASS;
  57281             vlan_match_info.port_class = match->port_class;
  57282         }
  57283         sal_memcpy(vlan_match_info.src_mac,
  57284                 match->src_mac, sizeof (bcm_mac_t));
  57285         rv = _bcm_trx_vlan_match_action_delete(unit,
  57286                 port, &vlan_match_info);
  57287         break;
  57288 #endif
  57289     default:
  57290         rv = BCM_E_PARAM;
  57291         break;
  57292     }
  57293     return rv;
  57294 #else
  57295     return BCM_E_UNAVAIL;
  57296 #endif
  57297 }
  57298 
  57299 /*
  57300  * Function:
  57301  *      bcm_port_match_replace
  57302  * Purpose:
  57303  *      Replace an old match with a new one for an existing port
  57304  * Parameters:
  57305  *      unit - (IN) Unit number.
  57306  *      port - (IN) Port or gport
  57307  *      old_match - (IN) Old match criteria
  57308  *      new_match - (IN) New match criteria
  57309  * Returns:
  57310  *      BCM_E_xxx
  57311  * Notes:
  57312  */
  57313 int
  57314 bcm_esw_port_match_replace(
  57315     int unit,
  57316     bcm_gport_t port,
  57317     bcm_port_match_info_t *old_match,
  57318     bcm_port_match_info_t *new_match)
  57319 {
  57320 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
  57321     int rv = BCM_E_NONE;
  57322     /* Make sure port module is initialized. */
  57323     PORT_INIT(unit);
  57324     rv = bcm_esw_port_match_delete(unit, port, old_match);
  57325     if (BCM_SUCCESS(rv)) {
  57326         rv = bcm_esw_port_match_add(unit, port, new_match);
  57327     }
  57328     return rv;
  57329 #else
  57330     return BCM_E_UNAVAIL;
  57331 #endif
  57332 }
  57333 
  57334 extern void
  57335 _bcm_trx_vlan_range_profile_entry_get(int unit, bcm_vlan_t *min_vlan,
  57336                                      bcm_vlan_t *max_vlan, uint32 index);
  57337 
  57338 int _bcm_esw_port_vp_gport_check(bcm_gport_t port,
  57339     int vp)
  57340 {
  57341     int matched = 0;
  57342     if (BCM_GPORT_IS_MIM_PORT(port)) {
  57343             if (vp == BCM_GPORT_MIM_PORT_ID_GET(port)) {
  57344                 matched = 1;
  57345             }
  57346         } else if (BCM_GPORT_IS_MPLS_PORT(port)) {
  57347             if (vp == BCM_GPORT_MPLS_PORT_ID_GET(port)) {
  57348                 matched = 1;
  57349             }
  57350         }
  57351 #if defined(BCM_TRIDENT2_SUPPORT)
  57352         else if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  57353             if (vp == BCM_GPORT_VXLAN_PORT_ID_GET(port)) {
  57354                 matched = 1;
  57355             }
  57356         } 
  57357 #endif
  57358 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  57359         else if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  57360             if (vp == BCM_GPORT_L2GRE_PORT_ID_GET(port)) {
  57361                 matched = 1;
  57362             }
  57363         }
  57364 #endif
  57365 #if defined(BCM_TRIUMPH2_SUPPORT)
  57366         else if(BCM_GPORT_IS_VLAN_PORT(port)) {
  57367             if (vp == BCM_GPORT_VLAN_PORT_ID_GET(port)) {
  57368                 matched = 1;
  57369             }
  57370         }
  57371 #endif
  57372     return matched;
  57373 }
  57374 /*
  57375  * Function:
  57376  *      bcm_port_match_multi_get
  57377  * Purpose:
  57378  *      Get all the matches for an existing port
  57379  * Parameters:
  57380  *      unit - (IN) Unit number.
  57381  *      port - (IN) Port or gport
  57382  *      size - (IN) Number of elements in match array
  57383  *      match_array - (OUT) Match array
  57384  *      count - (OUT) Match count
  57385  * Returns:
  57386  *      BCM_E_xxx
  57387  * Notes:
  57388  */
  57389 int
  57390 bcm_esw_port_match_multi_get(
  57391     int unit,
  57392     bcm_gport_t port,
  57393     int size,
  57394     bcm_port_match_info_t *match_array,
  57395     int *count)
  57396 {
  57397 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
  57398     int id, vp, prof_idx, i, j, index_min, index_max, ctr, rv = BCM_E_NONE;
  57399     int stm_idx = 0;
  57400     int key_type_value = 0, key_type = 0;
  57401     uint32 matched;
  57402     uint8 *vlan_xlate_buf = NULL; /* VLAN_XLATE DMA buffer */
  57403     uint8 *source_trunk_map_buf = NULL; /* SOURCE_TRUNK_MAP DMA buffer */
  57404     source_trunk_map_table_entry_t *source_trunk_map;
  57405     bcm_gport_t gp;
  57406     bcm_vlan_t min_vlan[8], max_vlan[8];
  57407     bcm_module_t mod_out, mod_in;
  57408     bcm_port_t port_out, port_in;
  57409     bcm_trunk_t trunk_id;
  57410     int mpls_action;
  57411     soc_mem_t mem;
  57412 #if defined(BCM_TRIUMPH3_SUPPORT)
  57413     vlan_xlate_entry_t vent;
  57414 #endif
  57415     bcm_vlan_action_set_t *action;
  57416     int profile_idx;
  57417     void *entry;
  57418 
  57419     bcm_trunk_member_t *member_array = NULL;
  57420 
  57421     /* Parameter checks */
  57422     if ((size < 0) || (count == NULL)) {
  57423         return BCM_E_PARAM;
  57424     }
  57425     if ((size > 0) && (match_array == NULL)) {
  57426         return BCM_E_PARAM;
  57427     }
  57428 
  57429     /* Make sure port module is initialized. */
  57430     PORT_INIT(unit);
  57431 
  57432     if (BCM_GPORT_IS_MIM_PORT(port)) {
  57433         if (!soc_feature(unit, soc_feature_mim)) {
  57434             return BCM_E_UNAVAIL;
  57435         }
  57436         vp = BCM_GPORT_MIM_PORT_ID_GET(port);
  57437         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
  57438             return BCM_E_NOT_FOUND;
  57439         }
  57440         BCM_IF_ERROR_RETURN(_bcm_tr2_mim_port_phys_gport_get(unit, vp, &gp));
  57441     } else if  (BCM_GPORT_IS_MPLS_PORT(port)) {
  57442         if (!soc_feature(unit, soc_feature_mpls)) {
  57443             return BCM_E_UNAVAIL;
  57444         }
  57445         vp = BCM_GPORT_MPLS_PORT_ID_GET(port);
  57446         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
  57447             return BCM_E_NOT_FOUND;
  57448         }
  57449 #if defined(BCM_MPLS_SUPPORT)
  57450         BCM_IF_ERROR_RETURN(bcm_tr_mpls_port_phys_gport_get(unit, vp, &gp));
  57451 #endif
  57452 
  57453     } else
  57454 #if defined(BCM_TRIDENT2_SUPPORT)
  57455     if (BCM_GPORT_IS_TRUNK(port)) {
  57456         if (!soc_feature(unit, soc_feature_vp_lag)) {
  57457             return BCM_E_UNAVAIL;
  57458         }
  57459         return _bcm_esw_trunk_match_multi_get(unit, BCM_GPORT_TRUNK_GET(port),
  57460                                               size, match_array, count);
  57461     } else
  57462 #endif /* BCM_TRIDENT2_SUPPORT */
  57463 #if defined(BCM_TRIDENT2_SUPPORT)
  57464     if (BCM_GPORT_IS_VXLAN_PORT(port)) {
  57465 
  57466         vp = BCM_GPORT_VXLAN_PORT_ID_GET(port);
  57467         if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan))) {
  57468             return BCM_E_NOT_FOUND;
  57469         }
  57470 
  57471         BCM_GPORT_VXLAN_PORT_ID_SET(gp,vp);
  57472     } else
  57473 #endif
  57474 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  57475     if (BCM_GPORT_IS_L2GRE_PORT(port)) {
  57476         _bcm_vp_info_t vp_info;
  57477 
  57478         if (!soc_feature(unit, soc_feature_vp_sharing)) {
  57479             return BCM_E_UNAVAIL;
  57480         }
  57481         vp = BCM_GPORT_L2GRE_PORT_ID_GET(port);
  57482 
  57483         BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info));
  57484         if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) {
  57485             return BCM_E_NOT_FOUND;
  57486         }
  57487 
  57488         BCM_GPORT_L2GRE_PORT_ID_SET(gp,vp);
  57489     } else
  57490 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
  57491 #if defined(BCM_TRIUMPH2_SUPPORT)
  57492     if (BCM_GPORT_IS_VLAN_PORT(port)) {
  57493         if (!soc_feature(unit, soc_feature_lltag)) {
  57494             return BCM_E_UNAVAIL;
  57495         }
  57496         vp = BCM_GPORT_VLAN_PORT_ID_GET(port);
  57497         if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) {
  57498             return BCM_E_NOT_FOUND;
  57499         }
  57500         BCM_IF_ERROR_RETURN(bcm_tr2_vlan_port_phys_gport_get(unit, vp, &gp));
  57501     } else 
  57502 #endif
  57503 #if defined(BCM_TRIDENT_SUPPORT)
  57504     if (BCM_GPORT_IS_NIV_PORT(port)) {
  57505         if (!soc_feature(unit, soc_feature_niv)) {
  57506             return BCM_E_UNAVAIL;
  57507         }
  57508         return _bcm_td_port_vif_match_multi_get(unit, port,
  57509                                                 size, match_array, count);
  57510     } else
  57511 #endif /* BCM_TRIDENT_SUPPORT */
  57512 #if defined(BCM_TRIDENT3_SUPPORT)
  57513     if (BCM_GPORT_IS_MIRROR(port)) {
  57514         if (!soc_feature(unit, soc_feature_mirror_encap_profile)) {
  57515             return BCM_E_UNAVAIL;
  57516         }
  57517         return _bcm_mirror_port_match_multi_get(unit, port, size, match_array,
  57518                                                 count);
  57519     } else
  57520 #endif /* BCM_TRIDENT3_SUPPORT */
  57521     {
  57522         return BCM_E_PORT;
  57523     }
  57524 
  57525     rv = _bcm_esw_gport_resolve(unit, gp, &mod_out, &port_out, &trunk_id, &id);
  57526     if (BCM_FAILURE(rv)) {
  57527         goto cleanup;
  57528     }
  57529 #if defined(BCM_TRIUMPH3_SUPPORT)
  57530     if (SOC_IS_TRIUMPH3(unit)) {
  57531         mem = VLAN_XLATE_EXTDm;
  57532     } else
  57533 #endif
  57534 #if defined(BCM_TRIDENT3_SUPPORT)
  57535     if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
  57536         mem = VLAN_XLATE_1_DOUBLEm;
  57537     } else
  57538 #endif
  57539     {
  57540         mem = VLAN_XLATEm;
  57541     }
  57542 
  57543         /* DMA the relevant tables for traversal */
  57544     vlan_xlate_buf = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, mem),
  57545                                   "VLAN_XLATE buffer");
  57546         if (NULL == vlan_xlate_buf) {
  57547             rv = BCM_E_MEMORY;
  57548             goto cleanup;
  57549         }
  57550 
  57551     index_min = soc_mem_index_min(unit, mem);
  57552     index_max = soc_mem_index_max(unit, mem);
  57553     if ((rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY,
  57554                                  index_min, index_max,
  57555                                  vlan_xlate_buf)) < 0 ) {
  57556         goto cleanup;
  57557     }
  57558     source_trunk_map_buf = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES
  57559                                  (unit, SOURCE_TRUNK_MAP_TABLEm),
  57560                                  "SOURCE_TRUNK_MAP_TABLE buffer");
  57561     if (NULL == source_trunk_map_buf) {
  57562         rv = BCM_E_MEMORY;
  57563         goto cleanup;
  57564     }
  57565     index_min = soc_mem_index_min(unit, SOURCE_TRUNK_MAP_TABLEm);
  57566     index_max = soc_mem_index_max(unit, SOURCE_TRUNK_MAP_TABLEm);
  57567     if ((rv = soc_mem_read_range(unit, SOURCE_TRUNK_MAP_TABLEm, MEM_BLOCK_ANY,
  57568                                  index_min, index_max,
  57569                                  source_trunk_map_buf)) < 0 ) {
  57570         goto cleanup;
  57571     }
  57572 
  57573     ctr = 0;
  57574     /* Get all VLAN_XLATE matches */
  57575     index_min = soc_mem_index_min(unit, mem);
  57576     index_max = soc_mem_index_max(unit, mem);
  57577     for (i = index_min; i <= index_max; i++) {
  57578         if ((size != 0) && (size <= ctr)) {
  57579             break;
  57580         }
  57581         if (SOC_IS_TRIUMPH3(unit)) {
  57582             mem = VLAN_XLATE_EXTDm;
  57583         }
  57584         entry = soc_mem_table_idx_to_pointer
  57585                 (unit, mem, void *, vlan_xlate_buf, i);
  57586 #if defined(BCM_TRIUMPH3_SUPPORT)
  57587         if (SOC_IS_TRIUMPH3(unit)) {
  57588             int key_type;
  57589 
  57590             /* double wide entry should always start at double wide boundary */
  57591             key_type = soc_mem_field32_get(unit, mem, entry, KEY_TYPE_0f);
  57592 
  57593             /* if key type is odd number, then it is double wide entry */
  57594             if (!(key_type & 1)) {
  57595                 continue;
  57596             }
  57597             mpls_action = soc_mem_field32_get(unit, mem, entry, MPLS_ACTIONf);
  57598             vp = soc_mem_field32_get(unit, mem, entry, SOURCE_VPf);
  57599             sal_memset(&vent, 0, sizeof(vent));
  57600             rv = _bcm_tr3_vxlate_extd2vxlate(unit, (vlan_xlate_extd_entry_t *)entry, &vent, 0);
  57601             if (rv != BCM_E_NONE) {
  57602                 goto cleanup;
  57603             }
  57604             entry = &vent;
  57605             mem = VLAN_XLATEm;
  57606         } else
  57607 #endif  /* BCM_TRIUMPH3_SUPPORT */
  57608         {
  57609             mpls_action = soc_mem_field32_get(unit, mem, entry, MPLS_ACTIONf);
  57610             vp = soc_mem_field32_get(unit, mem, entry, SOURCE_VPf);
  57611         }
  57612 
  57613 #if defined(BCM_TRIDENT3_SUPPORT)
  57614         if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) {
  57615             if (soc_mem_field32_get(unit, mem, entry, BASE_VALID_0f) != 3) {
  57616             continue;
  57617         }
  57618             if (soc_mem_field32_get(unit, mem, entry, BASE_VALID_1f) != 7) {
  57619                 continue;
  57620             }
  57621         }
  57622 #endif
  57623 
  57624         if (SOC_MEM_FIELD_VALID(unit, mem, VALIDf)) {
  57625             if (soc_mem_field32_get(unit, mem, entry, VALIDf) == 0) {
  57626                 continue;
  57627             }
  57628         }
  57629 
  57630         if (!(mpls_action & 0x1)) {
  57631             continue; /* Entry is not for an SVP */
  57632         }
  57633 
  57634         key_type_value = (int)soc_mem_field32_get(unit, mem, entry, KEY_TYPEf);
  57635 
  57636         rv = _bcm_esw_vlan_xlate_key_type_get(unit,key_type_value,&key_type);
  57637         if (rv != BCM_E_NONE) {
  57638             goto cleanup;
  57639         }
  57640 
  57641         matched = _bcm_esw_port_vp_gport_check(port, vp);
  57642 
  57643         if (matched) {
  57644             soc_field_t field;
  57645             int port_count;
  57646             int tid;
  57647             int gport_id;
  57648             int outer_vlan_range_found = 0, inner_vlan_range_found = 0;
  57649             ctr++;
  57650             if (size >= ctr) {
  57651                 switch (key_type) {
  57652                 case VLXLT_HASH_KEY_TYPE_OVID:
  57653                     match_array->match = BCM_PORT_MATCH_PORT_VLAN;
  57654                     match_array->match_vlan =
  57655                         soc_mem_field32_get(unit, mem, entry, XLATE__OVIDf);
  57656 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  57657                     if (SOC_MEM_FIELD_VALID(unit, mem, VFIf)) {
  57658                         if (soc_feature(unit, soc_feature_vfi_zero_invalid) &&
  57659                             (soc_mem_field32_get(unit, mem, entry, XLATE__VFIf)) == 0) {
  57660                             match_array->vpn = 0;
  57661                         } else {
  57662                             _BCM_VXLAN_VPN_SET(match_array->vpn, _BCM_VPN_TYPE_VFI,
  57663                                 soc_mem_field32_get(unit, mem, entry, XLATE__VFIf));
  57664                         }
  57665                     } else {
  57666                         match_array->vpn = 0;
  57667                     }
  57668 #endif
  57669                     /* Check if this match is a VLAN range match */
  57670                     if (BCM_TRUNK_INVALID != trunk_id) {
  57671                         rv = bcm_esw_trunk_get(unit, trunk_id, NULL, 0, NULL,
  57672                                                &port_count);
  57673                         if (BCM_FAILURE(rv)) {
  57674                             goto cleanup;
  57675                         }
  57676                         
  57677                         member_array = sal_alloc(sizeof(bcm_trunk_member_t) * port_count,
  57678                                 "trunk member array");
  57679                         if (member_array == NULL) {
  57680                             rv = BCM_E_MEMORY;
  57681                             goto cleanup;
  57682                         }
  57683                         sal_memset(member_array, 0, sizeof(bcm_trunk_member_t) * port_count);
  57684                         
  57685                         rv = bcm_esw_trunk_get(unit, trunk_id, NULL, port_count,
  57686                                 member_array, &port_count);
  57687                         if (BCM_FAILURE(rv)) {
  57688                             goto cleanup;
  57689                         }
  57690                                 
  57691                         rv = _bcm_esw_gport_resolve(unit, member_array[0].gport,
  57692                                 &mod_out, &port_out, &tid, &gport_id);
  57693                         if (BCM_FAILURE(rv)) {
  57694                             goto cleanup;
  57695                         }
  57696 
  57697                     }
  57698                     rv = _bcm_esw_src_mod_port_table_index_get(
  57699                                 unit, mod_out, port_out, &stm_idx);
  57700                     if (BCM_FAILURE(rv)) {
  57701                         goto cleanup;
  57702                     }
  57703 
  57704                         source_trunk_map = soc_mem_table_idx_to_pointer
  57705                                               (unit, SOURCE_TRUNK_MAP_TABLEm,
  57706                                                source_trunk_map_table_entry_t *,
  57707                                                source_trunk_map_buf, stm_idx);
  57708                         if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
  57709                             OUTER_VLAN_RANGE_IDXf)) {
  57710                             field = OUTER_VLAN_RANGE_IDXf;
  57711                         } else {
  57712                             field = VLAN_RANGE_IDXf;
  57713                         }
  57714                         prof_idx = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit,
  57715                                              source_trunk_map, field);
  57716                         _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan,
  57717                                                             max_vlan, prof_idx);
  57718                         for (j = 0; j < 8; j++) {
  57719                             if (min_vlan[j] == match_array->match_vlan) {
  57720                                 match_array->match_vlan_max = max_vlan[j];
  57721                                 match_array->match =
  57722                                            BCM_PORT_MATCH_PORT_VLAN_RANGE;
  57723                                 break; /* Found a VLAN range match */
  57724                             }
  57725                         }
  57726                         if (j == 8) {
  57727                             match_array->match = BCM_PORT_MATCH_PORT_VLAN;
  57728                         }
  57729                     if (soc_mem_field32_get(unit, mem, entry, XLATE__Tf)) {
  57730                         trunk_id = soc_mem_field32_get(unit, mem, entry, XLATE__TGIDf);
  57731                         BCM_GPORT_TRUNK_SET(gp, trunk_id);
  57732                     } else {
  57733                         mod_in = soc_mem_field32_get(unit, mem, entry, XLATE__MODULE_IDf);
  57734                         port_in = soc_mem_field32_get(unit, mem, entry, XLATE__PORT_NUMf);
  57735 
  57736                         rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET,
  57737                                         mod_in, port_in, &mod_out, &port_out);
  57738                         BCM_GPORT_MODPORT_SET(gp, mod_out, port_out);
  57739                     }
  57740                     match_array->port = gp;
  57741                     match_array++;
  57742                     break;
  57743                 case VLXLT_HASH_KEY_TYPE_IVID:
  57744                     match_array->match = BCM_PORT_MATCH_PORT_INNER_VLAN;
  57745                     match_array->match_inner_vlan =
  57746                         soc_mem_field32_get(unit, mem, entry, XLATE__IVIDf);
  57747 
  57748 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  57749                     if (SOC_MEM_FIELD_VALID(unit, mem, VFIf)) {
  57750                         if (soc_feature(unit, soc_feature_vfi_zero_invalid) &&
  57751                             (soc_mem_field32_get(unit, mem, entry, XLATE__VFIf) == 0)) {
  57752 
  57753                             match_array->vpn = 0;
  57754                         } else {
  57755                             _BCM_VXLAN_VPN_SET(match_array->vpn, _BCM_VPN_TYPE_VFI,
  57756                                 soc_mem_field32_get(unit, mem, entry, XLATE__VFIf));
  57757 
  57758                         }
  57759                     } else {
  57760                         match_array->vpn = 0;
  57761                     }
  57762 #endif
  57763                     /* Check if this match is a VLAN range match */
  57764                     if (BCM_TRUNK_INVALID != trunk_id) {
  57765                         rv = bcm_esw_trunk_get(unit, trunk_id, NULL, 0, NULL,
  57766                                                &port_count);
  57767                         if (BCM_FAILURE(rv)) {
  57768                             goto cleanup;
  57769                         }
  57770                         
  57771                         member_array = sal_alloc(sizeof(bcm_trunk_member_t) * port_count,
  57772                                 "trunk member array");
  57773                         if (member_array == NULL) {
  57774                             rv = BCM_E_MEMORY;
  57775                             goto cleanup;
  57776                         }
  57777                         sal_memset(member_array, 0, sizeof(bcm_trunk_member_t) * port_count);
  57778                         
  57779                         rv = bcm_esw_trunk_get(unit, trunk_id, NULL, port_count,
  57780                                 member_array, &port_count);
  57781                         if (BCM_FAILURE(rv)) {
  57782                             goto cleanup;
  57783                         }
  57784                                 
  57785                         rv = _bcm_esw_gport_resolve(unit, member_array[0].gport,
  57786                                 &mod_out, &port_out, &tid, &gport_id);
  57787                         if (BCM_FAILURE(rv)) {
  57788                             goto cleanup;
  57789                         }
  57790 
  57791                     }
  57792 
  57793                     if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
  57794                         INNER_VLAN_RANGE_IDXf)) {
  57795 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT)
  57796                         if (soc_feature(unit, soc_feature_src_modid_base_index)) {
  57797                             int is_local;
  57798                             bcm_module_t modid = mod_out;
  57799 
  57800                             rv = _bcm_esw_stk_modmap_map(
  57801                                     unit, BCM_STK_MODMAP_SET, modid, -1,
  57802                                     &mod_out, NULL);
  57803                             if (BCM_SUCCESS(rv)) {
  57804                                 rv = _bcm_esw_modid_is_local(unit, mod_out,
  57805                                                              &is_local);
  57806                             }
  57807                             if (BCM_SUCCESS(rv)) {
  57808                                 rv = _bcm_esw_src_modid_base_index_get(
  57809                                         unit, modid, is_local, &stm_idx);
  57810                             }
  57811                             if (BCM_FAILURE(rv)) {
  57812                                 goto cleanup;
  57813                             }
  57814                             stm_idx += port_out;
  57815                         } else
  57816 #endif /* BCM_TRIDENT_SUPPORT || BCM_HURRICANE3_SUPPORT */
  57817                         {
  57818                             stm_idx = (mod_out * (SOC_PORT_ADDR_MAX(unit) + 1))
  57819                                        + port_out;
  57820                         }
  57821                         source_trunk_map = 
  57822                             soc_mem_table_idx_to_pointer(unit, SOURCE_TRUNK_MAP_TABLEm,
  57823                                                          source_trunk_map_table_entry_t *,
  57824                                                          source_trunk_map_buf, 
  57825                                                          stm_idx); 
  57826                         field = INNER_VLAN_RANGE_IDXf;
  57827                         prof_idx = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit,
  57828                                              source_trunk_map, field);
  57829                         _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan,
  57830                                                             max_vlan, prof_idx);
  57831                         for (j = 0; j < 8; j++) {
  57832                             if (min_vlan[j] == match_array->match_inner_vlan) {
  57833                                 match_array->match_inner_vlan_max = max_vlan[j];
  57834                                 match_array->match =
  57835                                            BCM_PORT_MATCH_PORT_INNER_VLAN_RANGE;
  57836                                 break; /* Found a VLAN range match */
  57837                             }
  57838                         } 
  57839                     }
  57840                     if (soc_mem_field32_get(unit, mem, entry, XLATE__Tf)) {
  57841                         trunk_id = soc_mem_field32_get(unit, mem, entry, XLATE__TGIDf);
  57842                         BCM_GPORT_TRUNK_SET(gp, trunk_id);
  57843                     } else {
  57844                         mod_in = soc_mem_field32_get(unit, mem, entry, XLATE__MODULE_IDf);
  57845                         port_in = soc_mem_field32_get(unit, mem, entry, XLATE__PORT_NUMf);
  57846 
  57847                         rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET,
  57848                                         mod_in, port_in, &mod_out, &port_out);
  57849                         BCM_GPORT_MODPORT_SET(gp, mod_out, port_out);
  57850                     }
  57851                     match_array->port = gp;
  57852                     match_array++;
  57853                     break;
  57854                 case VLXLT_HASH_KEY_TYPE_PRI_CFI:
  57855                     match_array->match = BCM_PORT_MATCH_PORT_VLAN16;
  57856                     match_array->match_vlan =
  57857                         soc_mem_field32_get(unit, mem, entry, OTAGf);
  57858 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  57859                     if (SOC_MEM_FIELD_VALID(unit, mem, VFIf)) {
  57860                         if (soc_feature(unit, soc_feature_vfi_zero_invalid) &&
  57861                             (soc_mem_field32_get(unit, mem, entry, VFIf) == 0)) {
  57862                             match_array->vpn = 0;
  57863                         } else {
  57864                             _BCM_VXLAN_VPN_SET(match_array->vpn, _BCM_VPN_TYPE_VFI,
  57865                                 soc_mem_field32_get(unit, mem, entry, VFIf));
  57866                         }
  57867                     } else {
  57868                         match_array->vpn = 0;
  57869                     }
  57870 #endif
  57871                     if (soc_mem_field32_get(unit, mem, entry, Tf)) {
  57872                         trunk_id = soc_mem_field32_get(unit, mem, entry, TGIDf);
  57873                         BCM_GPORT_TRUNK_SET(gp, trunk_id);
  57874                     } else {
  57875                         mod_in = soc_mem_field32_get(unit, mem, entry, MODULE_IDf);
  57876                         port_in = soc_mem_field32_get(unit, mem, entry, PORT_NUMf);
  57877 
  57878                         rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET,
  57879                                         mod_in, port_in, &mod_out, &port_out);
  57880                         BCM_GPORT_MODPORT_SET(gp, mod_out, port_out);
  57881                     }
  57882                     match_array->port = gp;
  57883                     match_array++;
  57884                     break;
  57885                 case VLXLT_HASH_KEY_TYPE_IVID_OVID:
  57886                     match_array->match = BCM_PORT_MATCH_PORT_VLAN_STACKED;
  57887                     match_array->match_vlan =
  57888                         soc_mem_field32_get(unit, mem, entry, OVIDf);
  57889                     match_array->match_inner_vlan =
  57890                         soc_mem_field32_get(unit, mem, entry, IVIDf);
  57891 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
  57892                     if (SOC_MEM_FIELD_VALID(unit, mem, VFIf)) {
  57893                         if (soc_feature(unit, soc_feature_vfi_zero_invalid) &&
  57894                             (soc_mem_field32_get(unit, mem, entry, VFIf) == 0)) {
  57895                             match_array->vpn = 0;
  57896                         } else {
  57897                             _BCM_VXLAN_VPN_SET(match_array->vpn, _BCM_VPN_TYPE_VFI,
  57898                                 soc_mem_field32_get(unit, mem, entry, VFIf));
  57899                         }
  57900                     } else {
  57901                         match_array->vpn = 0;
  57902                     }
  57903 #endif
  57904 
  57905                     /* Check if this match is a VLAN range match */
  57906                     if (BCM_TRUNK_INVALID != trunk_id) {
  57907                         rv = bcm_esw_trunk_get(unit, trunk_id, NULL, 0, NULL,
  57908                                                &port_count);
  57909                         if (BCM_FAILURE(rv)) {
  57910                             goto cleanup;
  57911                         }
  57912                         
  57913                         member_array = sal_alloc(sizeof(bcm_trunk_member_t) * port_count,
  57914                                 "trunk member array");
  57915                         if (member_array == NULL) {
  57916                             rv = BCM_E_MEMORY;
  57917                             goto cleanup;
  57918                         }
  57919                         sal_memset(member_array, 0, sizeof(bcm_trunk_member_t) * port_count);
  57920                         
  57921                         rv = bcm_esw_trunk_get(unit, trunk_id, NULL, port_count,
  57922                                 member_array, &port_count);
  57923                         if (BCM_FAILURE(rv)) {
  57924                             goto cleanup;
  57925                         }
  57926                                 
  57927                         rv = _bcm_esw_gport_resolve(unit, member_array[0].gport,
  57928                                 &mod_out, &port_out, &tid, &gport_id);
  57929                         if (BCM_FAILURE(rv)) {
  57930                             goto cleanup;
  57931                         }
  57932 
  57933                     }
  57934                     if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
  57935                         OUTER_VLAN_RANGE_IDXf)) {
  57936 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT)
  57937                         if (soc_feature(unit, soc_feature_src_modid_base_index)) {
  57938                             int is_local;
  57939                             bcm_module_t modid = mod_out;
  57940 
  57941                             rv = _bcm_esw_stk_modmap_map(
  57942                                     unit, BCM_STK_MODMAP_SET, modid, -1,
  57943                                     &mod_out, NULL);
  57944                             if (BCM_SUCCESS(rv)) {
  57945                                 rv = _bcm_esw_modid_is_local(unit, mod_out,
  57946                                                              &is_local);
  57947                             }
  57948                             if (BCM_SUCCESS(rv)) {
  57949                                 rv = _bcm_esw_src_modid_base_index_get(
  57950                                         unit, modid, is_local, &stm_idx);
  57951                             }
  57952                             if (BCM_FAILURE(rv)) {
  57953                                 goto cleanup;
  57954                             }
  57955                             stm_idx += port_out;
  57956                         } else
  57957 #endif /* BCM_TRIDENT_SUPPORT || BCM_HURRICANE3_SUPPORT */
  57958                         {
  57959                             stm_idx = (mod_out * (SOC_PORT_ADDR_MAX(unit) + 1))
  57960                                        + port_out;
  57961                         }
  57962                         source_trunk_map = 
  57963                             soc_mem_table_idx_to_pointer(unit, SOURCE_TRUNK_MAP_TABLEm,
  57964                                                          source_trunk_map_table_entry_t *,
  57965                                                          source_trunk_map_buf, 
  57966                                                          stm_idx); 
  57967                         field = OUTER_VLAN_RANGE_IDXf;
  57968                         prof_idx = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit,
  57969                                              source_trunk_map, field);
  57970                         _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan,
  57971                                                             max_vlan, prof_idx);
  57972                         for (j = 0; j < 8; j++) {
  57973                             if (min_vlan[j] == match_array->match_vlan) {
  57974                                 match_array->match_vlan_max = max_vlan[j];
  57975                                 outer_vlan_range_found = 1;
  57976                                 break; /* Found a VLAN range match */
  57977                             }
  57978                         }            
  57979                     }
  57980                     
  57981                     if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm,
  57982                         INNER_VLAN_RANGE_IDXf)) {
  57983 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT)
  57984                         if (soc_feature(unit, soc_feature_src_modid_base_index)) {
  57985                             int is_local;
  57986                             bcm_module_t modid = mod_out;
  57987 
  57988                             rv = _bcm_esw_stk_modmap_map(
  57989                                     unit, BCM_STK_MODMAP_SET, modid, -1,
  57990                                     &mod_out, NULL);
  57991                             if (BCM_SUCCESS(rv)) {
  57992                                 rv = _bcm_esw_modid_is_local(unit, mod_out,
  57993                                                              &is_local);
  57994                             }
  57995                             if (BCM_SUCCESS(rv)) {
  57996                                 rv = _bcm_esw_src_modid_base_index_get(
  57997                                         unit, modid, is_local, &stm_idx);
  57998                             }
  57999                             if (BCM_FAILURE(rv)) {
  58000                                 goto cleanup;
  58001                             }
  58002                             stm_idx += port_out;
  58003                         } else
  58004 #endif /* BCM_TRIDENT_SUPPORT || BCM_HURRICANE3_SUPPORT */
  58005                         {
  58006                             stm_idx = (mod_out * (SOC_PORT_ADDR_MAX(unit) + 1))
  58007                                        + port_out;
  58008                         }
  58009                         source_trunk_map = 
  58010                             soc_mem_table_idx_to_pointer(unit, SOURCE_TRUNK_MAP_TABLEm,
  58011                                                          source_trunk_map_table_entry_t *,
  58012                                                          source_trunk_map_buf, 
  58013                                                          stm_idx); 
  58014                         field = INNER_VLAN_RANGE_IDXf;
  58015                         prof_idx = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit,
  58016                                              source_trunk_map, field);
  58017                         _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan,
  58018                                                             max_vlan, prof_idx);
  58019                         for (j = 0; j < 8; j++) {
  58020                             if (min_vlan[j] == match_array->match_inner_vlan) {
  58021                                 match_array->match_inner_vlan_max = max_vlan[j];
  58022                                 inner_vlan_range_found = 1;
  58023                                 break; /* Found a VLAN range match */
  58024                             }
  58025                         }            
  58026                     }
  58027                     if (inner_vlan_range_found && outer_vlan_range_found) {
  58028                         match_array->match = BCM_PORT_MATCH_PORT_VLAN_STACKED_RANGE;
  58029                     }
  58030 
  58031                     if (soc_mem_field32_get(unit, mem, entry, Tf)) {
  58032                         trunk_id = soc_mem_field32_get(unit, mem, entry, TGIDf);
  58033                         BCM_GPORT_TRUNK_SET(gp, trunk_id);
  58034                     } else {
  58035                         mod_in = soc_mem_field32_get(unit, mem, entry, MODULE_IDf);
  58036                         port_in = soc_mem_field32_get(unit, mem, entry, PORT_NUMf);
  58037 
  58038                         rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET,
  58039                                         mod_in, port_in, &mod_out, &port_out);
  58040                         BCM_GPORT_MODPORT_SET(gp, mod_out, port_out);
  58041                     }
  58042                     match_array->port = gp;
  58043                     match_array++;
  58044                     break;
  58045 #if defined (BCM_TRIUMPH2_SUPPORT)
  58046                 case VLXLT_HASH_KEY_TYPE_LLVID:
  58047                 case VLXLT_HASH_KEY_TYPE_LLVID_OVID:
  58048                 case VLXLT_HASK_KEY_TYPE_LLVID_IVID:
  58049                     if (key_type == VLXLT_HASH_KEY_TYPE_LLVID) {
  58050                         match_array->match = BCM_PORT_MATCH_PORT_PON_TUNNEL;
  58051                     } else if (key_type == VLXLT_HASH_KEY_TYPE_LLVID_OVID) {
  58052                         match_array->match = BCM_PORT_MATCH_PORT_PON_TUNNEL_VLAN;
  58053                     } else {
  58054                         match_array->match = BCM_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN;
  58055                     }
  58056                     
  58057                     match_array->match_pon_tunnel =
  58058                         soc_mem_field32_get(unit, mem, entry, LLTAG__LLVIDf);
  58059                     match_array->match_inner_vlan =
  58060                         soc_mem_field32_get(unit, mem, entry, LLTAG__IVIDf);
  58061                     match_array->match_vlan =
  58062                         soc_mem_field32_get(unit, mem, entry, LLTAG__OVIDf);
  58063 
  58064                     if (soc_mem_field32_get(unit, mem, entry, Tf)) {
  58065                         trunk_id = soc_mem_field32_get(unit, mem, entry, TGIDf);
  58066                         BCM_GPORT_TRUNK_SET(gp, trunk_id);
  58067                     } else {
  58068                         mod_in = soc_mem_field32_get(unit, mem, entry, MODULE_IDf);
  58069                         port_in = soc_mem_field32_get(unit, mem, entry, PORT_NUMf);
  58070 
  58071                         rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET,
  58072                                         mod_in, port_in, &mod_out, &port_out);
  58073                         BCM_GPORT_MODPORT_SET(gp, mod_out, port_out);
  58074                     }
  58075                     
  58076                     if (match_array->action != NULL) {
  58077                         action = match_array->action;
  58078                         action->new_outer_vlan =
  58079                             soc_mem_field32_get(unit, mem, entry, NEW_OVIDf);
  58080                         action->new_inner_vlan =
  58081                             soc_mem_field32_get(unit, mem, entry, NEW_IVIDf);
  58082                         if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) {
  58083                             action->priority = 
  58084                                     soc_mem_field32_get(unit, mem, entry, NEW_OPRIf);
  58085                             action->new_outer_cfi =
  58086                                     soc_mem_field32_get(unit, mem, entry, NEW_OCFIf);
  58087                             action->new_inner_pkt_prio =
  58088                                     soc_mem_field32_get(unit, mem, entry, NEW_IPRIf);
  58089                             action->new_inner_cfi =
  58090                                     soc_mem_field32_get(unit, mem, entry, NEW_ICFIf);
  58091                         } 
  58092                         profile_idx = soc_mem_field32_get(unit, mem, entry, TAG_ACTION_PROFILE_PTRf);
  58093                         _bcm_trx_vlan_action_profile_entry_get(unit, action, profile_idx);
  58094                     }
  58095                     match_array->port = gp;
  58096                     match_array++;
  58097                     break;                    
  58098 #endif
  58099                 default:
  58100                     break;
  58101                 }
  58102             }
  58103         }
  58104     }
  58105 
  58106 #if defined(BCM_TRX_SUPPORT)
  58107     /* Get the list from VLAN_MACm */
  58108     if (BCM_SUCCESS(rv)) {
  58109         rv = _bcm_vlan_match_action_multi_get(unit,
  58110                 port, size, match_array, ctr, &ctr);
  58111     }
  58112 #endif
  58113 
  58114     *count = ctr;
  58115 
  58116 cleanup:
  58117     if (vlan_xlate_buf) {
  58118         soc_cm_sfree(unit, vlan_xlate_buf);
  58119     }
  58120     if (source_trunk_map_buf) {
  58121         soc_cm_sfree(unit, source_trunk_map_buf);
  58122     }
  58123     if (member_array) {
  58124         sal_free(member_array);
  58125     }
  58126     return rv;
  58127 #else
  58128     return BCM_E_UNAVAIL;
  58129 #endif
  58130 }
  58131 
  58132 /*
  58133  * Function:
  58134  *      bcm_port_match_set
  58135  * Purpose:
  58136  *      Assign a set of matches to an existing port
  58137  * Parameters:
  58138  *      unit - (IN) Unit number.
  58139  *      port - (IN) Port or gport
  58140  *      size - (IN) Number of elements in match array
  58141  *      match_array - (IN) Match array
  58142  * Returns:
  58143  *      BCM_E_xxx
  58144  * Notes:
  58145  */
  58146 int
  58147 bcm_esw_port_match_set(
  58148     int unit,
  58149     bcm_gport_t port,
  58150     int size,
  58151     bcm_port_match_info_t *match_array)
  58152 {
  58153 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
  58154     int i, rv = BCM_E_NONE;
  58155     if ((size <= 0) || (match_array == NULL)) {
  58156         return BCM_E_PARAM;
  58157     }
  58158 
  58159     /* Make sure port module is initialized. */
  58160     PORT_INIT(unit);
  58161 
  58162     /* Add every single match */
  58163     for (i = 0; i < size; i++) {
  58164         rv = bcm_esw_port_match_add(unit, port, match_array + i);
  58165         if (BCM_FAILURE(rv)) {
  58166             return rv;
  58167         }
  58168     }
  58169     return rv;
  58170 #else
  58171     return BCM_E_UNAVAIL;
  58172 #endif
  58173 }
  58174 
  58175 /*
  58176  * Function:
  58177  *      bcm_port_match_delete_all
  58178  * Purpose:
  58179  *      Delete all matches for an existing port
  58180  * Parameters:
  58181  *      unit - (IN) Unit number.
  58182  *      port - (IN) Port or gport
  58183  * Returns:
  58184  *      BCM_E_xxx
  58185  * Notes:
  58186  */
  58187 int
  58188 bcm_esw_port_match_delete_all(
  58189     int unit,
  58190     bcm_gport_t port)
  58191 {
  58192 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3)
  58193     int i, size, count, rv = BCM_E_NONE;
  58194     bcm_port_match_info_t *match_array = NULL;
  58195 
  58196     /* Make sure port module is initialized. */
  58197     PORT_INIT(unit);
  58198 
  58199     /* First get number of entries */
  58200     rv = bcm_esw_port_match_multi_get(unit, port, 0, match_array, &count);
  58201     if (BCM_FAILURE(rv) || (count == 0)) {
  58202         return rv;
  58203     }
  58204     match_array = sal_alloc(sizeof(bcm_port_match_info_t) * count,
  58205                             "match_array");
  58206     if (match_array == NULL) {
  58207         return BCM_E_MEMORY;
  58208     }
  58209     sal_memset(match_array, 0, sizeof(bcm_port_match_info_t) * count);
  58210 
  58211     /* Get all matches */
  58212     size = count;
  58213     rv = bcm_esw_port_match_multi_get(unit, port, size, match_array, &count);
  58214     if (BCM_FAILURE(rv)) {
  58215         sal_free(match_array);
  58216         return rv;
  58217     }
  58218 
  58219     /* Delete every single match */
  58220     for (i = 0; i < count; i++) {
  58221         rv = bcm_esw_port_match_delete(unit, port, match_array + i);
  58222         if (BCM_FAILURE(rv)) {
  58223             sal_free(match_array);
  58224             return rv;
  58225         }
  58226     }
  58227     sal_free(match_array);
  58228     return rv;
  58229 #else
  58230     return BCM_E_UNAVAIL;
  58231 #endif
  58232 }
  58233 
  58234 int
  58235 bcmi_esw_port_eee_cfg_get(int unit, bcm_port_t port, int *value)
  58236 {
  58237 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) || \
  58238     defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_SHADOW_SUPPORT) || \
  58239     defined(BCM_HURRICANE2_SUPPORT)
  58240     if ((port < 0) || (port >= SOC_MAX_NUM_PORTS)) {
  58241         return BCM_E_PORT;
  58242     }
  58243 
  58244     *value = eee_cfg[unit][port];
  58245 
  58246     return BCM_E_NONE;
  58247 #else
  58248     return BCM_E_UNAVAIL;
  58249 #endif
  58250 }
  58251 
  58252 
  58253 
  58254 /*
  58255  * Function:
  58256  *      bcm_esw_port_timesync_config_get
  58257  * Purpose:
  58258  *      Delete all matches for an existing port
  58259  * Parameters:
  58260  *      unit - (IN) Unit number.
  58261  *      port - (IN) Port
  58262  *      conf - (IN) Configuration
  58263  * Returns:
  58264  *      BCM_E_xxx
  58265  * Notes:
  58266  */
  58267 
  58268 int
  58269 bcm_esw_port_timesync_config_get(int unit, bcm_port_t port, int array_size,
  58270                                   bcm_port_timesync_config_t *config_array,
  58271                                   int *array_count)
  58272 {
  58273     int rv;
  58274     int is_remote_port = FALSE;
  58275  
  58276     /* Make sure port module is initialized. */
  58277     PORT_INIT(unit);
  58278 
  58279     if (SOC_IS_TRIDENT3X(unit) && BCM_GPORT_IS_PROXY(port)) {
  58280         if (bcm_esw_port_local_get(unit, port, &port) != BCM_E_NONE) {
  58281             /* the port is remote mod port */
  58282             is_remote_port = TRUE;
  58283         }
  58284     }
  58285 
  58286     if (!is_remote_port) {
  58287         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  58288     }
  58289 
  58290     COMPILER_REFERENCE(array_size);
  58291     COMPILER_REFERENCE(config_array);
  58292     COMPILER_REFERENCE(array_count);
  58293 
  58294 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || \
  58295     defined(BCM_TIMESYNC_V3_SUPPORT)|| defined(BCM_SABER2_SUPPORT) || \
  58296     defined(BCM_APACHE_SUPPORT)
  58297     /*
  58298      * Internal timesync function handles port lock and retrieves
  58299      * timesync config profiles
  58300      */
  58301     if ((soc_feature(unit, soc_feature_timesync_v3) || SOC_IS_TRIUMPH3(unit) ||
  58302          SOC_IS_KATANAX(unit)|| SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) ||
  58303          SOC_IS_APACHE(unit)) &&
  58304         (soc_feature(unit,soc_feature_timesync_support))) {
  58305         rv = _bcm_esw_port_timesync_config_get(unit, port, array_size,
  58306                                            config_array, array_count, is_remote_port);
  58307     } else
  58308 #endif /* defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) ||
  58309           defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) */
  58310     {
  58311         rv = BCM_E_UNAVAIL;
  58312     }
  58313 
  58314     return rv;
  58315 }
  58316 
  58317 /*
  58318  * Function:
  58319  *      bcm_esw_port_timesync_config_set
  58320  * Purpose:
  58321  *      Set Timesync Configuration profiles for the port
  58322  * Parameters:
  58323  *      unit            - (IN) bcm device
  58324  *      port            - (IN) port
  58325  *      config_count    - (IN)Count of timesync profile
  58326  *      *config_array   - (IN/OUT) Pointer to array of timesync profiles
  58327  * Returns:
  58328  *      BCM_E_xxx
  58329  * Notes:
  58330  */
  58331 int
  58332 bcm_esw_port_timesync_config_set(int unit, bcm_port_t port, int config_count,
  58333                                   bcm_port_timesync_config_t *config_array)
  58334 {
  58335     int rv;
  58336     int is_remote_port = FALSE;
  58337 
  58338     /* Make sure port module is initialized. */
  58339     PORT_INIT(unit);
  58340 
  58341     if (SOC_IS_TRIDENT3X(unit) && BCM_GPORT_IS_PROXY(port)) {
  58342         if (bcm_esw_port_local_get(unit, port, &port) != BCM_E_NONE) {
  58343             int cnt;
  58344             bcm_port_timesync_config_t *ts_config;
  58345             is_remote_port = TRUE;
  58346             for (cnt = 0; cnt < config_count; cnt++)
  58347             {
  58348                 ts_config = (bcm_port_timesync_config_t*) (config_array + cnt);
  58349                 /* the params can't be configured on remote logical port */
  58350                 if (ts_config->flags & BCM_PORT_TIMESYNC_ONE_STEP_TIMESTAMP ||
  58351                     ts_config->flags & BCM_PORT_TIMESYNC_TWO_STEP_TIMESTAMP ||
  58352                     ts_config->flags & BCM_PORT_TIMESYNC_TIMESTAMP_CFUPDATE_ALL ||
  58353                     ts_config->pkt_drop & BCM_PORT_TIMESYNC_PKT_INVALID) {
  58354                     return BCM_E_PORT;
  58355                 }
  58356             }
  58357         }
  58358     }
  58359 
  58360     if (!is_remote_port) {
  58361         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  58362     }
  58363 
  58364     COMPILER_REFERENCE(config_count);
  58365     COMPILER_REFERENCE(config_array);
  58366 
  58367 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || \
  58368     defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) || \
  58369     defined(BCM_APACHE_SUPPORT)
  58370     /*
  58371      * Internal timesync function handles port lock and adds
  58372      * timesync config profiles
  58373      */
  58374     if ((soc_feature(unit, soc_feature_timesync_v3) || SOC_IS_TRIUMPH3(unit) ||
  58375          SOC_IS_KATANAX(unit)|| SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) ||
  58376          SOC_IS_APACHE(unit)) &&
  58377         (soc_feature(unit,soc_feature_timesync_support))) {
  58378         rv = _bcm_esw_port_timesync_config_set(unit, port, config_count,
  58379                                            config_array, is_remote_port);
  58380     } else
  58381 #endif /* defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) ||
  58382           defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) */
  58383     {
  58384         rv = BCM_E_UNAVAIL;
  58385     }
  58386 
  58387     return rv;
  58388 }
  58389 
  58390 /*
  58391  * Function:
  58392  *     bcm_esw_port_timesync_tx_timestamp_and_seqid_get 
  58393  * Purpose:
  58394  *    Retrives two-step PTP timestamp and seqid from MAC FIFO after packet TX 
  58395  * Parameters:
  58396  *      unit - (IN) Unit number.
  58397  *      port - (IN) Port
  58398  *      conf - (IN) Configuration
  58399  * Returns:
  58400  *      BCM_E_xxx
  58401  * Notes:
  58402  */
  58403 
  58404 int
  58405 bcm_esw_port_timesync_tx_info_get(int unit, bcm_port_t port,
  58406                                   bcm_port_timesync_tx_info_t *tx_info)
  58407 {
  58408     int rv;
  58409 
  58410     /* Make sure port module is initialized. */
  58411     PORT_INIT(unit);
  58412 
  58413     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  58414 
  58415 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT) \
  58416     || defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) \
  58417     || defined(BCM_SABER2_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT)
  58418     /*
  58419      * Internal timesync function handles port lock and retrieves
  58420      * timesync config profiles
  58421      */
  58422     if (((SOC_IS_TD2_TT2(unit)) || SOC_IS_HURRICANE3(unit) || SOC_IS_SABER2(unit) || SOC_IS_TRIDENT2(unit)) &&
  58423         (soc_feature(unit,soc_feature_timesync_support))) {
  58424         if (SOC_USE_PORTCTRL(unit)) {
  58425             rv = _bcm_esw_port_timesync_tx_info_get(unit, port, tx_info);
  58426         } else {
  58427             soc_port_timesync_tx_info_t info;
  58428             sal_memset(&info, 0, sizeof(soc_port_timesync_tx_info_t));
  58429 
  58430             PORT_LOCK(unit)
  58431             rv = MAC_TIMESYNC_TX_INFO_GET(PORT(unit, port).p_mac, unit, port, &info);
  58432             PORT_UNLOCK(unit);
  58433             COMPILER_64_SET(tx_info->timestamp, info.timestamps_in_fifo_hi, info.timestamps_in_fifo);
  58434             tx_info->sequence_id = info.sequence_id;
  58435         }
  58436     } else
  58437 #endif /* defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT)
  58438           || defined(BCM_TOMAHAWK2_SUPPORT) */
  58439     {
  58440         rv = BCM_E_UNAVAIL;
  58441     }
  58442 
  58443     return rv;
  58444 }
  58445 
  58446 /*
  58447  * Function:
  58448  *     bcm_esw_port_timestamp_adjust_get
  58449  * Purpose:
  58450  *     get OSTS,TSTS timestamp adjust based on current speed
  58451  * Parameters:
  58452  *      unit - (IN) Unit number.
  58453  *      port - (IN) Port
  58454  *      ts_adjust - (OUT) configuration for tsts,osts timestamp adjustment.
  58455  * Returns:
  58456  *      BCM_E_xxx
  58457  * Notes:
  58458  */
  58459 int
  58460 bcm_esw_port_timestamp_adjust_get(int unit, bcm_port_t port,
  58461                                   bcm_port_timestamp_adjust_t *ts_adjust)
  58462 {
  58463         int rv;
  58464 
  58465         /* Make sure port module is initialized. */
  58466         PORT_INIT(unit);
  58467 
  58468         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  58469 
  58470 #ifdef PORTMOD_SUPPORT
  58471         if (SOC_USE_PORTCTRL(unit)) {
  58472             PORT_LOCK(unit);
  58473             rv = bcmi_esw_portctrl_timestamp_adjust_get(unit, port, ts_adjust);
  58474             PORT_UNLOCK(unit);
  58475         } else
  58476 #endif /* PORTMOD_SUPPORT */
  58477         {
  58478             rv = BCM_E_UNAVAIL;
  58479         }
  58480 
  58481         return rv;
  58482 
  58483 }
  58484 
  58485 /*
  58486  * Function:
  58487  *     bcm_esw_port_timestamp_adjust_set
  58488  * Purpose:
  58489  *     set OSTS,TSTS timestamp adjust based on speed
  58490  * Parameters:
  58491  *      unit - (IN) Unit number.
  58492  *      port - (IN) Port.
  58493  *      ts_adjust - (IN) configuration for tsts,osts timestamp adjust.
  58494  * Returns:
  58495  *      BCM_E_xxx
  58496  * Notes:
  58497  */
  58498 int
  58499 bcm_esw_port_timestamp_adjust_set(int unit, bcm_port_t port,
  58500                                   bcm_port_timestamp_adjust_t *ts_adjust)
  58501 {
  58502         int rv;
  58503         /* Make sure port module is initialized. */
  58504         PORT_INIT(unit);
  58505 
  58506         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  58507 
  58508 #ifdef PORTMOD_SUPPORT
  58509         if (SOC_USE_PORTCTRL(unit)) {
  58510             PORT_LOCK(unit);
  58511             rv = bcmi_esw_portctrl_timestamp_adjust_set(unit, port, ts_adjust);
  58512             PORT_UNLOCK(unit);
  58513         } else
  58514 #endif /* PORTMOD_SUPPORT */
  58515         {
  58516             rv = BCM_E_UNAVAIL;
  58517         }
  58518 
  58519         return rv;
  58520 
  58521 }
  58522 
  58523 /*
  58524  * Function:
  58525  *      bcm_esw_port_phy_timesync_config_set
  58526  * Purpose:
  58527  *      Delete all matches for an existing port
  58528  * Parameters:
  58529  *      unit - (IN) Unit number.
  58530  *      port - (IN) Port
  58531  *      conf - (IN) Configuration
  58532  * Returns:
  58533  *      BCM_E_xxx
  58534  * Notes:
  58535  */
  58536 int
  58537 bcm_esw_port_phy_timesync_config_set(int unit, bcm_port_t port,
  58538                                      bcm_port_phy_timesync_config_t *conf)
  58539 {
  58540     int rv;
  58541     /* Make sure port module is initialized. */
  58542     PORT_INIT(unit);
  58543 
  58544     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  58545 
  58546 #ifdef PORTMOD_SUPPORT
  58547     if (SOC_USE_PORTCTRL(unit)) {
  58548         PORT_LOCK(unit);
  58549         rv = soc_portctrl_phy_timesync_config_set(unit, port,
  58550              (soc_port_phy_timesync_config_t *)conf);
  58551         PORT_UNLOCK(unit);
  58552     } else
  58553 #endif /* PORTMOD_SUPPORT */
  58554     {
  58555         PORT_LOCK(unit);
  58556         rv = soc_port_phy_timesync_config_set(unit, port,
  58557              (soc_port_phy_timesync_config_t *)conf);
  58558         PORT_UNLOCK(unit);
  58559     }
  58560 
  58561     return rv;
  58562 }
  58563 
  58564 /*
  58565  * Function:
  58566  *      bcm_esw_port_phy_timesync_config_get
  58567  * Purpose:
  58568  *      Delete all matches for an existing port
  58569  * Parameters:
  58570  *      unit - (IN) Unit number.
  58571  *      port - (IN) Port
  58572  *      conf - (OUT) Configuration
  58573  * Returns:
  58574  *      BCM_E_xxx
  58575  * Notes:
  58576  */
  58577 int
  58578 bcm_esw_port_phy_timesync_config_get(int unit, bcm_port_t port,
  58579                                      bcm_port_phy_timesync_config_t *conf)
  58580 {
  58581     int rv;
  58582 
  58583     /* Make sure port module is initialized. */
  58584     PORT_INIT(unit);
  58585 
  58586     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  58587 
  58588 #ifdef PORTMOD_SUPPORT
  58589     if (SOC_USE_PORTCTRL(unit)) {
  58590         PORT_LOCK(unit);
  58591         rv = soc_portctrl_phy_timesync_config_get(unit, port,
  58592              (soc_port_phy_timesync_config_t *)conf);
  58593         PORT_UNLOCK(unit);
  58594     } else
  58595 #endif /* PORTMOD_SUPPORT */
  58596     {
  58597         PORT_LOCK(unit);
  58598         rv = soc_port_phy_timesync_config_get(unit, port,
  58599              (soc_port_phy_timesync_config_t *)conf);
  58600         PORT_UNLOCK(unit);
  58601     }
  58602 
  58603     return rv;
  58604 }
  58605 
  58606 /*
  58607  * Function:
  58608  *      bcm_esw_port_control_phy_timesync_set
  58609  * Purpose:
  58610  *      Delete all matches for an existing port
  58611  * Parameters:
  58612  *      unit - (IN) Unit number.
  58613  *      port - (IN) Port
  58614  *      type - (IN) Operation
  58615  *      value- (IN) Arg to operation
  58616  * Returns:
  58617  *      BCM_E_xxx
  58618  * Notes:
  58619  */
  58620 int
  58621 bcm_esw_port_control_phy_timesync_set(int unit, bcm_port_t port,
  58622                                       bcm_port_control_phy_timesync_t type,
  58623                                       uint64 value)
  58624 {
  58625     int rv;
  58626 
  58627     /* Make sure port module is initialized. */
  58628     PORT_INIT(unit);
  58629 
  58630     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  58631 
  58632 #ifdef PORTMOD_SUPPORT
  58633     if (SOC_USE_PORTCTRL(unit)) {
  58634         PORT_LOCK(unit);
  58635         rv = soc_portctrl_control_phy_timesync_set(unit, port, type, value);
  58636         PORT_UNLOCK(unit);
  58637     } else
  58638 #endif /* PORTMOD_SUPPORT */
  58639     {
  58640         PORT_LOCK(unit);
  58641         rv = soc_port_control_phy_timesync_set(unit, port, type, value);
  58642         PORT_UNLOCK(unit);
  58643     }
  58644 
  58645     return rv;
  58646 }
  58647 
  58648 /*
  58649  * Function:
  58650  *      bcm_esw_port_control_phy_timesync_get
  58651  * Purpose:
  58652  *      Delete all matches for an existing port
  58653  * Parameters:
  58654  *      unit - (IN) Unit number.
  58655  *      port - (IN) Port
  58656  *      type - (IN) Operation
  58657  *      value- (OUT) Pointer to arg for operation
  58658  * Returns:
  58659  *      BCM_E_xxx
  58660  * Notes:
  58661  */
  58662 int
  58663 bcm_esw_port_control_phy_timesync_get(int unit, bcm_port_t port,
  58664                                       bcm_port_control_phy_timesync_t type,
  58665                                       uint64 *value)
  58666 {
  58667     int rv;
  58668 
  58669     /* Make sure port module is initialized. */
  58670     PORT_INIT(unit);
  58671 
  58672     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  58673 
  58674 #ifdef PORTMOD_SUPPORT
  58675     if (SOC_USE_PORTCTRL(unit)) {
  58676         PORT_LOCK(unit);
  58677         rv = soc_portctrl_control_phy_timesync_get(unit, port, type, value);
  58678         PORT_UNLOCK(unit);
  58679     } else
  58680 #endif /* PORTMOD_SUPPORT */
  58681     {
  58682         PORT_LOCK(unit);
  58683         rv = soc_port_control_phy_timesync_get(unit, port, type, value);
  58684         PORT_UNLOCK(unit);
  58685     }
  58686 
  58687     return rv;
  58688 }
  58689 
  58690 /*
  58691  * Function:
  58692  *      bcm_esw_port_phy_timesync_enhanced_capture_get
  58693  * Purpose:
  58694  *      Delete all matches for an existing port
  58695  * Parameters:
  58696  *      unit - (IN) Unit number.
  58697  *      port - (IN) Port
  58698  *      value - (OUT) Configuration
  58699  * Returns:
  58700  *      BCM_E_xxx
  58701  * Notes:
  58702  */
  58703 int
  58704 bcm_esw_port_phy_timesync_enhanced_capture_get(int unit, bcm_port_t port,
  58705                                      bcm_port_phy_timesync_enhanced_capture_t *value)
  58706 {
  58707     int rv;
  58708     /* Make sure port module is initialized. */
  58709     PORT_INIT(unit);
  58710 
  58711     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  58712 
  58713     PORT_LOCK(unit);
  58714     rv = soc_port_phy_timesync_enhanced_capture_get(unit, port,
  58715                                           (soc_port_phy_timesync_enhanced_capture_t *)value);
  58716     PORT_UNLOCK(unit);
  58717 
  58718     return rv;
  58719 }
  58720 
  58721 /* bcm_port_config_phy_oam_set */
  58722 int bcm_esw_port_config_phy_oam_set(int unit, bcm_port_t port,
  58723                                     bcm_port_config_phy_oam_t *conf){
  58724     int rv;
  58725 
  58726     /* Make sure port module is initialized. */
  58727     PORT_INIT(unit);
  58728     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  58729 
  58730 #ifdef PORTMOD_SUPPORT
  58731     if (SOC_USE_PORTCTRL(unit)) {
  58732         rv = BCM_E_UNAVAIL;
  58733     } else
  58734 #endif /* PORTMOD_SUPPORT */
  58735     {
  58736 
  58737         PORT_LOCK(unit);
  58738         rv = soc_port_config_phy_oam_set(unit, port,
  58739                                          (soc_port_config_phy_oam_t *)conf);
  58740         PORT_UNLOCK(unit);
  58741     }
  58742 
  58743     return rv;
  58744 }
  58745 
  58746 /* bcm_port_config_phy_oam_get */
  58747 int bcm_esw_port_config_phy_oam_get(int unit, bcm_port_t port,
  58748                                     bcm_port_config_phy_oam_t *conf){
  58749     int rv;
  58750 
  58751     /* Make sure port module is initialized. */
  58752     PORT_INIT(unit);
  58753     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  58754 
  58755 #ifdef PORTMOD_SUPPORT
  58756     if (SOC_USE_PORTCTRL(unit)) {
  58757         rv = BCM_E_UNAVAIL;
  58758     } else
  58759 #endif /* PORTMOD_SUPPORT */
  58760     {
  58761         PORT_LOCK(unit);
  58762         rv = soc_port_config_phy_oam_get(unit, port,
  58763                                          (soc_port_config_phy_oam_t *)conf);
  58764         PORT_UNLOCK(unit);
  58765     }
  58766 
  58767     return rv;
  58768 }
  58769 
  58770 /* bcm_port_control_phy_oam_set */
  58771 int bcm_esw_port_control_phy_oam_set(int unit, bcm_port_t port,
  58772                                      bcm_port_control_phy_oam_t type,
  58773                                      uint64 value){
  58774     int rv;
  58775 
  58776     /* Make sure port module is initialized. */
  58777     PORT_INIT(unit);
  58778     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  58779 
  58780 #ifdef PORTMOD_SUPPORT
  58781     if (SOC_USE_PORTCTRL(unit)) {
  58782         rv = BCM_E_UNAVAIL;
  58783     } else
  58784 #endif /* PORTMOD_SUPPORT */
  58785     {
  58786         PORT_LOCK(unit);
  58787         rv = soc_port_control_phy_oam_set(unit, port,type, value);
  58788         PORT_UNLOCK(unit);
  58789     }
  58790 
  58791     return rv;
  58792 }
  58793 
  58794 /* bcm_port_control_phy_oam_get */
  58795 int bcm_esw_port_control_phy_oam_get(int unit, bcm_port_t port,
  58796                                      bcm_port_control_phy_oam_t type,
  58797                                      uint64 *value){
  58798     int rv;
  58799 
  58800     /* Make sure port module is initialized. */
  58801     PORT_INIT(unit);
  58802     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  58803 
  58804 #ifdef PORTMOD_SUPPORT
  58805     if (SOC_USE_PORTCTRL(unit)) {
  58806         rv = BCM_E_UNAVAIL;
  58807     } else
  58808 #endif /* PORTMOD_SUPPORT */
  58809     {
  58810         PORT_LOCK(unit);
  58811         rv = soc_port_control_phy_oam_get(unit, port,type, value);
  58812         PORT_UNLOCK(unit);
  58813     }
  58814 
  58815     return rv;
  58816 }
  58817 
  58818 /*
  58819  * Function:
  58820  *      bcm_esw_port_tpid_get_all
  58821  * Purpose:
  58822  *      Get a list of tpids and associated color selections for a given port
  58823  * Parameters:
  58824  *      unit  - (IN) Unit number.
  58825  *      port  - (IN) Port
  58826  *      size  - (IN) number of elements of the next two array parameters
  58827  *tpid_array  - (OUT) buffer array to hold a list of retrieved tpids
  58828  *color_array - (OUT) buffer array to hold a list of retrieved color selections
  58829  *      count - (OUT) actual number of tpids retrieved.
  58830  * Returns:
  58831  *      BCM_E_xxx
  58832  */
  58833 int
  58834 bcm_esw_port_tpid_get_all(int unit, bcm_port_t port,
  58835      int size,            /* number of elements of the arrays */
  58836      uint16 *tpid_array,  /* buffer array to hold a list of retrieved tpids */
  58837      int    *color_array, /* buffer array to hold a list of retrieved colors */
  58838      int    *count)       /* actual number of tpids retrieved. */
  58839 {
  58840     int rv = BCM_E_UNAVAIL;
  58841     bcm_module_t mod_out;
  58842     bcm_port_t port_out;
  58843     bcm_trunk_t tgid_out;
  58844     int id_out;
  58845     int is_local = 0;
  58846 
  58847     /* safety check */
  58848     if (size < 0 || count == NULL) {
  58849         return BCM_E_PARAM;
  58850     }
  58851     if ((size > 0) && (tpid_array == NULL || color_array == NULL)) {
  58852         return BCM_E_PARAM;
  58853     }
  58854 
  58855     *count = 0;
  58856 
  58857     /* Make sure port module is initialized. */
  58858     PORT_INIT(unit);
  58859     if (BCM_GPORT_IS_SET(port)) {
  58860         /* Handle virtual ports separetly */
  58861         if (BCM_GPORT_IS_MPLS_PORT(port) ||
  58862             BCM_GPORT_IS_MIM_PORT(port) ||
  58863             BCM_GPORT_IS_TRILL_PORT(port) ||
  58864             BCM_GPORT_IS_VXLAN_PORT(port) ||
  58865             BCM_GPORT_IS_VLAN_PORT(port)) {
  58866 
  58867             if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  58868 #if defined(BCM_TRX_SUPPORT)
  58869                 PORT_LOCK(unit);
  58870                 rv = _bcm_trx_vp_tpid_get_all(unit, port, size,
  58871                          tpid_array, color_array,count);
  58872                 PORT_UNLOCK(unit);
  58873 #endif
  58874             }
  58875             return rv;
  58876         } else {
  58877             BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
  58878                         &mod_out, &port_out, &tgid_out, &id_out));
  58879             if ((-1 != tgid_out) || (-1 != id_out)) {
  58880                 return BCM_E_PARAM;
  58881             }
  58882 
  58883             BCM_IF_ERROR_RETURN
  58884                 (_bcm_esw_modid_is_local(unit, mod_out, &is_local));
  58885             if (!is_local) {
  58886                 return BCM_E_PORT;
  58887             } else {
  58888                 BCM_IF_ERROR_RETURN(
  58889                         bcm_esw_port_local_get(unit, port, &port));
  58890             }
  58891         }
  58892 
  58893     } else if (!SOC_PORT_VALID(unit, port)) {
  58894         return BCM_E_PORT;
  58895     }
  58896 
  58897 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \
  58898     || defined(BCM_RAVEN_SUPPORT)
  58899     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
  58900         PORT_LOCK(unit);
  58901         rv = _bcm_fb2_port_tpid_get_all(unit, port, size,tpid_array,
  58902                                 color_array, count);
  58903         PORT_UNLOCK(unit);
  58904     }
  58905 #endif
  58906     return (rv);
  58907 }
  58908 void bcm_esw_kt2_port_lock(int unit)
  58909 {
  58910     PORT_LOCK(unit);
  58911 }
  58912 void bcm_esw_kt2_port_unlock(int unit)
  58913 {
  58914     PORT_UNLOCK(unit);
  58915 }
  58916 
  58917 #ifdef BCM_WARM_BOOT_SUPPORT
  58918 int
  58919 _bcm_port_cleanup(int unit)
  58920 {
  58921 #if defined(BCM_FIREBOLT_SUPPORT)
  58922     if (SOC_IS_FB_FX_HX(unit)) {
  58923         bcm_port_t port;
  58924 
  58925         for (port = 0; port < SOC_MAX_NUM_PORTS; port++) {
  58926             if (PORT(unit, port).p_vd_pbvl != NULL) {
  58927                 sal_free(PORT(unit, port).p_vd_pbvl);
  58928                 PORT(unit, port).p_vd_pbvl = NULL;
  58929             }
  58930 
  58931             if (PORT(unit, port).e2ecc_config != NULL) {
  58932                 sal_free(PORT(unit, port).e2ecc_config);
  58933                 PORT(unit, port).e2ecc_config = NULL;
  58934             }
  58935         }
  58936 
  58937         if (bcm_port_info[unit] != NULL) {
  58938             sal_free(bcm_port_info[unit]);
  58939             bcm_port_info[unit] = NULL;
  58940         }
  58941     }
  58942 #endif /* BCM_FIREBOLT_SUPPORT */
  58943 
  58944     return BCM_E_NONE;
  58945 }
  58946 #endif /* BCM_WARM_BOOT_SUPPORT */
  58947 
  58948 #ifndef BCM_SW_STATE_DUMP_DISABLE
  58949 /*
  58950  * Function:
  58951  *     _bcm_port_sw_dump
  58952  * Purpose:
  58953  *     Displays port information maintained by software.
  58954  * Parameters:
  58955  *     unit - Device unit number
  58956  * Returns:
  58957  *     None
  58958  * Note:
  58959  *    Skip following structure fields: p_phy, p_mac
  58960  */
  58961 void
  58962 _bcm_port_sw_dump(int unit)
  58963 {
  58964     _bcm_port_info_t *info;
  58965     int              i, j;
  58966     int              idxmax, entries, max_num_ports = 0;
  58967     bcm_port_t       port;
  58968     bcm_pbmp_t       all_pbmp;
  58969 
  58970     info = bcm_port_info[unit];
  58971     idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm) + 1;
  58972     entries = (idxmax + (_BCM_PORT_VD_PBVL_ESIZE -  1)) / _BCM_PORT_VD_PBVL_ESIZE;
  58973 
  58974     max_num_ports = SOC_MAX_NUM_PORTS;
  58975 
  58976     SOC_PBMP_CLEAR(all_pbmp);
  58977     SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit));
  58978 
  58979 #ifdef BCM_KATANA2_SUPPORT
  58980     if (soc_feature(unit, soc_feature_linkphy_coe) ||
  58981         soc_feature(unit, soc_feature_subtag_coe)) {
  58982         _bcm_kt2_subport_pbmp_update (unit, &all_pbmp);
  58983         if (SOC_INFO(unit).linkphy_enabled ||
  58984             SOC_INFO(unit).subtag_enabled) {
  58985             max_num_ports = SOC_MAX_NUM_PP_PORTS;
  58986         }
  58987     }
  58988 #endif
  58989 
  58990 
  58991     LOG_CLI((BSL_META_U(unit,
  58992                         "\nSW Information Port - Unit %d\n"), unit));
  58993 
  58994     if (info != NULL) {
  58995         for (i = 0; i < max_num_ports; i++) {
  58996             LOG_CLI((BSL_META_U(unit,
  58997                                 "       Port %2d : "), i));
  58998             LOG_CLI((BSL_META_U(unit,
  58999                                 "     MAC driver - %s\n"),
  59000                      ((SOC_PORT_VALID(unit, i)) && (info[i].p_mac != NULL)) ?
  59001                      (info[i].p_mac)->drv_name : "none"));
  59002             LOG_CLI((BSL_META_U(unit,
  59003                                 "     Untagged priority - %d\n"),
  59004                      info[i].p_ut_prio));
  59005             LOG_CLI((BSL_META_U(unit,
  59006                                 "     Double-tag mode - ")));
  59007             if (0 != info[i].dtag_mode) {
  59008                 if (0 != (info[i].dtag_mode &
  59009                           BCM_PORT_DTAG_MODE_INTERNAL)) {
  59010                     LOG_CLI((BSL_META_U(unit,
  59011                                         " Internal")));
  59012                 }
  59013                 if (0 != (info[i].dtag_mode &
  59014                           BCM_PORT_DTAG_MODE_EXTERNAL)) {
  59015                     LOG_CLI((BSL_META_U(unit,
  59016                                         " External")));
  59017                 }
  59018                 if (0 != (info[i].dtag_mode &
  59019                           BCM_PORT_DTAG_ADD_EXTERNAL_TAG)) {
  59020                     LOG_CLI((BSL_META_U(unit,
  59021                                         " AddTag")));
  59022                 }
  59023                 if (0 != (info[i].dtag_mode &
  59024                           BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG)) {
  59025                     LOG_CLI((BSL_META_U(unit,
  59026                                         " RemoveTag")));
  59027                 }
  59028             } else {
  59029                 LOG_CLI((BSL_META_U(unit,
  59030                                     " None")));
  59031             }
  59032             LOG_CLI((BSL_META_U(unit,
  59033                                 "\n")));
  59034             LOG_CLI((BSL_META_U(unit,
  59035                                 "     VLAN_PROTOCOL_DATA index - %d\n"),
  59036                      info[i].vlan_prot_ptr));
  59037             LOG_CLI((BSL_META_U(unit,
  59038                                 "     Number of VPs - %d\n"),
  59039                      info[i].vp_count));
  59040         }
  59041 
  59042         LOG_CLI((BSL_META_U(unit,
  59043                             "\n")));
  59044 
  59045         LOG_CLI((BSL_META_U(unit,
  59046                             "     Protocol based VLAN - \n")));
  59047         LOG_CLI((BSL_META_U(unit,
  59048                             "       Total Entries : %d\n"), entries));
  59049 
  59050         PBMP_ITER(all_pbmp, port) {
  59051             LOG_CLI((BSL_META_U(unit,
  59052                                 "       Port %2d : "), port));
  59053             if (info[port].p_vd_pbvl == NULL) {
  59054                 LOG_CLI((BSL_META_U(unit,
  59055                                     "\n")));
  59056                 continue;
  59057             }
  59058 
  59059             for (j = 0; j < entries; j++) {
  59060                 if ((j > 0) && !(j % 10)) {
  59061                     LOG_CLI((BSL_META_U(unit,
  59062                                         "\n                 ")));
  59063                 }
  59064                 LOG_CLI((BSL_META_U(unit,
  59065                                     " 0x%2.2x"), info[port].p_vd_pbvl[j]));
  59066             }
  59067             LOG_CLI((BSL_META_U(unit,
  59068                                 "\n")));
  59069         }
  59070 
  59071         if (soc_feature(unit, soc_feature_e2ecc)) {
  59072             bcm_port_congestion_config_t *e2ep;
  59073 
  59074             LOG_CLI((BSL_META_U(unit,
  59075                                 "\n")));
  59076             LOG_CLI((BSL_META_U(unit,
  59077                                 "     E2E Congestion Control - \n")));
  59078             PBMP_ALL_ITER(unit, port) {
  59079                 e2ep = info[port].e2ecc_config;
  59080                 if (NULL == e2ep) {
  59081                    continue;
  59082                 }
  59083 
  59084                 if ((0 == (e2ep->flags & (BCM_PORT_CONGESTION_CONFIG_E2ECC |
  59085                         BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL |
  59086                         BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE  |
  59087                         BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE)))) {
  59088                     continue;
  59089                 }
  59090 
  59091                 LOG_CLI((BSL_META_U(unit,
  59092                                     "\n       Port : %d\n"), port));
  59093                 if ((e2ep->flags &
  59094                      BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE) ||
  59095                     (e2ep->flags &
  59096                      BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE)) {
  59097                     LOG_CLI((BSL_META_U(unit,
  59098                           "         E2ECC COE Flags:  %s %s \n"),
  59099                           (e2ep->flags &
  59100                            BCM_PORT_CONGESTION_CONFIG_RX) ?
  59101                                         "RX" : "",
  59102                           ((e2ep->flags &
  59103                             BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE) ?
  59104                                        "FLEX mode":
  59105                           (e2ep->flags &
  59106                            BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) ?
  59107                                         "STRICT mode" : ""))) ;
  59108                 } else {
  59109                     LOG_CLI((BSL_META_U(unit,
  59110                                     "         Flags : %s %s %s\n"),
  59111                             (e2ep->flags & BCM_PORT_CONGESTION_CONFIG_E2ECC) ?
  59112                             "E2ECC" : "DestMod Flow control",
  59113                             (e2ep->flags & BCM_PORT_CONGESTION_CONFIG_TX) ?
  59114                             "TX" : "",
  59115                             (e2ep->flags & BCM_PORT_CONGESTION_CONFIG_RX) ?
  59116                             "RX" : ""));
  59117                 }
  59118 
  59119                 if (e2ep->flags & BCM_PORT_CONGESTION_CONFIG_TX) {
  59120                     LOG_CLI((BSL_META_U(unit,
  59121                                         "         Port bits : 0x%02x\n"),
  59122                              e2ep->port_bits));
  59123                     LOG_CLI((BSL_META_U(unit,
  59124                                         "         Packets/sec : %d\n"),
  59125                              e2ep->packets_per_sec));
  59126                     LOG_CLI((BSL_META_U(unit,
  59127                                         "         Source gport : 0x%08x\n"),
  59128                              e2ep->src_port));
  59129                     LOG_CLI((BSL_META_U(unit,
  59130                                         "         Multicast ID : 0x%04x\n"),
  59131                              e2ep->multicast_id));
  59132                     LOG_CLI((BSL_META_U(unit,
  59133                                         "         Traffic class : %d\n"),
  59134                              e2ep->traffic_class));
  59135                     LOG_CLI((BSL_META_U(unit,
  59136                                         "         Color : %d\n"),
  59137                              e2ep->color));
  59138                     LOG_CLI((BSL_META_U(unit,
  59139                                         "         Source MAC : 0x%02x%02x%02x%02x%02x%02x\n"),
  59140                              e2ep->src_mac[0], e2ep->src_mac[1],
  59141                              e2ep->src_mac[2], e2ep->src_mac[3],
  59142                              e2ep->src_mac[4], e2ep->src_mac[5]));
  59143                 }
  59144 
  59145                 LOG_CLI((BSL_META_U(unit,
  59146                                     "         Destination MAC : "
  59147                                     "0x%02x%02x%02x%02x%02x%02x\n"),
  59148                          e2ep->dest_mac[0], e2ep->dest_mac[1],
  59149                          e2ep->dest_mac[2], e2ep->dest_mac[3],
  59150                          e2ep->dest_mac[4], e2ep->dest_mac[5]));
  59151                 LOG_CLI((BSL_META_U(unit,
  59152                                     "         Ethertype : 0x%04x\n"),
  59153                          e2ep->ethertype));
  59154                 LOG_CLI((BSL_META_U(unit,
  59155                                     "         Opcode : 0x%04x\n"),
  59156                          e2ep->opcode));
  59157             }
  59158         }
  59159 
  59160 #ifdef BCM_TRIUMPH2_SUPPORT
  59161         if (soc_feature(unit, soc_feature_src_modid_blk_profile)) {
  59162 
  59163             LOG_CLI((BSL_META_U(unit,
  59164                                 "\n")));
  59165             LOG_CLI((BSL_META_U(unit,
  59166                                 "     Source Modid Egress Blocking Profiles - \n")));
  59167             PBMP_ITER(all_pbmp, port) {
  59168                 if (-1 == PORT_SRC_MOD_EGR_PROF_PTR(unit, port)) {
  59169                     continue;
  59170                 }
  59171                 LOG_CLI((BSL_META_U(unit,
  59172                                     "       Port %2d : "), port));
  59173                 LOG_CLI((BSL_META_U(unit,
  59174                                     "Profile index %d\n"),
  59175                          PORT_SRC_MOD_EGR_PROF_PTR(unit, port)));
  59176             }
  59177             /* Display those entries with reference count > 0 */
  59178             if (PORT_SRC_MOD_EGR_PROFILE(unit) != NULL) {
  59179                 int     i;
  59180                 int     num_entries;
  59181                 int     ref_count;
  59182                 int     entries_per_set;
  59183                 int     modid_count;
  59184                 uint32  index;
  59185                 pbmp_t  sme_pbmp;
  59186                 src_modid_egress_entry_t *entry_p;
  59187                 char    sme_pfm[SOC_PBMP_FMT_LEN];
  59188 
  59189                 num_entries = soc_mem_index_count(unit,
  59190                       PORT_SRC_MOD_EGR_PROFILE(unit)->tables[0].mem);
  59191                 LOG_CLI((BSL_META_U(unit,
  59192                                     "  Source Modid Egress Profile\n")));
  59193                 LOG_CLI((BSL_META_U(unit,
  59194                                     "      Number of entries: %d\n"), num_entries));
  59195                 LOG_CLI((BSL_META_U(unit,
  59196                                     "      Index RefCount EntriesPerSet - "
  59197                          "PortBlockMaskBitmap\n")));
  59198 
  59199                 modid_count = SOC_MODID_MAX(unit) + 1;
  59200                 for (index = 0; index < num_entries; index += modid_count) {
  59201                     if (SOC_FAILURE(soc_profile_mem_ref_count_get(unit,
  59202                                         PORT_SRC_MOD_EGR_PROFILE(unit),
  59203                                                  index, &ref_count))) {
  59204                         break;
  59205                     }
  59206 
  59207                     if (ref_count <= 0) {
  59208                         continue;
  59209                     }
  59210 
  59211                     for (i = 0; i < modid_count; i++) {
  59212                         entries_per_set =
  59213                             PORT_SRC_MOD_EGR_PROFILE(unit)->tables[0].\
  59214                             entries[index+i].entries_per_set;
  59215                         entry_p = SOC_PROFILE_MEM_ENTRY(unit,
  59216                                       PORT_SRC_MOD_EGR_PROFILE(unit),
  59217                                       src_modid_egress_entry_t *,
  59218                                                         index + i);
  59219                         soc_mem_pbmp_field_get(unit, SRC_MODID_EGRESSm,
  59220                                                entry_p,
  59221                                                PORT_BLOCK_MASK_BITMAPf,
  59222                                                &sme_pbmp);
  59223 
  59224                         if (BCM_PBMP_NOT_NULL(sme_pbmp)) {
  59225                             LOG_CLI((BSL_META_U(unit,
  59226                                                 "     %5d %8d %13d    "),
  59227                                      index + i, ref_count,
  59228                                      entries_per_set));
  59229                             LOG_CLI((BSL_META_U(unit,
  59230                                                 "%s\n"),
  59231                                      SOC_PBMP_FMT(sme_pbmp, sme_pfm)));
  59232                         }
  59233                     }
  59234                 }
  59235             }
  59236         }
  59237 #endif /* BCM_TRIUMPH2_SUPPORT */
  59238     }
  59239 
  59240     LOG_CLI((BSL_META_U(unit,
  59241                         "\n")));
  59242 
  59243     return;
  59244 }
  59245 #endif /* BCM_SW_STATE_DUMP_DISABLE */
  59246 
  59247 
  59248 /*
  59249  * Function:
  59250  *      _bcm_esw_port_gport_phyn_validate
  59251  * Purpose:
  59252  *      Validate PHY specific gport
  59253  * Parameters:
  59254  *      unit       -  (IN)  Unit number.
  59255  *      port       -  (IN)  Port number.
  59256  *      local_port -  (OUT) Local Port number.
  59257  *      phyn       -  (OUT) Phy number
  59258  *      phy_lane   -  (OUT) Lane number
  59259  *      sys_side   -  (OUT) System side(1)or line side(0).
  59260  * Returns:
  59261  *      BCM_E_XXX
  59262  */
  59263 
  59264 int
  59265 _bcm_esw_port_gport_phyn_validate(int unit, bcm_port_t port,
  59266                                   bcm_port_t *local_port, int *phyn,
  59267                                   int *phy_lane, int *sys_side)
  59268 {
  59269     /* Validate input arguments */
  59270     if (local_port == NULL || phy_lane == NULL ||
  59271         phyn == NULL || sys_side == NULL) {
  59272        return BCM_E_PARAM;
  59273     }
  59274 
  59275     if (BCM_PHY_GPORT_IS_PHYN(port)) {
  59276         *local_port = BCM_PHY_GPORT_PHYN_PORT_PORT_GET(port);
  59277         *phyn = BCM_PHY_GPORT_PHYN_PORT_PHYN_GET(port);
  59278         *phy_lane = -1;
  59279     } else if(BCM_PHY_GPORT_IS_PHYN_LANE(port)) {
  59280         *local_port = BCM_PHY_GPORT_PHYN_LANE_PORT_PORT_GET(port);
  59281         *phyn = BCM_PHY_GPORT_PHYN_LANE_PORT_PHYN_GET(port);
  59282         *phy_lane = BCM_PHY_GPORT_PHYN_LANE_PORT_LANE_GET(port);
  59283     } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE(port)) {
  59284         *local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PORT_GET(port);
  59285         *phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PHYN_GET(port);
  59286         *sys_side = TRUE;
  59287         *phy_lane = -1;
  59288     } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE_LANE(port)) {
  59289         *local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PORT_GET(port);
  59290         *phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PHYN_GET(port);
  59291         *phy_lane = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_LANE_GET(port);
  59292         *sys_side = TRUE;
  59293     } else if (BCM_PHY_GPORT_IS_LANE(port)) {
  59294         *local_port = BCM_PHY_GPORT_LANE_PORT_PORT_GET(port);
  59295         *phy_lane = BCM_PHY_GPORT_LANE_PORT_LANE_GET(port);
  59296     } else {
  59297         *local_port = -1;
  59298         return BCM_E_NONE;
  59299     }
  59300 
  59301     if (!SOC_PORT_VALID(unit, *local_port)) {
  59302        return BCM_E_PORT;
  59303     }
  59304 
  59305     return BCM_E_NONE;
  59306 }
  59307 
  59308 /**
  59309  * Function:
  59310  *      _bcm_esw_link_force_for_disabled_loopback_port
  59311  * Purpose:
  59312  *      Force linkscan's current link status on for a disabled port
  59313  *      which is configured to MAC loopback.
  59314  * Parameters:
  59315  *      unit - (IN) Unit number.
  59316  * Returns:
  59317  *      BCM_E_xxx
  59318  * Notes:
  59319  */
  59320 int
  59321 _bcm_esw_link_force_for_disabled_loopback_port(int unit)
  59322 {
  59323     bcm_port_t port;
  59324     int loopback;
  59325     int enable;
  59326     bcm_pbmp_t pbmp;
  59327 
  59328     SOC_PBMP_ASSIGN(pbmp, PBMP_E_ALL(unit));
  59329 #if defined(BCM_SABER2_SUPPORT)
  59330     if(SOC_IS_SABER2(unit)){
  59331         /*
  59332          * During warmboot init, the oamp port is not removed
  59333          * from ethernet bitmaps till sat is initialized.
  59334          * So manually removing it here.
  59335          */
  59336         int oamp_enable;
  59337         (void)bcm_sb2_sat_oamp_enable_get(unit, &oamp_enable);
  59338         /* Skip OAMP port for saber2 device */
  59339         if(oamp_enable) {
  59340             SOC_PBMP_PORT_REMOVE(pbmp,
  59341                     _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER);
  59342         }
  59343     }
  59344 #endif
  59345 
  59346     PBMP_ITER(pbmp,port) {
  59347         BCM_IF_ERROR_RETURN(
  59348             bcm_esw_port_loopback_get(unit, port, &loopback));
  59349         BCM_IF_ERROR_RETURN(
  59350             bcm_esw_port_enable_get(unit, port, &enable));
  59351         if ((loopback == BCM_PORT_LOOPBACK_MAC) && (enable == FALSE)) {
  59352             BCM_IF_ERROR_RETURN
  59353                 (_bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, TRUE));
  59354         }
  59355     }
  59356 
  59357     return BCM_E_NONE;
  59358 }
  59359 
  59360 #ifdef BCM_MAVERICK2_SUPPORT
  59361 /**
  59362  * Function:
  59363  *      _bcm_esw_mv2_asf_init
  59364  * Purpose:
  59365  *      Initialize ASF subsystem and configure all the applicable ports
  59366  *      to the specified forwarding mode
  59367  * Parameters:
  59368  *      unit - (IN) Unit number.
  59369  *      mode - (IN) forwarding mode
  59370  * Returns:
  59371  *      BCM_E_xxx
  59372  */
  59373 STATIC int
  59374 _bcm_esw_mv2_asf_init(
  59375     int                 unit,
  59376     soc_mv2_asf_mode_e  asf_mode)
  59377 {
  59378     bcm_port_t port;
  59379     int        speed;
  59380     soc_info_t *si;
  59381 
  59382     if (!(si = &SOC_INFO(unit))) {
  59383         return BCM_E_INTERNAL;
  59384     }
  59385 
  59386     BCM_IF_ERROR_RETURN(soc_mv2_asf_init_start(unit));
  59387 
  59388     PBMP_ALL_ITER(unit, port) {
  59389         if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) {
  59390             continue;
  59391         }
  59392         speed = si->port_init_speed[port];
  59393         if (speed == 0) {
  59394             BCM_IF_ERROR_RETURN(
  59395                 bcm_esw_port_speed_get(unit, port, &speed));
  59396         }
  59397         BCM_IF_ERROR_RETURN(
  59398             soc_mv2_port_asf_init(unit, port, speed, asf_mode));
  59399     }
  59400     BCM_IF_ERROR_RETURN(soc_mv2_asf_init_done(unit));
  59401 
  59402     return BCM_E_NONE;
  59403 }
  59404 
  59405 STATIC int
  59406 _bcm_esw_mv2_port_asf_mode_set(
  59407     int         unit,
  59408     bcm_port_t  port,
  59409     int         mode)
  59410 {
  59411     int rv = BCM_E_NONE, speed;
  59412     soc_info_t *si;
  59413     int txp = 0, rxp = 0;
  59414     pbmp_t *pause_bmp;
  59415 
  59416     if (!(si = &SOC_INFO(unit))) {
  59417         return SOC_E_INTERNAL;
  59418     }
  59419 
  59420     pause_bmp = soc_mv2_port_asf_pause_bpmp_get(unit);
  59421     if (pause_bmp == NULL) {
  59422         return BCM_E_INTERNAL;
  59423     }
  59424 
  59425     /* Update Pause for ASF mode */
  59426     if (_SOC_MV2_ASF_MODE_SAF != mode) {
  59427         /* Disable rx pause for cut through */
  59428         BCM_IF_ERROR_RETURN
  59429             (bcm_esw_port_pause_get(unit, port, &txp, &rxp));
  59430 
  59431         if (rxp) {
  59432             SOC_PBMP_PORT_ADD((*pause_bmp), port);
  59433         }
  59434         BCM_IF_ERROR_RETURN
  59435             (bcm_esw_port_pause_set(unit, port, txp, 0));
  59436 
  59437     }
  59438 
  59439     speed = si->port_init_speed[port];
  59440     if (speed == 0) {
  59441         BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed));
  59442     }
  59443     PORT_LOCK(unit);
  59444     rv = soc_mv2_port_asf_mode_set(unit, port, speed, mode);
  59445     PORT_UNLOCK(unit);
  59446 
  59447     /* Update Pause for ASF mode */
  59448     if (((rv != SOC_E_NONE) && (_SOC_MV2_ASF_MODE_SAF != mode)) ||
  59449         ((rv == SOC_E_NONE) && (_SOC_MV2_ASF_MODE_SAF == mode))) {
  59450         /* restore pause */
  59451         if (SOC_PBMP_MEMBER((*pause_bmp), port)) {
  59452             BCM_IF_ERROR_RETURN
  59453                 (bcm_esw_port_pause_get(unit, port, &txp, &rxp));
  59454             BCM_IF_ERROR_RETURN
  59455                 (bcm_esw_port_pause_set(unit, port, txp, 1));
  59456             SOC_PBMP_PORT_REMOVE((*pause_bmp), port);
  59457         }
  59458     }
  59459 
  59460     return rv;
  59461 }
  59462 #endif
  59463 
  59464 #ifdef BCM_TRIDENT3_SUPPORT
  59465 /**
  59466  * Function:
  59467  *      _bcm_esw_td3_asf_init
  59468  * Purpose:
  59469  *      Initialize ASF subsystem and configure all the applicable ports
  59470  *      to the specified forwarding mode
  59471  * Parameters:
  59472  *      unit - (IN) Unit number.
  59473  *      mode - (IN) forwarding mode
  59474  * Returns:
  59475  *      BCM_E_xxx
  59476  */
  59477 STATIC int
  59478 _bcm_esw_td3_asf_init(
  59479     int                 unit,
  59480     soc_td3_asf_mode_e  asf_mode)
  59481 {
  59482     bcm_port_t port;
  59483     int        speed;
  59484     soc_info_t *si;
  59485 
  59486     if (!(si = &SOC_INFO(unit))) {
  59487         return BCM_E_INTERNAL;
  59488     }
  59489 
  59490     BCM_IF_ERROR_RETURN(soc_td3_asf_init_start(unit));
  59491 
  59492     PBMP_ALL_ITER(unit, port) {
  59493         if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) {
  59494             continue;
  59495         }
  59496         speed = si->port_init_speed[port];
  59497         if (speed == 0) {
  59498             BCM_IF_ERROR_RETURN(
  59499                 bcm_esw_port_speed_get(unit, port, &speed));
  59500         }
  59501         BCM_IF_ERROR_RETURN(
  59502             soc_td3_port_asf_init(unit, port, speed, asf_mode));
  59503     }
  59504     BCM_IF_ERROR_RETURN(soc_td3_asf_init_done(unit));
  59505 
  59506     return BCM_E_NONE;
  59507 }
  59508 
  59509 STATIC int
  59510 _bcm_esw_td3_port_asf_mode_set(
  59511     int         unit,
  59512     bcm_port_t  port,
  59513     int         mode)
  59514 {
  59515     int rv = BCM_E_NONE, speed;
  59516     soc_info_t *si;
  59517     int txp = 0, rxp = 0;
  59518     pbmp_t *pause_bmp;
  59519 
  59520     if (!(si = &SOC_INFO(unit))) {
  59521         return SOC_E_INTERNAL;
  59522     }
  59523 
  59524     pause_bmp = soc_td3_port_asf_pause_bpmp_get(unit);
  59525     if (pause_bmp == NULL) {
  59526         return BCM_E_INTERNAL;
  59527     }
  59528 
  59529     /* Update Pause for ASF mode */
  59530     if (_SOC_TD3_ASF_MODE_SAF != mode) {
  59531         /* Disable rx pause for cut through */
  59532         BCM_IF_ERROR_RETURN
  59533             (bcm_esw_port_pause_get(unit, port, &txp, &rxp));
  59534 
  59535         if (rxp) {
  59536             SOC_PBMP_PORT_ADD((*pause_bmp), port);
  59537         }
  59538         BCM_IF_ERROR_RETURN
  59539             (bcm_esw_port_pause_set(unit, port, txp, 0));
  59540 
  59541     }
  59542 
  59543     speed = si->port_init_speed[port];
  59544     if (speed == 0) {
  59545         BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed));
  59546     }
  59547     PORT_LOCK(unit);
  59548     rv = soc_td3_port_asf_mode_set(unit, port, speed, mode);
  59549     PORT_UNLOCK(unit);
  59550 
  59551     /* Update Pause for ASF mode */
  59552     if (((rv != SOC_E_NONE) && (_SOC_TD3_ASF_MODE_SAF != mode)) ||
  59553         ((rv == SOC_E_NONE) && (_SOC_TD3_ASF_MODE_SAF == mode))) {
  59554         /* restore pause */
  59555         if (SOC_PBMP_MEMBER((*pause_bmp), port)) {
  59556             BCM_IF_ERROR_RETURN
  59557                 (bcm_esw_port_pause_get(unit, port, &txp, &rxp));
  59558             BCM_IF_ERROR_RETURN
  59559                 (bcm_esw_port_pause_set(unit, port, txp, 1));
  59560             SOC_PBMP_PORT_REMOVE((*pause_bmp), port);
  59561         }
  59562     }
  59563 
  59564     return rv;
  59565 }
  59566 #endif
  59567 
  59568 #if defined(BCM_TOMAHAWK_SUPPORT)
  59569 /* ASF (Cut-thru Forwarding) */
  59570 
  59571 /**
  59572  * Function:
  59573  *      _bcm_esw_asf_init
  59574  * Purpose:
  59575  *      Initialize ASF subsystem and configure all the applicable ports
  59576  *      to the specified forwarding mode
  59577  * Parameters:
  59578  *      unit - (IN) Unit number.
  59579  *      mode - (IN) forwarding mode
  59580  * Returns:
  59581  *      BCM_E_xxx
  59582  */
  59583 STATIC int
  59584 _bcm_esw_asf_init(
  59585     int                 unit,
  59586     soc_th_asf_mode_e   asf_mode)
  59587 {
  59588     bcm_port_t port;
  59589     int        speed;
  59590     soc_info_t *si;
  59591 
  59592     if (!(si = &SOC_INFO(unit))) {
  59593         return SOC_E_INTERNAL;
  59594     }
  59595 
  59596     if (!soc_feature(unit, soc_feature_asf_multimode)) {
  59597         return BCM_E_UNAVAIL;
  59598     }
  59599 
  59600 #ifdef BCM_WARM_BOOT_SUPPORT
  59601     if (SOC_WARM_BOOT(unit)) {
  59602         /* WB recovery happens in _bcm_esw_port_wb_recover context */
  59603         return BCM_E_NONE;
  59604     }
  59605 #endif /* BCM_WARM_BOOT_SUPPORT */
  59606 
  59607 #ifdef BCM_TOMAHAWK3_SUPPORT
  59608     if (SOC_IS_TOMAHAWK3(unit)) {
  59609         return soc_th3_asf_init(unit);
  59610     } else
  59611 #endif
  59612     {
  59613         BCM_IF_ERROR_RETURN(soc_th_asf_init_start(unit));
  59614 
  59615         PBMP_ALL_ITER(unit, port) {
  59616             if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) {
  59617                 continue;
  59618             }
  59619             speed = si->port_init_speed[port];
  59620             BCM_IF_ERROR_RETURN(
  59621                 soc_th_port_asf_init(unit, port, speed, asf_mode));
  59622         }
  59623         BCM_IF_ERROR_RETURN(soc_th_asf_init_done(unit));
  59624     }
  59625 
  59626     return BCM_E_NONE;
  59627 }
  59628 
  59629 /**
  59630  * Function:
  59631  *      _bcm_esw_asf_deinit
  59632  * Purpose:
  59633  *      Deinitialize ASF subsystem and release ASF internal structures
  59634  * Parameters:
  59635  *      unit - (IN) Unit number.
  59636  * Returns:
  59637  *      BCM_E_xxx
  59638  */
  59639 STATIC int
  59640 _bcm_esw_asf_deinit(int unit)
  59641 {
  59642 #ifdef BCM_TRIDENT3_SUPPORT
  59643     if (SOC_IS_TRIDENT3X(unit)) {
  59644         return soc_td3_asf_deinit(unit);
  59645     } else
  59646 #endif
  59647 #ifdef BCM_TOMAHAWK3_SUPPORT
  59648     if (SOC_IS_TOMAHAWK3(unit)) {
  59649         return soc_th3_asf_deinit(unit);
  59650     } else
  59651 #endif
  59652     {
  59653         if (SOC_IS_TOMAHAWKX(unit)) {
  59654             return soc_th_asf_deinit(unit);
  59655         }
  59656     }
  59657 
  59658     return BCM_E_NONE;
  59659 }
  59660 
  59661 #ifdef BCM_WARM_BOOT_SUPPORT
  59662 /**
  59663  * Function:
  59664  *      bcm_esw_asf_wb_memsz_get
  59665  * Purpose:
  59666  *      Returns the WB Memory requirement from ASF subsystem
  59667  * Parameters:
  59668  *      unit - (IN) Unit number
  59669  *      mem_sz - (OUT) WB Memory required in bytes
  59670  * Returns:
  59671  *      BCM_E_xxx
  59672  */
  59673 STATIC int
  59674 _bcm_esw_asf_wb_memsz_get(
  59675     int               unit,
  59676     OUT uint32* const mem_sz,
  59677     uint16            scache_ver)
  59678 {
  59679     int rv;
  59680 
  59681     if (soc_feature(unit, soc_feature_asf_multimode)) {
  59682 #ifdef  BCM_MAVERICK2_SUPPORT 
  59683         if (SOC_IS_MAVERICK2(unit)) {
  59684             rv = soc_mv2_asf_wb_memsz_get(unit, mem_sz, scache_ver);
  59685         } else
  59686 #endif
  59687 #ifdef BCM_TRIDENT3_SUPPORT
  59688         if (SOC_IS_TRIDENT3X(unit) && !SOC_IS_MAVERICK2(unit)) {
  59689             rv = soc_td3_asf_wb_memsz_get(unit, mem_sz, scache_ver);
  59690         } else
  59691 #endif
  59692 #ifdef BCM_TOMAHAWK3_SUPPORT
  59693         if (SOC_IS_TOMAHAWK3(unit)) {
  59694             rv = soc_th3_asf_wb_memsz_get(unit, mem_sz, scache_ver);
  59695         } else
  59696 #endif
  59697         if (SOC_IS_TOMAHAWKX(unit)) {
  59698             rv = soc_th_asf_wb_memsz_get(unit, mem_sz, scache_ver);
  59699         } else {
  59700             *mem_sz = 0;
  59701             rv = BCM_E_NONE;
  59702         }
  59703     } else {
  59704         *mem_sz = 0;
  59705         rv = BCM_E_NONE;
  59706     }
  59707 
  59708     return rv;
  59709 }
  59710 
  59711 /**
  59712  * Function:
  59713  *      _bcm_esw_asf_wb_sync
  59714  * Purpose:
  59715  *      ASF Warmboot Sync
  59716  * Parameters:
  59717  *      unit - (IN) Unit number
  59718  *      wb_data - (IN/OUT) ptr to ASF WB data area
  59719  * Returns:
  59720  *      BCM_E_xxx
  59721  */
  59722 STATIC int
  59723 _bcm_esw_asf_wb_sync(
  59724     int    unit,
  59725     IN_OUT uint8* wb_data)
  59726 {
  59727     int rv;
  59728 
  59729     if (soc_feature(unit, soc_feature_asf_multimode)) {
  59730 #ifdef  BCM_MAVERICK2_SUPPORT 
  59731         if (SOC_IS_MAVERICK2(unit)) {
  59732             rv = soc_mv2_asf_wb_sync(unit, wb_data);
  59733         } else
  59734 #endif
  59735 #ifdef BCM_TRIDENT3_SUPPORT
  59736         if (SOC_IS_TRIDENT3X(unit) && !SOC_IS_MAVERICK2(unit)) {
  59737             rv = soc_td3_asf_wb_sync(unit, wb_data);
  59738         } else
  59739 #endif
  59740 #ifdef BCM_TOMAHAWK3_SUPPORT
  59741         if (SOC_IS_TOMAHAWK3(unit)) {
  59742             rv = soc_th3_asf_wb_sync(unit, wb_data);
  59743         } else
  59744 #endif
  59745 
  59746         if (SOC_IS_TOMAHAWKX(unit)) {
  59747             rv = soc_th_asf_wb_sync(unit, wb_data);
  59748         } else {
  59749             rv = BCM_E_NONE;
  59750         }
  59751     } else {
  59752         rv = BCM_E_NONE;
  59753     }
  59754 
  59755     return rv;
  59756 }
  59757 
  59758 /**
  59759  * Function:
  59760  *      _bcm_esw_asf_wb_recover
  59761  * Purpose:
  59762  *      ASF Warmboot Recovery
  59763  * Parameters:
  59764  *      unit - (IN) Unit number
  59765  *      wb_data - (IN) pointer to ASF WB data area
  59766  * Returns:
  59767  *      BCM_E_xxx
  59768  */
  59769 STATIC int
  59770 _bcm_esw_asf_wb_recover(
  59771     int          unit,
  59772     uint8* const wb_data,
  59773     uint16       scache_ver)
  59774 {
  59775     int rv;
  59776 
  59777     if (soc_feature(unit, soc_feature_asf_multimode)) {
  59778 #ifdef  BCM_MAVERICK2_SUPPORT 
  59779         if (SOC_IS_MAVERICK2(unit)) {
  59780             rv = soc_mv2_asf_wb_recover(unit, wb_data, scache_ver);
  59781         } else
  59782 #endif
  59783 #ifdef BCM_TRIDENT3_SUPPORT
  59784         if (SOC_IS_TRIDENT3X(unit) && !SOC_IS_MAVERICK2(unit)) {
  59785             rv = soc_td3_asf_wb_recover(unit, wb_data, scache_ver);
  59786         } else
  59787 #endif
  59788 #ifdef BCM_TOMAHAWK3_SUPPORT
  59789         if (SOC_IS_TOMAHAWK3(unit)) {
  59790             rv = soc_th3_asf_wb_recover(unit, wb_data, scache_ver);
  59791         } else
  59792 #endif
  59793 
  59794         if (SOC_IS_TOMAHAWKX(unit)) {
  59795             rv = soc_th_asf_wb_recover(unit, wb_data, scache_ver);
  59796         } else {
  59797             rv = BCM_E_NONE;
  59798         }
  59799     } else {
  59800         rv = BCM_E_NONE;
  59801     }
  59802 
  59803     return rv;
  59804 }
  59805 #endif /* BCM_WARMBOOT_SUPPORT */
  59806 
  59807 /**
  59808  * Function:
  59809  *      bcm_esw_port_asf_mode_get
  59810  * Purpose:
  59811  *      Returns the forwarding mode configured on the specified port
  59812  * Parameters:
  59813  *      unit - (IN)  Unit number
  59814  *      port - (IN)  Logical port
  59815  *      mode - (OUT) SAF/ASF mode configured on the port
  59816  *              0=SAF, 1=ASF(Same Speed), 2=ASF(Slow to Fast)
  59817  *              3=ASF (Fast to Slow)
  59818  * Returns:
  59819  *      BCM_E_xxx
  59820  */
  59821 int
  59822 bcm_esw_port_asf_mode_get(
  59823     int              unit,
  59824     bcm_port_t       port,
  59825     OUT int* const   mode)
  59826 {
  59827     int rv = BCM_E_UNAVAIL, speed;
  59828     soc_info_t *si;
  59829 
  59830     if (!(si = &SOC_INFO(unit))) {
  59831         return SOC_E_INTERNAL;
  59832     }
  59833 
  59834     /* Make sure port module is initialized. */
  59835     PORT_INIT(unit);
  59836     if (!soc_feature(unit, soc_feature_asf_multimode)) {
  59837         return BCM_E_UNAVAIL;
  59838     }
  59839     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  59840     speed = si->port_init_speed[port];
  59841 
  59842     PORT_LOCK(unit);
  59843 #ifdef BCM_MAVERICK2_SUPPORT
  59844     if (SOC_IS_MAVERICK2(unit)) {
  59845         rv = soc_mv2_port_asf_mode_get(unit, port, speed,
  59846                (soc_mv2_asf_mode_e *) mode );
  59847     } else
  59848 #endif
  59849 #ifdef BCM_TRIDENT3_SUPPORT
  59850     if (SOC_IS_TRIDENT3X(unit)) {
  59851         rv = soc_td3_port_asf_mode_get(unit, port, speed,
  59852                                        (soc_td3_asf_mode_e *) mode);
  59853     } else
  59854 #endif
  59855 
  59856 #ifdef BCM_TOMAHAWK3_SUPPORT
  59857     if (SOC_IS_TOMAHAWK3(unit)) {
  59858         rv = soc_th3_port_asf_mode_get(unit, port, speed,
  59859                                           (soc_th3_asf_mode_t *) mode);
  59860     } else
  59861 #endif
  59862     if (SOC_IS_TOMAHAWKX(unit)) {
  59863         rv = soc_th_port_asf_mode_get(unit, port, speed,
  59864                                       (soc_th_asf_mode_e *) mode);
  59865     }
  59866     PORT_UNLOCK(unit);
  59867 
  59868     return rv;
  59869 }
  59870 
  59871 /**
  59872  * Function:
  59873  *      bcm_esw_port_asf_mode_set
  59874  * Purpose:
  59875  *      Configure specified SAF/ASF mode on the given port
  59876  * Parameters:
  59877  *      unit - (IN) Unit number
  59878  *      port - (IN) Logical port
  59879  *      mode - (IN) Forwarding mode to be configured on the port
  59880  *              0=SAF, 1=ASF(Same Speed), 2=ASF(Slow to Fast)
  59881  *              3=ASF (Fast to Slow)
  59882  * Returns:
  59883  *      BCM_E_xxx
  59884  */
  59885 int
  59886 bcm_esw_port_asf_mode_set(
  59887     int          unit,
  59888     bcm_port_t   port,
  59889     int          mode)
  59890 {
  59891     int rv = BCM_E_UNAVAIL, speed = 0;
  59892     soc_info_t *si;
  59893 #if defined(BCM_TOMAHAWK2_SUPPORT)
  59894     int txp = 0, rxp = 0;
  59895     pbmp_t *pause_bmp = NULL;
  59896 #endif /* BCM_TOMAHAWK2_SUPPORT */
  59897 
  59898     if (!(si = &SOC_INFO(unit))) {
  59899         return SOC_E_INTERNAL;
  59900     }
  59901 
  59902     /* Make sure port module is initialized. */
  59903     PORT_INIT(unit);
  59904     if (!soc_feature(unit, soc_feature_asf_multimode)) {
  59905         return BCM_E_UNAVAIL;
  59906     }
  59907     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  59908 
  59909 #if defined(BCM_TOMAHAWK2_SUPPORT)
  59910     /* Update Pause for ASF mode */
  59911     if (SOC_IS_TOMAHAWK2(unit)) {
  59912         pause_bmp = soc_th_port_asf_pause_bpmp_get(unit);
  59913         if (pause_bmp == NULL) {
  59914             return BCM_E_INTERNAL;
  59915         }
  59916 
  59917         if (_SOC_TH_ASF_MODE_SAF != mode) {
  59918             /* Disable rx pause for cut through */
  59919             BCM_IF_ERROR_RETURN
  59920                 (bcm_esw_port_pause_get(unit, port, &txp, &rxp));
  59921 
  59922             if (rxp) {
  59923                 SOC_PBMP_PORT_ADD((*pause_bmp), port);
  59924             }
  59925             BCM_IF_ERROR_RETURN
  59926                 (bcm_esw_port_pause_set(unit, port, txp, 0));
  59927         }
  59928     }
  59929 #endif /* BCM_TOMAHAWK2_SUPPORT */
  59930 
  59931 #ifdef BCM_MAVERICK2_SUPPORT
  59932     if (SOC_IS_MAVERICK2(unit)) {
  59933         rv = _bcm_esw_mv2_port_asf_mode_set(unit, port, mode);
  59934     } else
  59935 #endif
  59936 #ifdef BCM_TRIDENT3_SUPPORT
  59937     if (SOC_IS_TRIDENT3X(unit)) {
  59938         rv = _bcm_esw_td3_port_asf_mode_set(unit, port, mode);
  59939     } else
  59940 #endif
  59941 #ifdef BCM_TOMAHAWK3_SUPPORT
  59942     if(SOC_IS_TOMAHAWK3(unit)) {
  59943         if (mode >= 2) {
  59944             return BCM_E_PARAM;
  59945         }
  59946         speed = si->port_init_speed[port];
  59947         PORT_LOCK(unit);
  59948         rv = soc_th3_port_asf_mode_set(unit, port, speed, mode);
  59949         PORT_UNLOCK(unit);
  59950     } else
  59951 #endif
  59952     {
  59953     speed = si->port_init_speed[port];
  59954     PORT_LOCK(unit);
  59955     rv = soc_th_port_asf_mode_set(unit, port, speed, mode);
  59956     PORT_UNLOCK(unit);
  59957     }
  59958 
  59959 #if defined(BCM_TOMAHAWK2_SUPPORT)
  59960     /* Update Pause for ASF mode */
  59961     if (SOC_IS_TOMAHAWK2(unit)) {
  59962       if (_SOC_TH_ASF_MODE_SAF == mode) { /* SAF */
  59963             /* restore pause */
  59964             if (SOC_PBMP_MEMBER((*pause_bmp), port)) {
  59965                 BCM_IF_ERROR_RETURN
  59966                     (bcm_esw_port_pause_get(unit, port, &txp, &rxp));
  59967                 BCM_IF_ERROR_RETURN
  59968                     (bcm_esw_port_pause_set(unit, port, txp, 1));
  59969                 SOC_PBMP_PORT_REMOVE((*pause_bmp), port);
  59970             }
  59971         }
  59972     }
  59973 #endif /* BCM_TOMAHAWK2_SUPPORT */
  59974 
  59975     return rv;
  59976 }
  59977 
  59978 /**
  59979  * Function:
  59980  *      bcm_esw_asf_diag
  59981  * Purpose:
  59982  *      Dump all ASF configurations specific to the unit
  59983  * Parameters:
  59984  *      unit - (IN) Unit number
  59985  * Returns:
  59986  *      BCM_E_xxx
  59987  */
  59988 int
  59989 bcm_esw_asf_diag(int unit)
  59990 {
  59991     /* Make sure port module is initialized. */
  59992     PORT_INIT(unit);
  59993     if (!soc_feature(unit, soc_feature_asf_multimode)) {
  59994         return BCM_E_UNAVAIL;
  59995     }
  59996 
  59997 #ifdef BCM_MAVERICK2_SUPPORT
  59998     if (SOC_IS_MAVERICK2(unit)) {
  59999         return soc_mv2_asf_config_dump(unit);
  60000     } else
  60001 #endif
  60002 #ifdef BCM_TRIDENT3_SUPPORT
  60003     if (SOC_IS_TRIDENT3X(unit)) {
  60004         return soc_td3_asf_config_dump(unit);
  60005     } else
  60006 #endif
  60007 #ifdef BCM_TOMAHAWK3_SUPPORT
  60008     if(SOC_IS_TOMAHAWK3(unit)) {
  60009         return soc_th3_asf_config_dump(unit);
  60010     } else
  60011 #endif
  60012     if (SOC_IS_TOMAHAWKX(unit)) {
  60013     return soc_th_asf_config_dump(unit);
  60014 }
  60015 
  60016     return BCM_E_UNAVAIL;
  60017 }
  60018 
  60019 /**
  60020  * Function:
  60021  *      bcm_esw_port_asf_show
  60022  * Purpose:
  60023  *      Display formatted ASF information for a port
  60024  * Parameters:
  60025  *      unit - (IN) Unit number
  60026  *      port - (IN) Logical port
  60027  * Returns:
  60028  *      BCM_E_xxx
  60029  */
  60030 int
  60031 bcm_esw_port_asf_show(
  60032     int          unit,
  60033     bcm_port_t   port)
  60034 {
  60035     int speed;
  60036     soc_info_t *si;
  60037 
  60038     if (!(si = &SOC_INFO(unit))) {
  60039         return SOC_E_INTERNAL;
  60040     }
  60041 
  60042     /* Make sure port module is initialized. */
  60043     PORT_INIT(unit);
  60044     if (!soc_feature(unit, soc_feature_asf_multimode)) {
  60045         return BCM_E_UNAVAIL;
  60046     }
  60047     if(!SOC_IS_TOMAHAWK3(unit)) {
  60048     
  60049         BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed));
  60050     } else {
  60051         speed = si->port_init_speed[port];
  60052     }
  60053 #ifdef BCM_MAVERICK2_SUPPORT 
  60054     if (SOC_IS_MAVERICK2(unit)) {
  60055         return soc_mv2_port_asf_show(unit, port, speed);
  60056     } else
  60057 #endif
  60058 #ifdef BCM_TRIDENT3_SUPPORT
  60059     if (SOC_IS_TRIDENT3X(unit)) {
  60060         return soc_td3_port_asf_show(unit, port, speed);
  60061     } else
  60062 #endif
  60063 #ifdef BCM_TOMAHAWK3_SUPPORT
  60064     if(SOC_IS_TOMAHAWK3(unit)) {
  60065         return soc_th3_port_asf_show(unit, port, speed);
  60066     } else
  60067 #endif
  60068     if (SOC_IS_TOMAHAWKX(unit)) {
  60069     return soc_th_port_asf_show(unit, port, speed);
  60070 }
  60071 
  60072     return BCM_E_UNAVAIL;
  60073 }
  60074 
  60075 /**
  60076  * Function:
  60077  *      bcm_esw_port_asf_diag
  60078  * Purpose:
  60079  *      Dump all related ASF configurations for the given port
  60080  * Parameters:
  60081  *      unit - (IN) Unit number
  60082  *      port - (IN) Logical port
  60083  * Returns:
  60084  *      BCM_E_xxx
  60085  */
  60086 int
  60087 bcm_esw_port_asf_diag(
  60088     int          unit,
  60089     bcm_port_t   port)
  60090 {
  60091     int speed;
  60092     soc_info_t *si;
  60093 
  60094     if (!(si = &SOC_INFO(unit))) {
  60095         return SOC_E_INTERNAL;
  60096     }
  60097 
  60098     /* Make sure port module is initialized. */
  60099     PORT_INIT(unit);
  60100     if (!soc_feature(unit, soc_feature_asf_multimode)) {
  60101         return BCM_E_UNAVAIL;
  60102     }
  60103     if(!SOC_IS_TOMAHAWK3(unit)) {
  60104     
  60105         BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed));
  60106     } else {
  60107         speed = si->port_init_speed[port];
  60108     }
  60109 #ifdef BCM_MAVERICK2_SUPPORT
  60110     if (SOC_IS_MAVERICK2(unit)) {
  60111         return soc_mv2_port_asf_config_dump(unit, port, speed);
  60112     } else
  60113 #endif
  60114 #ifdef BCM_TRIDENT3_SUPPORT
  60115     if (SOC_IS_TRIDENT3X(unit)) {
  60116         return soc_td3_port_asf_config_dump(unit, port, speed);
  60117     } else
  60118 #endif
  60119 #ifdef BCM_TOMAHAWK3_SUPPORT
  60120     if (SOC_IS_TOMAHAWK3(unit)) {
  60121         return soc_th3_port_asf_config_dump(unit, port, speed);
  60122     } else
  60123 #endif
  60124     if (SOC_IS_TOMAHAWKX(unit)) {
  60125     return soc_th_port_asf_config_dump(unit, port, speed);
  60126 }
  60127 
  60128     return BCM_E_UNAVAIL;
  60129 }
  60130 #endif /* BCM_TOMAHAWK_SUPPORT */
  60131 
  60132 /**
  60133  * Function :
  60134  *      _bcm_esw_port_sw_info_display
  60135  * Purpose:
  60136  *      To display status of port related software structures  
  60137  * Parameters:
  60138  *      unit - (IN) Unit number
  60139  *      port - (IN) Port number
  60140  * Returns :
  60141  *      BCM_E_xxxx
  60142  * Note:
  60143  *      Implementation currently limited to KATANA2 and SABER2 ONLY
  60144  */
  60145 int
  60146 _bcm_esw_port_sw_info_display(int unit, bcm_port_t port)
  60147 {
  60148 #ifdef BCM_METROLITE_SUPPORT
  60149     if (SOC_IS_METROLITE(unit)) {
  60150         BCM_IF_ERROR_RETURN(_bcm_ml_port_sw_info_display(unit, port));
  60151     } else
  60152 #endif
  60153 #ifdef BCM_SABER2_SUPPORT
  60154     if (SOC_IS_SABER2(unit)) {
  60155         BCM_IF_ERROR_RETURN(_bcm_sb2_port_sw_info_display(unit, port));
  60156     } else
  60157 #endif
  60158 #ifdef BCM_KATANA2_SUPPORT
  60159     if (SOC_IS_KATANA2(unit)) {
  60160         BCM_IF_ERROR_RETURN(_bcm_kt2_port_sw_info_display(unit, port));
  60161     } else
  60162 #endif
  60163     {
  60164         LOG_ERROR(BSL_LS_BCM_PORT,
  60165                   (BSL_META_U(unit,
  60166                           "_bcm_esw_port_sw_info_display \
  60167                           implementation not implemented\n")));
  60168         return SOC_E_UNIT;
  60169     }
  60170    
  60171     return BCM_E_NONE;
  60172 }
  60173 
  60174 /** 
  60175  * Function :
  60176  *      _bcm_esw_port_hw_info_display
  60177  * Purpose:
  60178  *     To display status of port related harware registers.
  60179  * Parameters:
  60180  *     unit - (IN) Unit number.
  60181  *     port - (IN) Port number
  60182  * Returns:
  60183  *     BCM_E_xxxx
  60184  * Notes:
  60185  *      Implementation currently limited to KATANA2 and SABER2 ONLY
  60186  */
  60187 int 
  60188 _bcm_esw_port_hw_info_display(int unit, bcm_port_t port) 
  60189 {
  60190 #ifdef BCM_METROLITE_SUPPORT
  60191     if (SOC_IS_METROLITE(unit)) {
  60192         BCM_IF_ERROR_RETURN(_bcm_ml_port_hw_info_display(unit, port));
  60193     } else
  60194 #endif
  60195 #ifdef BCM_SABER2_SUPPORT
  60196     if (SOC_IS_SABER2(unit)) {
  60197         BCM_IF_ERROR_RETURN(_bcm_sb2_port_hw_info_display(unit, port));
  60198     } else
  60199 #endif
  60200 #ifdef BCM_KATANA2_SUPPORT
  60201     if (SOC_IS_KATANA2(unit)) {
  60202     BCM_IF_ERROR_RETURN(_bcm_kt2_port_hw_info_display(unit, port));
  60203     } else
  60204 #endif
  60205     {
  60206         LOG_ERROR(BSL_LS_BCM_PORT,
  60207                   (BSL_META_U(unit,
  60208                           "_bcm_esw_port_hw_info_display \
  60209                           implementation not implemented\n")));
  60210         return SOC_E_UNIT;
  60211     }
  60212 
  60213     return BCM_E_NONE;
  60214 }
  60215 
  60216 
  60217 /*
  60218  * Function:
  60219  *      bcm_esw_port_resource_set
  60220  * Purpose:
  60221  *      Modify the following port resources: 
  60222  *      - Logical to physical port mapping
  60223  *      - Speed
  60224  *      - Number of PHY lanes
  60225  *      - Encapsulation mode
  60226  * Parameters:
  60227  *      unit     - (IN) Unit number.
  60228  *      port     - (IN) Logical port.
  60229  *      resource - (IN) Port resource configuration.
  60230  * Returns:
  60231  *      BCM_E_XXX
  60232  */
  60233 int
  60234 bcm_esw_port_resource_set(int unit, 
  60235                           bcm_gport_t port, bcm_port_resource_t *resource)
  60236 {
  60237     int rv = BCM_E_UNAVAIL;
  60238 
  60239     PORT_INIT(unit);
  60240 
  60241     PORT_LOCK(unit);
  60242 
  60243     if (BCM_ESW_PORT_DRV(unit)!= NULL) {
  60244         if (BCM_ESW_PORT_DRV(unit)->resource_set != NULL) {
  60245             rv = BCM_ESW_PORT_DRV(unit)->resource_set(unit, port, resource);
  60246         }
  60247     }
  60248         
  60249     if (BCM_SUCCESS(rv) && (BCM_ESW_PORT_DRV(unit)->resource_status_update != NULL)) {
  60250         BCM_ESW_PORT_DRV(unit)->resource_status_update(unit, 1, resource);
  60251     } 
  60252 
  60253     PORT_UNLOCK(unit);
  60254 
  60255     return rv;
  60256 }
  60257 
  60258 
  60259 /*
  60260  * Function:
  60261  *      bcm_esw_port_resource_get
  60262  * Purpose:
  60263  *      Get the port resource configuration for the specified logical port.
  60264  * Parameters:
  60265  *      unit      - (IN) Unit number.
  60266  *      port      - (IN) Logical port.
  60267  *      resource  - (OUT) Returns port resource information.
  60268  * Returns:
  60269  *      BCM_E_XXX
  60270  */
  60271 int
  60272 bcm_esw_port_resource_get(int unit, 
  60273                           bcm_gport_t port, bcm_port_resource_t *resource)
  60274 {
  60275     int rv = BCM_E_UNAVAIL;
  60276 
  60277     PORT_INIT(unit);
  60278 
  60279     PORT_LOCK(unit);
  60280 
  60281     if (BCM_ESW_PORT_DRV(unit)!= NULL) {
  60282         if (BCM_ESW_PORT_DRV(unit)->resource_get != NULL) {
  60283             rv = BCM_ESW_PORT_DRV(unit)->resource_get(unit, port, resource);
  60284         }
  60285     }
  60286         
  60287     PORT_UNLOCK(unit);
  60288 
  60289     return rv;
  60290 }
  60291 
  60292 /*
  60293  * Function:
  60294  *      bcm_esw_port_resource_multi_set
  60295  * Purpose:
  60296  *      Modify the following port resources: 
  60297  *      - Logical to physical port mapping
  60298  *      - Speedu
  60299  *      - Number of PHY lanes
  60300  *      - Encapsulation mode
  60301  * Parameters:
  60302  *      unit     - (IN) Unit number.
  60303  *      nport    - (IN) Number of elements in array resource.
  60304  *      resource - (IN) Port resource configuration array.
  60305  * Returns:
  60306  *      BCM_E_XXX
  60307  */
  60308 int
  60309 bcm_esw_port_resource_multi_set(int unit, 
  60310                                 int nport, bcm_port_resource_t *resource)
  60311 {
  60312     int rv = BCM_E_UNAVAIL;
  60313 
  60314     PORT_INIT(unit);
  60315 
  60316     PORT_LOCK(unit);
  60317 
  60318     if (BCM_ESW_PORT_DRV(unit)!= NULL) {
  60319         if (BCM_ESW_PORT_DRV(unit)->resource_multi_set != NULL) {
  60320             rv = BCM_ESW_PORT_DRV(unit)->resource_multi_set(unit, nport,
  60321                                                             resource);
  60322         }
  60323     }
  60324         
  60325     if (BCM_SUCCESS(rv) && (BCM_ESW_PORT_DRV(unit)->resource_status_update != NULL)) {
  60326         BCM_ESW_PORT_DRV(unit)->resource_status_update(unit, nport, resource);
  60327     } 
  60328 
  60329     PORT_UNLOCK(unit);
  60330 
  60331     return rv;
  60332 }
  60333 /*
  60334  * Function:
  60335  *      bcm_esw_port_resource_speed_config_validate
  60336  * Purpose:
  60337  *      Validate the resource configuration
  60338  * Parameters:
  60339  *      unit      - (IN) Unit number.
  60340  *      resource  - (IN) Port resource information.
  60341  *      pbmp      - (OUT) Returns the affected sister ports
  60342  * Returns:
  60343  *      BCM_E_NONE - Config is honred without affecting sister ports
  60344  *      BCM_E_PARAM - Config will affect sister ports in pbmp
  60345  */
  60346 int
  60347 bcm_esw_port_resource_speed_config_validate(int unit, 
  60348                            bcm_port_resource_t *resource, bcm_pbmp_t *pbmp)
  60349 {    
  60350     int rv = BCM_E_UNAVAIL;
  60351 
  60352     /* Make sure port module is initialized. */
  60353     PORT_INIT(unit);
  60354 
  60355     /* Call Port Control module */
  60356     if (SOC_USE_PORTCTRL(unit)) {
  60357         rv = bcmi_esw_portctrl_resource_speed_config_validate(unit,
  60358                                                             resource, pbmp);
  60359     }
  60360 
  60361     return rv;
  60362 }
  60363 
  60364 /*
  60365  * Function:
  60366  *      bcm_esw_port_resource_speed_get
  60367  * Purpose:
  60368  *      Get the speed port resource configuration for the specified logical
  60369  *      port.
  60370  * Parameters:
  60371  *      unit      - (IN) Unit number.
  60372  *      port      - (IN) Logical port.
  60373  *      resource  - (OUT) Returns port resource information.
  60374  * Returns:
  60375  *      BCM_E_XXX
  60376  */
  60377 int
  60378 bcm_esw_port_resource_speed_get(int unit, 
  60379                           bcm_gport_t port, bcm_port_resource_t *resource)
  60380 {
  60381     int rv = BCM_E_UNAVAIL;
  60382 
  60383     rv = bcm_esw_port_resource_get(unit, port, resource);
  60384 
  60385     return rv;
  60386 }
  60387 
  60388 /*
  60389  * Function:
  60390  *      bcm_esw_port_resource_speed_set
  60391  * Purpose:
  60392  *      Modify the following port resources: 
  60393  *      - Speed
  60394  *      Note: The parameter for this function will be used to derive the
  60395  *            associated physical port
  60396  * Parameters:
  60397  *      unit     - (IN) Unit number.
  60398  *      gport    - (IN) Logical Port.
  60399  *      resource - (IN) Port resource configuration array.
  60400  * Returns:
  60401  *      BCM_E_XXX
  60402  */
  60403 int
  60404 bcm_esw_port_resource_speed_set(int unit, 
  60405                                 bcm_gport_t port, bcm_port_resource_t *resource)
  60406 {
  60407     int rv = BCM_E_UNAVAIL;
  60408     int lport;
  60409 
  60410     if (NULL == resource) {
  60411         return BCM_E_PARAM;
  60412     }
  60413 
  60414     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &lport));
  60415 
  60416     /* Use the passed in logical port to be consistent with port_speed_set */
  60417     resource->port = lport;
  60418 
  60419     rv = bcm_esw_port_resource_speed_multi_set(unit, 1, resource);
  60420 
  60421     return rv;
  60422 }
  60423 
  60424 /*
  60425  * Function:
  60426  *      bcm_esw_port_resource_speed_multi_set
  60427  * Purpose:
  60428  *      Modify the following port resources: 
  60429  *      - Speed
  60430  * Parameters:
  60431  *      unit     - (IN) Unit number.
  60432  *      nport    - (IN) Number of elements in array resource.
  60433  *      resource - (IN) Port resource configuration array.
  60434  * Returns:
  60435  *      BCM_E_XXX
  60436  */
  60437 int
  60438 bcm_esw_port_resource_speed_multi_set(int unit, 
  60439                                 int nport, bcm_port_resource_t *resource)
  60440 {
  60441     int i, max_speed;
  60442     pbmp_t pbm;
  60443     int *enable;
  60444     int rv = BCM_E_UNAVAIL;
  60445     
  60446     
  60447     PORT_INIT(unit);
  60448 
  60449     /* Do this check because we don't want to allocate 4 billion ints
  60450      * if there's bad input
  60451      */
  60452     if ((nport < 0) || (nport > SOC_MAX_NUM_PORTS)) {
  60453         return BCM_E_PARAM;
  60454     }
  60455 
  60456     if (resource == NULL) {
  60457         return BCM_E_PARAM;
  60458     }
  60459 
  60460     enable = sal_alloc(nport * sizeof(int), "port enable array");
  60461     if (NULL == enable) {
  60462         return BCM_E_MEMORY;
  60463     }
  60464 
  60465     /* Iterate through each entry and do some sanity checks */
  60466     for (i = 0; i < nport; i++) {
  60467         rv = (_bcm_esw_port_gport_validate(unit,
  60468                     resource[i].port, &resource[i].port));
  60469         if(!BCM_SUCCESS(rv)) {
  60470             goto speed_multi_cleanup;
  60471         }
  60472 
  60473         rv = (bcm_esw_port_speed_max(unit,resource[i].port, &max_speed));
  60474         if(!BCM_SUCCESS(rv)) {
  60475             goto speed_multi_cleanup;
  60476         }
  60477 
  60478 
  60479         if ((resource[i].speed < 0) || (resource[i].speed > max_speed)) {
  60480             if ((resource[i].speed > max_speed) &&
  60481                 !soc_feature(unit, soc_feature_flexport_based_speed_set))
  60482             rv = BCM_E_PARAM;
  60483             if(!BCM_SUCCESS(rv)) {
  60484                 goto speed_multi_cleanup;
  60485             }
  60486         }
  60487 
  60488         /*
  60489          * When performing flexport based speed changes, disable port
  60490          * first prior to affecting speed change, but keep track of whether
  60491          * the port was enabled
  60492          */
  60493         if (soc_feature(unit, soc_feature_flexport_based_speed_set) &&
  60494             !SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), resource[i].port) &&
  60495             !SOC_USE_PORTCTRL(unit)) {
  60496             rv = (bcm_esw_port_enable_get(unit,
  60497                                         resource[i].port, &enable[i]));
  60498             if(!BCM_SUCCESS(rv)) {
  60499                 goto speed_multi_cleanup;
  60500             }
  60501 
  60502             if (TRUE == enable[i]) {
  60503                 rv = (bcm_esw_port_enable_set(unit, resource[i].port, FALSE));
  60504                 if(!BCM_SUCCESS(rv)) {
  60505                     goto speed_multi_cleanup;
  60506                 }
  60507 
  60508             }
  60509         }
  60510 
  60511     }
  60512     PORT_LOCK(unit);
  60513     rv = bcmi_esw_portctrl_speed_multi_set(unit, nport, resource);
  60514     PORT_UNLOCK(unit);
  60515     if(!BCM_SUCCESS(rv)) {
  60516         goto speed_multi_cleanup;
  60517     }
  60518 
  60519     for (i = 0; i < nport; i++) {
  60520         /*
  60521          * Restore port's enable state based on what was read prior
  60522          * to setting speed
  60523          */
  60524         if (soc_feature(unit, soc_feature_flexport_based_speed_set) &&
  60525             !SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), resource[i].port) &&
  60526             !SOC_USE_PORTCTRL(unit)) {
  60527             if (TRUE == enable[i]) {
  60528                 rv = bcm_esw_port_enable_set(unit, resource[i].port, TRUE);
  60529                 if(!BCM_SUCCESS(rv)) {
  60530                     goto speed_multi_cleanup;
  60531                 }
  60532             }
  60533         }
  60534 
  60535         if (BCM_SUCCESS(rv) && !SAL_BOOT_SIMULATION) {
  60536             SOC_PBMP_CLEAR(pbm);
  60537             SOC_PBMP_PORT_ADD(pbm, resource[i].port);
  60538             (void)bcm_esw_link_change(unit, pbm);
  60539         }
  60540 
  60541         rv = _bcm_esw_port_link_delay_update(unit, resource[i].port,
  60542                                                 resource[i].speed);
  60543         if(!BCM_SUCCESS(rv)) {
  60544             goto speed_multi_cleanup;
  60545         }
  60546     }
  60547 
  60548 
  60549 speed_multi_cleanup:
  60550     if (NULL != enable) {
  60551         sal_free(enable);
  60552     }
  60553 
  60554     return rv;
  60555 }
  60556 /*
  60557  * Function:
  60558  *      bcm_esw_port_resource_traverse
  60559  * Purpose:
  60560  *      Iterates over the port resource configurations on a given
  60561  *      unit and calls user-provided callback for every entry.
  60562  * Parameters:
  60563  *      unit       - (IN) Unit number.
  60564  *      trav_fn    - (IN) Callback function to execute.
  60565  *      user_data  - (IN) Pointer to any user data.
  60566  * Returns:
  60567  *      BCM_E_XXX
  60568  */
  60569 int
  60570 bcm_esw_port_resource_traverse(int unit, 
  60571                                bcm_port_resource_traverse_cb trav_fn, 
  60572                                void *user_data)
  60573 {
  60574     int rv = BCM_E_UNAVAIL;
  60575 
  60576     PORT_INIT(unit);
  60577 
  60578     PORT_LOCK(unit);
  60579 
  60580     if (BCM_ESW_PORT_DRV(unit)!= NULL) {
  60581         if (BCM_ESW_PORT_DRV(unit)->resource_traverse != NULL) {
  60582             rv = BCM_ESW_PORT_DRV(unit)->resource_traverse(unit, trav_fn,
  60583                                                            user_data);
  60584         }
  60585     }
  60586         
  60587     PORT_UNLOCK(unit);
  60588 
  60589     return rv;
  60590 }
  60591 
  60592 /*
  60593  * Function:
  60594  *      bcm_esw_port_priority_group_mapping_set
  60595  * Purpose:
  60596  *      Assign a Priority Group for the input priority.
  60597  * Parameters:
  60598  *      unit       - (IN) device id.
  60599  *      gport     - (IN) generic port.
  60600  *      prio       - (IN) input priority.
  60601  *      priority_group  - (IN) priority group ID that the input priority mapped to.
  60602  * Returns:
  60603  *      BCM_E_XXX
  60604  */
  60605 int
  60606 bcm_esw_port_priority_group_mapping_set(int unit, bcm_gport_t gport, int prio, int priority_group)
  60607 {
  60608     int rv = BCM_E_UNAVAIL;
  60609 
  60610     PORT_INIT(unit);
  60611     if (soc_feature(unit, soc_feature_priority_flow_control)) {
  60612 #ifdef BCM_SABER2_SUPPORT
  60613         if (SOC_IS_SABER2(unit)) {
  60614             return (bcm_kt2_port_priority_group_mapping_set(unit, gport, prio, priority_group));
  60615         }
  60616 #endif
  60617 #if defined(BCM_GREYHOUND_SUPPORT)
  60618         if (soc_feature(unit, soc_feature_gh_style_pfc_config)) {
  60619             return (bcm_gh_port_priority_group_mapping_set(unit, gport, prio, priority_group));
  60620         }
  60621 #endif /* BCM_GREYHOUND_SUPPORT */
  60622 #if defined(BCM_TRIDENT3_SUPPORT)
  60623         if (SOC_IS_TRIDENT3X(unit)) {
  60624             return (bcm_td3_port_priority_group_mapping_set(unit, gport, prio,
  60625                                                             priority_group));
  60626         }
  60627 #endif /* BCM_TRIDENT3_SUPPORT */
  60628 #if defined(BCM_TRIDENT2_SUPPORT)
  60629         if (SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit) ||
  60630             SOC_IS_TITAN2X(unit)) {
  60631             return (bcm_td2_port_priority_group_mapping_set(unit, gport, prio,
  60632                                                             priority_group));
  60633         }
  60634 #endif /* BCM_TRIDENT2_SUPPORT */
  60635 #if defined(BCM_TOMAHAWK3_SUPPORT)
  60636         if (SOC_IS_TOMAHAWK3(unit)) {
  60637             return BCM_E_UNAVAIL;
  60638         }
  60639 #endif /* BCM_TOMAHAWK3_SUPPORT */
  60640 #if defined(BCM_TOMAHAWK_SUPPORT)
  60641         if (SOC_IS_TOMAHAWKX(unit)) {
  60642             return (bcm_th_port_priority_group_mapping_set(unit, gport, prio,
  60643                                                             priority_group));
  60644         }
  60645 #endif /* BCM_TOMAHAWK_SUPPORT */
  60646 #if defined(BCM_APACHE_SUPPORT)
  60647         if (SOC_IS_APACHE(unit)){
  60648             return (bcm_ap_port_priority_group_mapping_set(unit, gport, prio,
  60649                                                             priority_group));
  60650         }
  60651 #endif
  60652     }
  60653     return rv;
  60654 }
  60655 
  60656 /*
  60657  * Function:
  60658  *      bcm_esw_port_priority_group_mapping_get
  60659  * Purpose:
  60660  *      Get the assigned Priority Group ID of the input priority.
  60661  * Parameters:
  60662  *      unit       - (IN) device id.
  60663  *      gport     - (IN) generic port.
  60664  *      prio       - (IN) input priority.
  60665  *      priority_group  - (OUT) priority group ID that the input priority mapped to.
  60666  * Returns:
  60667  *      BCM_E_XXX
  60668  */
  60669 int
  60670 bcm_esw_port_priority_group_mapping_get(int unit, bcm_gport_t gport, int prio, int *priority_group)
  60671 {
  60672     int rv = BCM_E_UNAVAIL;
  60673 
  60674     PORT_INIT(unit);
  60675     if (soc_feature(unit, soc_feature_priority_flow_control)) {
  60676 #ifdef BCM_SABER2_SUPPORT
  60677         if (SOC_IS_SABER2(unit)) {
  60678             return (bcm_kt2_port_priority_group_mapping_get(unit, gport, prio, priority_group));
  60679         }
  60680 #endif
  60681 
  60682 #if defined(BCM_GREYHOUND_SUPPORT)
  60683         if (soc_feature(unit, soc_feature_gh_style_pfc_config)) {
  60684             return (bcm_gh_port_priority_group_mapping_get(unit, gport, prio, priority_group));
  60685         }
  60686 #endif /* BCM_GREYHOUND_SUPPORT */
  60687 #if defined(BCM_TRIDENT3_SUPPORT)
  60688         if (SOC_IS_TRIDENT3X(unit)) {
  60689             return (bcm_td3_port_priority_group_mapping_get(unit, gport, prio,
  60690                                                             priority_group));
  60691         }
  60692 #endif /* BCM_TRIDENT3_SUPPORT */
  60693 #if defined(BCM_TRIDENT2_SUPPORT)
  60694         if (SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit) ||
  60695             SOC_IS_TITAN2X(unit)) {
  60696             return (bcm_td2_port_priority_group_mapping_get(unit, gport, prio,
  60697                                                             priority_group));
  60698         }
  60699 #endif /* BCM_TRIDENT2_SUPPORT */
  60700 #if defined(BCM_TOMAHAWK3_SUPPORT)
  60701         if (SOC_IS_TOMAHAWK3(unit)) {
  60702             return BCM_E_UNAVAIL;
  60703         }
  60704 #endif /* BCM_TOMAHAWK3_SUPPORT */
  60705 #if defined(BCM_TOMAHAWK_SUPPORT)
  60706         if (SOC_IS_TOMAHAWKX(unit)) {
  60707             return (bcm_th_port_priority_group_mapping_get(unit, gport, prio,
  60708                                                             priority_group));
  60709         }
  60710 #endif /* BCM_TOMAHAWK_SUPPORT */
  60711 #if defined(BCM_APACHE_SUPPORT)
  60712         if (SOC_IS_APACHE(unit)) {
  60713             return (bcm_ap_port_priority_group_mapping_get(unit, gport, prio,
  60714                                                             priority_group));
  60715         }
  60716 #endif
  60717     }
  60718     return rv;
  60719 }
  60720 
  60721 /*
  60722  * Function:
  60723  *      bcm_esw_port_priority_group_config_set
  60724  * Purpose:
  60725  *      Set the port priority group configuration.
  60726  * Parameters:
  60727  *      unit       - (IN) device id.
  60728  *      gport     - (IN) generic port.
  60729  *      priority_group - (IN) priority group id.
  60730  *      prigrp_config  - (IN) structure describes port priority group configuration.
  60731  * Returns:
  60732  *      BCM_E_XXX
  60733  */
  60734 int
  60735 bcm_esw_port_priority_group_config_set(int unit, bcm_gport_t gport, int priority_group, bcm_port_priority_group_config_t *prigrp_config)
  60736 {
  60737     int rv = BCM_E_UNAVAIL;
  60738 
  60739     PORT_INIT(unit);
  60740     if (soc_feature(unit, soc_feature_priority_flow_control)) {
  60741 #if defined(BCM_GREYHOUND_SUPPORT)
  60742         if (soc_feature(unit, soc_feature_gh_style_pfc_config)) {
  60743             return (bcm_gh_port_priority_group_config_set(unit, gport, priority_group, prigrp_config));
  60744         }
  60745 #endif /* BCM_GREYHOUND_SUPPORT */
  60746 #if defined(BCM_TRIDENT3_SUPPORT)
  60747         if (SOC_IS_TRIDENT3X(unit)) {
  60748             return (bcm_td3_port_priority_group_config_set(unit, gport,
  60749                         priority_group, prigrp_config));
  60750         }
  60751 #endif /* BCM_TRIDENT3_SUPPORT */
  60752 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT)
  60753         if (SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit) ||
  60754             SOC_IS_TITAN2X(unit) || SOC_IS_MONTEREY(unit) ||
  60755             SOC_IS_APACHE(unit)) {
  60756             if (SOC_USE_PORTCTRL(unit)) {
  60757                 return bcmi_esw_portctrl_priority_group_config_set(unit, gport,
  60758                         priority_group, prigrp_config);
  60759             }
  60760             return (bcm_td2_port_priority_group_config_set(unit, gport,
  60761                         priority_group, prigrp_config));
  60762         }
  60763 #endif /* BCM_TRIDENT2_SUPPORT */
  60764 #if defined(BCM_TOMAHAWK_SUPPORT)
  60765         if (SOC_IS_TOMAHAWKX(unit) && !SOC_IS_TOMAHAWK3(unit)) {
  60766             return (bcm_th_port_priority_group_config_set(unit, gport,
  60767                         priority_group, prigrp_config));
  60768         }
  60769 #endif /* BCM_TOMAHAWK_SUPPORT */
  60770 
  60771 #if defined(BCM_TOMAHAWK3_SUPPORT)
  60772         if(SOC_IS_TOMAHAWK3(unit)) {
  60773             return (bcm_th3_port_priority_group_config_set(unit, gport,
  60774                         priority_group, prigrp_config));
  60775         }
  60776 #endif
  60777 
  60778     }
  60779     return rv;
  60780 }
  60781 
  60782 /*
  60783  * Function:
  60784  *      bcm_esw_port_priority_group_config_get
  60785  * Purpose:
  60786  *      Get the port priority group configuration.
  60787  * Parameters:
  60788  *      unit       - (IN) device id.
  60789  *      gport     - (IN) generic port.
  60790  *      priority_group - (IN) priority group id.
  60791  *      prigrp_config  - (OUT) structure describes port priority group configuration.
  60792  * Returns:
  60793  *      BCM_E_XXX
  60794  */
  60795 int
  60796 bcm_esw_port_priority_group_config_get(int unit, bcm_gport_t gport, int priority_group, bcm_port_priority_group_config_t *prigrp_config)
  60797 {
  60798     int rv = BCM_E_UNAVAIL;
  60799 
  60800     PORT_INIT(unit);
  60801     if (soc_feature(unit, soc_feature_priority_flow_control)) {
  60802 #if defined(BCM_GREYHOUND_SUPPORT)
  60803         if (soc_feature(unit, soc_feature_gh_style_pfc_config)) {
  60804             return (bcm_gh_port_priority_group_config_get(unit, gport, priority_group, prigrp_config));
  60805         }
  60806 #endif /* BCM_GREYHOUND_SUPPORT */
  60807 #if defined(BCM_TRIDENT3_SUPPORT)
  60808         if (SOC_IS_TRIDENT3X(unit)) {
  60809             return (bcm_td3_port_priority_group_config_get(unit, gport,
  60810                         priority_group, prigrp_config));
  60811         }
  60812 #endif /* BCM_TRIDENT3_SUPPORT */
  60813 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT)
  60814         if (SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit) ||
  60815             SOC_IS_TITAN2X(unit) || SOC_IS_MONTEREY(unit) ||
  60816             SOC_IS_APACHE(unit)) {
  60817             return (bcm_td2_port_priority_group_config_get(unit, gport,
  60818                         priority_group, prigrp_config));
  60819         }
  60820 #endif /* BCM_TRIDENT2_SUPPORT */
  60821 
  60822 #if defined(BCM_TOMAHAWK3_SUPPORT)
  60823         if (SOC_IS_TOMAHAWK3(unit)) {
  60824             return (bcm_th3_port_priority_group_config_get(unit, gport,
  60825                         priority_group, prigrp_config));
  60826         }
  60827 #endif /* BCM_TOMAHAWK3_SUPPORT */
  60828 
  60829 #if defined(BCM_TOMAHAWK_SUPPORT)
  60830         if (SOC_IS_TOMAHAWKX(unit)) {
  60831             return (bcm_th_port_priority_group_config_get(unit, gport,
  60832                         priority_group, prigrp_config));
  60833         }
  60834 #endif /* BCM_TOMAHAWK_SUPPORT */
  60835 
  60836     }
  60837     return rv;
  60838 }
  60839 
  60840 /*
  60841  * Function:
  60842  *      bcm_esw_port_redirect_config_t_init
  60843  * Purpose:
  60844  *      Initialize the redirection config structure
  60845  * Parameters:
  60846  *      redirect_config  - (IN) Pointer to the redirection config structure
  60847  * Returns:
  60848  *      None
  60849  */
  60850 void bcm_esw_port_redirect_config_t_init(
  60851                     bcm_port_redirect_config_t *redirect_config)
  60852 {
  60853     return;
  60854 }
  60855 
  60856 /*
  60857  * Function:
  60858  *      bcm_esw_port_redirect_set
  60859  * Purpose:
  60860  *      Configure the redirection data
  60861  * Parameters:
  60862  *      unit             - (IN) device id.
  60863  *      port             - (IN) Port number. 
  60864  *      redirect_config  - (IN) Pointer to the redirection config structure
  60865  * Returns:
  60866  *      None
  60867  */
  60868 int
  60869 bcm_esw_port_redirect_config_set(int unit, int port,
  60870                                  bcm_port_redirect_config_t *redirect_config)
  60871 {
  60872     int rv = BCM_E_UNAVAIL;
  60873 
  60874     PORT_INIT(unit);
  60875 
  60876     PORT_LOCK(unit);
  60877 
  60878     if (BCM_ESW_PORT_DRV(unit)!= NULL) {
  60879         if (BCM_ESW_PORT_DRV(unit)->port_redirect_set != NULL) {
  60880             rv = BCM_ESW_PORT_DRV(unit)->port_redirect_set(unit, port,
  60881                                                             redirect_config);
  60882         }
  60883     }
  60884 
  60885     PORT_UNLOCK(unit);
  60886 
  60887     return rv;
  60888 }
  60889 
  60890 
  60891 /*
  60892  * Function:
  60893  *      bcm_esw_port_redirect_get
  60894  * Purpose:
  60895  *      Configure the redirection data
  60896  * Parameters:
  60897  *      unit             - (IN) device id.
  60898  *      port             - (IN) Port number.
  60899  *      redirect_config  - (IN) Pointer to the redirection config structure
  60900  * Returns:
  60901  *      None
  60902  */
  60903 int
  60904 bcm_esw_port_redirect_config_get(int unit, int port,
  60905                                  bcm_port_redirect_config_t *redirect_config)
  60906 {
  60907     int rv = BCM_E_UNAVAIL;
  60908 
  60909     PORT_INIT(unit);
  60910 
  60911     PORT_LOCK(unit);
  60912 
  60913     if (BCM_ESW_PORT_DRV(unit)!= NULL) {
  60914         if (BCM_ESW_PORT_DRV(unit)->port_redirect_get != NULL) {
  60915             rv = BCM_ESW_PORT_DRV(unit)->port_redirect_get(unit, port,
  60916                                                             redirect_config);
  60917         }
  60918     }
  60919 
  60920     PORT_UNLOCK(unit);
  60921 
  60922     return rv;
  60923 }
  60924 
  60925 /*
  60926  * Function    : _bcm_esw_glp_bits_pos
  60927  * Description : Internal function to get modid, port, and trunk_id
  60928  *               from a glp
  60929  * Parameters  : (IN)  unit          - BCM device number
  60930  *               (OUT) trunk_pos     - Trunk ID position
  60931  *               (OUT) max_modid     - Max module ID bits
  60932  *               (OUT) modid_pos     - Module ID position
  60933  *               (OUT) max_port      - Max port addr bits
  60934  * Returns     : BCM_E_XXX
  60935  * Notes       : The trunkid, modid and port are used for 16 bits {T, MODID[7:0], PORT[7:0]},
  60936  *               get qualifiers for GLP related fields in FP_TCAM
  60937  */
  60938 static int
  60939 _bcm_esw_glp_bits_pos(int unit,
  60940                       uint8 *trunk_pos, uint8 *max_modid,
  60941                       uint8 *modid_pos, uint8 *max_port)
  60942 {
  60943     if ((NULL == trunk_pos) || (NULL == max_modid) || (NULL == modid_pos) ||
  60944         (NULL == max_port)) {
  60945         return BCM_E_PARAM;
  60946     }
  60947 
  60948 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_KATANA2_SUPPORT)  || \
  60949     defined(BCM_TITAN_SUPPORT)  || defined(BCM_TRIDENT_SUPPORT)  || \
  60950     defined(BCM_TITAN2_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \
  60951     defined(BCM_HELIX4_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \
  60952     defined(BCM_SABER2_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) || \
  60953     defined(BCM_APACHE_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT)
  60954     if(SOC_IS_KATANA(unit) || SOC_IS_KATANA2(unit)  ||
  60955             SOC_IS_TITAN(unit)  || SOC_IS_TRIDENT(unit)  ||
  60956             SOC_IS_TITAN2(unit) || SOC_IS_TRIDENT2(unit) ||
  60957             SOC_IS_HELIX4(unit) || SOC_IS_TRIUMPH3(unit) ||
  60958             SOC_IS_SABER2(unit) || SOC_IS_TRIDENT2PLUS(unit) ||
  60959             SOC_IS_APACHE(unit) || SOC_IS_GREYHOUND2(unit)) {
  60960         *trunk_pos = 15;
  60961         *max_modid = 0xff;
  60962         *modid_pos = 7;
  60963         *max_port  = 0x7f;
  60964     } else
  60965 #endif
  60966 #if defined(BCM_TOMAHAWK_SUPPORT)
  60967         if (SOC_IS_TOMAHAWKX(unit)) {
  60968             *trunk_pos = 16;
  60969             *max_modid = 0xff;
  60970             *modid_pos = 8;
  60971             *max_port  = 0xff;
  60972         } else
  60973 #endif
  60974 #if defined(BCM_CONQUEROR_SUPPORT) || defined(BCM_SCORPION_SUPPORT) || \
  60975     defined(BCM_SHADOW_SUPPORT)
  60976             if (SOC_IS_CONQUEROR(unit) || SOC_IS_SCORPION(unit) ||
  60977                 SOC_IS_SHADOW(unit)) {
  60978                 *trunk_pos = 14;
  60979                 *max_modid = 0xff;
  60980                 *modid_pos = 6;
  60981                 *max_port  = 0x3f;
  60982             } else
  60983 #endif
  60984 #if defined(BCM_RAPTOR_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \
  60985             defined(BCM_HAWKEYE_SUPPORT)
  60986             if (SOC_IS_RAPTOR(unit) || SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) {
  60987                 *trunk_pos = 0;
  60988                 *max_modid = 0x0;
  60989                 *modid_pos = 6;
  60990                 *max_port  = 0x3f;
  60991             } else
  60992 #endif
  60993             {
  60994                 *trunk_pos = 13;
  60995                 *max_modid = 0x7f;
  60996                 *modid_pos = 6;
  60997                 *max_port  = 0x3f;
  60998             }
  60999 
  61000     return BCM_E_NONE;
  61001 }
  61002 
  61003 /*
  61004  * Function    : _bcm_esw_glp_construct
  61005  * Description : Internal function to set GLP port
  61006  *               from modid, port, and trunk_id
  61007  * Parameters  : (IN)  unit      - BCM device number
  61008  *               (IN)  modid     - Module ID
  61009  *               (IN)  port      - Port number
  61010  *               (IN)  trunk_id  - Trunk ID
  61011  *               (OUT) glp       - is trunk + modid + port num
  61012  * Returns     : BCM_E_XXX
  61013  * Notes       : The trunkid, modid and port are used for 16 bits {T, MODID[7:0], PORT[7:0]},
  61014  *               set qualifiers for GLP related fields in FP_TCAM
  61015  */
  61016 int
  61017 _bcm_esw_glp_construct(int unit, bcm_trunk_t trunk_id,
  61018                        bcm_module_t modid, bcm_port_t port,
  61019                        bcm_gport_t *glp)
  61020 {
  61021     uint8 trunk_pos = 0;
  61022     uint8 max_modid = 0;
  61023     uint8 modid_pos = 0;
  61024     uint8 max_port  = 0;
  61025 
  61026     if (NULL == glp) {
  61027         return BCM_E_PARAM;
  61028     }
  61029 
  61030     BCM_IF_ERROR_RETURN
  61031         (_bcm_esw_glp_bits_pos(unit,
  61032                        &trunk_pos, &max_modid,
  61033                        &modid_pos, &max_port));
  61034 
  61035     if (trunk_id != BCM_TRUNK_INVALID) {
  61036         *glp = ((1 << trunk_pos) | trunk_id);
  61037     } else {
  61038         *glp = (((modid & max_modid) << modid_pos) |
  61039                    (port & max_port));
  61040     }
  61041 
  61042     return BCM_E_NONE;
  61043 }
  61044 
  61045 /*
  61046  * Function    : _bcm_esw_glp_resolve
  61047  * Description : Internal function to get modid, port, and trunk_id
  61048  *               from a glp
  61049  * Parameters  : (IN)  unit      - BCM device number
  61050  *               (IN)  glp       - trunk + modid + port num
  61051  *               (OUT) modid     - Module ID
  61052  *               (OUT) port      - Port number
  61053  *               (OUT) trunk_id  - Trunk ID
  61054  * Returns     : BCM_E_XXX
  61055  * Notes       : The trunkid, modid and port are used for 16 bits {T, MODID[7:0], PORT[7:0]},
  61056  *               get qualifiers for GLP related fields in FP_TCAM
  61057  */
  61058 int
  61059 _bcm_esw_glp_resolve(int unit, bcm_trunk_t *trunk_id,
  61060                      bcm_module_t *modid, bcm_port_t *port,
  61061                      bcm_gport_t glp)
  61062 {
  61063     uint8 trunk_pos = 0;
  61064     uint8 max_modid = 0;
  61065     uint8 modid_pos = 0;
  61066     uint8 max_port  = 0;
  61067 
  61068     if ((NULL == trunk_id) || (NULL == modid) || (NULL == port)){
  61069         return BCM_E_PARAM;
  61070     }
  61071 
  61072     BCM_IF_ERROR_RETURN
  61073         (_bcm_esw_glp_bits_pos(unit,
  61074                        &trunk_pos, &max_modid,
  61075                        &modid_pos, &max_port));
  61076 
  61077     if (glp & (1 << trunk_pos)) {
  61078         *trunk_id = (glp & ~(1 << trunk_pos));
  61079     } else {
  61080         *port = (glp & max_port);
  61081         *modid = ((glp >> modid_pos) & max_modid);
  61082     }
  61083 
  61084     return BCM_E_NONE;
  61085 }
  61086 
  61087 /*
  61088  * Function    : _bcm_esw_gport_to_glp
  61089  * Description : Internal function to set GLP port from gport
  61090  * Parameters  : (IN)  unit      - BCM device number
  61091  *               (IN)  gport     - trunk + modid + port num
  61092  *               (OUT) glp       - trunk + modid + port num
  61093  * Returns     : BCM_E_XXX
  61094  * Notes       : The glport as Eg: 16 bits {T, MODID[7:0], PORT[7:0]},
  61095  *               get qualifiers for GLP related fields in FP_TCAM
  61096  */
  61097 int
  61098 _bcm_esw_gport_to_glp(int unit, bcm_gport_t gport, bcm_gport_t *glp)
  61099 {
  61100     bcm_trunk_t  trunk_id;
  61101     bcm_module_t mod_id;
  61102     bcm_port_t   port;
  61103     int          local_id;
  61104 
  61105     if (BCM_GPORT_IS_SET(gport)) {
  61106         SOC_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, gport, &mod_id,
  61107                     &port, &trunk_id, &local_id));
  61108 
  61109         BCM_IF_ERROR_RETURN
  61110             (_bcm_esw_glp_construct(unit,
  61111                                     trunk_id, mod_id,
  61112                                     port, glp));
  61113         return BCM_E_NONE;
  61114     }
  61115 
  61116     return BCM_E_PARAM;
  61117 }
  61118 
  61119 /*
  61120  * Function:
  61121  *      bcmi_esw_port_eee_cfg_get
  61122  * Purpose:
  61123  *      Set the eee_cfg value for given port.
  61124  * Parameters:
  61125  *      unit     - (IN) Unit number.
  61126  *      port     - (IN) Logical port, BCM format.
  61127  *      value    - (IN) Value to set.
  61128  * Returns:
  61129  *      BCM_E_XXX
  61130  * Notes:
  61131  */
  61132 int
  61133 bcmi_esw_port_eee_cfg_set(int unit, bcm_port_t port, int value)
  61134 {
  61135 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) || \
  61136     defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_SHADOW_SUPPORT) || \
  61137     defined(BCM_HURRICANE2_SUPPORT)
  61138     if ((port < 0) || (port >= SOC_MAX_NUM_PORTS)) {
  61139         return BCM_E_PORT;
  61140     }
  61141 
  61142     eee_cfg[unit][port] = value;
  61143 
  61144     return BCM_E_NONE;
  61145 #else
  61146     return BCM_E_UNAVAIL;
  61147 #endif
  61148 }
  61149 
  61150 
  61151 /*
  61152  * Function:
  61153  *      bcmi_esw_port_egr_prof_ptr_set
  61154  * Purpose:
  61155  *      Set the port_src_mod_egr_prof_ptr value for given port.
  61156  * Parameters:
  61157  *      unit          - (IN) Unit number.
  61158  *      port          - (IN) Logical port, BCM format.
  61159  *      egr_prof_ptr  - (IN) Value to set.
  61160  * Returns:
  61161  *      BCM_E_XXX
  61162  * Notes:
  61163  */
  61164 int
  61165 bcmi_esw_port_egr_prof_ptr_set(int unit, bcm_port_t port, int value)
  61166 {
  61167 #ifdef BCM_TRIUMPH2_SUPPORT
  61168     if ((port < 0) || (port >= SOC_MAX_NUM_PORTS)) {
  61169         return BCM_E_PORT;
  61170     }
  61171 
  61172     PORT_SRC_MOD_EGR_PROF_PTR(unit, port) = value;
  61173 
  61174     return BCM_E_NONE;
  61175 #else
  61176     return BCM_E_UNAVAIL;
  61177 #endif /* BCM_TRIUMPH2_SUPPORT */
  61178 }
  61179 
  61180 
  61181 /*
  61182  * Function:
  61183  *      bcmi_port_force_lb_set
  61184  * Purpose:
  61185  *      Force port into internal loopback accroding to bond options.
  61186  * Parameters:
  61187  *      unit          - (IN) Unit number.
  61188  *      port          - (IN) Logical port, BCM format.
  61189  *      egr_prof_ptr  - (IN) Value to set.
  61190  * Returns:
  61191  *      BCM_E_XXX
  61192  * Notes:
  61193  */
  61194 int
  61195 bcmi_port_force_lb_set(int unit)
  61196 {
  61197     int rv = BCM_E_UNAVAIL;
  61198 
  61199     PORT_INIT(unit);
  61200 
  61201     PORT_LOCK(unit);
  61202 
  61203     if (BCM_ESW_PORT_DRV(unit)!= NULL) {
  61204         if (BCM_ESW_PORT_DRV(unit)->force_lb_set != NULL) {
  61205             rv = BCM_ESW_PORT_DRV(unit)->force_lb_set(unit);
  61206         }
  61207     }
  61208 
  61209     PORT_UNLOCK(unit);
  61210 
  61211     return rv;
  61212 }
  61213 
  61214 /*
  61215  * Function:
  61216  *      bcm_esw_port_preemption_control_set
  61217  * Purpose:
  61218  *      Set various configurations for Preemption.
  61219  * Parameters:
  61220  *      unit         - (IN) Unit number.
  61221  *      gport        - (IN) gport id
  61222  *      type         - (IN) preemption control type defined in bcm_port_preempt_control_t
  61223  *      arg          - (IN) the preemption control value
  61224  * Returns:
  61225  *      BCM_E_XXX
  61226  * Notes:
  61227  */
  61228 int
  61229 bcm_esw_port_preemption_control_set(int unit, bcm_gport_t gport,
  61230                                     bcm_port_preempt_control_t type,
  61231                                     uint32 arg)
  61232 {
  61233     PORT_INIT(unit);
  61234 
  61235 #if defined(BCM_PREEMPTION_SUPPORT)
  61236     if (soc_feature(unit, soc_feature_preemption)) {
  61237         bcm_port_t local_port;
  61238         uint32 preempt_support;
  61239 #ifdef BCM_MONTEREY_SUPPORT
  61240         int link = BCM_PORT_LINK_STATUS_DOWN;
  61241 #endif
  61242 
  61243         BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport, &local_port));
  61244         if(!SOC_PBMP_MEMBER(PBMP_E_ALL(unit), local_port)) {
  61245             /* hg port does not support preemption */
  61246             BCM_IF_ERROR_RETURN(BCM_E_UNAVAIL);
  61247         }
  61248 #ifdef BCM_MONTEREY_SUPPORT
  61249         if (SOC_IS_MONTEREY(unit)) {
  61250             if ((type == bcmPortPreemptControlVerifyTime) ||
  61251                 (type == bcmPortPreemptControlVerifyAttempts) ||
  61252                 (type == bcmPortPreemptControlVerifyEnable)) {
  61253                 return BCM_E_UNAVAIL;
  61254             }
  61255             if (type == bcmPortPreemptControlPreemptionSupport) {
  61256                 /* Intentionally supreesing return type to avoid unrelated error */
  61257                 (void)_bcm_esw_link_get(unit, local_port, &link);
  61258                 if (!arg && (link == BCM_PORT_LINK_STATUS_UP)) {
  61259                     return BCM_E_CONFIG;
  61260                 }
  61261             }
  61262         }
  61263 #endif /* BCM_MONTEREY_SUPPORT */
  61264         PORT_LOCK(unit);
  61265         switch (type) {
  61266             /*  only need set mac-related */
  61267             case bcmPortPreemptControlEnableTx:
  61268             case bcmPortPreemptControlVerifyEnable:
  61269                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  61270                     bcmi_esw_preemption_capability_get(unit,
  61271                                                        local_port,
  61272                                                        &preempt_support));
  61273                 if (0 == preempt_support) {
  61274                     /* need to enable preempt ability on this port first */
  61275                     _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(BCM_E_PARAM);
  61276                 }
  61277             /* fall-through */
  61278             case bcmPortPreemptControlVerifyTime:
  61279             case bcmPortPreemptControlVerifyAttempts:
  61280             case bcmPortPreemptControlNonFinalFragSizeRx:
  61281             case bcmPortPreemptControlFinalFragSizeRx:
  61282                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  61283                     bcmi_esw_preemption_mac_config_set(unit,
  61284                                                        local_port,
  61285                                                        type, arg));
  61286                 break;
  61287             /* only need setup chip-related */
  61288             case bcmPortPreemptControlNonFinalFragSizeTx:
  61289                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  61290                     bcmi_esw_preemption_frag_config_tx_set(unit,
  61291                                                            local_port, 0,
  61292                                                            arg));
  61293                 break;
  61294             case bcmPortPreemptControlFinalFragSizeTx:
  61295                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  61296                     bcmi_esw_preemption_frag_config_tx_set(unit,
  61297                                                            local_port, 1,
  61298                                                            arg));
  61299                 break;
  61300             case bcmPortPreemptControlHoldReqCntMode:
  61301                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  61302                     bcmi_esw_preemption_hold_request_mode_set(unit,
  61303                                                               local_port,
  61304                                                               arg));
  61305                 break;
  61306             case bcmPortPreemptControlQueueBitmap:
  61307                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  61308                     bcmi_esw_preemption_queue_bitmap_set(unit,
  61309                                                          local_port,
  61310                                                          arg));
  61311                 break;
  61312             case bcmPortPreemptControlPreemptionSupport:
  61313                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  61314                     bcmi_esw_preemption_capability_set(unit,
  61315                                                        local_port,
  61316                                                        arg));
  61317                 break;
  61318             default:
  61319                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(BCM_E_PARAM);
  61320 
  61321         }
  61322         PORT_UNLOCK(unit);
  61323         return BCM_E_NONE;
  61324     } else
  61325 #endif /* BCM_PREEMPTION_SUPPORT */
  61326     {
  61327         return BCM_E_UNAVAIL;
  61328     }
  61329 }
  61330 
  61331 
  61332 /*
  61333  * Function:
  61334  *      bcmi_esw_port_mac_type_get
  61335  * Purpose:
  61336  *      Get mactype for a given logical port
  61337  * Parameters:
  61338  *      unit         - (IN) Unit number.
  61339  *      lport        - (IN) logical port
  61340  *      type         - (OUT) mac type defined in bcmi_port_mac_type_t
  61341  * Returns:
  61342  *      BCM_E_XXX
  61343  * Notes:
  61344  */
  61345 int bcmi_esw_port_mac_type_get(int unit, bcm_port_t lport,
  61346                                bcmi_port_mac_type_t *type) {
  61347 #if defined(BCM_GREYHOUND2_SUPPORT)
  61348     if(SOC_IS_GREYHOUND2(unit)) {
  61349         return bcmi_gh2_port_mac_type_get(unit, lport, type);
  61350     } else
  61351 #endif /* BCM_GREYHOUND2_SUPPORT */
  61352     {
  61353         if (NULL == type) {
  61354             return SOC_E_PARAM;
  61355         }
  61356         *type = bcmiPortMacTypePortmode;
  61357     }
  61358     return BCM_E_NONE;
  61359 }
  61360 
  61361 /*
  61362  * Function:
  61363  *      bcm_esw_port_preemption_control_get
  61364  * Purpose:
  61365  *      Get various configurations for Preemption.
  61366  * Parameters:
  61367  *      unit         - (IN) Unit number.
  61368  *      gport        - (IN) gport id
  61369  *      type         - (IN) preemption control type defined in bcm_port_preempt_control_t
  61370  *      arg          - (OUT) the preemption control value
  61371  * Returns:
  61372  *      BCM_E_XXX
  61373  * Notes:
  61374  */
  61375 int
  61376 bcm_esw_port_preemption_control_get(int unit, bcm_gport_t gport,
  61377                                     bcm_port_preempt_control_t type, 
  61378                                     uint32 *arg)
  61379 {
  61380     PORT_INIT(unit);
  61381 
  61382 #if defined(BCM_PREEMPTION_SUPPORT)
  61383     if (soc_feature(unit, soc_feature_preemption)) {
  61384         bcm_port_t local_port;
  61385 
  61386         BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport, &local_port));
  61387         if(!SOC_PBMP_MEMBER(PBMP_E_ALL(unit), local_port)) {
  61388             /* hg port does not support preemption */
  61389             BCM_IF_ERROR_RETURN(BCM_E_UNAVAIL);
  61390         }
  61391 #ifdef BCM_MONTEREY_SUPPORT
  61392         if (SOC_IS_MONTEREY(unit)) {
  61393             if ((type == bcmPortPreemptControlVerifyTime) ||
  61394                 (type == bcmPortPreemptControlVerifyAttempts) ||
  61395                 (type == bcmPortPreemptControlVerifyEnable)) {
  61396                 return BCM_E_UNAVAIL;
  61397             }
  61398         }
  61399 #endif /* BCM_MONTEREY_SUPPORT */
  61400         PORT_LOCK(unit);
  61401         switch (type) {
  61402             /*  mac-related */
  61403             case bcmPortPreemptControlEnableTx:
  61404             case bcmPortPreemptControlVerifyEnable:
  61405             case bcmPortPreemptControlVerifyTime:
  61406             case bcmPortPreemptControlVerifyAttempts:
  61407             case bcmPortPreemptControlNonFinalFragSizeRx:
  61408             case bcmPortPreemptControlFinalFragSizeRx:
  61409                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  61410                     bcmi_esw_preemption_mac_config_get(unit,
  61411                                                        local_port,
  61412                                                        type, arg));
  61413                 break;
  61414             /* chip-related */
  61415             case bcmPortPreemptControlNonFinalFragSizeTx:
  61416                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  61417                     bcmi_esw_preemption_frag_config_tx_get(unit,
  61418                                                            local_port, 0,
  61419                                                            arg));
  61420                 break;
  61421             case bcmPortPreemptControlFinalFragSizeTx:
  61422                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  61423                     bcmi_esw_preemption_frag_config_tx_get(unit,
  61424                                                            local_port, 1,
  61425                                                            arg));
  61426                 break;
  61427             case bcmPortPreemptControlHoldReqCntMode:
  61428                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  61429                     bcmi_esw_preemption_hold_request_mode_get(unit,
  61430                                                               local_port,
  61431                                                               arg));
  61432                 break;
  61433             case bcmPortPreemptControlQueueBitmap:
  61434                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  61435                     bcmi_esw_preemption_queue_bitmap_get(unit,
  61436                                                          local_port,
  61437                                                          arg));
  61438                 break;
  61439             case bcmPortPreemptControlPreemptionSupport:
  61440                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  61441                     bcmi_esw_preemption_capability_get(unit,
  61442                                                        local_port,
  61443                                                        arg));
  61444                 break;
  61445             default:
  61446                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(BCM_E_PARAM);
  61447 
  61448         }
  61449         PORT_UNLOCK(unit);
  61450         return BCM_E_NONE;
  61451     } else
  61452 #endif /* BCM_PREEMPTION_SUPPORT */
  61453     {
  61454         return BCM_E_UNAVAIL;
  61455     }
  61456 }
  61457 
  61458 
  61459 /*
  61460  * Function:
  61461  *      bcm_esw_port_preemption_status_get
  61462  * Purpose:
  61463  *      Get the specified preemption status.
  61464  * Parameters:
  61465  *      unit         - (IN) Unit number.
  61466  *      gport        - (IN) gport id
  61467  *      type         - (IN) preemption status type defined in bcm_port_preempt_status_t
  61468  *      status       - (OUT) the preemption status
  61469  *                           For bcmPortPreemptStatusTx type, the status value
  61470  *                           defined in bcm_port_preempt_status_tx_t.
  61471  *                           For bcmPortPreemptStatusVerify type, the status value
  61472  *                           defined in bcm_port_preempt_status_verify_t.
  61473  * Returns:
  61474  *      BCM_E_XXX
  61475  * Notes:
  61476  */
  61477 int bcm_esw_port_preemption_status_get(int unit, bcm_gport_t gport,
  61478                                        bcm_port_preempt_status_t type,
  61479                                        uint32 *status)
  61480 {
  61481     PORT_INIT(unit);
  61482 
  61483 #if defined(BCM_PREEMPTION_SUPPORT)
  61484     if (soc_feature(unit, soc_feature_preemption)) {
  61485         bcm_port_t local_port;
  61486         BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport, &local_port));
  61487         PORT_LOCK(unit);
  61488         switch (type) {
  61489             case bcmPortPreemptStatusTx:
  61490                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  61491                     bcmi_esw_preemption_status_tx_get(unit, local_port,
  61492                                                       status));
  61493                 break;
  61494             case bcmPortPreemptStatusVerify:
  61495                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(
  61496                     bcmi_esw_preemption_status_verify_get(unit, local_port,
  61497                                                           status));
  61498                 break;
  61499             default:
  61500                 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(BCM_E_PARAM);
  61501         }
  61502         PORT_UNLOCK(unit);
  61503         return BCM_E_NONE;
  61504     } else
  61505 #endif /* BCM_PREEMPTION_SUPPORT */
  61506     {
  61507         return BCM_E_UNAVAIL;
  61508     }
  61509 }
  61510 
  61511 /*
  61512  * Description:
  61513  *      Enable and configure the remote module to apply E2EFC mechanism.
  61514  *      Or disable it.
  61515  * Parameter:
  61516  *      unit           - (IN) unit number
  61517  *      remote_module  - (IN) remote module id
  61518  *      mode           - (IN) selected mode
  61519  *      enable         - (IN) enable or disable selection
  61520  *      e2efc_rmod_cfg - (IN) structure containing the configuration.
  61521  *                       Ignored when enable = 0.
  61522  */
  61523 int
  61524 bcm_esw_port_e2efc_remote_module_enable_set(
  61525     int unit,
  61526     bcm_module_t remote_module,
  61527     bcm_port_e2efc_mode_t mode,
  61528     int enable,
  61529     bcm_port_e2efc_remote_module_config_t *e2efc_rmod_cfg)
  61530 {
  61531     if (e2efc_rmod_cfg == NULL) {
  61532         return BCM_E_UNAVAIL;
  61533     }
  61534 
  61535     if (soc_feature(unit, soc_feature_e2efc)) {
  61536 #if defined(BCM_GREYHOUND2_SUPPORT)
  61537         if (SOC_IS_GREYHOUND2(unit)) {
  61538             return bcmi_gh2_port_e2efc_remote_module_enable_set(unit,
  61539                                 remote_module, mode, enable, e2efc_rmod_cfg);
  61540         }
  61541 #endif /* BCM_GREYHOUND2_SUPPORT */
  61542 
  61543 #if defined(BCM_KATANA2_SUPPORT)
  61544         if (SOC_IS_KATANA2(unit)) {
  61545             return bcmi_kt2_port_e2efc_remote_module_enable_set(unit,
  61546                                 remote_module, mode, enable, e2efc_rmod_cfg);
  61547         }
  61548 #endif /* BCM_KATANA2_SUPPORT */
  61549     }
  61550 
  61551     return BCM_E_UNAVAIL;
  61552 }
  61553 
  61554 /*
  61555  * Description:
  61556  *      Get the enable mode and configuration of the remote module that
  61557  *      applies E2EFC mechanism.
  61558  * Parameter:
  61559  *      unit           - (IN) unit number
  61560  *      remote_module  - (IN) remote module id
  61561  *      mode           - (IN) selected mode
  61562  *      enable         - (OUT) enable or disable selection
  61563  *      e2efc_rmod_cfg - (OUT) structure containing the configuration.
  61564  *                       Only valid if the remote module is enabled.
  61565  */
  61566 int
  61567 bcm_esw_port_e2efc_remote_module_enable_get(
  61568     int unit,
  61569     bcm_module_t remote_module,
  61570     bcm_port_e2efc_mode_t mode,
  61571     int *enable,
  61572     bcm_port_e2efc_remote_module_config_t *e2efc_rmod_cfg)
  61573 {
  61574 
  61575     if (e2efc_rmod_cfg == NULL || enable == NULL) {
  61576         return BCM_E_UNAVAIL;
  61577     }
  61578 
  61579     if (soc_feature(unit, soc_feature_e2efc)) {
  61580 #if defined(BCM_GREYHOUND2_SUPPORT)
  61581         if (SOC_IS_GREYHOUND2(unit)) {
  61582             return bcmi_gh2_port_e2efc_remote_module_enable_get(unit,
  61583                                 remote_module, mode, enable, e2efc_rmod_cfg);
  61584         }
  61585 #endif /* BCM_GREYHOUND2_SUPPORT */
  61586 
  61587 #if defined(BCM_KATANA2_SUPPORT)
  61588         if (SOC_IS_KATANA2(unit)) {
  61589             return bcmi_kt2_port_e2efc_remote_module_enable_get(unit,
  61590                                 remote_module, mode, enable, e2efc_rmod_cfg);
  61591         }
  61592 #endif /* BCM_KATANA2_SUPPORT */
  61593     }
  61594 
  61595     return BCM_E_UNAVAIL;
  61596 }
  61597 
  61598 /*
  61599  * Description:
  61600  *      Traverse enabled remote modules that apply E2EFC mechanism.
  61601  * Parameter:
  61602  *      unit      - (IN) unit number
  61603  *      cb        - (IN) call back function to execute
  61604  *      user_data - (IN) pointer to user data
  61605 */
  61606 int
  61607 bcm_esw_port_e2efc_remote_module_traverse(
  61608     int unit,
  61609     bcm_port_e2efc_remote_module_traverse_cb cb,
  61610     void *user_data)
  61611 {
  61612     if ( user_data == NULL || cb == NULL) {
  61613         return BCM_E_PARAM;
  61614     }
  61615 
  61616     if (soc_feature(unit, soc_feature_e2efc)) {
  61617 #if defined(BCM_GREYHOUND2_SUPPORT)
  61618         if (SOC_IS_GREYHOUND2(unit)) {
  61619             return bcmi_gh2_port_e2efc_remote_module_traverse(unit, cb,
  61620                                                               user_data);
  61621         }
  61622 #endif /* BCM_GREYHOUND2_SUPPORT */
  61623 
  61624 #if defined(BCM_KATANA2_SUPPORT)
  61625         if (SOC_IS_KATANA2(unit)) {
  61626             return bcmi_kt2_port_e2efc_remote_module_traverse(unit, cb,
  61627                                                               user_data);
  61628         }
  61629 #endif /* BCM_KATANA2_SUPPORT */
  61630     }
  61631     return BCM_E_UNAVAIL;
  61632 }
  61633 
  61634 /*
  61635  * Description:
  61636  *      Add remote module-port and set configuration.
  61637  *      Return a handle id for the bcm_port_e2efc_remote_port_xxx APIs.
  61638  *      The API of remote module-port configuration is only for E2EFC
  61639  *      transmission.
  61640  * Parameter:
  61641  *      unit            - (IN) unit number
  61642  *      e2efc_rport_cfg - (IN) structure containing the configuration
  61643  *      rport_handle_id - (OUT) remote port handle id, to be used for the rest
  61644  *                        of bcm_port_e2efc_remote_port_xxx APIs
  61645  */
  61646 int
  61647 bcm_esw_port_e2efc_remote_port_add(
  61648     int unit,
  61649     bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg,
  61650     int *rport_handle_id)
  61651 {
  61652     if (e2efc_rport_cfg == NULL || rport_handle_id == NULL) {
  61653         return BCM_E_UNAVAIL;
  61654     }
  61655     if (soc_feature(unit, soc_feature_e2efc)) {
  61656 #if defined(BCM_GREYHOUND2_SUPPORT)
  61657         if (SOC_IS_GREYHOUND2(unit)) {
  61658             return bcmi_gh2_port_e2efc_remote_port_add(unit, e2efc_rport_cfg,
  61659                                                        rport_handle_id);
  61660         }
  61661 #endif /* BCM_GREYHOUND2_SUPPORT */
  61662 
  61663 #if defined(BCM_KATANA2_SUPPORT)
  61664         if (SOC_IS_KATANA2(unit)) {
  61665             return bcmi_kt2_port_e2efc_remote_port_add(unit, e2efc_rport_cfg,
  61666                                                        rport_handle_id);
  61667         }
  61668 #endif /* BCM_KATANA2_SUPPORT */
  61669     }
  61670     return BCM_E_UNAVAIL;
  61671 }
  61672 
  61673 /*
  61674  * Description:
  61675  *      Set (modify) configuration of the remote port.
  61676  * Parameter:
  61677  *      unit            - (IN) unit number
  61678  *      rport_handle_id - (IN) remote port handle id
  61679  *      e2efc_rport_cfg - (IN) structure containing the configuration
  61680  */
  61681 int
  61682 bcm_esw_port_e2efc_remote_port_set(
  61683     int unit,
  61684     int rport_handle_id,
  61685     bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg)
  61686 {
  61687     if (e2efc_rport_cfg == NULL) {
  61688         return BCM_E_UNAVAIL;
  61689     }
  61690     if (soc_feature(unit, soc_feature_e2efc)) {
  61691 #if defined(BCM_GREYHOUND2_SUPPORT)
  61692         if (SOC_IS_GREYHOUND2(unit)) {
  61693             return bcmi_gh2_port_e2efc_remote_port_set(unit, rport_handle_id,
  61694                                                        e2efc_rport_cfg);
  61695         }
  61696 #endif /* BCM_GREYHOUND2_SUPPORT */
  61697 
  61698 #if defined(BCM_KATANA2_SUPPORT)
  61699         if (SOC_IS_KATANA2(unit)) {
  61700             return bcmi_kt2_port_e2efc_remote_port_set(unit, rport_handle_id,
  61701                                                        e2efc_rport_cfg);
  61702         }
  61703 #endif /* BCM_KATANA2_SUPPORT */
  61704     }
  61705     return BCM_E_UNAVAIL;
  61706 }
  61707 
  61708 /*
  61709  * Description:
  61710  *      Get configuration of the remote port.
  61711  *      Return the remote module, remote port and configuration of the
  61712  *      handle id.
  61713  * Parameter:
  61714  *      unit            - (IN) unit number
  61715  *      rport_handle_id - (IN) remote port handle id
  61716  *      e2efc_rport_cfg - (OUT) structure containing the configuration
  61717  */
  61718 int
  61719 bcm_esw_port_e2efc_remote_port_get(
  61720     int unit,
  61721     int rport_handle_id,
  61722     bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg)
  61723 {
  61724     if (e2efc_rport_cfg == NULL) {
  61725         return BCM_E_UNAVAIL;
  61726     }
  61727     if (soc_feature(unit, soc_feature_e2efc)) {
  61728 #if defined(BCM_GREYHOUND2_SUPPORT)
  61729         if (SOC_IS_GREYHOUND2(unit)) {
  61730             return bcmi_gh2_port_e2efc_remote_port_get(unit, rport_handle_id,
  61731                                                        e2efc_rport_cfg);
  61732         }
  61733 #endif /* BCM_GREYHOUND2_SUPPORT */
  61734 
  61735 #if defined(BCM_KATANA2_SUPPORT)
  61736         if (SOC_IS_KATANA2(unit)) {
  61737             return bcmi_kt2_port_e2efc_remote_port_get(unit, rport_handle_id,
  61738                                                        e2efc_rport_cfg);
  61739         }
  61740 #endif /* BCM_KATANA2_SUPPORT */
  61741     }
  61742     return BCM_E_UNAVAIL;
  61743 }
  61744 
  61745 /*
  61746  * Description:
  61747  *      Delete remote port.
  61748  * Parameter:
  61749  *      unit            - (IN) unit number
  61750  *      rport_handle_id - (IN) remote port handle id
  61751  */
  61752 int
  61753 bcm_esw_port_e2efc_remote_port_delete(
  61754     int unit,
  61755     int rport_handle_id)
  61756 {
  61757 
  61758     if (soc_feature(unit, soc_feature_e2efc)) {
  61759 #if defined(BCM_GREYHOUND2_SUPPORT)
  61760         if (SOC_IS_GREYHOUND2(unit)) {
  61761             return bcmi_gh2_port_e2efc_remote_port_delete(unit,
  61762                                                           rport_handle_id);
  61763         }
  61764 #endif /* BCM_GREYHOUND2_SUPPORT */
  61765 
  61766 #if defined(BCM_KATANA2_SUPPORT)
  61767         if (SOC_IS_KATANA2(unit)) {
  61768             return bcmi_kt2_port_e2efc_remote_port_delete(unit,
  61769                                                           rport_handle_id);
  61770         }
  61771 #endif /* BCM_KATANA2_SUPPORT */
  61772     }
  61773     return BCM_E_UNAVAIL;
  61774 }
  61775 
  61776 /*
  61777  * Description:
  61778  *      Traverse remote ports.
  61779  * Parameter:
  61780  *      unit      - (IN) unit number
  61781  *      cb        - (IN) call back function to execute
  61782  *      user_data - (IN) pointer to user data
  61783  */
  61784 int
  61785 bcm_esw_port_e2efc_remote_port_traverse(
  61786     int unit,
  61787     bcm_port_e2efc_remote_port_traverse_cb cb,
  61788     void *user_data)
  61789 {
  61790     if ( user_data == NULL || cb == NULL) {
  61791         return BCM_E_PARAM;
  61792     }
  61793 
  61794     if (soc_feature(unit, soc_feature_e2efc)) {
  61795 #if defined(BCM_GREYHOUND2_SUPPORT)
  61796         if (SOC_IS_GREYHOUND2(unit)) {
  61797             return bcmi_gh2_port_e2efc_remote_port_traverse(unit, cb,
  61798                                                             user_data);
  61799         }
  61800 #endif /* BCM_GREYHOUND2_SUPPORT */
  61801 
  61802 #if defined(BCM_KATANA2_SUPPORT)
  61803         if (SOC_IS_KATANA2(unit)) {
  61804             return bcmi_kt2_port_e2efc_remote_port_traverse(unit, cb,
  61805                                                             user_data);
  61806         }
  61807 #endif /* BCM_KATANA2_SUPPORT */
  61808     }
  61809     return BCM_E_UNAVAIL;
  61810 }
  61811 
  61812 #ifdef SW_AUTONEG_SUPPORT
  61813 /*
  61814  * Function    : _bcm_esw_port_notify_link_down_evt
  61815  * Description : Notify Link_Down event to SW AN SM.
  61816  * Parameters  : (IN) unit      - BCM device number
  61817  *               (IN) port       - Port number
  61818  * Returns     : BCM_E_XXX
  61819  */
  61820 int
  61821 _bcm_esw_port_notify_link_down_evt(int unit, bcm_port_t port)
  61822 {
  61823     int    an_mode = 0;
  61824     int    an_enabled = 0;
  61825     int    rv = BCM_E_NONE;
  61826 
  61827     if (soc_feature(unit, soc_feature_sw_autoneg)) {
  61828         /* if the link is down notify the SW AN thread
  61829          * to restart AN if AN is enabled for the port
  61830          */
  61831         an_mode = soc_property_port_get(unit, port,
  61832                           spn_PHY_AN_C73, an_mode);
  61833 
  61834         /* phy_an_c73 value of 3 indicated MSA AN mode */
  61835         if ((an_mode == SW_AN_MODE_CL73_MSA) ||
  61836             (an_mode == SW_AN_MODE_MSA_ONLY)) {
  61837 
  61838 
  61839             rv = bcm_esw_port_autoneg_get(unit, port , &an_enabled);
  61840             if (BCM_FAILURE(rv)) {
  61841                 LOG_WARN(BSL_LS_BCM_PORT,
  61842                          (BSL_META_U(unit,
  61843                                      "u=%d p=%d AUTONEG GET FALSE rv=%d\n"),
  61844                           unit, port, rv));
  61845                 PORT_UNLOCK(unit);
  61846                 return rv;
  61847             }
  61848 
  61849             if (an_enabled) {
  61850                 /* notify the SW AN thread of link down event */
  61851                 rv = bcm_sw_an_post_event(unit, port, BCM_PORT_SW_AN_EVENT_AN_LINK_DOWN);
  61852             }
  61853 
  61854             if (BCM_FAILURE(rv)) {
  61855                 LOG_WARN(BSL_LS_BCM_PORT,
  61856                          (BSL_META_U(unit,
  61857                                      "u=%d p=%d SW AN POST EVENT FAILED rv=%d\n"),
  61858                           unit, port, rv));
  61859             }
  61860         }
  61861     }
  61862     return BCM_E_NONE;
  61863 }
  61864 #endif
  61865 
  61866 
  61867 /*
  61868  * Function:
  61869  *      bcm_esw_port_phy_tx_set
  61870  * Purpose:
  61871  *      Set port phy tx properties
  61872  * Parameters:
  61873  *      unit - StrataSwitch Unit #.
  61874  *      port - StrataSwitch port #.
  61875  *      tx   - tx properties
  61876  * Returns:
  61877  *      BCM_E_NONE
  61878  *      BCM_E_XXX
  61879  */
  61880 int
  61881 bcm_esw_port_phy_tx_set(int unit, bcm_port_t port, bcm_port_phy_tx_t *tx) {
  61882     int rv = BCM_E_UNAVAIL;
  61883 
  61884     if (NULL == tx) {
  61885         return BCM_E_PARAM;
  61886     }
  61887 
  61888     /* Make sure port module is initialized. */
  61889     PORT_INIT(unit);
  61890 
  61891     if (SOC_IS_TOMAHAWK3(unit)) {
  61892         /* Call Port Control module */
  61893         if (SOC_USE_PORTCTRL(unit)) {
  61894             rv = bcmi_esw_portctrl_phy_tx_set(unit, port, tx);
  61895         }
  61896     }
  61897 
  61898     return rv;
  61899 }
  61900 
  61901 /*
  61902  * Function:
  61903  *      bcm_esw_port_phy_tx_get
  61904  * Purpose:
  61905  *      Get port phy tx properties
  61906  * Parameters:
  61907  *      unit - StrataSwitch Unit #.
  61908  *      port - StrataSwitch port #.
  61909  *      tx   - tx properties
  61910  * Returns:
  61911  *      BCM_E_NONE
  61912  *      BCM_E_XXX
  61913  */
  61914 int
  61915 bcm_esw_port_phy_tx_get(int unit, bcm_port_t port, bcm_port_phy_tx_t *tx) {
  61916     int rv = BCM_E_UNAVAIL;
  61917 
  61918     if (NULL == tx) {
  61919         return BCM_E_PARAM;
  61920     }
  61921 
  61922     /* Make sure port module is initialized. */
  61923     PORT_INIT(unit);
  61924 
  61925     if (SOC_IS_TOMAHAWK3(unit)) {
  61926         /* Call Port Control module */
  61927         if (SOC_USE_PORTCTRL(unit)) {
  61928             rv = bcmi_esw_portctrl_phy_tx_get(unit, port, tx);
  61929         }
  61930     }
  61931 
  61932     return rv;
  61933 }
  61934 
  61935 /*
  61936  * Function:
  61937  *      bcm_esw_port_rlm_config_set
  61938  * Purpose:
  61939  *      Set port rlm config properties
  61940  * Parameters:
  61941  *      unit       - (IN) StrataSwitch Unit #.
  61942  *      port       - (IN) StrataSwitch port #.
  61943  *      rlm_config - (IN) rlm properties
  61944  *      enable     - (IN) enable or disable rlm
  61945  * Returns:
  61946  *      BCM_E_NONE
  61947  *      BCM_E_XXX
  61948  */
  61949 int
  61950 bcm_esw_port_rlm_config_set(int unit, bcm_port_t port,
  61951                             bcm_port_rlm_config_t *rlm_config, int enable) {
  61952     int rv = BCM_E_UNAVAIL;
  61953     int port_enabled = 0;
  61954     int link;
  61955 
  61956     if (NULL == rlm_config) {
  61957         return BCM_E_PARAM;
  61958     }
  61959 
  61960     /* Make sure port module is initialized. */
  61961     PORT_INIT(unit);
  61962 
  61963     /* Check for valid port */
  61964     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  61965 
  61966     if (!enable) {
  61967         /* need to disable the port first if disable RLM */
  61968         rv = bcm_esw_port_enable_set(unit, port, 0);
  61969     } else {
  61970         /*next check if the port is enabled */
  61971         rv = bcm_esw_port_enable_get(unit, port, &port_enabled);
  61972         if (!port_enabled) {
  61973             LOG_ERROR(BSL_LS_BCM_PORT,
  61974                       (BSL_META_U(unit,
  61975                                   "port %d is not enabled \n"), port));
  61976             return BCM_E_CONFIG;
  61977         }
  61978 
  61979         /* check link status */
  61980         SOC_IF_ERROR_RETURN
  61981             (bcm_esw_port_link_status_get(unit, port, &link));
  61982         if (FALSE == link) {
  61983             LOG_ERROR(BSL_LS_BCM_PORT,
  61984                       (BSL_META_U(unit,
  61985                                   "port %d link is not up \n"), port));
  61986             return BCM_E_CONFIG;
  61987         }
  61988     }
  61989 
  61990     if (SOC_IS_TOMAHAWK3(unit)) {
  61991         /* Call Port Control module */
  61992         if (SOC_USE_PORTCTRL(unit)) {
  61993             rv = bcmi_esw_portctrl_rlm_config_set(unit,
  61994                                  port,
  61995                                  rlm_config,
  61996                                  enable);
  61997         }
  61998     }
  61999 
  62000     if (!enable) {
  62001         /* need to re-enable the port after RLM is disabled */
  62002         rv = bcm_esw_port_enable_set(unit, port, 1);
  62003     }
  62004 
  62005     return rv;
  62006 }
  62007 
  62008 /*
  62009  * Function:
  62010  *      bcm_esw_port_rlm_config_get
  62011  * Purpose:
  62012  *      Get port phy tx properties
  62013  * Parameters:
  62014  *      unit       - (IN) StrataSwitch Unit #.
  62015  *      port       - (IN) StrataSwitch port #.
  62016  *      rlm_config - (OUT) rlm config properties
  62017  *      enable     - (OUT) enable/disable
  62018  * Returns:
  62019  *      BCM_E_NONE
  62020  *      BCM_E_XXX
  62021  */
  62022 int
  62023 bcm_esw_port_rlm_config_get(int unit, bcm_port_t port,
  62024                             bcm_port_rlm_config_t *rlm_config, int *enable) {
  62025     int rv = BCM_E_UNAVAIL;
  62026 
  62027     if (NULL == rlm_config) {
  62028         return BCM_E_PARAM;
  62029     }
  62030 
  62031     /* Make sure port module is initialized. */
  62032     PORT_INIT(unit);
  62033 
  62034     /* Check for valid port */
  62035     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  62036 
  62037     if (SOC_IS_TOMAHAWK3(unit)) {
  62038         /* Call Port Control module */
  62039         if (SOC_USE_PORTCTRL(unit)) {
  62040             rv = bcmi_esw_portctrl_rlm_config_get(unit,
  62041                                  port,
  62042                                  rlm_config,
  62043                                  enable);
  62044         }
  62045     }
  62046 
  62047     return rv;
  62048 }
  62049 /*
  62050  * Function:
  62051  *      bcm_esw_port_rlm_status_get
  62052  * Purpose:
  62053  *      Get port rlm status
  62054  * Parameters:
  62055  *      unit       - (IN) StrataSwitch Unit #.
  62056  *      port       - (IN) StrataSwitch port #.
  62057  *      rlm_status - (OUT) rlm config properties
  62058  * Returns:
  62059  *      BCM_E_NONE
  62060  *      BCM_E_XXX
  62061  */
  62062 int
  62063 bcm_esw_port_rlm_status_get(int unit, bcm_port_t port,
  62064                             bcm_port_rlm_status_t *rlm_status) {
  62065     int rv = BCM_E_UNAVAIL;
  62066 
  62067     if (NULL == rlm_status) {
  62068         return BCM_E_PARAM;
  62069     }
  62070 
  62071     /* Make sure port module is initialized. */
  62072     PORT_INIT(unit);
  62073 
  62074     /* Check for valid port */
  62075     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
  62076 
  62077     if (SOC_IS_TOMAHAWK3(unit)) {
  62078         /* Call Port Control module */
  62079         if (SOC_USE_PORTCTRL(unit)) {
  62080             rv = bcmi_esw_portctrl_rlm_status_get(unit,
  62081                                  port,
  62082                                  rlm_status);
  62083         }
  62084     }
  62085 
  62086     return rv;
  62087 }